aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/qmljs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/qmljs')
-rw-r--r--src/libs/qmljs/CMakeLists.txt53
-rw-r--r--src/libs/qmljs/parser/qmljslexer.cpp67
-rw-r--r--src/libs/qmljs/parser/qmljslexer_p.h3
-rw-r--r--src/libs/qmljs/persistenttrie.cpp1
-rw-r--r--src/libs/qmljs/persistenttrie.h1
-rw-r--r--src/libs/qmljs/qmljs-lib.pri2
-rw-r--r--src/libs/qmljs/qmljs.qbs1
-rw-r--r--src/libs/qmljs/qmljsbundle.cpp5
-rw-r--r--src/libs/qmljs/qmljsbundle.h1
-rw-r--r--src/libs/qmljs/qmljscheck.cpp59
-rw-r--r--src/libs/qmljs/qmljsdialect.cpp7
-rw-r--r--src/libs/qmljs/qmljsdialect.h14
-rw-r--r--src/libs/qmljs/qmljsdocument.cpp8
-rw-r--r--src/libs/qmljs/qmljsdocument.h1
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.cpp6
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp10
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h1
-rw-r--r--src/libs/qmljs/qmljslink.cpp5
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp14
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.h6
-rw-r--r--src/libs/qmljs/qmljsqrcparser.cpp556
-rw-r--r--src/libs/qmljs/qmljsqrcparser.h85
-rw-r--r--src/libs/qmljs/qmljsreformatter.cpp76
23 files changed, 253 insertions, 729 deletions
diff --git a/src/libs/qmljs/CMakeLists.txt b/src/libs/qmljs/CMakeLists.txt
new file mode 100644
index 0000000000..6a4ef362bc
--- /dev/null
+++ b/src/libs/qmljs/CMakeLists.txt
@@ -0,0 +1,53 @@
+add_qtc_library(qmljs
+ DEPENDS ExtensionSystem Utils
+ PUBLIC_DEPENDS CPlusPlus Qt5::Widgets Qt5::Xml LanguageUtils
+ SOURCES
+ jsoncheck.cpp jsoncheck.h
+ parser/qmldirparser.cpp parser/qmldirparser_p.h
+ parser/qmlerror.cpp parser/qmlerror.h
+ parser/qmljsast.cpp parser/qmljsast_p.h
+ parser/qmljsastfwd_p.h
+ parser/qmljsastvisitor.cpp parser/qmljsastvisitor_p.h
+ parser/qmljsengine_p.cpp parser/qmljsengine_p.h
+ parser/qmljsglobal_p.h
+ parser/qmljsgrammar.cpp parser/qmljsgrammar_p.h
+ parser/qmljskeywords_p.h
+ parser/qmljslexer.cpp parser/qmljslexer_p.h
+ parser/qmljsmemorypool_p.h
+ parser/qmljsparser.cpp parser/qmljsparser_p.h
+ persistenttrie.cpp persistenttrie.h
+ qmljs_global.h
+ qmljsbind.cpp qmljsbind.h
+ qmljsbundle.cpp qmljsbundle.h
+ qmljscheck.cpp qmljscheck.h
+ qmljscodeformatter.cpp qmljscodeformatter.h
+ qmljscompletioncontextfinder.cpp qmljscompletioncontextfinder.h
+ qmljsconstants.h
+ qmljscontext.cpp qmljscontext.h
+ qmljsdialect.cpp qmljsdialect.h
+ qmljsdocument.cpp qmljsdocument.h
+ qmljsevaluate.cpp qmljsevaluate.h
+ qmljsfindexportedcpptypes.cpp qmljsfindexportedcpptypes.h
+ qmljsicons.cpp qmljsicons.h
+ qmljsicontextpane.h
+ qmljsimportdependencies.cpp qmljsimportdependencies.h
+ qmljsindenter.cpp qmljsindenter.h
+ qmljsinterpreter.cpp qmljsinterpreter.h
+ qmljslineinfo.cpp qmljslineinfo.h
+ qmljslink.cpp qmljslink.h
+ qmljsmodelmanagerinterface.cpp qmljsmodelmanagerinterface.h
+ qmljsplugindumper.cpp qmljsplugindumper.h
+ qmljspropertyreader.cpp qmljspropertyreader.h
+ qmljsreformatter.cpp qmljsreformatter.h
+ qmljsrewriter.cpp qmljsrewriter.h
+ qmljsscanner.cpp qmljsscanner.h
+ qmljsscopeastpath.cpp qmljsscopeastpath.h
+ qmljsscopebuilder.cpp qmljsscopebuilder.h
+ qmljsscopechain.cpp qmljsscopechain.h
+ qmljssimplereader.cpp qmljssimplereader.h
+ qmljsstaticanalysismessage.cpp qmljsstaticanalysismessage.h
+ qmljstypedescriptionreader.cpp qmljstypedescriptionreader.h
+ qmljsutils.cpp qmljsutils.h
+ qmljsvalueowner.cpp qmljsvalueowner.h
+ qmljsviewercontext.cpp qmljsviewercontext.h
+)
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
index 19d367be1b..ab7a33917e 100644
--- a/src/libs/qmljs/parser/qmljslexer.cpp
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
@@ -116,6 +116,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_tokenText.reserve(1024);
_errorMessage.clear();
_tokenSpell = QStringRef();
+ _rawString = QStringRef();
_codePtr = code.unicode();
_endPtr = _codePtr + code.length();
@@ -149,13 +150,20 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
void Lexer::scanChar()
{
- unsigned sequenceLength = isLineTerminatorSequence();
+ if (_skipLinefeed) {
+ Q_ASSERT(*_codePtr == QLatin1Char('\n'));
+ ++_codePtr;
+ _skipLinefeed = false;
+ }
_char = *_codePtr++;
- if (sequenceLength == 2)
- _char = *_codePtr++;
-
++_currentColumnNumber;
+
if (isLineTerminator()) {
+ if (_char == QLatin1Char('\r')) {
+ if (_codePtr < _endPtr && *_codePtr == QLatin1Char('\n'))
+ _skipLinefeed = true;
+ _char = QLatin1Char('\n');
+ }
++_currentLineNumber;
_currentColumnNumber = 0;
}
@@ -232,6 +240,7 @@ int Lexer::lex()
again:
_tokenSpell = QStringRef();
+ _rawString = QStringRef();
_tokenKind = scanToken();
_tokenLength = _codePtr - _tokenStartPtr - 1;
@@ -807,12 +816,15 @@ int Lexer::scanString(ScanStringMode mode)
QChar quote = (mode == TemplateContinuation) ? QChar(TemplateHead) : QChar(mode);
bool multilineStringLiteral = false;
- const QChar *startCode = _codePtr;
+ const QChar *startCode = _codePtr - 1;
+ // in case we just parsed a \r, we need to reset this flag to get things working
+ // correctly in the loop below and afterwards
+ _skipLinefeed = false;
if (_engine) {
while (_codePtr <= _endPtr) {
- if (isLineTerminator() && quote != QLatin1Char('`')) {
- if (qmlMode())
+ if (isLineTerminator()) {
+ if ((quote == QLatin1Char('`') || qmlMode()))
break;
_errorCode = IllegalCharacter;
_errorMessage = QCoreApplication::translate("QmlParser", "Stray newline in string literal");
@@ -822,7 +834,8 @@ int Lexer::scanString(ScanStringMode mode)
} else if (_char == '$' && quote == QLatin1Char('`')) {
break;
} else if (_char == quote) {
- _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
+ _tokenSpell = _engine->midRef(startCode - _code.unicode(), _codePtr - startCode - 1);
+ _rawString = _tokenSpell;
scanChar();
if (quote == QLatin1Char('`'))
@@ -835,28 +848,36 @@ int Lexer::scanString(ScanStringMode mode)
else
return T_STRING_LITERAL;
}
- scanChar();
+ // don't use scanChar() here, that would transform \r sequences and the midRef() call would create the wrong result
+ _char = *_codePtr++;
+ ++_currentColumnNumber;
}
}
+ // rewind by one char, so things gets scanned correctly
+ --_codePtr;
+
_validTokenText = true;
- _tokenText.resize(0);
- startCode--;
- while (startCode != _codePtr - 1)
- _tokenText += *startCode++;
+ _tokenText = QString(startCode, _codePtr - startCode);
+
+ auto setRawString = [&](const QChar *end) {
+ QString raw(startCode, end - startCode - 1);
+ raw.replace(QLatin1String("\r\n"), QLatin1String("\n"));
+ raw.replace(QLatin1Char('\r'), QLatin1Char('\n'));
+ _rawString = _engine->newStringRef(raw);
+ };
+
+ scanChar();
while (_codePtr <= _endPtr) {
- if (unsigned sequenceLength = isLineTerminatorSequence()) {
- multilineStringLiteral = true;
- _tokenText += _char;
- if (sequenceLength == 2)
- _tokenText += *_codePtr;
- scanChar();
- } else if (_char == mode) {
+ if (_char == quote) {
scanChar();
- if (_engine)
+ if (_engine) {
_tokenSpell = _engine->newStringRef(_tokenText);
+ if (quote == QLatin1Char('`'))
+ setRawString(_codePtr - 1);
+ }
if (quote == QLatin1Char('`'))
_bracesCount = _outerTemplateBraceCount.pop();
@@ -871,8 +892,10 @@ int Lexer::scanString(ScanStringMode mode)
scanChar();
scanChar();
_bracesCount = 1;
- if (_engine)
+ if (_engine) {
_tokenSpell = _engine->newStringRef(_tokenText);
+ setRawString(_codePtr - 2);
+ }
return (mode == TemplateHead ? T_TEMPLATE_HEAD : T_TEMPLATE_MIDDLE);
} else if (_char == QLatin1Char('\\')) {
diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h
index 39128b4409..5773606c39 100644
--- a/src/libs/qmljs/parser/qmljslexer_p.h
+++ b/src/libs/qmljs/parser/qmljslexer_p.h
@@ -146,6 +146,7 @@ public:
int tokenStartColumn() const { return _tokenColumn; }
inline QStringRef tokenSpell() const { return _tokenSpell; }
+ inline QStringRef rawString() const { return _rawString; }
double tokenValue() const { return _tokenValue; }
QString tokenText() const;
@@ -198,6 +199,7 @@ private:
QString _tokenText;
QString _errorMessage;
QStringRef _tokenSpell;
+ QStringRef _rawString;
const QChar *_codePtr;
const QChar *_endPtr;
@@ -233,6 +235,7 @@ private:
bool _followsClosingBrace;
bool _delimited;
bool _qmlMode;
+ bool _skipLinefeed = false;
int _generatorLevel = 0;
bool _staticIsKeyword = false;
};
diff --git a/src/libs/qmljs/persistenttrie.cpp b/src/libs/qmljs/persistenttrie.cpp
index f3be5a48ca..08c17dd164 100644
--- a/src/libs/qmljs/persistenttrie.cpp
+++ b/src/libs/qmljs/persistenttrie.cpp
@@ -545,7 +545,6 @@ QDebug &operator<<(QDebug &dbg, const Trie &trie)
}
Trie::Trie() {}
Trie::Trie(const TrieNode::Ptr &trie) : trie(trie) {}
-Trie::Trie(const Trie &o) : trie(o.trie){}
QStringList Trie::complete(const QString &root, const QString &base,
LookupFlags flags) const
diff --git a/src/libs/qmljs/persistenttrie.h b/src/libs/qmljs/persistenttrie.h
index 35ab652967..184525b13e 100644
--- a/src/libs/qmljs/persistenttrie.h
+++ b/src/libs/qmljs/persistenttrie.h
@@ -79,7 +79,6 @@ class QMLJS_EXPORT Trie
public:
Trie();
Trie(const TrieNode::Ptr &t);
- Trie(const Trie &o);
QStringList complete(const QString &root, const QString &base = QString(),
LookupFlags flags = LookupFlags(CaseInsensitive|Partial)) const;
diff --git a/src/libs/qmljs/qmljs-lib.pri b/src/libs/qmljs/qmljs-lib.pri
index 2aa95a9f7a..47967446bf 100644
--- a/src/libs/qmljs/qmljs-lib.pri
+++ b/src/libs/qmljs/qmljs-lib.pri
@@ -36,7 +36,6 @@ HEADERS += \
$$PWD/jsoncheck.h \
$$PWD/qmljssimplereader.h \
$$PWD/persistenttrie.h \
- $$PWD/qmljsqrcparser.h \
$$PWD/qmljsconstants.h \
$$PWD/qmljsimportdependencies.h \
$$PWD/qmljsviewercontext.h \
@@ -70,7 +69,6 @@ SOURCES += \
$$PWD/jsoncheck.cpp \
$$PWD/qmljssimplereader.cpp \
$$PWD/persistenttrie.cpp \
- $$PWD/qmljsqrcparser.cpp \
$$PWD/qmljsimportdependencies.cpp \
$$PWD/qmljsviewercontext.cpp \
$$PWD/qmljsdialect.cpp
diff --git a/src/libs/qmljs/qmljs.qbs b/src/libs/qmljs/qmljs.qbs
index ddfb4c200e..a2580cab1e 100644
--- a/src/libs/qmljs/qmljs.qbs
+++ b/src/libs/qmljs/qmljs.qbs
@@ -42,7 +42,6 @@ Project {
"qmljsmodelmanagerinterface.cpp", "qmljsmodelmanagerinterface.h",
"qmljsplugindumper.cpp", "qmljsplugindumper.h",
"qmljspropertyreader.cpp", "qmljspropertyreader.h",
- "qmljsqrcparser.cpp", "qmljsqrcparser.h",
"qmljsreformatter.cpp", "qmljsreformatter.h",
"qmljsrewriter.cpp", "qmljsrewriter.h",
"qmljsscanner.cpp", "qmljsscanner.h",
diff --git a/src/libs/qmljs/qmljsbundle.cpp b/src/libs/qmljs/qmljsbundle.cpp
index ec46379f2c..9789d37492 100644
--- a/src/libs/qmljs/qmljsbundle.cpp
+++ b/src/libs/qmljs/qmljsbundle.cpp
@@ -35,11 +35,6 @@
namespace QmlJS {
typedef PersistentTrie::Trie Trie;
-QmlBundle::QmlBundle(const QmlBundle &o)
- : m_name(o.m_name), m_searchPaths(o.searchPaths()), m_installPaths(o.installPaths()),
- m_supportedImports(o.m_supportedImports), m_implicitImports(o.m_implicitImports)
-{ }
-
QmlBundle::QmlBundle()
{ }
diff --git a/src/libs/qmljs/qmljsbundle.h b/src/libs/qmljs/qmljsbundle.h
index 0bf00ab755..8057abc6d7 100644
--- a/src/libs/qmljs/qmljsbundle.h
+++ b/src/libs/qmljs/qmljsbundle.h
@@ -51,7 +51,6 @@ class QMLJS_EXPORT QmlBundle
{
typedef PersistentTrie::Trie Trie;
public:
- QmlBundle(const QmlBundle &o);
QmlBundle();
QmlBundle(const QString &name,
const Trie &searchPaths,
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index ea43a4dec8..e5243830cd 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -384,6 +384,7 @@ protected:
_possiblyUndeclaredUses.clear();
_seenNonDeclarationStatement = false;
_formalParameterNames.clear();
+ QTC_ASSERT(_block == 0, _block = 0);
}
void postVisit(Node *ast)
@@ -399,8 +400,11 @@ protected:
if (ast->name.isEmpty())
return false;
const QString &name = ast->name.toString();
- if (!_declaredFunctions.contains(name) && !_declaredVariables.contains(name))
+ if (!_declaredFunctions.contains(name)
+ && !(_declaredVariables.contains(name)
+ || _declaredBlockVariables.contains({name, _block}))) {
_possiblyUndeclaredUses[name].append(ast->identifierToken);
+ }
return false;
}
@@ -416,13 +420,26 @@ protected:
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
return true;
const QString &name = ast->bindingIdentifier.toString();
-
- if (_formalParameterNames.contains(name))
+ VariableScope scope = ast->scope;
+ if (_formalParameterNames.contains(name)) {
addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name);
- else if (_declaredFunctions.contains(name))
+ } else if (_declaredFunctions.contains(name)) {
addMessage(WarnAlreadyFunction, ast->identifierToken, name);
- else if (_declaredVariables.contains(name))
- addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
+ } else if (scope == VariableScope::Let || scope == VariableScope::Const) {
+ if (_declaredBlockVariables.contains({name, _block}))
+ addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
+ } else if (scope == VariableScope::Var) {
+ if (_declaredVariables.contains(name)) {
+ addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
+ } else {
+ for (auto k : _declaredBlockVariables.keys()) {
+ if (k.first == name) {
+ addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
+ break;
+ }
+ }
+ }
+ }
if (_possiblyUndeclaredUses.contains(name)) {
foreach (const SourceLocation &loc, _possiblyUndeclaredUses.value(name)) {
@@ -430,7 +447,10 @@ protected:
}
_possiblyUndeclaredUses.remove(name);
}
- _declaredVariables[name] = ast;
+ if (scope == VariableScope::Let || scope == VariableScope::Const)
+ _declaredBlockVariables[{name, _block}] = ast;
+ else
+ _declaredVariables[name] = ast;
return true;
}
@@ -451,7 +471,7 @@ protected:
if (_formalParameterNames.contains(name))
addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name);
- else if (_declaredVariables.contains(name))
+ else if (_declaredVariables.contains(name) || _declaredBlockVariables.contains({name, _block}))
addMessage(WarnAlreadyVar, ast->identifierToken, name);
else if (_declaredFunctions.contains(name))
addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
@@ -469,6 +489,25 @@ protected:
return false;
}
+ bool visit(Block *) override
+ {
+ ++_block;
+ return true;
+ }
+
+ void endVisit(Block *) override
+ {
+ auto it = _declaredBlockVariables.begin();
+ auto end = _declaredBlockVariables.end();
+ while (it != end) {
+ if (it.key().second == _block)
+ it = _declaredBlockVariables.erase(it);
+ else
+ ++it;
+ }
+ --_block;
+ }
+
private:
void addMessage(Type type, const SourceLocation &loc, const QString &arg1 = QString())
{
@@ -478,9 +517,11 @@ private:
QList<Message> _messages;
QStringList _formalParameterNames;
QHash<QString, PatternElement *> _declaredVariables;
+ QHash<QPair<QString, uint>, PatternElement *> _declaredBlockVariables;
QHash<QString, FunctionDeclaration *> _declaredFunctions;
QHash<QString, QList<SourceLocation> > _possiblyUndeclaredUses;
bool _seenNonDeclarationStatement;
+ uint _block = 0;
};
class IdsThatShouldNotBeUsedInDesigner : public QStringList
@@ -1635,7 +1676,7 @@ bool Check::visit(CallExpression *ast)
if (!whiteListedFunction && !isMathFunction && !isDateFunction && !isDirectInConnectionsScope)
addMessage(ErrFunctionsNotSupportedInQmlUi, location);
- static const QStringList globalFunctions = {"String", "Boolean", "Date", "Number", "Object", "QT_TR_NOOP", "QT_TRANSLATE_NOOP", "QT_TRID_NOOP"};
+ static const QStringList globalFunctions = {"String", "Boolean", "Date", "Number", "Object", "Array", "QT_TR_NOOP", "QT_TRANSLATE_NOOP", "QT_TRID_NOOP"};
if (!name.isEmpty() && name.at(0).isUpper() && !globalFunctions.contains(name)) {
addMessage(WarnExpectedNewWithUppercaseFunction, location);
diff --git a/src/libs/qmljs/qmljsdialect.cpp b/src/libs/qmljs/qmljsdialect.cpp
index 0cb463b2e5..cfe71b2265 100644
--- a/src/libs/qmljs/qmljsdialect.cpp
+++ b/src/libs/qmljs/qmljsdialect.cpp
@@ -30,7 +30,6 @@
namespace QmlJS {
-
bool Dialect::isQmlLikeLanguage() const
{
switch (m_dialect) {
@@ -233,7 +232,7 @@ QDebug operator << (QDebug &dbg, const Dialect &dialect)
return dbg;
}
-PathAndLanguage::PathAndLanguage(const Utils::FileName &path, Dialect language)
+PathAndLanguage::PathAndLanguage(const Utils::FilePath &path, Dialect language)
: m_path(path), m_language(language)
{ }
@@ -294,11 +293,11 @@ void PathsAndLanguages::compact()
return;
int oldCompactionPlace = 0;
- Utils::FileName oldPath = m_list.first().path();
+ Utils::FilePath oldPath = m_list.first().path();
QList<PathAndLanguage> compactedList;
bool restrictFailed = false;
for (int i = 1; i < m_list.length(); ++i) {
- Utils::FileName newPath = m_list.at(i).path();
+ Utils::FilePath newPath = m_list.at(i).path();
if (newPath == oldPath) {
int newCompactionPlace = i - 1;
compactedList << m_list.mid(oldCompactionPlace, newCompactionPlace - oldCompactionPlace);
diff --git a/src/libs/qmljs/qmljsdialect.h b/src/libs/qmljs/qmljsdialect.h
index 8d1ca30deb..230642e145 100644
--- a/src/libs/qmljs/qmljsdialect.h
+++ b/src/libs/qmljs/qmljsdialect.h
@@ -78,11 +78,8 @@ QMLJS_EXPORT QDebug operator << (QDebug &dbg, const Dialect &dialect);
class QMLJS_EXPORT PathAndLanguage {
public:
- PathAndLanguage(const Utils::FileName &path = Utils::FileName(), Dialect language = Dialect::AnyLanguage);
- PathAndLanguage(const PathAndLanguage &o)
- : m_path(o.path()), m_language(o.language())
- { }
- Utils::FileName path() const {
+ PathAndLanguage(const Utils::FilePath &path = Utils::FilePath(), Dialect language = Dialect::AnyLanguage);
+ Utils::FilePath path() const {
return m_path;
}
Dialect language() const {
@@ -91,7 +88,7 @@ public:
bool operator ==(const PathAndLanguage &other) const;
bool operator < (const PathAndLanguage &other) const;
private:
- Utils::FileName m_path;
+ Utils::FilePath m_path;
Dialect m_language;
};
@@ -130,11 +127,8 @@ public:
explicit PathsAndLanguages(const QList<PathAndLanguage> &list)
: m_list(list)
{ }
- PathsAndLanguages(const PathsAndLanguages &o)
- : m_list(o.m_list)
- { }
- bool maybeInsert(const Utils::FileName &path, Dialect language = Dialect::AnyLanguage) {
+ bool maybeInsert(const Utils::FilePath &path, Dialect language = Dialect::AnyLanguage) {
return maybeInsert(PathAndLanguage(path, language));
}
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index a4551b1c1c..6ebe5b0b2f 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -458,14 +458,6 @@ Snapshot::~Snapshot()
{
}
-Snapshot::Snapshot(const Snapshot &o)
- : _documents(o._documents),
- _documentsByPath(o._documentsByPath),
- _libraries(o._libraries),
- _dependencies(o._dependencies)
-{
-}
-
void Snapshot::insert(const Document::Ptr &document, bool allowInvalid)
{
if (document && (allowInvalid || document->qmlProgram() || document->jsProgram())) {
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 4029373992..82df720776 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -230,7 +230,6 @@ class QMLJS_EXPORT Snapshot
public:
Snapshot();
- Snapshot(const Snapshot &o);
~Snapshot();
typedef Base::iterator iterator;
diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp
index adc9c9ff57..afa8d58b3a 100644
--- a/src/libs/qmljs/qmljsimportdependencies.cpp
+++ b/src/libs/qmljs/qmljsimportdependencies.cpp
@@ -25,9 +25,9 @@
#include "qmljsimportdependencies.h"
#include "qmljsinterpreter.h"
-#include "qmljsqrcparser.h"
#include "qmljsviewercontext.h"
+#include <utils/qrcparser.h>
#include <utils/qtcassert.h>
#include <QCryptographicHash>
@@ -139,10 +139,10 @@ ImportKey::ImportKey(ImportType::Enum type, const QString &path, int majorVersio
break;
case ImportType::File:
case ImportType::QrcFile:
- splitPath = QrcParser::normalizedQrcFilePath(path).split(QLatin1Char('/'));
+ splitPath = Utils::QrcParser::normalizedQrcFilePath(path).split(QLatin1Char('/'));
break;
case ImportType::QrcDirectory:
- splitPath = QrcParser::normalizedQrcDirectoryPath(path).split(QLatin1Char('/'));
+ splitPath = Utils::QrcParser::normalizedQrcDirectoryPath(path).split(QLatin1Char('/'));
if (splitPath.length() > 1 && splitPath.last().isEmpty())
splitPath.removeLast();
break;
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 03083501b6..91f195f8fc 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -2340,6 +2340,16 @@ Import::Import(const Import &other)
valid(other.valid), used(false)
{ }
+Import &Import::operator=(const Import &other)
+{
+ object = other.object;
+ info = other.info;
+ libraryPath = other.libraryPath;
+ valid = other.valid;
+ used = false;
+ return *this;
+}
+
TypeScope::TypeScope(const Imports *imports, ValueOwner *valueOwner)
: ObjectValue(valueOwner)
, m_imports(imports)
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 9da1aa8635..f2e953180c 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -1038,6 +1038,7 @@ class QMLJS_EXPORT Import {
public:
Import();
Import(const Import &other);
+ Import &operator=(const Import &other);
// const!
ObjectValue *object;
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 737ec6cc46..1acdb68ed9 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -30,9 +30,10 @@
#include "qmljsbind.h"
#include "qmljsutils.h"
#include "qmljsmodelmanagerinterface.h"
-#include "qmljsqrcparser.h"
#include "qmljsconstants.h"
+#include <utils/qrcparser.h>
+
#include <QDir>
using namespace LanguageUtils;
@@ -557,7 +558,7 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
foreach (const QString &path,
ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName())) {
processImport(ImportInfo::qrcDirectoryImport(
- QrcParser::qrcDirectoryPathForQrcFilePath(path)));
+ Utils::QrcParser::qrcDirectoryPathForQrcFilePath(path)));
}
}
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 82d4da3f4a..6bb1bc8ff9 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -52,6 +52,8 @@
#include <stdio.h>
+using namespace Utils;
+
namespace QmlJS {
QMLJS_EXPORT Q_LOGGING_CATEGORY(qmljsLog, "qtc.qmljs.common", QtWarningMsg)
@@ -1098,14 +1100,14 @@ void ModelManagerInterface::updateImportPaths()
PathAndLanguage pAndL = iPaths.at(i);
const QString canonicalPath = pAndL.path().toFileInfo().canonicalFilePath();
if (!canonicalPath.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(canonicalPath),
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(canonicalPath),
pAndL.language());
}
}
while (vCtxsIter.hasNext()) {
vCtxsIter.next();
foreach (const QString &path, vCtxsIter.value().paths)
- allImportPaths.maybeInsert(Utils::FileName::fromString(path), vCtxsIter.value().language);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(path), vCtxsIter.value().language);
}
pInfoIter.toFront();
while (pInfoIter.hasNext()) {
@@ -1116,7 +1118,7 @@ void ModelManagerInterface::updateImportPaths()
.searchPaths().stringList()) {
const QString canonicalPath = QFileInfo(path).canonicalFilePath();
if (!canonicalPath.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(canonicalPath), l);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(canonicalPath), l);
}
}
}
@@ -1125,16 +1127,16 @@ void ModelManagerInterface::updateImportPaths()
pInfoIter.next();
QString pathAtt = pInfoIter.value().qtQmlPath;
if (!pathAtt.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(pathAtt), Dialect::QmlQtQuick2);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
}
{
QString pathAtt = defaultProjectInfo().qtQmlPath;
if (!pathAtt.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(pathAtt), Dialect::QmlQtQuick2);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
}
foreach (const QString &path, m_defaultImportPaths)
- allImportPaths.maybeInsert(Utils::FileName::fromString(path), Dialect::Qml);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(path), Dialect::Qml);
allImportPaths.compact();
{
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h
index 5de25eead3..cd36cbca2f 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.h
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h
@@ -28,11 +28,11 @@
#include "qmljs_global.h"
#include "qmljsbundle.h"
#include "qmljsdocument.h"
-#include "qmljsqrcparser.h"
#include "qmljsdialect.h"
#include <cplusplus/CppDocument.h>
#include <utils/environment.h>
+#include <utils/qrcparser.h>
#include <QFuture>
#include <QHash>
@@ -255,7 +255,7 @@ private:
void cleanupFutures();
void iterateQrcFiles(ProjectExplorer::Project *project,
QrcResourceSelector resources,
- std::function<void(QrcParser::ConstPtr)> callback);
+ std::function<void(Utils::QrcParser::ConstPtr)> callback);
mutable QMutex m_mutex;
QmlJS::Snapshot m_validSnapshot;
@@ -272,7 +272,7 @@ private:
QTimer *m_asyncResetTimer = nullptr;
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
QFuture<void> m_cppQmlTypesUpdater;
- QrcCache m_qrcCache;
+ Utils::QrcCache m_qrcCache;
QHash<QString, QString> m_qrcContents;
CppDataHash m_cppDataHash;
diff --git a/src/libs/qmljs/qmljsqrcparser.cpp b/src/libs/qmljs/qmljsqrcparser.cpp
deleted file mode 100644
index 0a68ebe2fb..0000000000
--- a/src/libs/qmljs/qmljsqrcparser.cpp
+++ /dev/null
@@ -1,556 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "qmljsqrcparser.h"
-#include "qmljsconstants.h"
-#include <QFile>
-#include <QDir>
-#include <QFileInfo>
-#include <QStringList>
-#include <QDomDocument>
-#include <QLocale>
-#include <QMutex>
-#include <QSet>
-#include <QMutexLocker>
-#include <QMultiHash>
-#include <QCoreApplication>
-#include <utils/qtcassert.h>
-
-namespace QmlJS {
-
-namespace Internal {
-/*!
- * \class QrcParser
- * \brief Parses one or more qrc files, and keeps their content cached
- *
- * A Qrc resource contains files read from the filesystem but organized in a possibly different way.
- *
- * To easily describe that with a simple structure we use a map from qrc paths to the paths in the
- * filesystem.
- * By using a map we can easily find all qrc paths that start with a given prefix, and thus loop
- * on a qrc directory.
- *
- * Qrc files also support languages, those are mapped to a prefix of the qrc path.
- * For example the french /image/bla.png (lang=fr) will have the path "fr/image/bla.png".
- * The empty language represent the default resource.
- * Languages are looked up using the locale uiLanguages() property
- *
- * For a single qrc a given path maps to a single file, but when one has multiple
- * (platform specific exclusive) qrc files, then multiple files match, so QStringList are used.
- *
- * Especially the collect* functions are thought as low level interface.
- */
-class QrcParserPrivate
-{
- Q_DECLARE_TR_FUNCTIONS(QmlJS::QrcParser)
-public:
- typedef QMap<QString,QStringList> SMap;
- QrcParserPrivate(QrcParser *q);
- bool parseFile(const QString &path, const QString &contents);
- QString firstFileAtPath(const QString &path, const QLocale &locale) const;
- void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = 0) const;
- bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
- void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
- const QLocale *locale = 0) const;
- void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res,
- const QLocale *locale = 0) const;
-
- QStringList errorMessages() const;
- QStringList languages() const;
-private:
- static QString fixPrefix(const QString &prefix);
- QStringList allUiLanguages(const QLocale *locale) const;
-
- SMap m_resources;
- SMap m_files;
- QStringList m_languages;
- QStringList m_errorMessages;
-};
-
-class QrcCachePrivate
-{
- Q_DECLARE_TR_FUNCTIONS(QmlJS::QrcCachePrivate)
-public:
- QrcCachePrivate(QrcCache *q);
- QrcParser::Ptr addPath(const QString &path, const QString &contents);
- void removePath(const QString &path);
- QrcParser::Ptr updatePath(const QString &path, const QString &contents);
- QrcParser::Ptr parsedPath(const QString &path);
- void clear();
-private:
- QHash<QString, QPair<QrcParser::Ptr,int> > m_cache;
- QMutex m_mutex;
-};
-} // namespace Internal
-
-/*! \brief normalizes the path to a file in a qrc resource by dropping the "qrc:/" or ":" and
- * any extra slashes at the beginning
- */
-QString QrcParser::normalizedQrcFilePath(const QString &path) {
- QString normPath = path;
- int endPrefix = 0;
- if (path.startsWith(QLatin1String("qrc:/")))
- endPrefix = 4;
- else if (path.startsWith(QLatin1String(":/")))
- endPrefix = 1;
- if (endPrefix < path.size() && path.at(endPrefix) == QLatin1Char('/'))
- while (endPrefix + 1 < path.size() && path.at(endPrefix+1) == QLatin1Char('/'))
- ++endPrefix;
- normPath = path.right(path.size()-endPrefix);
- if (!normPath.startsWith(QLatin1Char('/')))
- normPath.insert(0, QLatin1Char('/'));
- return normPath;
-}
-
-/*! \brief normalizes the path to a directory in a qrc resource by dropping the "qrc:/" or ":" and
- * any extra slashes at the beginning, and ensuring it ends with a slash
- */
-QString QrcParser::normalizedQrcDirectoryPath(const QString &path) {
- QString normPath = normalizedQrcFilePath(path);
- if (!normPath.endsWith(QLatin1Char('/')))
- normPath.append(QLatin1Char('/'));
- return normPath;
-}
-
-QString QrcParser::qrcDirectoryPathForQrcFilePath(const QString &file)
-{
- return file.left(file.lastIndexOf(QLatin1Char('/')));
-}
-
-QrcParser::QrcParser()
-{
- d = new Internal::QrcParserPrivate(this);
-}
-
-QrcParser::~QrcParser()
-{
- delete d;
-}
-
-bool QrcParser::parseFile(const QString &path, const QString &contents)
-{
- return d->parseFile(path, contents);
-}
-
-/*! \brief returns fs path of the first (active) file at the given qrc path
- */
-QString QrcParser::firstFileAtPath(const QString &path, const QLocale &locale) const
-{
- return d->firstFileAtPath(path, locale);
-}
-
-/*! \brief adds al the fs paths for the given qrc path to *res
- * If locale is null all possible files are added, otherwise just the first match
- * using that locale.
- */
-void QrcParser::collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale) const
-{
- d->collectFilesAtPath(path, res, locale);
-}
-
-/*! \brief returns true if the given path is a non empty directory
- */
-bool QrcParser::hasDirAtPath(const QString &path, const QLocale *locale) const
-{
- return d->hasDirAtPath(path, locale);
-}
-
-/*! \brief adds the directory contents of the given qrc path to res
- *
- * adds the qrcFileName => fs paths associations contained in the given qrc path
- * to res. If addDirs is true directories are also added.
- * If locale is null all possible files are added, otherwise just the first match
- * using that locale.
- */
-void QrcParser::collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs,
- const QLocale *locale) const
-{
- d->collectFilesInPath(path, res, addDirs, locale);
-}
-
-void QrcParser::collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res,
- const QLocale *locale) const
-{
- d->collectResourceFilesForSourceFile(sourceFile, res, locale);
-}
-
-/*! \brief returns the errors found while parsing
- */
-QStringList QrcParser::errorMessages() const
-{
- return d->errorMessages();
-}
-
-/*! \brief returns all languages used in this qrc resource
- */
-QStringList QrcParser::languages() const
-{
- return d->languages();
-}
-
-/*! \brief if the contents are valid
- */
-bool QrcParser::isValid() const
-{
- return errorMessages().isEmpty();
-}
-
-QrcParser::Ptr QrcParser::parseQrcFile(const QString &path, const QString &contents)
-{
- Ptr res(new QrcParser);
- if (!path.isEmpty())
- res->parseFile(path, contents);
- return res;
-}
-
-// ----------------
-
-QrcCache::QrcCache()
-{
- d = new Internal::QrcCachePrivate(this);
-}
-
-QrcCache::~QrcCache()
-{
- delete d;
-}
-
-QrcParser::ConstPtr QrcCache::addPath(const QString &path, const QString &contents)
-{
- return d->addPath(path, contents);
-}
-
-void QrcCache::removePath(const QString &path)
-{
- d->removePath(path);
-}
-
-QrcParser::ConstPtr QrcCache::updatePath(const QString &path, const QString &contents)
-{
- return d->updatePath(path, contents);
-}
-
-QrcParser::ConstPtr QrcCache::parsedPath(const QString &path)
-{
- return d->parsedPath(path);
-}
-
-void QrcCache::clear()
-{
- d->clear();
-}
-
-// --------------------
-
-namespace Internal {
-
-QrcParserPrivate::QrcParserPrivate(QrcParser *)
-{ }
-
-bool QrcParserPrivate::parseFile(const QString &path, const QString &contents)
-{
- QDomDocument doc;
- QDir baseDir(QFileInfo(path).path());
-
- if (contents.isEmpty()) {
- // Regular file
- QFile file(path);
- if (!file.open(QIODevice::ReadOnly)) {
- m_errorMessages.append(file.errorString());
- return false;
- }
-
- QString error_msg;
- int error_line, error_col;
- if (!doc.setContent(&file, &error_msg, &error_line, &error_col)) {
- m_errorMessages.append(tr("XML error on line %1, col %2: %3")
- .arg(error_line).arg(error_col).arg(error_msg));
- return false;
- }
- } else {
- // Virtual file from qmake evaluator
- QString error_msg;
- int error_line, error_col;
- if (!doc.setContent(contents, &error_msg, &error_line, &error_col)) {
- m_errorMessages.append(tr("XML error on line %1, col %2: %3")
- .arg(error_line).arg(error_col).arg(error_msg));
- return false;
- }
- }
-
- QDomElement root = doc.firstChildElement(QLatin1String("RCC"));
- if (root.isNull()) {
- m_errorMessages.append(tr("The <RCC> root element is missing."));
- return false;
- }
-
- QDomElement relt = root.firstChildElement(QLatin1String("qresource"));
- for (; !relt.isNull(); relt = relt.nextSiblingElement(QLatin1String("qresource"))) {
-
- QString prefix = fixPrefix(relt.attribute(QLatin1String("prefix")));
- const QString language = relt.attribute(QLatin1String("lang"));
- if (!m_languages.contains(language))
- m_languages.append(language);
-
- QDomElement felt = relt.firstChildElement(QLatin1String("file"));
- for (; !felt.isNull(); felt = felt.nextSiblingElement(QLatin1String("file"))) {
- const QString fileName = felt.text();
- const QString alias = felt.attribute(QLatin1String("alias"));
- QString filePath = baseDir.absoluteFilePath(fileName);
- QString accessPath;
- if (!alias.isEmpty())
- accessPath = language + prefix + alias;
- else
- accessPath = language + prefix + fileName;
- QStringList &resources = m_resources[accessPath];
- if (!resources.contains(filePath))
- resources.append(filePath);
- QStringList &files = m_files[filePath];
- if (!files.contains(accessPath))
- files.append(accessPath);
- }
- }
- return true;
-}
-
-// path is assumed to be a normalized absolute path
-QString QrcParserPrivate::firstFileAtPath(const QString &path, const QLocale &locale) const
-{
- QTC_CHECK(path.startsWith(QLatin1Char('/')));
- QStringList langs = allUiLanguages(&locale);
- foreach (const QString &language, langs) {
- if (m_languages.contains(language)) {
- SMap::const_iterator res = m_resources.find(language + path);
- if (res != m_resources.end())
- return res.value().at(0);
- }
- }
- return QString();
-}
-
-void QrcParserPrivate::collectFilesAtPath(const QString &path, QStringList *files,
- const QLocale *locale) const
-{
- QTC_CHECK(path.startsWith(QLatin1Char('/')));
- QStringList langs = allUiLanguages(locale);
- foreach (const QString &language, langs) {
- if (m_languages.contains(language)) {
- SMap::const_iterator res = m_resources.find(language + path);
- if (res != m_resources.end())
- (*files) << res.value();
- }
- }
-}
-
-// path is expected to be normalized and start and end with a slash
-bool QrcParserPrivate::hasDirAtPath(const QString &path, const QLocale *locale) const
-{
- QTC_CHECK(path.startsWith(QLatin1Char('/')));
- QTC_CHECK(path.endsWith(QLatin1Char('/')));
- QStringList langs = allUiLanguages(locale);
- foreach (const QString &language, langs) {
- if (m_languages.contains(language)) {
- QString key = language + path;
- SMap::const_iterator res = m_resources.lowerBound(key);
- if (res != m_resources.end() && res.key().startsWith(key))
- return true;
- }
- }
- return false;
-}
-
-void QrcParserPrivate::collectFilesInPath(const QString &path, QMap<QString,QStringList> *contents,
- bool addDirs, const QLocale *locale) const
-{
- QTC_CHECK(path.startsWith(QLatin1Char('/')));
- QTC_CHECK(path.endsWith(QLatin1Char('/')));
- SMap::const_iterator end = m_resources.end();
- QStringList langs = allUiLanguages(locale);
- foreach (const QString &language, langs) {
- QString key = language + path;
- SMap::const_iterator res = m_resources.lowerBound(key);
- while (res != end && res.key().startsWith(key)) {
- const QString &actualKey = res.key();
- int endDir = actualKey.indexOf(QLatin1Char('/'), key.size());
- if (endDir == -1) {
- QString fileName = res.key().right(res.key().size()-key.size());
- QStringList &els = (*contents)[fileName];
- foreach (const QString &val, res.value())
- if (!els.contains(val))
- els << val;
- ++res;
- } else {
- QString dirName = res.key().mid(key.size(), endDir - key.size() + 1);
- if (addDirs)
- contents->insert(dirName, QStringList());
- QString key2 = key + dirName;
- do {
- ++res;
- } while (res != end && res.key().startsWith(key2));
- }
- }
- }
-}
-
-void QrcParserPrivate::collectResourceFilesForSourceFile(const QString &sourceFile,
- QStringList *results,
- const QLocale *locale) const
-{
- // TODO: use FileName from fileutils for file paths
-
- QStringList langs = allUiLanguages(locale);
- SMap::const_iterator file = m_files.find(sourceFile);
- if (file == m_files.end())
- return;
- foreach (const QString &resource, file.value()) {
- foreach (const QString &language, langs) {
- if (resource.startsWith(language) && !results->contains(resource))
- results->append(resource);
- }
- }
-}
-
-QStringList QrcParserPrivate::errorMessages() const
-{
- return m_errorMessages;
-}
-
-QStringList QrcParserPrivate::languages() const
-{
- return m_languages;
-}
-
-QString QrcParserPrivate::fixPrefix(const QString &prefix)
-{
- const QChar slash = QLatin1Char('/');
- QString result = QString(slash);
- for (int i = 0; i < prefix.size(); ++i) {
- const QChar c = prefix.at(i);
- if (c == slash && result.at(result.size() - 1) == slash)
- continue;
- result.append(c);
- }
-
- if (!result.endsWith(slash))
- result.append(slash);
-
- return result;
-}
-
-QStringList QrcParserPrivate::allUiLanguages(const QLocale *locale) const
-{
- if (!locale)
- return languages();
- QStringList langs = locale->uiLanguages();
- foreach (const QString &language, langs) { // qt4 support
- if (language.contains(QLatin1Char('_')) || language.contains(QLatin1Char('-'))) {
- QStringList splits = QString(language).replace(QLatin1Char('_'), QLatin1Char('-'))
- .split(QLatin1Char('-'));
- if (splits.size() > 1 && !langs.contains(splits.at(0)))
- langs.append(splits.at(0));
- }
- }
- if (!langs.contains(QString()))
- langs.append(QString());
- return langs;
-}
-
-// ----------------
-
-QrcCachePrivate::QrcCachePrivate(QrcCache *)
-{ }
-
-QrcParser::Ptr QrcCachePrivate::addPath(const QString &path, const QString &contents)
-{
- QPair<QrcParser::Ptr,int> currentValue;
- {
- QMutexLocker l(&m_mutex);
- currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
- currentValue.second += 1;
- if (currentValue.second > 1) {
- m_cache.insert(path, currentValue);
- return currentValue.first;
- }
- }
- QrcParser::Ptr newParser = QrcParser::parseQrcFile(path, contents);
- if (!newParser->isValid())
- qCWarning(qmljsLog) << "adding invalid qrc " << path << " to the cache:" << newParser->errorMessages();
- {
- QMutexLocker l(&m_mutex);
- QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
- if (currentValue.first.isNull())
- currentValue.first = newParser;
- currentValue.second += 1;
- m_cache.insert(path, currentValue);
- return currentValue.first;
- }
-}
-
-void QrcCachePrivate::removePath(const QString &path)
-{
- QPair<QrcParser::Ptr,int> currentValue;
- {
- QMutexLocker l(&m_mutex);
- currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
- if (currentValue.second == 1) {
- m_cache.remove(path);
- } else if (currentValue.second > 1) {
- currentValue.second -= 1;
- m_cache.insert(path, currentValue);
- } else {
- QTC_CHECK(!m_cache.contains(path));
- }
- }
-}
-
-QrcParser::Ptr QrcCachePrivate::updatePath(const QString &path, const QString &contents)
-{
- QrcParser::Ptr newParser = QrcParser::parseQrcFile(path, contents);
- {
- QMutexLocker l(&m_mutex);
- QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
- currentValue.first = newParser;
- if (currentValue.second == 0)
- currentValue.second = 1; // add qrc files that are not in the resources of a project
- m_cache.insert(path, currentValue);
- return currentValue.first;
- }
-}
-
-QrcParser::Ptr QrcCachePrivate::parsedPath(const QString &path)
-{
- QMutexLocker l(&m_mutex);
- QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, {QrcParser::Ptr(0), 0});
- return currentValue.first;
-}
-
-void QrcCachePrivate::clear()
-{
- QMutexLocker l(&m_mutex);
- m_cache.clear();
-}
-
-} // namespace Internal
-} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljsqrcparser.h b/src/libs/qmljs/qmljsqrcparser.h
deleted file mode 100644
index 6973fa6d39..0000000000
--- a/src/libs/qmljs/qmljsqrcparser.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-#include "qmljs_global.h"
-
-#include <QMap>
-#include <QSharedPointer>
-#include <QString>
-#include <QStringList>
-
-QT_FORWARD_DECLARE_CLASS(QLocale)
-
-namespace QmlJS {
-
-namespace Internal {
-class QrcParserPrivate;
-class QrcCachePrivate;
-}
-
-class QMLJS_EXPORT QrcParser
-{
-public:
- typedef QSharedPointer<QrcParser> Ptr;
- typedef QSharedPointer<const QrcParser> ConstPtr;
- ~QrcParser();
- bool parseFile(const QString &path, const QString &contents);
- QString firstFileAtPath(const QString &path, const QLocale &locale) const;
- void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = 0) const;
- bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
- void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
- const QLocale *locale = 0) const;
- void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *results,
- const QLocale *locale = 0) const;
-
- QStringList errorMessages() const;
- QStringList languages() const;
- bool isValid() const;
-
- static Ptr parseQrcFile(const QString &path, const QString &contents);
- static QString normalizedQrcFilePath(const QString &path);
- static QString normalizedQrcDirectoryPath(const QString &path);
- static QString qrcDirectoryPathForQrcFilePath(const QString &file);
-private:
- QrcParser();
- QrcParser(const QrcParser &);
- Internal::QrcParserPrivate *d;
-};
-
-class QMLJS_EXPORT QrcCache
-{
-public:
- QrcCache();
- ~QrcCache();
- QrcParser::ConstPtr addPath(const QString &path, const QString &contents);
- void removePath(const QString &path);
- QrcParser::ConstPtr updatePath(const QString &path, const QString &contents);
- QrcParser::ConstPtr parsedPath(const QString &path);
- void clear();
-private:
- Internal::QrcCachePrivate *d;
-};
-}
diff --git a/src/libs/qmljs/qmljsreformatter.cpp b/src/libs/qmljs/qmljsreformatter.cpp
index e95ff2f339..d60d6179f3 100644
--- a/src/libs/qmljs/qmljsreformatter.cpp
+++ b/src/libs/qmljs/qmljsreformatter.cpp
@@ -96,6 +96,7 @@ class Rewriter : protected Visitor
int _lastNewlineOffset = -1;
bool _hadEmptyLine = false;
int _binaryExpDepth = 0;
+ bool _hasOpenComment = false;
public:
Rewriter(Document::Ptr doc)
@@ -201,6 +202,9 @@ protected:
void out(const QString &str, const SourceLocation &lastLoc = SourceLocation())
{
+ if (_hasOpenComment) {
+ newLine();
+ }
if (lastLoc.isValid()) {
QList<SourceLocation> comments = _doc->engine()->comments();
for (; _nextComment < comments.size(); ++_nextComment) {
@@ -371,6 +375,7 @@ protected:
{
// if preceded by a newline, it's an empty line!
_hadEmptyLine = _line.trimmed().isEmpty();
+ _hasOpenComment = false;
// if the preceding line wasn't empty, reindent etc.
if (!_hadEmptyLine) {
@@ -524,6 +529,7 @@ protected:
out(" ");
out(toString(nextCommentLoc));
+ _hasOpenComment = true;
}
}
}
@@ -531,6 +537,39 @@ protected:
bool visit(UiPragma *ast) override
{
out("pragma ", ast->pragmaToken);
+ out(ast->name.toString());
+ newLine();
+ return false;
+ }
+
+ bool visit(UiEnumDeclaration *ast) override
+ {
+ out(ast->enumToken);
+ out(" ");
+ out(ast->name.toString());
+ out(" ");
+ out("{"); // TODO: out(ast->lbraceToken);
+ newLine();
+
+ accept(ast->members);
+
+ out(ast->rbraceToken);
+ return false;
+ }
+
+ bool visit(UiEnumMemberList *list) override
+ {
+ for (UiEnumMemberList *it = list; it; it = it->next) {
+ out(it->memberToken);
+ if (it->valueToken.isValid()) {
+ out(" = ");
+ out(it->valueToken);
+ }
+ if (it->next) {
+ out(",");
+ }
+ newLine();
+ }
return false;
}
@@ -563,9 +602,10 @@ protected:
bool visit(UiObjectInitializer *ast) override
{
out(ast->lbraceToken);
- if (ast->members)
+ if (ast->members) {
lnAcceptIndented(ast->members);
- newLine();
+ newLine();
+ }
out(ast->rbraceToken);
return false;
}
@@ -593,10 +633,10 @@ protected:
if (!ast->typeModifier.isNull()) {
out(ast->typeModifierToken);
out("<");
- out(ast->typeToken);
+ accept(ast->memberType);
out(">");
} else {
- out(ast->typeToken);
+ accept(ast->memberType);
}
out(" ");
if (ast->statement) {
@@ -677,8 +717,10 @@ protected:
bool visit(ObjectPattern *ast) override
{
out(ast->lbraceToken);
- lnAcceptIndented(ast->properties);
- newLine();
+ if (ast->properties) {
+ lnAcceptIndented(ast->properties);
+ newLine();
+ }
out(ast->rbraceToken);
return false;
}
@@ -914,14 +956,23 @@ protected:
bool visit(VariableStatement *ast) override
{
- out("var ", ast->declarationKindToken);
+ out(ast->declarationKindToken);
+ out(" ");
accept(ast->declarations);
return false;
}
bool visit(PatternElement *ast) override
{
-
+ if (ast->isForDeclaration) {
+ if (ast->scope == VariableScope::Var) {
+ out("var ");
+ } else if (ast->scope == VariableScope::Let) {
+ out("let ");
+ } else if (ast->scope == VariableScope::Const) {
+ out("const ");
+ }
+ }
out(ast->identifierToken);
if (ast->initializer) {
if (ast->isVariableDeclaration())
@@ -985,7 +1036,12 @@ protected:
out(ast->forToken);
out(" ");
out(ast->lparenToken);
- accept(ast->initialiser);
+ if (ast->initialiser) {
+ accept(ast->initialiser);
+ } else if (ast->declarations) {
+ out("var ");
+ accept(ast->declarations);
+ }
out("; ", ast->firstSemicolonToken);
accept(ast->condition);
out("; ", ast->secondSemicolonToken);
@@ -1273,6 +1329,8 @@ protected:
{
for (FormalParameterList *it = ast; it; it = it->next) {
out(it->element->bindingIdentifier.toString()); // TODO
+ if (it->next)
+ out(", ");
}
return false;
}