diff options
Diffstat (limited to 'src/qml/parser/qqmljslexer_p.h')
-rw-r--r-- | src/qml/parser/qqmljslexer_p.h | 234 |
1 files changed, 131 insertions, 103 deletions
diff --git a/src/qml/parser/qqmljslexer_p.h b/src/qml/parser/qqmljslexer_p.h index e2ee4ae351..b6144e8894 100644 --- a/src/qml/parser/qqmljslexer_p.h +++ b/src/qml/parser/qqmljslexer_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QQMLJSLEXER_P_H #define QQMLJSLEXER_P_H @@ -59,6 +23,8 @@ QT_BEGIN_NAMESPACE +class QDebug; + namespace QQmlJS { class Engine; @@ -129,52 +95,44 @@ public: NoQmlImport }; + enum class LexMode { WholeCode, LineByLine }; + + enum class CodeContinuation { Reset, Continue }; + public: - Lexer(Engine *engine); - - int parseModeFlags() const { - int flags = 0; - if (qmlMode()) - flags |= QmlMode|StaticIsKeyword; - if (yieldIsKeyWord()) - flags |= YieldIsKeyword; - if (_staticIsKeyword) - flags |= StaticIsKeyword; - return flags; - } + Lexer(Engine *engine, LexMode lexMode = LexMode::WholeCode); bool qmlMode() const; - bool yieldIsKeyWord() const { return _generatorLevel != 0; } + bool yieldIsKeyWord() const { return _state.generatorLevel != 0; } void setStaticIsKeyword(bool b) { _staticIsKeyword = b; } QString code() const; - void setCode(const QString &code, int lineno, bool qmlMode = true); + void setCode(const QString &code, int lineno, bool qmlMode = true, + CodeContinuation codeContinuation = CodeContinuation::Reset); int lex(); bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix); bool scanDirectives(Directives *directives, DiagnosticMessage *error); - int regExpFlags() const { return _patternFlags; } + int regExpFlags() const { return _state.patternFlags; } QString regExpPattern() const { return _tokenText; } - int tokenKind() const { return _tokenKind; } - int tokenOffset() const { return _tokenStartPtr - _code.unicode(); } + int tokenKind() const { return _state.tokenKind; } + int tokenOffset() const { return _currentOffset + _tokenStartPtr - _code.unicode(); } int tokenLength() const { return _tokenLength; } int tokenStartLine() const { return _tokenLine; } int tokenStartColumn() const { return _tokenColumn; } - inline QStringRef tokenSpell() const { return _tokenSpell; } - inline QStringRef rawString() const { return _rawString; } - double tokenValue() const { return _tokenValue; } + inline QStringView tokenSpell() const { return _tokenSpell; } + inline QStringView rawString() const { return _rawString; } + double tokenValue() const { return _state.tokenValue; } QString tokenText() const; Error errorCode() const; QString errorMessage() const; - bool prevTerminator() const; - bool followsClosingBrace() const; bool canInsertAutomaticSemicolon(int token) const; enum ParenthesesState { @@ -183,14 +141,102 @@ public: BalancedParentheses }; - void enterGeneratorBody() { ++_generatorLevel; } - void leaveGeneratorBody() { --_generatorLevel; } + enum class CommentState { NoComment, HadComment, InMultilineComment }; + + void enterGeneratorBody() { ++_state.generatorLevel; } + void leaveGeneratorBody() { --_state.generatorLevel; } + + struct State + { + Error errorCode = NoError; + + QChar currentChar = u'\n'; + double tokenValue = 0; + + // parentheses state + ParenthesesState parenthesesState = IgnoreParentheses; + int parenthesesCount = 0; + + // template string stack + QStack<int> outerTemplateBraceCount; + int bracesCount = -1; + + int stackToken = -1; + + int patternFlags = 0; + int tokenKind = 0; + ImportState importState = ImportState::NoQmlImport; + + bool validTokenText = false; + bool prohibitAutomaticSemicolon = false; + bool restrictedKeyword = false; + bool terminator = false; + bool followsClosingBrace = false; + bool delimited = true; + bool handlingDirectives = false; + CommentState comments = CommentState::NoComment; + int generatorLevel = 0; + + friend bool operator==(State const &s1, State const &s2) + { + if (s1.errorCode != s2.errorCode) + return false; + if (s1.currentChar != s2.currentChar) + return false; + if (s1.tokenValue != s2.tokenValue) + return false; + if (s1.parenthesesState != s2.parenthesesState) + return false; + if (s1.parenthesesCount != s2.parenthesesCount) + return false; + if (s1.outerTemplateBraceCount != s2.outerTemplateBraceCount) + return false; + if (s1.bracesCount != s2.bracesCount) + return false; + if (s1.stackToken != s2.stackToken) + return false; + if (s1.patternFlags != s2.patternFlags) + return false; + if (s1.tokenKind != s2.tokenKind) + return false; + if (s1.importState != s2.importState) + return false; + if (s1.validTokenText != s2.validTokenText) + return false; + if (s1.prohibitAutomaticSemicolon != s2.prohibitAutomaticSemicolon) + return false; + if (s1.restrictedKeyword != s2.restrictedKeyword) + return false; + if (s1.terminator != s2.terminator) + return false; + if (s1.followsClosingBrace != s2.followsClosingBrace) + return false; + if (s1.delimited != s2.delimited) + return false; + if (s1.handlingDirectives != s2.handlingDirectives) + return false; + if (s1.generatorLevel != s2.generatorLevel) + return false; + return true; + } + + friend bool operator!=(State const &s1, State const &s2) { return !(s1 == s2); } + + friend QML_PARSER_EXPORT QDebug operator<<(QDebug dbg, State const &s); + }; + + const State &state() const; + void setState(const State &state); protected: static int classify(const QChar *s, int n, int parseModeFlags); private: + int parseModeFlags() const; + bool prevTerminator() const; + bool followsClosingBrace() const; inline void scanChar(); + inline QChar peekChar(); int scanToken(); int scanNumber(QChar ch); int scanVersionNumber(QChar ch); @@ -213,54 +259,36 @@ private: uint decodeUnicodeEscapeCharacter(bool *ok); QChar decodeHexEscapeCharacter(bool *ok); + friend QML_PARSER_EXPORT QDebug operator<<(QDebug dbg, const Lexer &l); + private: Engine *_engine; + LexMode _lexMode = LexMode::WholeCode; QString _code; - QString _tokenText; - QString _errorMessage; - QStringRef _tokenSpell; - QStringRef _rawString; - - const QChar *_codePtr; const QChar *_endPtr; - const QChar *_tokenStartPtr; - - QChar _char; - Error _errorCode; - - int _currentLineNumber; - int _currentColumnNumber; - double _tokenValue; - - // parentheses state - ParenthesesState _parenthesesState; - int _parenthesesCount; - - // template string stack - QStack<int> _outerTemplateBraceCount; - int _bracesCount = -1; - - int _stackToken; - - int _patternFlags; - int _tokenKind; - int _tokenLength; - int _tokenLine; - int _tokenColumn; - ImportState _importState = ImportState::NoQmlImport; - - bool _validTokenText; - bool _prohibitAutomaticSemicolon; - bool _restrictedKeyword; - bool _terminator; - bool _followsClosingBrace; - bool _delimited; bool _qmlMode; - bool _skipLinefeed = false; - int _generatorLevel = 0; bool _staticIsKeyword = false; - bool _handlingDirectives = false; + + bool _skipLinefeed = false; + + int _currentLineNumber = 0; + int _currentColumnNumber = 0; + int _currentOffset = 0; + + int _tokenLength = 0; + int _tokenLine = 0; + int _tokenColumn = 0; + + QString _tokenText; + QString _errorMessage; + QStringView _tokenSpell; + QStringView _rawString; + + const QChar *_codePtr = nullptr; + const QChar *_tokenStartPtr = nullptr; + + State _state; }; } // end of namespace QQmlJS |