aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
Commit message (Collapse)AuthorAgeFilesLines
* 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>
* qmlls: find definitions of function parametersSami Shalayel2023-06-052-11/+10
| | | | | | | | | | | | | | | Function parameter definitions in the QQmlJSScope were lacking their source location, such that asking the definition of a parameter always returned the location of the first parameter. Fix it by writing the proper Location in the QQmlJSScope. This requires adding the location information to BoundName(s). Also added some tests. Task-number: QTBUG-111409 Change-Id: Ieb6155f120ca24e899af4b3824cab561788d008b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
* QmlDom: support function parameters and coSami Shalayel2023-06-021-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Implement function parameters for function definitions in the Dom, as otherwise the unused scriptelements in the stack will make the following script element construction fail. Also implement all the dom elements required by function parameters. Instead of filling in only the script element for the defaultValues, (and failing when encountering more complex expressions), add a ScriptExpression that can model more complex expressions in the argument (including default value, deconstruction, type annotations, etc.) in the Dom::MethodParameter class and leave the pre-existing defaultValue as is for now. Requirements for successful function parameter construction: * Add support for JS arrays and JS objects literals in the Dom. These ones are required to model parameter deconstruction, e.g. to pick certain list elements or object properties from the argument object/array * Fix the iteration order for PatternElementLists and PatternPropertyLists, as both are required for the JS arrays and objects * Add all kind of property names (used in JS object literals and JS object deconstruction) as literals in qqmldomastcreator. * JS array and object deconstruction happened to reveal a bug for VariableDeclarations, fix it (because you can use deconstruction in variable declarations) + add tests for that. * Support Type annotations in the Dom: this means that type annotations for methods are also created and also needs to be collected. Add a field returnType in Dom::MethodInfo for this. * Make sure that all QQmlJSScope's in the Dom are wrapped in optionals (because they are null when the semantic analysis option is not passed) and adapt the getters to it. Task-number: QTBUG-92876 Change-Id: I81df66989e833c9acd75f854b49dcc15b0729e99 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmlformat: change comment handling behaviorSemih Yavuz2023-04-121-2/+2
| | | | | | | | | | | | | | | | | | | | | | Cumulative commit for adding zero-length comments in qmljsengine and also handling of empty lines after comments. qmljsengine only adds comments if the relavant comment length is larger than 0. Allow adding zero length comments since empty comments might be useful and required in some situations. Unlike the other formatting tools (clang-format, rustfmt) qmlformat didnt respect the emptylines after comments and stick the comments to the associated element. Change this behavior such that a newline/ blankline is added(but no more than one). A few tests in qmldom/reformatter needed to be edited due to this new behavior. Pick-to: 6.5 Fixes: QTBUG-111231 Change-Id: I2fcdda0bfe569b7a1d19c4058e1604cb0d73291d Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* Use X-Macro for AST-visitor declarationSami Shalayel2023-04-121-650/+133
| | | | | | | | | Use the X-Macro to simplify the AST-Visitor and BaseVisitor definitions. Task-number: QTBUG-92876 Change-Id: I8f20490ae551a27a50cd037eb705baac3673eba5 Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Kill TypeArgument(List)Sami Shalayel2023-04-123-8/+0
| | | | | | | | | | | Remove the forward declarations of TypeArgument(List) and its uses. This amends e89a06753c772bd96b3299e03b2f7ad78ffc9fb9 that removed TypeArgument(List)'s definition while leaving its forward declarations and uses around. Change-Id: I1a3e27ce18611beaf84b7c59e01a622f9e7f2477 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QML: Allow pragmas with multiple valuesUlf Hermann2023-02-225-5/+83
| | | | | | | | | This will be needed in follow-up changes. Task-number: QTBUG-94807 Change-Id: I6243ea31290251c30dd0aceaae878568bc1c0525 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QmlCompiler: Fix recognition of builtin list typesUlf Hermann2022-12-152-12/+12
| | | | | | | | | | | | | Previously all list types used as arguments or return types for methods had to be looked up via the imports. However, builtin types are not part of the imports at run time. Therefore, recognize list types already early on, when generating the IR. This is the same way we do it for property types and it allows us to easily identify lists of builtins. Pick-to: 6.5 Fixes: QTBUG-109147 Change-Id: I91fa9c8fc99c1e0155cc5db5faddd928ca7fabbc Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Parser: Simplify argument "lists" for type annotationsUlf Hermann2022-10-195-89/+38
| | | | | | | | | | There can in fact only be one type argument, and we don't need a finish() method. In fact the finish() method didn't return the type argument at all. Task-number: QTBUG-107171 Change-Id: Ifb7d85ca42a38d37da71b6453b458c7ec10cd64d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qml: fix TypeArgumentListFawzi Mohamed2022-10-191-1/+1
| | | | | | | | | | | | | | | | | | All type annotations in qml did drop any typeArgument due to a bug in TypeArgumentList: instead of keeping a circular list that is inverted while building, and finally transformed in the inverse in the finish() method, it kept a singly linked list and the finish method would return a nullptr. Fix the formatting and indenting of type annotations now that they work. Pick-to: 6.4 Task-number: QTBUG-107171 Change-Id: I9deff83d328c5c0784a4104e406036a435278945 Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Port from container::count() and length() to size()Marc Mutz2022-10-071-2/+2
| | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8: auto QtContainerClass = anyOf( expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o), expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)); makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container', with the extended set of container classes recognized. Change-Id: Idb1f75dfe2323bd1d9e8b4d58d54f1b4b80c7ed7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Remove unused includes in qml, first partSemih Yavuz2022-09-141-1/+0
| | | | | | | | | | | | | | | Drop unnecessary includes detected by clangd-iwyu. Add new includes due to the transitive includes. Also, some of the includes were detected as unused even if they were actually in use. In those cases, use angular brackets instead of "" which deceives the tool not to complain. Affected subfolders: Debugger, Compiler, JsApi, JsRuntime, Memory, Parser Task-number: QTBUG-106473 Change-Id: I01d996a2a2ba31cbbc5f60f5454c8f850298f528 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmldom: line by line indentation/reformattingFawzi Mohamed2022-09-011-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | Introduces support for line by line indentation and reformatting This is done with a simplified restartable lexer and parser. * qqmldomscanner: a tokenizer for a single line, built on the top of the normal lexer. One of the key property is that the state can be stored and restarted. Thus after an edit, re-indenting or split of a line one can restart the lexer with the state at the end of the previous line, and re-evaluate from there on. * qqmlcodeformatter: contains a stack based parser that is used for syntax highlighting and indentation. The state is a stack of integers, and along with it also the indent level is stored and the accepted syntax is a superset of the grammar (typically repetitions are allowed and order is more permissive). This builds on the top of the scanner, and also allows restarts. The public interface focuses on having the stored state of the parser and lexer, and being able to update it after a line of text, or give the correct indentation for a line. * qqmldomindentinglinewriter: has a LineWriter that uses the CodeFormatter internally to re-indent every line. Change-Id: Ifce9ed14ecd157bec65fb740b2c7ee8a5fc0729a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qqmljslexer: add dump to qDebugFawzi Mohamed2022-08-302-0/+70
| | | | | Change-Id: I8ce66f5d7a75ae8ba8733ddb464c2198bd18ce27 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Parser: Preserve keywordiness of "static" across nested classesUlf Hermann2022-08-301-6/+6
| | | | | | | | | | | | | | | | "static" is a keyword in the context of JS classes, no matter how deeply nested. Therefore, keep track of the nesting level. Switching the keywordiness of "static" off during method definition parsing makes no sense as the standard doesn't mention such a thing. Method bodies are strict code where you cannot use "static" as identifier. Methods and properties can be called "static" no matter if static is a keyword or not. Pick-to: 6.4 Fixes: QTBUG-96631 Change-Id: Ia09e52fe2ae72721fe1c8a9b95899a31095db988 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qml: make lexer line by line & restartableFawzi Mohamed2022-08-183-243/+441
| | | | | | | | | | | | | | The Qml lexer was not restartable, make it so that a line can be parsed independently from another. This is a requirement for efficient indenting and highlighting. Old approach in creator used a separate finite state machien "scanner", now it is possible to use the same lexer as the parser. One can "checkpoint" every few lines, and restart the process form the line above the change, and stop when the status is the same as before. Change-Id: I72a13a767ac7adfe103e56e60902e61c88e4fd82 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
* qqmljs.g: improve performance avoiding reference counted containerFawzi Mohamed2022-07-251-2/+2
| | | | | | | | | | | | | | | | As detected in Creator by hjk: Detaching the rawString_stack alone shows up at 0.85% when loading Creator inside Creator. One write access is actually used from qmljs.g:593, so making the whole function const would need more work. Take a short cut and replace the unneeded reference counted container with a non-reference counted one. Change-Id: I480d539f532f9dbfbb0ddef986a7177dfca9b173 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QML: Support negative values in enumsFabian Kosmale2022-07-191-0/+24
| | | | | | | | [ChangeLog][QML] It is now possible to use negative integers as values for QML enum declarations. Change-Id: I321ad45ab41d5ef23d37d202a384d40e2e1e239d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Explicitly include qtaggedpointer.hIvan Solovev2022-07-011-0/+1
| | | | | | | | | | It is now transitively included from qversionnumber.h (via qmetatype.h), but that will change soon. Pick-to: 6.4 Task-number: QTBUG-102350 Change-Id: Ida458c446ca241f3f603628eb9b2d15c0a546b3e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmlast: add missing tokens for enum declarationMoody Liu2022-06-242-0/+4
| | | | | | | this adds possibility for qmlls to highlight an enum name Change-Id: If802bfa3afd8bdcd5eed894fce50bad5907464bf Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlJS::AST: Do not dereference nullptr to get static AST kindUlf Hermann2022-06-151-2/+4
| | | | | | | | Coverity-Id: 394805 Change-Id: I7fe8994d28fe9d13a4c441a5c527aeb77ce78b6c Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Use SPDX license identifiersLucie Gérard2022-06-1111-493/+27
| | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Pick-to: 6.4 Task-number: QTBUG-67283 Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Make sure all private headers include at least one otherThiago Macieira2022-03-101-2/+2
| | | | | | | | | | See script in qtbase/util/includeprivate for the rules. Since these files are being touched anyway, I also ran the updatecopyright.pl script too. Change-Id: Ib056b47dde3341ef9a52ffff13ef677e471674b6 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QML: Take care of QVariant when converting function argumentsUlf Hermann2022-02-231-0/+3
| | | | | | | | | | | | | We cannot convert to QVariant using QMetaType::convert(). But we can just construct a QVariant with the desired type and data. This will become an issue once we automatically convert argument types to match the desired type inside the function. As a side effect, also allow declaring "var" arguments to functions. Change-Id: Idc14021d8d85d3d09ee7b7f286de91b56ea02bfd Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qqmljslexer: Make lexer restartableMaximilian Goldstein2022-02-182-485/+509
| | | | | | | | | | | Moves all variables that represent the lexers state into a separate struct that can be read and modified from the outside. This is necessary in order to enable per-line formatting in qmldom Change-Id: Iedde139cec6380bd62fa12c5ddec2a943a3b50f9 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QML: Allow declaring and binding list<foo> properties in one stepUlf Hermann2022-01-311-4/+21
| | | | | | | | | | | We apply the same trick we already use for the UiObjectMember rules: We add an ExpressionStatementLookahead before the T_LBRACKET starting the UiArrayMemberList. Task-number: QTBUG-82443 Change-Id: Ibdb3111b7721d2af087c14b79538dee131b8e301 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QQmlJs: Add a missing includeOrgad Shaneh2022-01-041-0/+1
| | | | | | | | Amends c9380aa42805cf55736dc87c87149d912282c0ae. Pick-to: 6.3 Change-Id: I0ccf5263f97463ba4e6f012c42dc516dbe50696c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QmlCompiler: Fix return type calculationUlf Hermann2021-12-061-0/+9
| | | | | | | | | | We can return void from a function, explicitly or implicitly, and we need to be able to wrap that into a QVariant. In order to explicitly return void, we need the void type to be exposed and understood. Pick-to: 6.2 Change-Id: I513cabb25469b89a85b5d212a6825a037400729d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML/AST: Remove dead codeFabian Kosmale2021-11-261-6/+0
| | | | | | | | The qmldevtools library is no more, therefore we can resolve the TODO and remove the method that only existed for it. Change-Id: I685d9305e4b42a34ade56baccce0ec2e49cbcf4a Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* Clean up property attributes (2/2)Fabian Kosmale2021-11-173-145/+175
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit introduces a new AST node for property attributes (currently required, default and readonly). That node is not integrated into our visitors, as it is only meant as an internal implementaion detail of UiPublicMember. All information stored in it is meant to be accessed by UiPublicMember's methods (see also the note below). We use an union of SourceLocation and a node pointer to only pay the overhead of the new node for properties; signals simply store the signal token. The grammar is rewritten with a new UiPropertyAttributes rule, which avoids quite a bit of duplication in various rules, which had to deal with the combinatorial explosion of attributes. Some parse errors are now turned into semantic errors instead (readonly without initializer, required with initializer). By centralizing the handling of attributes in the grammar, we now can easily support e.g. default properties with a list initializer. As part of this restructuring, UiPublicMember's firstSourceLocation is fixed to ensure that we actually return the first source location, independent of the order in which the attributes are written. Note: In theory, we would not need to make UiPropertyAttributes an AST node. It could be a simple data class. However, the parser currently assumes that every pointer in its parser stack is an AST node, and touching that part would be a larger undertaking. As we use a pool allocator, the cost is not that high (though we use more memory from the pool then we would strictly need to). Change-Id: Ia1d9fd7a6553d443cc57bc3d773f5be0aebe0e0e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Clean up property attributes (1/2)Fabian Kosmale2021-11-172-48/+42
| | | | | | | | | | | | Instead of directly accessing the attribute related members of UiPublicMember, we access them via a function. Moreover, we remove some redundancy: A property is readonly/default/required if and only if the corresponding token is valid. Thus we can drop the boolean members. Change-Id: I22f15b2b037e857d2f9d3167cb761cba9516a135 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* qqmljs.g: always set operatorTokenFawzi Mohamed2021-11-041-0/+1
| | | | | | | operatorToken was not set in all cases for assignments Change-Id: I0c2a3aba022034ed9b3c8021433b71b3df4b3ccf Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add a Pragma for list assign behaviorUlf Hermann2021-10-132-2/+13
| | | | | | | | | | [ChangeLog][QtQml] You can now specify the list property assignment behavior in QML using the "ListPropertyAssignBehavior" pragma. This is analogous to the macros you can use in C++. Fixes: QTBUG-93642 Change-Id: I9bdcf198031f1e24891f947b0990a3253d29a998 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>