aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qqmlirbuilder.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2014-12-05 16:32:56 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2015-01-08 22:08:19 +0100
commit9d7b27f5bf44a46707e6d50ebf51ecf73f91dd1b (patch)
tree69ec84f34655b892c8bc855aa9a378a4bb2716fa /src/qml/compiler/qqmlirbuilder.cpp
parentbede2a3ac794120be65fa50bfbc8ed04082c10e0 (diff)
Clean up JS .import/.pragma directive scanning
There's a scanner in QQmlJS::Lexer::scanDirectives that can parse those, so let's get rid of extra parser that operates on a string. Instead this way we can do the scanning all in one shot, avoid detaching a copy of the source code string and (most importantly) bring the parser closer to the copy in Qt Creator, which uses the directives approach to extract imports and pragma. Change-Id: Iff6eb8d91a45d8a70f383f953115692be48259de Reviewed-by: Fawzi Mohamed <fawzi.mohamed@theqtcompany.com>
Diffstat (limited to 'src/qml/compiler/qqmlirbuilder.cpp')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp285
1 files changed, 39 insertions, 246 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 07ea2a6fff..dc2389c30e 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -216,60 +216,6 @@ static void replaceWithSpace(QString &str, int idx, int n)
*data++ = space;
}
-#define CHECK_LINE if (l.tokenStartLine() != startLine) return;
-#define CHECK_TOKEN(t) if (token != QQmlJSGrammar:: t) return;
-
-static const int uriTokens[] = {
- QQmlJSGrammar::T_IDENTIFIER,
- QQmlJSGrammar::T_PROPERTY,
- QQmlJSGrammar::T_SIGNAL,
- QQmlJSGrammar::T_READONLY,
- QQmlJSGrammar::T_ON,
- QQmlJSGrammar::T_BREAK,
- QQmlJSGrammar::T_CASE,
- QQmlJSGrammar::T_CATCH,
- QQmlJSGrammar::T_CONTINUE,
- QQmlJSGrammar::T_DEFAULT,
- QQmlJSGrammar::T_DELETE,
- QQmlJSGrammar::T_DO,
- QQmlJSGrammar::T_ELSE,
- QQmlJSGrammar::T_FALSE,
- QQmlJSGrammar::T_FINALLY,
- QQmlJSGrammar::T_FOR,
- QQmlJSGrammar::T_FUNCTION,
- QQmlJSGrammar::T_IF,
- QQmlJSGrammar::T_IN,
- QQmlJSGrammar::T_INSTANCEOF,
- QQmlJSGrammar::T_NEW,
- QQmlJSGrammar::T_NULL,
- QQmlJSGrammar::T_RETURN,
- QQmlJSGrammar::T_SWITCH,
- QQmlJSGrammar::T_THIS,
- QQmlJSGrammar::T_THROW,
- QQmlJSGrammar::T_TRUE,
- QQmlJSGrammar::T_TRY,
- QQmlJSGrammar::T_TYPEOF,
- QQmlJSGrammar::T_VAR,
- QQmlJSGrammar::T_VOID,
- QQmlJSGrammar::T_WHILE,
- QQmlJSGrammar::T_CONST,
- QQmlJSGrammar::T_DEBUGGER,
- QQmlJSGrammar::T_RESERVED_WORD,
- QQmlJSGrammar::T_WITH,
-
- QQmlJSGrammar::EOF_SYMBOL
-};
-static inline bool isUriToken(int token)
-{
- const int *current = uriTokens;
- while (*current != QQmlJSGrammar::EOF_SYMBOL) {
- if (*current == token)
- return true;
- ++current;
- }
- return false;
-}
-
void Document::collectTypeReferences()
{
foreach (Object *obj, objects) {
@@ -296,198 +242,6 @@ void Document::collectTypeReferences()
}
}
-void Document::extractScriptMetaData(QString &script, QQmlJS::DiagnosticMessage *error)
-{
- Q_ASSERT(error);
-
- const QString js(QLatin1String(".js"));
- const QString library(QLatin1String("library"));
-
- QQmlJS::MemoryPool *pool = jsParserEngine.pool();
-
- QQmlJS::Lexer l(0);
- l.setCode(script, 0);
-
- int token = l.lex();
-
- while (true) {
- if (token != QQmlJSGrammar::T_DOT)
- return;
-
- int startOffset = l.tokenOffset();
- int startLine = l.tokenStartLine();
- int startColumn = l.tokenStartColumn();
-
- error->loc.startLine = startLine + 1; // 0-based, adjust to be 1-based
-
- token = l.lex();
-
- CHECK_LINE;
-
- if (token == QQmlJSGrammar::T_IMPORT) {
-
- // .import <URI> <Version> as <Identifier>
- // .import <file.js> as <Identifier>
-
- token = l.lex();
-
- CHECK_LINE;
- QV4::CompiledData::Import *import = pool->New<QV4::CompiledData::Import>();
-
- if (token == QQmlJSGrammar::T_STRING_LITERAL) {
-
- QString file = l.tokenText();
-
- if (!file.endsWith(js)) {
- error->message = QCoreApplication::translate("QQmlParser","Imported file must be a script");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- bool invalidImport = false;
-
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_AS) || (l.tokenStartLine() != startLine)) {
- invalidImport = true;
- } else {
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_IDENTIFIER) || (l.tokenStartLine() != startLine))
- invalidImport = true;
- }
-
-
- if (invalidImport) {
- error->message = QCoreApplication::translate("QQmlParser","File import requires a qualifier");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- QString importId = script.mid(l.tokenOffset(), l.tokenLength());
-
- token = l.lex();
-
- if (!importId.at(0).isUpper() || (l.tokenStartLine() == startLine)) {
- error->message = QCoreApplication::translate("QQmlParser","Invalid import qualifier");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- replaceWithSpace(script, startOffset, endOffset - startOffset);
-
- import->type = QV4::CompiledData::Import::ImportScript;
- import->uriIndex = registerString(file);
- import->qualifierIndex = registerString(importId);
- import->location.line = startLine;
- import->location.column = startColumn;
- imports << import;
- } else {
- // URI
- QString uri;
-
- while (true) {
- if (!isUriToken(token)) {
- error->message = QCoreApplication::translate("QQmlParser","Invalid module URI");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- uri.append(l.tokenText());
-
- token = l.lex();
- CHECK_LINE;
- if (token != QQmlJSGrammar::T_DOT)
- break;
-
- uri.append(QLatin1Char('.'));
-
- token = l.lex();
- CHECK_LINE;
- }
-
- if (token != QQmlJSGrammar::T_NUMERIC_LITERAL) {
- error->message = QCoreApplication::translate("QQmlParser","Module import requires a version");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- int vmaj, vmin;
- IRBuilder::extractVersion(QStringRef(&script, l.tokenOffset(), l.tokenLength()),
- &vmaj, &vmin);
-
- bool invalidImport = false;
-
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_AS) || (l.tokenStartLine() != startLine)) {
- invalidImport = true;
- } else {
- token = l.lex();
-
- if ((token != QQmlJSGrammar::T_IDENTIFIER) || (l.tokenStartLine() != startLine))
- invalidImport = true;
- }
-
-
- if (invalidImport) {
- error->message = QCoreApplication::translate("QQmlParser","Module import requires a qualifier");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- QString importId = script.mid(l.tokenOffset(), l.tokenLength());
-
- token = l.lex();
-
- if (!importId.at(0).isUpper() || (l.tokenStartLine() == startLine)) {
- error->message = QCoreApplication::translate("QQmlParser","Invalid import qualifier");
- error->loc.startColumn = l.tokenStartColumn();
- return;
- }
-
- replaceWithSpace(script, startOffset, endOffset - startOffset);
-
- import->type = QV4::CompiledData::Import::ImportLibrary;
- import->uriIndex = registerString(uri);
- import->majorVersion = vmaj;
- import->minorVersion = vmin;
- import->qualifierIndex = registerString(importId);
- import->location.line = startLine;
- import->location.column = startColumn;
- imports << import;
- }
- } else if (token == QQmlJSGrammar::T_PRAGMA) {
- token = l.lex();
-
- CHECK_TOKEN(T_IDENTIFIER);
- CHECK_LINE;
-
- QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
- int endOffset = l.tokenLength() + l.tokenOffset();
-
- if (pragmaValue == library) {
- unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary;
- replaceWithSpace(script, startOffset, endOffset - startOffset);
- } else {
- return;
- }
-
- token = l.lex();
- if (l.tokenStartLine() == startLine)
- return;
-
- } else {
- return;
- }
- }
- return;
-}
-
void Document::removeScriptPragmas(QString &script)
{
const QString pragma(QLatin1String("pragma"));
@@ -541,6 +295,45 @@ Document::Document(bool debugMode)
{
}
+ScriptDirectivesCollector::ScriptDirectivesCollector(QQmlJS::Engine *engine, QV4::Compiler::JSUnitGenerator *unitGenerator)
+ : engine(engine)
+ , jsGenerator(unitGenerator)
+ , hasPragmaLibrary(false)
+{
+}
+
+void ScriptDirectivesCollector::pragmaLibrary()
+{
+ hasPragmaLibrary = true;
+}
+
+void ScriptDirectivesCollector::importFile(const QString &jsfile, const QString &module, int lineNumber, int column)
+{
+ QV4::CompiledData::Import *import = engine->pool()->New<QV4::CompiledData::Import>();
+ import->type = QV4::CompiledData::Import::ImportScript;
+ import->uriIndex = jsGenerator->registerString(jsfile);
+ import->qualifierIndex = jsGenerator->registerString(module);
+ import->location.line = lineNumber;
+ import->location.column = column;
+ imports << import;
+}
+
+void ScriptDirectivesCollector::importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column)
+{
+ QV4::CompiledData::Import *import = engine->pool()->New<QV4::CompiledData::Import>();
+ import->type = QV4::CompiledData::Import::ImportLibrary;
+ import->uriIndex = jsGenerator->registerString(uri);
+ int vmaj;
+ int vmin;
+ IRBuilder::extractVersion(QStringRef(&version), &vmaj, &vmin);
+ import->majorVersion = vmaj;
+ import->minorVersion = vmin;
+ import->qualifierIndex = jsGenerator->registerString(module);
+ import->location.line = lineNumber;
+ import->location.column = column;
+ imports << import;
+}
+
IRBuilder::IRBuilder(const QSet<QString> &illegalNames)
: illegalNames(illegalNames)
, _object(0)