bool ItemReaderASTVisitor::visit(AST::UiPublicMember *ast) { PropertyDeclaration p; if (Q_UNLIKELY(ast->name.isEmpty())) throw ErrorInfo(Tr::tr("public member without name")); if (Q_UNLIKELY(ast->memberType.isEmpty())) throw ErrorInfo(Tr::tr("public member without type")); if (Q_UNLIKELY(ast->type == AST::UiPublicMember::Signal)) throw ErrorInfo(Tr::tr("public member with signal type not supported")); p.setName(ast->name.toString()); p.setType(PropertyDeclaration::propertyTypeFromString(ast->memberType.toString())); if (p.type() == PropertyDeclaration::UnknownType) { throw ErrorInfo(Tr::tr("Unknown type '%1' in property declaration.") .arg(ast->memberType.toString()), toCodeLocation(ast->typeToken)); } if (ast->typeModifier.compare(QLatin1String("list"))) { p.setFlags(p.flags() | PropertyDeclaration::ListProperty); } else if (Q_UNLIKELY(!ast->typeModifier.isEmpty())) { throw ErrorInfo(Tr::tr("public member with type modifier '%1' not supported").arg( ast->typeModifier.toString())); } m_item->m_propertyDeclarations.insert(p.name(), p); const JSSourceValuePtr value = JSSourceValue::create(); value->setFile(m_file); if (ast->statement) { handleBindingRhs(ast->statement, value); const QStringList bindingName(p.name()); checkDuplicateBinding(m_item, bindingName, ast->colonToken); } m_item->setProperty(p.name(), value); return false; }
static void convertToPropertyType_impl(const QString &pathPropertiesBaseDir, const Item *item, const PropertyDeclaration& decl, const CodeLocation &location, QScriptValue &v) { if (v.isUndefined() || v.isError()) return; QString srcDir; QString actualBaseDir; if (item && !pathPropertiesBaseDir.isEmpty()) { const VariantValueConstPtr itemSourceDir = item->variantProperty(QLatin1String("sourceDirectory")); actualBaseDir = itemSourceDir ? itemSourceDir->value().toString() : pathPropertiesBaseDir; } switch (decl.type()) { case PropertyDeclaration::UnknownType: case PropertyDeclaration::Variant: break; case PropertyDeclaration::Boolean: if (!v.isBool()) v = v.toBool(); break; case PropertyDeclaration::Integer: if (!v.isNumber()) makeTypeError(decl, location, v); break; case PropertyDeclaration::Path: { if (!v.isString()) { makeTypeError(decl, location, v); break; } const QString srcDir = item ? overriddenSourceDirectory(item, actualBaseDir) : pathPropertiesBaseDir; if (!srcDir.isEmpty()) v = v.engine()->toScriptValue(QDir::cleanPath( FileInfo::resolvePath(srcDir, v.toString()))); break; } case PropertyDeclaration::String: if (!v.isString()) makeTypeError(decl, location, v); break; case PropertyDeclaration::PathList: srcDir = item ? overriddenSourceDirectory(item, actualBaseDir) : pathPropertiesBaseDir; // Fall-through. case PropertyDeclaration::StringList: { if (!v.isArray()) { QScriptValue x = v.engine()->newArray(1); x.setProperty(0, v); v = x; } const quint32 c = v.property(StringConstants::lengthProperty()).toUInt32(); for (quint32 i = 0; i < c; ++i) { QScriptValue elem = v.property(i); if (elem.isUndefined()) { ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' is undefined. " "String expected.").arg(i).arg(decl.name()), location); makeTypeError(error, v); break; } if (elem.isNull()) { ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' is null. " "String expected.").arg(i).arg(decl.name()), location); makeTypeError(error, v); break; } if (!elem.isString()) { ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' does not have " "string type.").arg(i).arg(decl.name()), location); makeTypeError(error, v); break; } if (srcDir.isEmpty()) continue; elem = v.engine()->toScriptValue( QDir::cleanPath(FileInfo::resolvePath(srcDir, elem.toString()))); v.setProperty(i, elem); } break; } case PropertyDeclaration::VariantList: if (!v.isArray()) { QScriptValue x = v.engine()->newArray(1); x.setProperty(0, v); v = x; } break; } }