aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
Commit message (Collapse)AuthorAgeFilesLines
* Qml: qqmljs.g adjust precedence and associativity of keywordsDmitrii Akshintsev12 days1-8/+14
| | | | | | | | This patch changes resolution of conflicts (dangling "else" and "as" ambiguity) using precedence only relationship, which should be sufficient. Additionally it makes most of the nonassoc keywords equal, instead of erroneous relationship that was there before. Change-Id: I8fea33214221af36021b7d122d6d044a09214309 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Qml language: add virtual and override property attributesDmitrii Akshintsev2025-11-274-14/+94
| | | | | | | | | | | | | | | This patch introduces 'virtual' and 'override' keywords. From the grammar perspective they are qml contextual keywords, first of all to preserve backwards compatibility (do not break the users code if they had object attributes named "virtual" or "override") "final" is made qml contextual keyword for the sake of consistency (to treat all "virt specifiers" equally) Change-Id: Ice13a77c8b54ce8219cd45cc7085fb3f10a5e908 Task-number: QTBUG-98320 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* qqlmjs.g: Remove expect statementFabian Kosmale2025-11-261-1/+0
| | | | | | | We do, in fact, not expect any parsing conflict. Change-Id: I2df5e27f42dbdd7660eb0383da3c2bb01c6fc84e Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QtQml: Support trailing comma in list propertiesUlf Hermann2025-10-091-4/+7
| | | | | | | Pick-to: 6.10 Fixes: QTBUG-119504 Change-Id: I553c8ea3277fef6a04e48aab4a5b510bee4e9e0c Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* qmlformat: format return type annotationsSami Shalayel2025-09-301-3/+2
| | | | | | | | | | | Adapt the parser to not ignore return type annotations in function declarations, and visit the return type annotations in the ScriptFormatter visitor. Pick-to: 6.10 Task-number: QTBUG-137944 Change-Id: Ib54aa17b056a87215baa83535038b867a3b7e195 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* qmlformat: format list type annotationsSami Shalayel2025-09-302-1/+7
| | | | | | | | | | | | | | | | Add sourcelocations for `<>` in list types like `list<int>` in AST::Type, and fix their lastSourceLocation() method to show the `>` location when applicable. Add the new sourcelocations to qqmldomcomments to also be able to anchor comments around the `<>`. Implement ScriptFormatter for list type annotations. Pick-to: 6.10 Task-number: QTBUG-137944 Change-Id: I73af498a9165f99fdceb69c8822ce5bb94e02ff9 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QML: Preserve return type annotation for function expressionsLuca Di Sera2025-09-181-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The parser for QML allows the specification of type hints on a series of callable elements; such as functions defined as part of a QML type. It is possible, for example, to provide an hint for the return type of a function expression, anonymous or not, such as: ``` import QtQml QtObject { property var: function (lhs: int, rhs: int)): int { return lhs + rhs; } } ``` While this parses correctly, the return type annotation is currently discarded as part of the parsing process, such that in turn it is invisible to the engine when managing the function. Hence, ensure that the return type annotation for function expressions is preserved during the parsing process so that it can later be visible to the engine. In particular, the AST node that represents this kind of element can already store a type annotation that refers to its return type and later down the line, the code generation phase is already able to take into account the annotation when it builds its representation of the function. Nonetheless, that storage is currently purposefully not used in the cases we are interested into, albeit it is in other cases that might be considered more common. This is most probably, albeit nowhere near certainly, due to simple historical reasons and partial implementations related to type hints. Thus, ensure that the return type annotation is correctly preserved and stored for `FunctionExpression` rules during the parsing process, such that it can later be recognized and used by the engine. A few test cases related to the return type annotation were added. Pick-to: 6.10 Task-number: QTBUG-137944 Change-Id: I6133bb286a916d0687ff5d5542b9aa769cfd493b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Mark security criticality for most files in qml/parserFabian Kosmale2025-09-1610-0/+10
| | | | | | | | | | | | | | | | | | | | | Mark the lexing / parsing code as security critical, because they are data parsers. While _running_ QML code needs to assume trusted input, we probably should not have this restriction on the parser, so that tools like qmllint, qmlls and qdoc can safely pass any file to the parser, without having to worry about security implications. The criticality extends to qqmljskeywords_p.h, as we do custom bounds checking in the functions defined there. qqmljsastfwd_p is marked as insignificant, as it only contains fowrard declarations and no logic at all. The other marked files have the default level (significant). QUIP: 23 Task-number: QTBUG-136966 Pick-to: 6.10 6.9 6.8 Change-Id: I1e44f346d91d6d66c8e9632f0dec4a11fffc935a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* ScriptFormatter: Preserve user spacing around commentsOlivier De Cannière2025-07-032-4/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | We want to respect the formatting and spacing of the user around comments. Comments already contain the information about spaces and new lines before and after them and they are included when writing the comment. However, this conflicts with the need the add spaces around tokens in the non-commented case. We need to only ensure a space if it doesn't come immediately before or after a comment since the comment already includes the spacing. Otherwise we would be duplicating the spaces. In order to do this, keep track of whether the last write was a comment and defer actually adding the spaces until we know no comment follows. This fixes errors where extra spaces were inserted around comments. Tests needed to be updated to adhere to the rule that we respect user spacing around comments. The SpaceBeforePostComment option is also no longer needed now and was removed. The remaining options were also renamed to better reflect their behavior. Task-number: QTBUG-133315 Change-Id: I38e7fb65ac76ead6287c9dcb2f43f8fdd09347da Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* qmlformat: Fix comment handling around enumsOlivier De Cannière2025-06-302-0/+7
| | | | | | | | | | | | | | | | | | Add more regions for comments to attach to. Remove special casing preventing comments to attach to the braces of an enum. It is no longer needed. The comma token belong to the enum entry after it. The opposite was assumpted to be true before which led to comments being attached to the wrong item and moving around. Task-number: QTBUG-133315 Task-number: QTBUG-123386 Pick-to: 6.10 6.9 6.8 Change-Id: I32f8c49aff6a4c88c323450beec9aa0f5bc5bbe5 Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qqmljs.g: Treat newly introduced keyword tokens like existing onesFabian Kosmale2025-06-161-1/+6
| | | | | | | | | | | | Keywords are not operators, and they have no associativity. This has the side effect of resolving shift/reduce errors. Amends f649231204f8e864ed1ef88257bd88eaca06731c Fixes: QTBUG-137703 Change-Id: Ied4423d6f760b9c6d7ee48a011e5b9c3c8aff8df Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* qqmljs.g: Only have T_REQUIRED in QMLReservedWord, not QMLContextualKeywordFabian Kosmale2025-06-161-1/+1
| | | | | | | | | | Otherwise, the two rules always conflict. Task-number: QTBUG-137703 Change-Id: Ia04304a5b6b1ca219c4d6a69867a053c6de449f9 Reviewed-by: Dmitrii Akshintsev <dmitrii.akshintsev@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qqmljs.g: Remove superfluous grammar ruleFabian Kosmale2025-06-161-2/+0
| | | | | | | | | | | | | | | | | | We had two rules for how to get a SimpleType from T_FINAL. One being SimpleType -> T_FINAL , the other being SimpleType -> UiQualifiedId -> MemberExpression -> PrimaryExpression -> IdentifierReference -> JSIdentifier -> QMLReservedWord -> T_FINAL Remove the first one as it creates a warning, and is already covered by the second one. Task-number: QTBUG-137703 Change-Id: Ibc491b6dda7b0452772160abdf0f67bccfdeb0fd Reviewed-by: Dmitrii Akshintsev <dmitrii.akshintsev@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Qml Language: qqmljs.g remove T_RESERVED_WORDDmitrii Akshintsev2025-06-123-8/+3
| | | | | | | | There is no logic in the code based on the T_RESERVED_WORD, therefore this commit removes it in favor of using explicit tokens. Change-Id: Ie71f805e87bcee5c0b41ca24dc0c8fb20d13871b Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QML Language: qqmljs.g update future reserved keywordsDmitrii Akshintsev2025-06-124-113/+38
| | | | | | | | | | | | Initial implementation was based on the 3rd edition of ECMAScript. Many things have changed since then and most of keywords were removed from that section, even starting from the 5th edition of the standard. This commit removes most of these reserved keywords, while leaving out some which might potentially be useful for QML in the future. Change-Id: I0190a6ea6d08b5d0797eb46c6636ffdb295b4565 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Qml Language: qqmljs.g restructure Identifiers and KeywordsDmitrii Akshintsev2025-06-121-66/+53
| | | | | | | | | | | | | | | | | | | | | This commit aims to add some clarity on what is considered QmlIdentifier, JsIdentifier, IdentifierName and related keywords. It adds clear reference points for the ES7, also aims to group tokens in the corresponding smaller sets. This commit also adds some comments, aiming to explain the existence of such definitions like JsIdentifier One of the motivations behind this commit to make it more clear and explicit for the maintenance and further addition of keywords, such as, for example virtual and override, which are going to be ContextualKeywords from the QML perspective, while still being totally valid Identifiers from the ECMA perspective. Change-Id: I3d335bda609e8977c7c720c62229633821b1da13 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* qqmljs.g Return spelling for T_ONDmitrii Akshintsev2025-06-101-0/+1
| | | | | | | | | | It seems it was accidentaly removed as part of alignment with ES7 standard. Returning it back to be usable / referable for matching instead of manually hardcoded spelling. Change-Id: Ib3c7fd7b103c611eea97ecc899963ab17a1f1e7b Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* AST: Move using declaration to fwd headerOlivier De Cannière2025-05-302-2/+2
| | | | | | | | | | | | | | | QQmlJS::AST::Expression was renamed to QQmlJS::AST::CommaExpression and a using declaration was introduced to not break outside users of the AST. There were still build issues due to the renaming. The using declaration should probably be in the fwd header to avoid them. Move it there. Amends 138889eab042fda149e13ed1d2c86d543da003d0 Pick-to: 6.9 6.8 Change-Id: Ia48fc738bf1ed32314871bf7cdcdc913351d136f Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QQmlJS::Lexer: Make Lexer::classify accept QStringViewDmitrii Akshintsev2025-05-263-16/+16
| | | | | | | | | | Accept QStringView instead of QChat* and size. This will be handy in later patches to compare keywords through strings and not by characters Change-Id: Ie6750feb643614ceb37cad508e3bb0b33ea13952 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Qml: Rename Expression to CommaExpression in the ASTOlivier De Cannière2025-05-165-7/+10
| | | | | | | | Expression is confusing. Pick-to: 6.9 6.8 6.5 Change-Id: I365ce06a266e24a506b14734fef8b977d6794a72 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmlformat: don't make comments jump around functionsSami Shalayel2025-03-183-10/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add more comment anchors around functions to avoid comments from "jumping through" parenthesis, the "function" keyword or through commas. Add missing sourcelocations to AST::FunctionExpression in the parser for arrow functions. This requires building the FunctionExpression* early so that it can access the location of the parentheses. Add the comma location in FormalParameterList in the parser. This allows qmlformat to properly attach comments to commas, function keywords, parentheses in lambdas and arrow functions instead of making the comments "jump" through them. Fix a domcomparison method to actually ignore parentheses during qmlformat checks: this is because qmlformat tends to remove parentheses of lambdas like `(x) => x` that become `x => x`. Now that we actually save the location of the parentheses, the domcomparison method sees that the parentheses disappear and complains wrongfully. Therefore, ignore the newly added parentheses sourcelocations when doing qmlformat checks. We have plenty of other tests that make sure the parentheses are the way they should be. Pick-to: 6.9 6.8 Task-number: QTBUG-123386 Change-Id: I08a3536cfb27fa1cdc2a78cc9849f609a8113a07 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qmlformat: Support the final property attributeOlivier De Cannière2025-03-065-21/+40
| | | | | | | | | Note that any actual language support for final will be added in later commits. Task-number: QTBUG-98320 Change-Id: I8b8f9fbc998219ed4cd504c10f54bc3483e65f06 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* qmlformat: Preserve "?." tokens for various member access expressionsOlivier De Cannière2025-01-292-0/+6
| | | | | | | Fixes: QTBUG-132280 Pick-to: 6.9 6.8 Change-Id: I9307a70eea4640da19124f65e49cb3c661d443a1 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* qml: limit qml file size to 2GB or 4GB in parserSami Shalayel2024-10-093-0/+28
| | | | | | | | | | | | | | | | | | | | | | | | | Add a check in the lexer and fail in the parser if the file to be parsed is too big for qsizetype and quint32. QQmlJS::SourceLocation uses quint32 to save the offset, and code using QQmlJS::SourceLocation's offset usually do their computation on qsizetype. Therefore, limit the QML file size to std::numerical_limits<quint32>::max() on 64 bits machine when qsizetype has a representation for std::numerical_limits<quint32>::max(), and to std::numerical_limits<qsizetype>::max() otherwise. Thats 2Gb on 32 bits machine and 4Gb on 64 bits machine. Currently, using qml tooling on files bigger than the limits mentioned above already leads to UB without this patch. Add a helper to construct SourceLocation from qsizetype indexes. Task-number: QTBUG-127833 Change-Id: Ic255964e13ebae08488ed160e59d504638f1b9ad Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* qqmldomastcreator: add filelocations for signal parenthesesSami Shalayel2024-08-232-0/+4
| | | | | | | | Adapt the parser and qqmldomastcreator to have the locations of the parentheses of a signal available as FileLocationRegion. Change-Id: Ib9bc5f6e94dfa44ff692a4f452abf45d9789edab Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* QML: Allow type annotations for all functions in QML modeUlf Hermann2024-08-091-0/+4
| | | | | | | Fixes: QTBUG-112638 Change-Id: Ib41c372aca3f9bb124ca92eeaa41f8e770f2a800 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* qqmljslexer: split T_FUNCTION_STAR into T_FUNCTION and T_STARSami Shalayel2024-07-033-78/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Partially reverts commit 4ba86a97011dda2d8792ee23f0e86015715a592e that tried to reduce the number of parser conflicts by introducing new parser rules and a new token T_FUNCTION_STAR. The new token T_FUNCTION_STAR seems unnecessary: removing it does not make new conflicts appear in the parser. Furthermore, it allows removing some special handling from the lexer. Therefore, remove all occurrences of T_FUNCTION_STAR and replace it with T_FUNCTION and T_STAR. Add the sourcelocation of the star to the FunctionExpression so it becomes available (previously the star was located at the end of the function-token sourcelocation). Change the parser to create Function Declaration early in its FunctionStar rule, so it can save the sourcelocation of the "function" keyword and the "*" token in FunctionDeclaration. Also fix indexes in the parser where T_FUNCTION T_STAR does shift all the following arguments by one position to the left. Pick-to: 6.8 Fixes: QTBUG-126676 Change-Id: I4c405c136137628e58469b91f2b93dc2edb110e3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* Lexer: Fix spelling error in translatable messageFriedemann Kleint2024-06-121-1/+1
| | | | | | Pick-to: 6.8 Change-Id: I0625e5675f9a7424eebee84b734faa69f676f74a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlJS::Lexer: fix QChar construction from enumMarc Mutz2024-06-052-2/+2
| | | | | | | | | | | | | | | We're going to make the QChar constructors not perform implicit conversions anymore, but only accept exactly the listed constructor arguments, and enums are not one of these, so fix by using char16_t instead. The variable is anyway only compared to char16_t literals in the rest of the function. As a drive-by, mark the variable const and remove overparenthesization. Amends dad5d1cc82a57a4f657aa3f37ad2f55b69d5b015 Change-Id: I81d6adbb290d994c8a3bb4b998572da3765c08a9 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Allow numeric separators in numeric literalsLuca Di Sera2024-05-081-0/+53
| | | | | | | | | | | | | | | | | | | | ES2021 introduced numeric separators in numeric literals to improve readability. For example, one billion can be written "1_000_000_000" where "_" are the numeric separators. Update the QML lexer to allow numeric separators, based on https://262.ecma-international.org/12.0/#prod-NumericLiteralSeparator. Add a non-exhaustive test case to `tst_qqmlparser` to track the behavior. Fixes: QTBUG-123792 Change-Id: Ie62d1f40fc8e0c7678e7dfea16408bdeeba6d150 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Dmitrii Akshintsev <dmitrii.akshintsev@qt.io>
* semantichighlighting: highlight for-declarationsSemih Yavuz2024-05-072-0/+8
| | | | | | | | | | | | | | Add declarationKindToken location in the pattern element node. This is required for semantic highlighting to highlight the type correctly within iteration statements. Add type identifier region for the declaration kind token in the for-declaration construct. Fixes: QTBUG-124677 Task-number: QTBUG-120000 Change-Id: I02520bdc6f1b9dfc5d47078cd7e5e8d2f40bf382 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* qqmljs.g: Add location for identifier in object destructuringSemih Yavuz2024-05-071-0/+1
| | | | | | | | | | | | Otherwise, we can't find the source location of the binding identifier in object destructuring syntax. For example, const {x: y = 34} = obj case, we now can get the location of y which is required for semantic highlighting. Task-number: QTBUG-120000 Change-Id: If8d78e7604179e9a13f62e3fd9ccdb2b3aefd6cd Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add file locations for Pragma keyword, id and the valuesSemih Yavuz2024-04-112-0/+3
| | | | | | | | | | | | | | | | | | Add missing identifier token location in the grammar file. Implement the missing file location regions for Pragma dom element. Those regions are the way to get source location of the corresponding dom element in the Dom API. It is needed in semantic highlighting implementation. Adding new region breaks a few of the pragma completions tests since it changes the closest item found and this makes the assumption that colon region exist wrong . Fix it by passing the Pragma element instead of the subelements of it to insidePragmaCompletion function. This guarantees that we find the ColonTokenRegion in the current item. Task-number: QTBUG-123775 Task-number: QTBUG-120000 Change-Id: I2759412810ce125d6ee36bb0d70509a859667266 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QQMLJSAST Change traversal order for ExportDeclarationDmitrii Akshintsev2024-03-131-1/+1
| | | | | | | | | | | It is not clear whether there are special corner cases when it's important to traverse first FromClause instead of ExportClause. However the order of traversing ExportClause will make it simpler for the formatting usecase when there is a need to format an export statement: `export ExportClause FromClause` Change-Id: I43bfbe7737bd925d55df3f05de72445d6d16aa6d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QMLJSASTVisitor. Add JSVisitorDmitrii Akshintsev2024-02-141-0/+24
| | | | | | | | | | | | This proxy visitor is helpful to be used in the cases where traversing only JS AST Nodes is needed, for example when formatting plain JS files This also allows to get rid of some of the same trivial implementations. Task-number: QTBUG-117849 Change-Id: If7d8086032f286b0cc7559df7f0f0ab9869bd12e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* qqmljs.g: use canonical form for recovery optionsSami Shalayel2023-12-291-12/+12
| | | | | | | Rename the properties to control recovery to use the canonical namings. Change-Id: I7f05a3ad95baa54d7a374391ae2bfb1d48db4789 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmlls: adapt parser for attached/grouped properties completionSami Shalayel2023-12-291-0/+21
| | | | | | | | | | | | | | | Add a recovery mode to the parser to accept bindings that are not completely written out, and create an empty statement for that. This mode is called enableIncompleteBindings and is only enabled for qmlls. Also adapt qqmldomastcreator to those empty statements, and qmllsutils. Pick-to: 6.7 Fixes: QTBUG-120169 Task-number: QTBUG-92876 Change-Id: Ic24cbb61e3be08368027371e377bf75ce87fafb1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qmlls: completions in variable declarationsSami Shalayel2023-12-053-2/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add the equal token sourcelocation into a ScriptPattern. This is somewhat cumbersome because the parser has no direct access to it. Instead, create a new ExpressionNode type called InitializerExpression: it contains an ExpressionNode and an equaltoken, and is populated in the parser for Initializer and Initializer_In rules. It also implements some pure virtual methods to not be abstract, and has its own Kind_InitializerExpression. The PatternElement constructor extracts the location of the equaltoken from the InitializerExpression in its constructor, and saves it in its new member equaltoken. Later on, the Dom constructor will be able to add the location of the equal token to the Dom, such that qmlls's completion can decide whether or not completion is required in variable declaration statements. With this commit, qmlls will provide completions only after the above mentioned equal token. The explanation is in a comment in qqmllsutils, but the rough idea is that everything before the '=' is a variable name (so it should not be in use yet, to avoid shadowing and confusing QML programs) and that everything behind a '=' is a default value that can be any arbitrary expression in JS. This default value can be a method name, a property name, etc, so provide completion at this place. Also takes care of completions inside of deconstructions nested inside variable declarations. Task-number: QTBUG-117445 Change-Id: Ie58ffda4de9636796a9a690537affef85ede398d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qqmljs.g: insert empty identifiers when missingSami Shalayel2023-11-281-22/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For the completion in qmlls, users usually expect to see a list of completions after typing in a T_DOT ("."). Sadly, this T_DOT usually makes the QML code invalid or ambiguous, such that the parser aborts parsing. For qmlls, this is quite bad: no completions can be proposed if the AST cannot be computed. Therefore, this commit tries to make the parser a little bit more resistant to missing T_IDENTIFIER behind T_DOT. Add a yyprevtoken field in the parser to keep track of what was the last successfully parsed token, and update it with yytoken before yytoken changes. Extract the pushTokenWithEmptyLocation() logic from the automatic semicolon inserting code, and reuse it for the automatic insertion of identifiers after dots. Add some tests in tst_qmlls_utils and adapt the qmlls completion code to work with missing right hand sides (RHS) of dotted expression `a.b`. Create a new file missingRHS.qml because yyy.qml does not seem to stop growing. The fix of this commit does not take care of all possible cases: when T_DOT is followed by an T_IDENTIFIER, then no T_IDENTIFIER is inserted even if the parsing fails afterwards. This happens when a JS statement is behind a T_DOT without identifier, for example. Add tests for that too, QEXPECT_FAIL them and put them in a separate file missingRHS.parserfail.qml. They need to be in a separate file because no completions can be obtained when the parser fails, and that affects all the completions of the entire file. This special file missingRHS.parserfail.qml also needs to be ignored by tst_qmlformat. Task-number: QTBUG-115836 Change-Id: If307430131a7df25ae9bd4ea0393d47c0641c8d3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qqmljs.g: add option to disable automatic identifier insertionSami Shalayel2023-11-281-0/+7
| | | | | | | | | | | | | | | | | Add a RecoveryOption enum that can be passed to QmlFile's constructor to enable or disable recovery. Extend DomCreationOption by another value WithRecovery, such that users of the Dom can enable recovery via the FileToLoad argument of the Dom's file to load. Enable the recovery in the qqmlcodemodel for qmlls. The actual recovery is implemented in a separate commit in the relation chain. Task-number: QTBUG-115836 Change-Id: Icb6b115cf667c77c596fa335bc37bb12bf680cce Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qmlls: fix completions on qualified identifiersSami Shalayel2023-11-162-0/+4
| | | | | | | | | | | | | | | | | | | | Typing `someProperty.x` would propose methods and properties that do not exist in someProperty in qmlls. Add the operator sourcelocation inside the BinaryExpression so that qmlls can distinguish if currently working on the left or right hand side of the binary expression. Also fix the resolveExpressionType call to not use the last bit of the qualified identifier: in `console.l`, only resolve up to `console` and ignore the `l` bit that might not have been spelled out completely. Previously, the resolution step would fail because of the `l` and no completion would get generated. Task-number: QTBUG-117445 Change-Id: I5929d7153d5b9f5104efd1b88d24d76e0d7a514a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* Allow pragma Translator to have a string literal as valueLucie Gérard2023-11-141-1/+2
| | | | | | | | Also add test and update documentation Task-number: QTBUG-114528 Change-Id: I7baa3a3268c4ccd2efe5bd8be7d790e909c430c6 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qmlls: do not autocomplete property definition nameSami Shalayel2023-10-121-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Make QQmlLSUtils::itemsFromTextLocation smarter: it differentiates now between property definitions and bindings. Example: For this property ``` property var somePropertyDef: Item { property var propertyDef: 42; } ``` The ranges of the filelocations are as follows: somePropertyDef FileLocations range: |------------------------------------------------------------------| propertyDef FileLocations range: |-----------------------------| binding FileLocations range: |----------------| The previous behavior of QQmlLSUtils::itemsFromTextLocation could not distinguish between a binding being alone or a binding being in a property definition, and would return the binding. The new implementation recognizes when a binding is inside a property definition, and returns this propertydefinition if the current text position is before the ':'-token. It even can choose the right property definition when there are nested ones, like in the example above with somePropertyDef and propertyDef. This means that qmlls can now differentiate between being inside a property definition name and the binding of the property definition. This allows to suppress completions inside of property definition names. Completion inside the binding of a property definition are still handled by the code for normal bindings. Fixes: QTBUG-117440 Change-Id: If0592ccadd8b1e3e9efbf4952c8044c40854202b Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qmlls: add completion for pragmasSami Shalayel2023-09-262-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | To be able to decide how a pragma is completed, one needs to know if we are before or after the ':', for example in 'pragma NativeMethodehavior: AcceptThisObject', one needs to know if we are completing the pragma names or the pragma values. For this, add a sourcelocation for the colon in AST::UiPragma in the parser, and pass it on in the FileLocations so the sourcelocation of the colon, when existing, can be accessed from the DomItem. Once the position of the colon is known, the names or values for the pragmas can be completed. To easily obtain the position of the colon of a DomItem, move some code from the Binding completion into a static helper to reuse it for pragmas. Also fix some typos in the warning messages about invalid pragmas in qqmljsimportvisitor. Task-number: QTBUG-116899 Change-Id: Ib20bb6aa50e9b8dc5830f426d0ca9719693c0a15 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* FormalParameterList: prepare for qmlformatSami Shalayel2023-09-111-8/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Remove useless arg#0 bindingIdentifier from FormalParameterList. They are used nowhere, are not tested and are not even set correctly: FormalParameterList::finish() sets next to nullptr before its forloop that goes from this to this->next (that was freshly set to nullptr three lines above)... Instead of setting bindingIdentifier to arg#0 when its empty and testing for arg#, just test for bindingIdentifier being empty. That saves some trouble in qmlformat because you dont have to care about the position that the current method parameter has. Apropos position of the current parameter: qmlformat needs some context when doing its reformatting test, to avoid reparsing code in completely wrong contexts. Add missing preCode and postCode to MethodParameter to provide an artificial context for qmlformat, so it knows that it is working on a MethodParameter, and also teach qmlformat how to get the FormalParameter out of the artificial context, by extracting it from the FormalParameterList. Pick-to: 6.6 6.5 Change-Id: I2bc82f65d95c3cd09ad846c60dd7561ac03efad3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* qml: fix parser grammar for argument deconstructionSami Shalayel2023-09-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, it was hardcoding a StringLiteralPropertyName for a BindingIdentifier. This does not make sense because BindingIdentifier cannot be string literals, they have to be identifiers. Also, this is problematic for deconstruction, e.g.: ``` function f(something) { let { x = 'x' } = something; // (1) return x; } ``` In (1), you cannot differentiate between the property name x and the string literal x, because the parser creates a string literal with value 'x' for both. Notably, qmlls cannot differentiate between a 'find usages' on the first x that is supposed to find the x in the return statement, and the second "x" that is supposed to find no usages because it is a string literal. Same happens also for deconstruction in method parameters. Add tests for qmlls for deconstruction in let-statements, and method parameters. Make sure qmlformat ignores this qmlfile as it cannot format deconstruction yet. Task-number: QTBUG-100084 Change-Id: Ib7df974437e442dc0bfca75381c773c4d30b11bb Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* qmlls: highlight names inside of inline component definitionsSami Shalayel2023-08-172-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of highlighting the base type of the inline component, highlight the name of the inline component, e.g. highlight 'C' in ``` component C: Item {} ``` instead of 'Item'. This requires changing QQmlLSUtils::findTypeDefinitionOf's signature to return a QQmlLSUtilsLocation instead of a DomItem. QQmlLSUtils::findDefinitionOf already returns a QQmlLSUtilsLocation. Also, the QQmlJS::UiInlineComponent parser class did not know about its identifier token. Add it, so the corresponding DomItem knows where its identifier lies. Fix the tests that finds definitions of inline components by removing the QEXPECT_FAIL and adjusting the column numbers. Also simplify the test by removing the "name" that is not related to the actual test. Fix other failing tests by setting their QEXPECT_FAIL at the right place (they fail earlier because of this change, when looking for the type definition of int for example). Change-Id: I00b2f73c2357b7e7fb74619bbc7b948e67619420 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmlls: check user-supplied names on renamingSami Shalayel2023-08-101-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Implement the checking of user-supplied names for renaming operations in QmlLSUtils and qqmlrenamesymbolsupport.cpp Add a helper method QQmlLSUtils::isValidEcmaScriptIdentifier that runs the lexer on an identifier. Reject identifiers that do not parse as T_IDENTIFIER, like keywords and invalid unicode escapes, for example. Extend QQmlLSUtilsExpressionType to contain the name of the current object. Drive-by change: fix a off-by-one bug in the lexer, where files (or identifiers, in this case) could not be lexed when they were ending with an unicode-sequence. Also, do not crash on JSIdentifiers without semantic scope in resolveIdentifierExpressionType. Add some tests, and fix a warning about positionAfterOneIndent not being used in tst_qmlls_modules.cpp. Add QQmlLSUtils::isChangedSignalName next to QQmlLSUtils::isChangedHandlerName, and QQmlLSUtils::isHandlerName and add tests for all three. Fixes: QTBUG-114951 Task-number: QTBUG-114788 Change-Id: I0f1a544b70dfb69bca4aef355a8a8658f1d23081 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QQmlJSLexer: make internal helper methods privateFabian Kosmale2023-08-082-13/+14
| | | | | | | | ...and move one of them out-of-line; it's only used inside the lexer's implementation file anyway. Change-Id: I19ad039dda804a4283f644b58b555e082a770f04 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qmlformat: fix formatting of object destructuringSemih Yavuz2023-08-011-6/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The following issues are fixed: - [1]Incorrect detection of the property name as a string literal and thus writing out them with quotation marks - [2] Duplication of property name when a scoped variable is used as property key - [3] Writing out additional brackets during deconstruction - [4] Incorrect formatting when a default is assigned to a lhs variable like [a = 24, b] = array - [5] Automatic addition of "" characters into the object keys - [6] Automatic addition of assignment operator, instead only add it when there is a pending initializer Also, add the colon token location which was missing in the pattern property rules. Remove it from a couple of rules that was giving incorrect result. We require the location information of the colon token to be correct when formatting. A few of tst_qmlformat and tst_reformatter tests are adapted to the above mentioned changes [1], [2], [5]. [ChangeLog][qmlformat][Important Behavior Changes] qmlformat will no longer add "" characters automatically in the object keys unless the object key is actually a string literal. Also, using a scoped variable as the property key will no longer result in the duplication of the property name. Pick-to: 6.6 Fixes: QTBUG-108275 Fixes: QTBUG-114839 Change-Id: I272d41d13df34ff5877f3efebe43c80255dd7c2b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>