qmllint: parse JS files for methods
Change-Id: I3888231ac82f9babd51e6332af3c5457bf3c9141 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
1cd494fbfb
commit
0989e5a2b7
|
@ -0,0 +1,3 @@
|
||||||
|
function foo() {
|
||||||
|
return "ttt"
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import QtQml 2.0
|
||||||
|
import "Methods.js" as Methods
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
objectName: Methods.foo()
|
||||||
|
}
|
|
@ -159,6 +159,7 @@ void TestQmllint::cleanQmlCode_data()
|
||||||
QTest::newRow("qmldirAndQmltypes") << QStringLiteral("qmldirAndQmltypes.qml");
|
QTest::newRow("qmldirAndQmltypes") << QStringLiteral("qmldirAndQmltypes.qml");
|
||||||
QTest::newRow("forLoop") << QStringLiteral("forLoop.qml");
|
QTest::newRow("forLoop") << QStringLiteral("forLoop.qml");
|
||||||
QTest::newRow("esmodule") << QStringLiteral("esmodule.mjs");
|
QTest::newRow("esmodule") << QStringLiteral("esmodule.mjs");
|
||||||
|
QTest::newRow("methodsInJavascript") << QStringLiteral("javascriptMethods.qml");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestQmllint::cleanQmlCode()
|
void TestQmllint::cleanQmlCode()
|
||||||
|
|
|
@ -40,6 +40,11 @@
|
||||||
#include <QtCore/qdiriterator.h>
|
#include <QtCore/qdiriterator.h>
|
||||||
#include <QtCore/qscopedvaluerollback.h>
|
#include <QtCore/qscopedvaluerollback.h>
|
||||||
|
|
||||||
|
static const QString prefixedName(const QString &prefix, const QString &name)
|
||||||
|
{
|
||||||
|
return prefix.isEmpty() ? name : (prefix + QLatin1Char('.') + name);
|
||||||
|
}
|
||||||
|
|
||||||
static QQmlDirParser createQmldirParserForFile(const QString &filename)
|
static QQmlDirParser createQmldirParserForFile(const QString &filename)
|
||||||
{
|
{
|
||||||
QFile f(filename);
|
QFile f(filename);
|
||||||
|
@ -67,6 +72,150 @@ void FindUnqualifiedIDVisitor::leaveEnvironment()
|
||||||
m_currentScope = m_currentScope->parentScope();
|
m_currentScope = m_currentScope->parentScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *header)
|
||||||
|
{
|
||||||
|
using namespace QQmlJS::AST;
|
||||||
|
|
||||||
|
while (header) {
|
||||||
|
if (auto import = cast<UiImport *>(header->headerItem)) {
|
||||||
|
if (import->version) {
|
||||||
|
QString path;
|
||||||
|
auto uri = import->importUri;
|
||||||
|
while (uri) {
|
||||||
|
path.append(uri->name);
|
||||||
|
path.append("/");
|
||||||
|
uri = uri->next;
|
||||||
|
}
|
||||||
|
path.chop(1);
|
||||||
|
QString prefix = QLatin1String("");
|
||||||
|
if (import->asToken.isValid()) {
|
||||||
|
prefix += import->importId + QLatin1Char('.');
|
||||||
|
}
|
||||||
|
importHelper(path, prefix, import->version->majorVersion,
|
||||||
|
import->version->minorVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header = header->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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->typeModifier.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)
|
||||||
|
{
|
||||||
|
using namespace QQmlJS::AST;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath };
|
enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned, BasePath };
|
||||||
|
|
||||||
QStringList completeImportPaths(const QString &uri, const QString &basePath, int vmaj, int vmin)
|
QStringList completeImportPaths(const QString &uri, const QString &basePath, int vmaj, int vmin)
|
||||||
|
@ -168,7 +317,7 @@ FindUnqualifiedIDVisitor::Import FindUnqualifiedIDVisitor::readQmldir(const QStr
|
||||||
|
|
||||||
auto mo = qmlComponents.find(it.key());
|
auto mo = qmlComponents.find(it.key());
|
||||||
if (mo == qmlComponents.end())
|
if (mo == qmlComponents.end())
|
||||||
mo = qmlComponents.insert(it.key(), localQmlFile2ScopeTree(filePath));
|
mo = qmlComponents.insert(it.key(), localFile2ScopeTree(filePath));
|
||||||
|
|
||||||
(*mo)->addExport(
|
(*mo)->addExport(
|
||||||
it.key(), reader.typeNamespace(),
|
it.key(), reader.typeNamespace(),
|
||||||
|
@ -203,11 +352,11 @@ void FindUnqualifiedIDVisitor::processImport(const QString &prefix, const FindUn
|
||||||
// add objects
|
// add objects
|
||||||
for (auto it = import.objects.begin(); it != import.objects.end(); ++it) {
|
for (auto it = import.objects.begin(); it != import.objects.end(); ++it) {
|
||||||
const auto &val = it.value();
|
const auto &val = it.value();
|
||||||
m_exportedName2Scope.insert(prefix + val->className(), val);
|
m_exportedName2Scope.insert(prefixedName(prefix, val->className()), val);
|
||||||
|
|
||||||
const auto exports = val->exports();
|
const auto exports = val->exports();
|
||||||
for (const auto &valExport : exports)
|
for (const auto &valExport : exports)
|
||||||
m_exportedName2Scope.insert(prefix + valExport.type(), val);
|
m_exportedName2Scope.insert(prefixedName(prefix, valExport.type()), val);
|
||||||
|
|
||||||
const auto enums = val->enums();
|
const auto enums = val->enums();
|
||||||
for (const auto &valEnum : enums)
|
for (const auto &valEnum : enums)
|
||||||
|
@ -248,11 +397,12 @@ void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeTree *FindUnqualifiedIDVisitor::localQmlFile2ScopeTree(const QString &filePath)
|
ScopeTree *FindUnqualifiedIDVisitor::localFile2ScopeTree(const QString &filePath)
|
||||||
{
|
{
|
||||||
using namespace QQmlJS::AST;
|
using namespace QQmlJS::AST;
|
||||||
auto scope = new ScopeTree(ScopeType::QMLScope);
|
auto scope = new ScopeTree(ScopeType::QMLScope);
|
||||||
QString baseName = QFileInfo { filePath }.baseName();
|
const QFileInfo info { filePath };
|
||||||
|
QString baseName = info.baseName();
|
||||||
scope->setClassName(baseName.endsWith(".ui") ? baseName.chopped(3) : baseName);
|
scope->setClassName(baseName.endsWith(".ui") ? baseName.chopped(3) : baseName);
|
||||||
QFile file(filePath);
|
QFile file(filePath);
|
||||||
if (!file.open(QFile::ReadOnly))
|
if (!file.open(QFile::ReadOnly))
|
||||||
|
@ -264,146 +414,48 @@ ScopeTree *FindUnqualifiedIDVisitor::localQmlFile2ScopeTree(const QString &fileP
|
||||||
QQmlJS::Engine engine;
|
QQmlJS::Engine engine;
|
||||||
QQmlJS::Lexer lexer(&engine);
|
QQmlJS::Lexer lexer(&engine);
|
||||||
|
|
||||||
lexer.setCode(code, 1, true);
|
const QString lowerSuffix = info.suffix().toLower();
|
||||||
|
const bool isJavaScript = (lowerSuffix == QLatin1String("js") || lowerSuffix == QLatin1String("mjs"));
|
||||||
|
const bool isESModule = lowerSuffix == QLatin1String("mjs");
|
||||||
|
lexer.setCode(code, /*line = */ 1, /*qmlMode=*/ !isJavaScript);
|
||||||
QQmlJS::Parser parser(&engine);
|
QQmlJS::Parser parser(&engine);
|
||||||
if (!parser.parse()) {
|
|
||||||
|
const bool success = isJavaScript ? (isESModule ? parser.parseModule()
|
||||||
|
: parser.parseProgram())
|
||||||
|
: parser.parse();
|
||||||
|
if (!success)
|
||||||
return scope;
|
return scope;
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
QQmlJS::AST::UiProgram *program = parser.ast();
|
|
||||||
auto header = program->headers;
|
|
||||||
while (header) {
|
|
||||||
if (auto import = cast<UiImport *>(header->headerItem)) {
|
|
||||||
if (import->version) {
|
|
||||||
QString path;
|
|
||||||
auto uri = import->importUri;
|
|
||||||
while (uri) {
|
|
||||||
path.append(uri->name);
|
|
||||||
path.append("/");
|
|
||||||
uri = uri->next;
|
|
||||||
}
|
|
||||||
path.chop(1);
|
|
||||||
QString prefix = QLatin1String("");
|
|
||||||
if (import->asToken.isValid()) {
|
|
||||||
prefix += import->importId + QLatin1Char('.');
|
|
||||||
}
|
|
||||||
importHelper(path, prefix, import->version->majorVersion,
|
|
||||||
import->version->minorVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
header = header->next;
|
|
||||||
}
|
|
||||||
auto member = program->members;
|
|
||||||
// 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: {
|
|
||||||
const MetaProperty property {
|
|
||||||
publicMember->name.toString(),
|
|
||||||
publicMember->typeModifier.toString(),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
scope->addProperty(property);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindUnqualifiedIDVisitor::importDirectory(const QString &directory, const QString &prefix)
|
void FindUnqualifiedIDVisitor::importFileOrDirectory(const QString &fileOrDirectory,
|
||||||
|
const QString &prefix)
|
||||||
{
|
{
|
||||||
QString dirname = directory;
|
QString name = fileOrDirectory;
|
||||||
QFileInfo info { dirname };
|
|
||||||
if (info.isRelative())
|
|
||||||
dirname = QDir(QFileInfo { m_filePath }.path()).filePath(dirname);
|
|
||||||
|
|
||||||
QDirIterator it { dirname, QStringList() << QLatin1String("*.qml"), QDir::NoFilter };
|
if (QFileInfo(name).isRelative())
|
||||||
|
name = QDir(QFileInfo { m_filePath }.path()).filePath(name);
|
||||||
|
|
||||||
|
if (QFileInfo(name).isFile()) {
|
||||||
|
m_exportedName2Scope.insert(prefix, ScopeTree::ConstPtr(localFile2ScopeTree(name)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDirIterator it { name, QStringList() << QLatin1String("*.qml"), QDir::NoFilter };
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
ScopeTree::ConstPtr scope(localQmlFile2ScopeTree(it.next()));
|
ScopeTree::ConstPtr scope(localFile2ScopeTree(it.next()));
|
||||||
if (!scope->className().isEmpty())
|
if (!scope->className().isEmpty())
|
||||||
m_exportedName2Scope.insert(prefix + scope->className(), scope);
|
m_exportedName2Scope.insert(prefixedName(prefix, scope->className()), scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +523,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiProgram *)
|
||||||
// using an empty ScopeTree
|
// using an empty ScopeTree
|
||||||
m_exportedName2Scope.insert(QFileInfo { m_filePath }.baseName(), {});
|
m_exportedName2Scope.insert(QFileInfo { m_filePath }.baseName(), {});
|
||||||
|
|
||||||
importDirectory(".", QString());
|
importFileOrDirectory(".", QString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,11 +830,11 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiImport *import)
|
||||||
// construct path
|
// construct path
|
||||||
QString prefix = QLatin1String("");
|
QString prefix = QLatin1String("");
|
||||||
if (import->asToken.isValid()) {
|
if (import->asToken.isValid()) {
|
||||||
prefix += import->importId + QLatin1Char('.');
|
prefix += import->importId;
|
||||||
}
|
}
|
||||||
auto dirname = import->fileName.toString();
|
auto dirname = import->fileName.toString();
|
||||||
if (!dirname.isEmpty())
|
if (!dirname.isEmpty())
|
||||||
importDirectory(dirname, prefix);
|
importFileOrDirectory(dirname, prefix);
|
||||||
|
|
||||||
QString path {};
|
QString path {};
|
||||||
if (!import->importId.isEmpty()) {
|
if (!import->importId.isEmpty()) {
|
||||||
|
|
|
@ -95,11 +95,15 @@ private:
|
||||||
Import readQmldir(const QString &dirname);
|
Import readQmldir(const QString &dirname);
|
||||||
void processImport(const QString &prefix, const Import &import);
|
void processImport(const QString &prefix, const Import &import);
|
||||||
|
|
||||||
ScopeTree *localQmlFile2ScopeTree(const QString &filePath);
|
ScopeTree *localFile2ScopeTree(const QString &filePath);
|
||||||
|
|
||||||
void importDirectory(const QString &directory, const QString &prefix);
|
void importFileOrDirectory(const QString &directory, const QString &prefix);
|
||||||
void importExportedNames(const QStringRef &prefix, QString name);
|
void importExportedNames(const QStringRef &prefix, QString name);
|
||||||
|
|
||||||
|
void parseHeaders(QQmlJS::AST::UiHeaderItemList *headers);
|
||||||
|
void parseMembers(QQmlJS::AST::UiObjectMemberList *members, ScopeTree *scope);
|
||||||
|
void parseProgram(QQmlJS::AST::Program *program, ScopeTree *scope);
|
||||||
|
|
||||||
void throwRecursionDepthError() override;
|
void throwRecursionDepthError() override;
|
||||||
|
|
||||||
// start block/scope handling
|
// start block/scope handling
|
||||||
|
|
Loading…
Reference in New Issue