aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qmllint/findunqualified.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmllint/findunqualified.cpp')
-rw-r--r--tools/qmllint/findunqualified.cpp159
1 files changed, 35 insertions, 124 deletions
diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp
index ea28884f7b..359510f5f7 100644
--- a/tools/qmllint/findunqualified.cpp
+++ b/tools/qmllint/findunqualified.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "findunqualified.h"
+#include "importedmembersvisitor.h"
#include "scopetree.h"
#include "typedescriptionreader.h"
@@ -99,121 +100,21 @@ void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *heade
}
}
-void FindUnqualifiedIDVisitor::parseMembers(QQmlJS::AST::UiObjectMemberList *member,
- ScopeTree *scope)
-{
- using namespace QQmlJS::AST;
-
- // member should be the sole element
- Q_ASSERT(!member->next);
- Q_ASSERT(member && member->member->kind == UiObjectMember::Kind_UiObjectDefinition);
- auto definition = cast<UiObjectDefinition *>(member->member);
- auto qualifiedId = definition->qualifiedTypeNameId;
- while (qualifiedId && qualifiedId->next) {
- qualifiedId = qualifiedId->next;
- }
- scope->setSuperclassName(qualifiedId->name.toString());
- UiObjectMemberList *initMembers = definition->initializer->members;
- while (initMembers) {
- switch (initMembers->member->kind) {
- case UiObjectMember::Kind_UiArrayBinding: {
- // nothing to do
- break;
- }
- case UiObjectMember::Kind_UiEnumDeclaration: {
- // nothing to do
- break;
- }
- case UiObjectMember::Kind_UiObjectBinding: {
- // nothing to do
- break;
- }
- case UiObjectMember::Kind_UiObjectDefinition: {
- // creates nothing accessible
- break;
- }
- case UiObjectMember::Kind_UiPublicMember: {
- auto publicMember = cast<UiPublicMember *>(initMembers->member);
- switch (publicMember->type) {
- case UiPublicMember::Signal: {
- UiParameterList *param = publicMember->parameters;
- MetaMethod method;
- method.setMethodType(MetaMethod::Signal);
- method.setMethodName(publicMember->name.toString());
- while (param) {
- method.addParameter(param->name.toString(), param->type->name.toString());
- param = param->next;
- }
- scope->addMethod(method);
- break;
- }
- case UiPublicMember::Property: {
- MetaProperty prop {
- publicMember->name.toString(),
- publicMember->memberType->name.toString(),
- false,
- false,
- false,
- 0
- };
- scope->addProperty(prop);
- break;
- }
- }
- break;
- }
- case UiObjectMember::Kind_UiScriptBinding: {
- // does not create anything new, ignore
- break;
- }
- case UiObjectMember::Kind_UiSourceElement: {
- auto sourceElement = cast<UiSourceElement *>(initMembers->member);
- if (FunctionExpression *fexpr = sourceElement->sourceElement->asFunctionDefinition()) {
- MetaMethod method;
- method.setMethodName(fexpr->name.toString());
- method.setMethodType(MetaMethod::Method);
- FormalParameterList *parameters = fexpr->formals;
- while (parameters) {
- method.addParameter(parameters->element->bindingIdentifier.toString(), "");
- parameters = parameters->next;
- }
- scope->addMethod(method);
- } else if (ClassExpression *clexpr =
- sourceElement->sourceElement->asClassDefinition()) {
- const MetaProperty prop { clexpr->name.toString(), "", false, false, false, 1 };
- scope->addProperty(prop);
- } else if (cast<VariableStatement *>(sourceElement->sourceElement)) {
- // nothing to do
- } else {
- const auto loc = sourceElement->firstSourceLocation();
- m_colorOut.writeUncolored(
- "unsupportedd sourceElement at "
- + QString::fromLatin1("%1:%2: ").arg(loc.startLine).arg(loc.startColumn)
- + QString::number(sourceElement->sourceElement->kind));
- }
- break;
- }
- default: {
- m_colorOut.writeUncolored("unsupported element of kind "
- + QString::number(initMembers->member->kind));
- }
- }
- initMembers = initMembers->next;
- }
-}
-
-void FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program, ScopeTree *scope)
+ScopeTree *FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program,
+ const QString &name)
{
using namespace QQmlJS::AST;
+ ScopeTree *result = new ScopeTree(ScopeType::JSLexicalScope, name);
for (auto *statement = program->statements; statement; statement = statement->next) {
if (auto *function = cast<FunctionDeclaration *>(statement->statement)) {
MetaMethod method(function->name.toString());
method.setMethodType(MetaMethod::Method);
for (auto *parameters = function->formals; parameters; parameters = parameters->next)
method.addParameter(parameters->element->bindingIdentifier.toString(), "");
- scope->addMethod(method);
+ result->addMethod(method);
}
}
+ return result;
}
enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath };
@@ -401,42 +302,47 @@ void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString
ScopeTree *FindUnqualifiedIDVisitor::localFile2ScopeTree(const QString &filePath)
{
using namespace QQmlJS::AST;
- auto scope = new ScopeTree(ScopeType::QMLScope);
const QFileInfo info { filePath };
QString baseName = info.baseName();
- scope->setClassName(baseName.endsWith(".ui") ? baseName.chopped(3) : baseName);
- QFile file(filePath);
- if (!file.open(QFile::ReadOnly))
- return scope;
-
- QString code = file.readAll();
- file.close();
+ const QString scopeName = baseName.endsWith(".ui") ? baseName.chopped(3) : baseName;
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
const QString lowerSuffix = info.suffix().toLower();
- const bool isJavaScript = (lowerSuffix == QLatin1String("js") || lowerSuffix == QLatin1String("mjs"));
const bool isESModule = lowerSuffix == QLatin1String("mjs");
+ const bool isJavaScript = isESModule || lowerSuffix == QLatin1String("js");
+
+ QFile file(filePath);
+ if (!file.open(QFile::ReadOnly)) {
+ return new ScopeTree(isJavaScript ? ScopeType::JSLexicalScope : ScopeType::QMLScope,
+ scopeName);
+ }
+
+ QString code = file.readAll();
+ file.close();
+
lexer.setCode(code, /*line = */ 1, /*qmlMode=*/ !isJavaScript);
QQmlJS::Parser parser(&engine);
const bool success = isJavaScript ? (isESModule ? parser.parseModule()
: parser.parseProgram())
: parser.parse();
- if (!success)
- return scope;
+ if (!success) {
+ return new ScopeTree(isJavaScript ? ScopeType::JSLexicalScope : ScopeType::QMLScope,
+ scopeName);
+ }
if (!isJavaScript) {
QQmlJS::AST::UiProgram *program = parser.ast();
parseHeaders(program->headers);
- parseMembers(program->members, scope);
- } else {
- // TODO: Anything special to do with ES modules here?
- parseProgram(QQmlJS::AST::cast<QQmlJS::AST::Program *>(parser.rootNode()), scope);
+ ImportedMembersVisitor membersVisitor(&m_colorOut);
+ program->members->accept(&membersVisitor);
+ return membersVisitor.result(scopeName);
}
- return scope;
+ // TODO: Anything special to do with ES modules here?
+ return parseProgram(QQmlJS::AST::cast<QQmlJS::AST::Program *>(parser.rootNode()), scopeName);
}
void FindUnqualifiedIDVisitor::importFileOrDirectory(const QString &fileOrDirectory,
@@ -705,7 +611,9 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiPublicMember *uipm)
uipm->memberType ? uipm->memberType->name.toString() : QString(),
uipm->typeModifier == QLatin1String("list"),
!uipm->isReadonlyMember,
- false, 0);
+ false,
+ uipm->memberType ? (uipm->memberType->name == QLatin1String("alias")) : false,
+ 0);
property.setType(m_exportedName2Scope.value(property.typeName()).get());
m_currentScope->insertPropertyIdentifier(property);
return true;
@@ -882,7 +790,8 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob)
}
name.chop(1);
- MetaProperty prop(uiob->qualifiedId->name.toString(), name, false, true, true, 0);
+ MetaProperty prop(uiob->qualifiedId->name.toString(), name, false, true, true,
+ name == QLatin1String("alias"), 0);
prop.setType(m_exportedName2Scope.value(uiob->qualifiedTypeNameId->name.toString()).get());
m_currentScope->addProperty(prop);
@@ -897,7 +806,9 @@ void FindUnqualifiedIDVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob)
leaveEnvironment();
MetaProperty property(uiob->qualifiedId->name.toString(),
uiob->qualifiedTypeNameId->name.toString(),
- false, true, true, 0);
+ false, true, true,
+ uiob->qualifiedTypeNameId->name == QLatin1String("alias"),
+ 0);
property.setType(childScope);
m_currentScope->addProperty(property);
}