summaryrefslogtreecommitdiff
path: root/src/libs/qmljs/parser/qmljslexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/qmljs/parser/qmljslexer.cpp')
-rw-r--r--src/libs/qmljs/parser/qmljslexer.cpp539
1 files changed, 278 insertions, 261 deletions
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
index b8c594f593..6c4eb70744 100644
--- a/src/libs/qmljs/parser/qmljslexer.cpp
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -43,8 +43,6 @@ Q_CORE_EXPORT double qstrntod(const char *s00, qsizetype len, char const **se, b
#endif
QT_END_NAMESPACE
-QT_QML_BEGIN_NAMESPACE
-
using namespace QmlJS;
static inline int regExpFlagFromChar(const QChar &ch)
@@ -79,7 +77,7 @@ Lexer::Lexer(Engine *engine)
, _codePtr(nullptr)
, _endPtr(nullptr)
, _tokenStartPtr(nullptr)
- , _char(QLatin1Char('\n'))
+ , _char(u'\n')
, _errorCode(NoError)
, _currentLineNumber(0)
, _currentColumnNumber(0)
@@ -131,7 +129,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_endPtr = _codePtr + code.length();
_tokenStartPtr = _codePtr;
- _char = QLatin1Char('\n');
+ _char = u'\n';
_errorCode = NoError;
_currentLineNumber = lineno;
@@ -160,7 +158,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
void Lexer::scanChar()
{
if (_skipLinefeed) {
- Q_ASSERT(*_codePtr == QLatin1Char('\n'));
+ Q_ASSERT(*_codePtr == u'\n');
++_codePtr;
_skipLinefeed = false;
}
@@ -168,16 +166,24 @@ void Lexer::scanChar()
++_currentColumnNumber;
if (isLineTerminator()) {
- if (_char == QLatin1Char('\r')) {
- if (_codePtr < _endPtr && *_codePtr == QLatin1Char('\n'))
+ if (_char == u'\r') {
+ if (_codePtr < _endPtr && *_codePtr == u'\n')
_skipLinefeed = true;
- _char = QLatin1Char('\n');
+ _char = u'\n';
}
++_currentLineNumber;
_currentColumnNumber = 0;
}
}
+QChar Lexer::peekChar()
+{
+ auto peekPtr = _codePtr;
+ if (peekPtr < _endPtr)
+ return *peekPtr;
+ return QChar();
+}
+
namespace {
inline bool isBinop(int tok)
{
@@ -225,19 +231,19 @@ inline bool isBinop(int tok)
int hexDigit(QChar c)
{
- if (c >= QLatin1Char('0') && c <= QLatin1Char('9'))
- return c.unicode() - '0';
- if (c >= QLatin1Char('a') && c <= QLatin1Char('f'))
- return c.unicode() - 'a' + 10;
- if (c >= QLatin1Char('A') && c <= QLatin1Char('F'))
- return c.unicode() - 'A' + 10;
+ if (c >= u'0' && c <= u'9')
+ return c.unicode() - u'0';
+ if (c >= u'a' && c <= u'f')
+ return c.unicode() - u'a' + 10;
+ if (c >= u'A' && c <= u'F')
+ return c.unicode() - u'A' + 10;
return -1;
}
int octalDigit(QChar c)
{
- if (c >= QLatin1Char('0') && c <= QLatin1Char('7'))
- return c.unicode() - '0';
+ if (c >= u'0' && c <= u'7')
+ return c.unicode() - u'0';
return -1;
}
@@ -248,70 +254,70 @@ int Lexer::lex()
const int previousTokenKind = _tokenKind;
again:
- _tokenSpell = QStringView();
- _rawString = QStringView();
- _tokenKind = scanToken();
- _tokenLength = _codePtr - _tokenStartPtr - 1;
-
- _delimited = false;
- _restrictedKeyword = false;
- _followsClosingBrace = (previousTokenKind == T_RBRACE);
-
- // update the flags
- switch (_tokenKind) {
- case T_LBRACE:
- if (_bracesCount > 0)
- ++_bracesCount;
- Q_FALLTHROUGH();
- case T_SEMICOLON:
- _importState = ImportState::NoQmlImport;
- Q_FALLTHROUGH();
- case T_QUESTION:
- case T_COLON:
- case T_TILDE:
- _delimited = true;
- break;
- case T_AUTOMATIC_SEMICOLON:
- case T_AS:
- _importState = ImportState::NoQmlImport;
- Q_FALLTHROUGH();
- default:
- if (isBinop(_tokenKind))
- _delimited = true;
- break;
-
- case T_IMPORT:
- if (qmlMode() || (_handlingDirectives && previousTokenKind == T_DOT))
- _importState = ImportState::SawImport;
- if (isBinop(_tokenKind))
- _delimited = true;
- break;
-
- case T_IF:
- case T_FOR:
- case T_WHILE:
- case T_WITH:
- _parenthesesState = CountParentheses;
- _parenthesesCount = 0;
- break;
-
- case T_ELSE:
- case T_DO:
- _parenthesesState = BalancedParentheses;
- break;
-
- case T_CONTINUE:
- case T_BREAK:
- case T_RETURN:
- case T_YIELD:
- case T_THROW:
- _restrictedKeyword = true;
- break;
- case T_RBRACE:
- if (_bracesCount > 0)
- --_bracesCount;
- if (_bracesCount == 0)
- goto again;
+ _tokenSpell = QStringView();
+ _rawString = QStringView();
+ _tokenKind = scanToken();
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
+
+ _delimited = false;
+ _restrictedKeyword = false;
+ _followsClosingBrace = (previousTokenKind == T_RBRACE);
+
+ // update the flags
+ switch (_tokenKind) {
+ case T_LBRACE:
+ if (_bracesCount > 0)
+ ++_bracesCount;
+ Q_FALLTHROUGH();
+ case T_SEMICOLON:
+ _importState = ImportState::NoQmlImport;
+ Q_FALLTHROUGH();
+ case T_QUESTION:
+ case T_COLON:
+ case T_TILDE:
+ _delimited = true;
+ break;
+ case T_AUTOMATIC_SEMICOLON:
+ case T_AS:
+ _importState = ImportState::NoQmlImport;
+ Q_FALLTHROUGH();
+ default:
+ if (isBinop(_tokenKind))
+ _delimited = true;
+ break;
+
+ case T_IMPORT:
+ if (qmlMode() || (_handlingDirectives && previousTokenKind == T_DOT))
+ _importState = ImportState::SawImport;
+ if (isBinop(_tokenKind))
+ _delimited = true;
+ break;
+
+ case T_IF:
+ case T_FOR:
+ case T_WHILE:
+ case T_WITH:
+ _parenthesesState = CountParentheses;
+ _parenthesesCount = 0;
+ break;
+
+ case T_ELSE:
+ case T_DO:
+ _parenthesesState = BalancedParentheses;
+ break;
+
+ case T_CONTINUE:
+ case T_BREAK:
+ case T_RETURN:
+ case T_YIELD:
+ case T_THROW:
+ _restrictedKeyword = true;
+ break;
+ case T_RBRACE:
+ if (_bracesCount > 0)
+ --_bracesCount;
+ if (_bracesCount == 0)
+ goto again;
} // switch
// update the parentheses state
@@ -340,7 +346,7 @@ int Lexer::lex()
uint Lexer::decodeUnicodeEscapeCharacter(bool *ok)
{
- Q_ASSERT(_char == QLatin1Char('u'));
+ Q_ASSERT(_char == u'u');
scanChar(); // skip u
if (_codePtr + 4 <= _endPtr && isHexDigit(_char)) {
uint codePoint = 0;
@@ -355,7 +361,7 @@ uint Lexer::decodeUnicodeEscapeCharacter(bool *ok)
*ok = true;
return codePoint;
- } else if (_codePtr < _endPtr && _char == QLatin1Char('{')) {
+ } else if (_codePtr < _endPtr && _char == u'{') {
scanChar(); // skip '{'
uint codePoint = 0;
if (!isHexDigit(_char))
@@ -373,7 +379,7 @@ uint Lexer::decodeUnicodeEscapeCharacter(bool *ok)
scanChar();
}
- if (_char != QLatin1Char('}'))
+ if (_char != u'}')
goto error;
scanChar(); // skip '}'
@@ -415,9 +421,9 @@ QChar Lexer::decodeHexEscapeCharacter(bool *ok)
static inline bool isIdentifierStart(uint ch)
{
// fast path for ascii
- if ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- ch == '$' || ch == '_')
+ if ((ch >= u'a' && ch <= u'z') ||
+ (ch >= u'A' && ch <= u'Z') ||
+ ch == u'$' || ch == u'_')
return true;
switch (QChar::category(ch)) {
@@ -437,10 +443,10 @@ static inline bool isIdentifierStart(uint ch)
static bool isIdentifierPart(uint ch)
{
// fast path for ascii
- if ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '$' || ch == '_' ||
+ if ((ch >= u'a' && ch <= u'z') ||
+ (ch >= u'A' && ch <= u'Z') ||
+ (ch >= u'0' && ch <= u'9') ||
+ ch == u'$' || ch == u'_' ||
ch == 0x200c /* ZWNJ */ || ch == 0x200d /* ZWJ */)
return true;
@@ -487,12 +493,12 @@ again:
// handle comment can be called after a '/' has been read
// and returns true if it actually encountered a comment
auto handleComment = [this](){
- if (_char == QLatin1Char('*')) {
+ if (_char == u'*') {
scanChar();
while (_codePtr <= _endPtr) {
- if (_char == QLatin1Char('*')) {
+ if (_char == u'*') {
scanChar();
- if (_char == QLatin1Char('/')) {
+ if (_char == u'/') {
scanChar();
if (_engine) {
@@ -506,7 +512,7 @@ again:
scanChar();
}
}
- } else if (_char == QLatin1Char('/')) {
+ } else if (_char == u'/') {
while (_codePtr <= _endPtr && !isLineTerminator()) {
scanChar();
}
@@ -548,81 +554,85 @@ again:
scanChar();
switch (ch.unicode()) {
- case '~': return T_TILDE;
- case '}': return T_RBRACE;
+ case u'~': return T_TILDE;
+ case u'}': return T_RBRACE;
- case '|':
- if (_char == QLatin1Char('|')) {
+ case u'|':
+ if (_char == u'|') {
scanChar();
return T_OR_OR;
- } else if (_char == QLatin1Char('=')) {
+ } else if (_char == u'=') {
scanChar();
return T_OR_EQ;
}
return T_OR;
- case '{': return T_LBRACE;
+ case u'{': return T_LBRACE;
- case '^':
- if (_char == QLatin1Char('=')) {
+ case u'^':
+ if (_char == u'=') {
scanChar();
return T_XOR_EQ;
}
return T_XOR;
- case ']': return T_RBRACKET;
- case '[': return T_LBRACKET;
- case '?': {
- if (_char == QLatin1Char('?')) {
+ case u']': return T_RBRACKET;
+ case u'[': return T_LBRACKET;
+ case u'?': {
+ if (_char == u'?') {
scanChar();
return T_QUESTION_QUESTION;
}
+ if (_char == u'.' && !peekChar().isDigit()) {
+ scanChar();
+ return T_QUESTION_DOT;
+ }
return T_QUESTION;
}
- case '>':
- if (_char == QLatin1Char('>')) {
+ case u'>':
+ if (_char == u'>') {
scanChar();
- if (_char == QLatin1Char('>')) {
+ if (_char == u'>') {
scanChar();
- if (_char == QLatin1Char('=')) {
+ if (_char == u'=') {
scanChar();
return T_GT_GT_GT_EQ;
}
return T_GT_GT_GT;
- } else if (_char == QLatin1Char('=')) {
+ } else if (_char == u'=') {
scanChar();
return T_GT_GT_EQ;
}
return T_GT_GT;
- } else if (_char == QLatin1Char('=')) {
+ } else if (_char == u'=') {
scanChar();
return T_GE;
}
return T_GT;
- case '=':
- if (_char == QLatin1Char('=')) {
+ case u'=':
+ if (_char == u'=') {
scanChar();
- if (_char == QLatin1Char('=')) {
+ if (_char == u'=') {
scanChar();
return T_EQ_EQ_EQ;
}
return T_EQ_EQ;
- } else if (_char == QLatin1Char('>')) {
+ } else if (_char == u'>') {
scanChar();
return T_ARROW;
}
return T_EQ;
- case '<':
- if (_char == QLatin1Char('=')) {
+ case u'<':
+ if (_char == u'=') {
scanChar();
return T_LE;
- } else if (_char == QLatin1Char('<')) {
+ } else if (_char == u'<') {
scanChar();
- if (_char == QLatin1Char('=')) {
+ if (_char == u'=') {
scanChar();
return T_LT_LT_EQ;
}
@@ -630,26 +640,26 @@ again:
}
return T_LT;
- case ';': return T_SEMICOLON;
- case ':': return T_COLON;
+ case u';': return T_SEMICOLON;
+ case u':': return T_COLON;
- case '/':
+ case u'/':
if (handleComment())
goto again;
- else if (_char == QLatin1Char('=')) {
+ else if (_char == u'=') {
scanChar();
return T_DIVIDE_EQ;
}
return T_DIVIDE_;
- case '.':
+ case u'.':
if (_importState == ImportState::SawImport)
return T_DOT;
if (isDecimalDigit(_char.unicode()))
return scanNumber(ch);
- if (_char == QLatin1Char('.')) {
+ if (_char == u'.') {
scanChar();
- if (_char == QLatin1Char('.')) {
+ if (_char == u'.') {
scanChar();
return T_ELLIPSIS;
} else {
@@ -660,11 +670,11 @@ again:
}
return T_DOT;
- case '-':
- if (_char == QLatin1Char('=')) {
+ case u'-':
+ if (_char == u'=') {
scanChar();
return T_MINUS_EQ;
- } else if (_char == QLatin1Char('-')) {
+ } else if (_char == u'-') {
scanChar();
if (_terminator && !_delimited && !_prohibitAutomaticSemicolon && _tokenKind != T_LPAREN) {
@@ -676,13 +686,13 @@ again:
}
return T_MINUS;
- case ',': return T_COMMA;
+ case u',': return T_COMMA;
- case '+':
- if (_char == QLatin1Char('=')) {
+ case u'+':
+ if (_char == u'=') {
scanChar();
return T_PLUS_EQ;
- } else if (_char == QLatin1Char('+')) {
+ } else if (_char == u'+') {
scanChar();
if (_terminator && !_delimited && !_prohibitAutomaticSemicolon && _tokenKind != T_LPAREN) {
@@ -694,13 +704,13 @@ again:
}
return T_PLUS;
- case '*':
- if (_char == QLatin1Char('=')) {
+ case u'*':
+ if (_char == u'=') {
scanChar();
return T_STAR_EQ;
- } else if (_char == QLatin1Char('*')) {
+ } else if (_char == u'*') {
scanChar();
- if (_char == QLatin1Char('=')) {
+ if (_char == u'=') {
scanChar();
return T_STAR_STAR_EQ;
}
@@ -708,32 +718,32 @@ again:
}
return T_STAR;
- case ')': return T_RPAREN;
- case '(': return T_LPAREN;
+ case u')': return T_RPAREN;
+ case u'(': return T_LPAREN;
- case '@': return T_AT;
+ case u'@': return T_AT;
- case '&':
- if (_char == QLatin1Char('=')) {
+ case u'&':
+ if (_char == u'=') {
scanChar();
return T_AND_EQ;
- } else if (_char == QLatin1Char('&')) {
+ } else if (_char == u'&') {
scanChar();
return T_AND_AND;
}
return T_AND;
- case '%':
- if (_char == QLatin1Char('=')) {
+ case u'%':
+ if (_char == u'=') {
scanChar();
return T_REMAINDER_EQ;
}
return T_REMAINDER;
- case '!':
- if (_char == QLatin1Char('=')) {
+ case u'!':
+ if (_char == u'=') {
scanChar();
- if (_char == QLatin1Char('=')) {
+ if (_char == u'=') {
scanChar();
return T_NOT_EQ_EQ;
}
@@ -741,34 +751,48 @@ again:
}
return T_NOT;
- case '`':
+ case u'`':
_outerTemplateBraceCount.push(_bracesCount);
Q_FALLTHROUGH();
- case '\'':
- case '"':
+ case u'\'':
+ case u'"':
return scanString(ScanStringMode(ch.unicode()));
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
+ case u'0':
+ case u'1':
+ case u'2':
+ case u'3':
+ case u'4':
+ case u'5':
+ case u'6':
+ case u'7':
+ case u'8':
+ case u'9':
if (_importState == ImportState::SawImport)
return scanVersionNumber(ch);
else
return scanNumber(ch);
+ case '#':
+ if (_currentLineNumber == 1 && _currentColumnNumber == 2) {
+ // shebang support
+ while (_codePtr <= _endPtr && !isLineTerminator()) {
+ scanChar();
+ }
+ if (_engine) {
+ _engine->addComment(tokenOffset(), _codePtr - _tokenStartPtr - 1,
+ tokenStartLine(), tokenStartColumn());
+ }
+ goto again;
+ }
+ Q_FALLTHROUGH();
+
default: {
uint c = ch.unicode();
bool identifierWithEscapeChars = false;
if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_char.unicode())) {
c = QChar::surrogateToUcs4(ushort(c), _char.unicode());
scanChar();
- } else if (c == '\\' && _char == QLatin1Char('u')) {
+ } else if (c == '\\' && _char == u'u') {
identifierWithEscapeChars = true;
bool ok = false;
c = decodeUnicodeEscapeCharacter(&ok);
@@ -791,7 +815,7 @@ again:
if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_codePtr->unicode())) {
scanChar();
c = QChar::surrogateToUcs4(ushort(c), _char.unicode());
- } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
+ } else if (_char == u'\\' && _codePtr[0] == u'u') {
if (!identifierWithEscapeChars) {
identifierWithEscapeChars = true;
_tokenText.resize(0);
@@ -808,13 +832,11 @@ again:
if (!isIdentifierPart(c))
break;
- if (identifierWithEscapeChars) {
- if (QChar::requiresSurrogates(c)) {
- _tokenText += QChar(QChar::highSurrogate(c));
- _tokenText += QChar(QChar::lowSurrogate(c));
- } else {
- _tokenText += QChar(c);
- }
+ if (QChar::requiresSurrogates(c)) {
+ _tokenText += QChar(QChar::highSurrogate(c));
+ _tokenText += QChar(QChar::lowSurrogate(c));
+ } else {
+ _tokenText += QChar(c);
}
continue;
}
@@ -844,11 +866,11 @@ again:
continue_skipping:
while (_codePtr < _endPtr && _char.isSpace())
scanChar();
- if (_char == QLatin1Char('*')) {
+ if (_char == u'*') {
_tokenLength = _codePtr - _tokenStartPtr - 1;
kind = T_FUNCTION_STAR;
scanChar();
- } else if (_char == QLatin1Char('/')) {
+ } else if (_char == u'/') {
scanChar();
if (handleComment())
goto continue_skipping;
@@ -882,27 +904,28 @@ int Lexer::scanString(ScanStringMode mode)
// correctly in the loop below and afterwards
_skipLinefeed = false;
bool first = true;
+
if (_engine) {
while (_codePtr <= _endPtr) {
if (isLineTerminator()) {
- if ((quote == QLatin1Char('`') || qmlMode())) {
+ if ((quote == u'`' || qmlMode())) {
if (first)
- --_currentLineNumber;
+ --_currentLineNumber; // will be read again in scanChar()
break;
}
_errorCode = IllegalCharacter;
_errorMessage = QCoreApplication::translate("QmlParser", "Stray newline in string literal");
return T_ERROR;
- } else if (_char == QLatin1Char('\\')) {
+ } else if (_char == u'\\') {
break;
- } else if (_char == '$' && quote == QLatin1Char('`')) {
+ } else if (_char == u'$' && quote == u'`') {
break;
} else if (_char == quote) {
_tokenSpell = _engine->midRef(startCode - _code.unicode(), _codePtr - startCode - 1);
_rawString = _tokenSpell;
scanChar();
- if (quote == QLatin1Char('`'))
+ if (quote == u'`')
_bracesCount = _outerTemplateBraceCount.pop();
if (mode == TemplateHead)
@@ -929,7 +952,7 @@ int Lexer::scanString(ScanStringMode mode)
auto setRawString = [&](const QChar *end) {
QString raw(startCode, end - startCode - 1);
raw.replace(QLatin1String("\r\n"), QLatin1String("\n"));
- raw.replace(QLatin1Char('\r'), QLatin1Char('\n'));
+ raw.replace(u'\r', u'\n');
_rawString = _engine->newStringRef(raw);
};
@@ -941,11 +964,11 @@ int Lexer::scanString(ScanStringMode mode)
if (_engine) {
_tokenSpell = _engine->newStringRef(_tokenText);
- if (quote == QLatin1Char('`'))
+ if (quote == u'`')
setRawString(_codePtr - 1);
}
- if (quote == QLatin1Char('`'))
+ if (quote == u'`')
_bracesCount = _outerTemplateBraceCount.pop();
if (mode == TemplateContinuation)
@@ -954,7 +977,7 @@ int Lexer::scanString(ScanStringMode mode)
return T_NO_SUBSTITUTION_TEMPLATE;
return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
- } else if (quote == QLatin1Char('`') && _char == QLatin1Char('$') && *_codePtr == '{') {
+ } else if (quote == u'`' && _char == u'$' && *_codePtr == u'{') {
scanChar();
scanChar();
_bracesCount = 1;
@@ -964,7 +987,7 @@ int Lexer::scanString(ScanStringMode mode)
}
return (mode == TemplateHead ? T_TEMPLATE_HEAD : T_TEMPLATE_MIDDLE);
- } else if (_char == QLatin1Char('\\')) {
+ } else if (_char == u'\\') {
scanChar();
if (_codePtr > _endPtr) {
_errorCode = IllegalEscapeSequence;
@@ -976,7 +999,7 @@ int Lexer::scanString(ScanStringMode mode)
switch (_char.unicode()) {
// unicode escape sequence
- case 'u': {
+ case u'u': {
bool ok = false;
uint codePoint = decodeUnicodeEscapeCharacter(&ok);
if (!ok)
@@ -991,7 +1014,7 @@ int Lexer::scanString(ScanStringMode mode)
} break;
// hex escape sequence
- case 'x': {
+ case u'x': {
bool ok = false;
u = decodeHexEscapeCharacter(&ok);
if (!ok) {
@@ -1002,38 +1025,38 @@ int Lexer::scanString(ScanStringMode mode)
} break;
// single character escape sequence
- case '\\': u = QLatin1Char('\\'); scanChar(); break;
- case '\'': u = QLatin1Char('\''); scanChar(); break;
- case '\"': u = QLatin1Char('\"'); scanChar(); break;
- case 'b': u = QLatin1Char('\b'); scanChar(); break;
- case 'f': u = QLatin1Char('\f'); scanChar(); break;
- case 'n': u = QLatin1Char('\n'); scanChar(); break;
- case 'r': u = QLatin1Char('\r'); scanChar(); break;
- case 't': u = QLatin1Char('\t'); scanChar(); break;
- case 'v': u = QLatin1Char('\v'); scanChar(); break;
-
- case '0':
+ case u'\\': u = u'\\'; scanChar(); break;
+ case u'\'': u = u'\''; scanChar(); break;
+ case u'\"': u = u'\"'; scanChar(); break;
+ case u'b': u = u'\b'; scanChar(); break;
+ case u'f': u = u'\f'; scanChar(); break;
+ case u'n': u = u'\n'; scanChar(); break;
+ case u'r': u = u'\r'; scanChar(); break;
+ case u't': u = u'\t'; scanChar(); break;
+ case u'v': u = u'\v'; scanChar(); break;
+
+ case u'0':
if (! _codePtr->isDigit()) {
scanChar();
- u = QLatin1Char('\0');
+ u = u'\0';
break;
}
Q_FALLTHROUGH();
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
+ case u'1':
+ case u'2':
+ case u'3':
+ case u'4':
+ case u'5':
+ case u'6':
+ case u'7':
+ case u'8':
+ case u'9':
_errorCode = IllegalEscapeSequence;
_errorMessage = QCoreApplication::translate("QmlParser", "Octal escape sequences are not allowed");
return T_ERROR;
- case '\r':
- case '\n':
+ case u'\r':
+ case u'\n':
case 0x2028u:
case 0x2029u:
scanChar();
@@ -1059,8 +1082,8 @@ int Lexer::scanString(ScanStringMode mode)
int Lexer::scanNumber(QChar ch)
{
- if (ch == QLatin1Char('0')) {
- if (_char == QLatin1Char('x') || _char == QLatin1Char('X')) {
+ if (ch == u'0') {
+ if (_char == u'x' || _char == u'X') {
ch = _char; // remember the x or X to use it in the error message below.
// parse hex integer literal
@@ -1084,7 +1107,7 @@ int Lexer::scanNumber(QChar ch)
_tokenValue = d;
return T_NUMERIC_LITERAL;
- } else if (_char == QLatin1Char('o') || _char == QLatin1Char('O')) {
+ } else if (_char == u'o' || _char == u'O') {
ch = _char; // remember the o or O to use it in the error message below.
// parse octal integer literal
@@ -1108,13 +1131,13 @@ int Lexer::scanNumber(QChar ch)
_tokenValue = d;
return T_NUMERIC_LITERAL;
- } else if (_char == QLatin1Char('b') || _char == QLatin1Char('B')) {
+ } else if (_char == u'b' || _char == u'B') {
ch = _char; // remember the b or B to use it in the error message below.
// parse binary integer literal
scanChar(); // consume 'b'
- if (_char.unicode() != '0' && _char.unicode() != '1') {
+ if (_char.unicode() != u'0' && _char.unicode() != u'1') {
_errorCode = IllegalNumber;
_errorMessage = QCoreApplication::translate("QmlParser", "At least one binary digit is required after '0%1'").arg(ch);
return T_ERROR;
@@ -1123,9 +1146,9 @@ int Lexer::scanNumber(QChar ch)
double d = 0.;
while (1) {
int digit = 0;
- if (_char.unicode() == '1')
+ if (_char.unicode() == u'1')
digit = 1;
- else if (_char.unicode() != '0')
+ else if (_char.unicode() != u'0')
break;
d *= 2;
d += digit;
@@ -1145,13 +1168,13 @@ int Lexer::scanNumber(QChar ch)
QVarLengthArray<char,32> chars;
chars.append(ch.unicode());
- if (ch != QLatin1Char('.')) {
+ if (ch != u'.') {
while (_char.isDigit()) {
chars.append(_char.unicode());
scanChar(); // consume the digit
}
- if (_char == QLatin1Char('.')) {
+ if (_char == u'.') {
chars.append(_char.unicode());
scanChar(); // consume `.'
}
@@ -1162,14 +1185,14 @@ int Lexer::scanNumber(QChar ch)
scanChar();
}
- if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
- if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ if (_char == u'e' || _char == u'E') {
+ if (_codePtr[0].isDigit() || ((_codePtr[0] == u'+' || _codePtr[0] == u'-') &&
_codePtr[1].isDigit())) {
chars.append(_char.unicode());
scanChar(); // consume `e'
- if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+ if (_char == u'+' || _char == u'-') {
chars.append(_char.unicode());
scanChar(); // consume the sign
}
@@ -1198,7 +1221,7 @@ int Lexer::scanNumber(QChar ch)
int Lexer::scanVersionNumber(QChar ch)
{
- if (ch == QLatin1Char('0')) {
+ if (ch == u'0') {
_tokenValue = 0;
return T_VERSION_NUMBER;
}
@@ -1223,11 +1246,11 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
_patternFlags = 0;
if (prefix == EqualPrefix)
- _tokenText += QLatin1Char('=');
+ _tokenText += u'=';
while (true) {
switch (_char.unicode()) {
- case '/':
+ case u'/':
scanChar();
// scan the flags
@@ -1246,7 +1269,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
_tokenLength = _codePtr - _tokenStartPtr - 1;
return true;
- case '\\':
+ case u'\\':
// regular expression backslash sequence
_tokenText += _char;
scanChar();
@@ -1260,15 +1283,15 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
scanChar();
break;
- case '[':
+ case u'[':
// regular expression class
_tokenText += _char;
scanChar();
while (_codePtr <= _endPtr && ! isLineTerminator()) {
- if (_char == QLatin1Char(']'))
+ if (_char == u']')
break;
- else if (_char == QLatin1Char('\\')) {
+ else if (_char == u'\\') {
// regular expression backslash sequence
_tokenText += _char;
scanChar();
@@ -1286,7 +1309,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
}
}
- if (_char != QLatin1Char(']')) {
+ if (_char != u']') {
_errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression class");
return false;
}
@@ -1339,10 +1362,9 @@ bool Lexer::isIdentLetter(QChar ch)
{
// ASCII-biased, since all reserved words are ASCII, aand hence the
// bulk of content to be parsed.
- if ((ch >= QLatin1Char('a') && ch <= QLatin1Char('z'))
- || (ch >= QLatin1Char('A') && ch <= QLatin1Char('Z'))
- || ch == QLatin1Char('$')
- || ch == QLatin1Char('_'))
+ if ((ch >= u'a' && ch <= u'z')
+ || (ch >= u'A' && ch <= u'Z')
+ || ch == u'$' || ch == u'_')
return true;
if (ch.unicode() < 128)
return false;
@@ -1351,19 +1373,19 @@ bool Lexer::isIdentLetter(QChar ch)
bool Lexer::isDecimalDigit(ushort c)
{
- return (c >= '0' && c <= '9');
+ return (c >= u'0' && c <= u'9');
}
bool Lexer::isHexDigit(QChar c)
{
- return ((c >= QLatin1Char('0') && c <= QLatin1Char('9'))
- || (c >= QLatin1Char('a') && c <= QLatin1Char('f'))
- || (c >= QLatin1Char('A') && c <= QLatin1Char('F')));
+ return ((c >= u'0' && c <= u'9')
+ || (c >= u'a' && c <= u'f')
+ || (c >= u'A' && c <= u'F'));
}
bool Lexer::isOctalDigit(ushort c)
{
- return (c >= '0' && c <= '7');
+ return (c >= u'0' && c <= u'7');
}
QString Lexer::tokenText() const
@@ -1533,9 +1555,10 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
setError(QCoreApplication::translate("QmlParser","Imported file must be a script"));
return false;
}
+ lex();
} else if (_tokenKind == T_IDENTIFIER) {
- // .import T_IDENTIFIER (. T_IDENTIFIER)* T_VERSION_NUMBER . T_VERSION_NUMBER as T_IDENTIFIER
+ // .import T_IDENTIFIER (. T_IDENTIFIER)* (T_VERSION_NUMBER (. T_VERSION_NUMBER)?)? as T_IDENTIFIER
while (true) {
if (!isUriToken(_tokenKind)) {
setError(QCoreApplication::translate("QmlParser","Invalid module URI"));
@@ -1552,7 +1575,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
if (_tokenKind != QmlJSGrammar::T_DOT)
break;
- pathOrUri.append(QLatin1Char('.'));
+ pathOrUri.append(u'.');
lex();
if (tokenStartLine() != lineNumber) {
@@ -1561,31 +1584,27 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
}
}
- if (_tokenKind != T_VERSION_NUMBER) {
- setError(QCoreApplication::translate("QmlParser","Module import requires a version"));
- return false; // expected the module version number
- }
-
- version = tokenText();
- lex();
- if (_tokenKind != T_DOT) {
- setError(QCoreApplication::translate( "QmlParser", "Module import requires a minor version (missing dot)"));
- return false; // expected the module version number
- }
- version += QLatin1Char('.');
-
- lex();
- if (_tokenKind != T_VERSION_NUMBER) {
- setError(QCoreApplication::translate( "QmlParser", "Module import requires a minor version (missing number)"));
- return false; // expected the module version number
+ if (_tokenKind == T_VERSION_NUMBER) {
+ version = tokenText();
+ lex();
+ if (_tokenKind == T_DOT) {
+ version += u'.';
+ lex();
+ if (_tokenKind != T_VERSION_NUMBER) {
+ setError(QCoreApplication::translate(
+ "QmlParser", "Incomplete version number (dot but no minor)"));
+ return false; // expected the module version number
+ }
+ version += tokenText();
+ lex();
+ }
}
- version += tokenText();
}
//
// recognize the mandatory `as' followed by the module name
//
- if (! (lex() == T_AS && tokenStartLine() == lineNumber)) {
+ if (! (_tokenKind == T_AS && tokenStartLine() == lineNumber)) {
if (fileImport)
setError(QCoreApplication::translate("QmlParser", "File import requires a qualifier"));
else
@@ -1628,5 +1647,3 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
return true;
}
-
-QT_QML_END_NAMESPACE