Uploaded image for project: 'Qt Design Studio'
  1. Qt Design Studio
  2. QDS-10257

Start with parsing defined expressions from QML

XMLWordPrintable

    • Icon: User Story User Story
    • Resolution: Done
    • Icon: Not Evaluated Not Evaluated
    • QDS 4.3
    • None
    • Logic Building
    • None
    • QDS Berlin - 2023 Week 27/28, QDS Berlin - 2023 Week 29/30
    • f018ea6d8 (qds/dev)

      Start with parsing defined expressions from QML

      This can be done test driven, starting with tests.

      qtcreator/tests/auto/qml contains tests for qml

      The implementation can go here the code can go here: qtcreator/src/libs/qmljs

      Notes:

      structure of if else statement

      Program
      StatementList
      IfStatement
      IdentifierExpression or BinaryExpression or FieldExpression or NotExpression
      Block
      StatementList (one item)
      ExpressionStatement
      CallExpression | FieldExpression
      BinaryExpression (assignment is BinaryExpression)
      LHS: FieldmemberExpression | IdentifierExpression | Literal
      RHS: FieldmemberExpression | IdentifierExpression | Literal
      [else]

      FieldExpression is multiple IdentifierExpression delimited with ".

      The else is part of AST::IfStatement

      class IfStatement
      ExpressionNode *expression; //ast allows inheritance this is e.g. IdentifierExpression or BinaryExpression or FieldExpression
      Statement *ok; //normal statement - should be always Block since we expect {}
      Statement *ko; //else statement can be 0 - should be always Block since we expect {}

      structure of expression

      IdentifierExpression || BinaryExpression || FieldExpression

      BinaryExpression can consist of (IdentifierExpression || BinaryExpression || FieldExpression || NotExpression) - but there can be literals
      literals: NumericLiteral and StringLiteral
      Literals should not be on LHS
      Operators are part of the BinaryExpression as token.

      class BinaryExpression

      { ExpressionNode *left; int op; //I expect this to hold the operator as int/enum ExpressionNode *right; SourceLocation operatorToken; }

      ;

      Thats it - afaik we do not expect anything else.

      The first step would be to run a checker that checks an ast for this expected structure and feeds a simple intermediate representation.
      We can always expect the if with blocks. The StatementLists and Expressions can have slightly different structure in each case.

      algorithm proposal

      1) parse signal handler code block using ast
      2) Match structure
      has if?
      match the statement
      match the condition-expression
      has else?
      match the statement
      3) AST is now stored in MatchedStatement
      If structure does not match the UI becomes readonly. User can reset "code" and start from scratch

      If structure does match we can represent MatchedStatement in UI
      4) UI changes are represented only in MatchedStatement until applied
      5) Once changes are applied we write QML code reparse/rematch and compare

      done

      The ast is read-only and cannot represent an invalid state like if (a &&) ...

      struct Hanlder

      { bool hasIf bool hasElse MatchedStatement ok atchedStatement ko //else statement MatchedCondition condition }

      struct MatchedStatement {
      enum Type

      { FunctionCall, //calling a function Assignment, // assign variable to variable ProperttySet, //assigning literal StateSet //setting state QVariant matchedLiteral //If there is a literal we can store it here. Here we do support numbers, strings/colors and bool literals (true/false) BindingProperty lhs //There always should be a binding property on the left hand side. The first identifier is considered node MatchedFunction function //CallExpression consisting of identifiers with ".". First identifier is considered node. Variable rhs //Similar to function but no function call. Just regular FieldExpression/binding }

      //This should be sufficient to represent any supported statement

      struct MatchedCondition

      { list<ConditionToken> tokens }

      struct ConditionToken {
      enum Type

      { Not, And, Or, LargerThan, LargerEuqalsThan, SmallerThan, SmallerEqualsThan, Equals, LiteralString, LiteralNumber, Variable }

      union

      { //If one these we require extra data Variable variable LiteralString string LiteralNumber number }

      }

      struct MatchedFunction

      { //First item before "." is considered node string nodeId string functionName }

      struct Variable

      { //Only one level for now (.) string nodeId string propertyName }

        For Gerrit Dashboard: QDS-10257
        # Subject Branch Project Status CR V

            ali.kianian Ali Kianian
            thohartm Thomas Hartmann
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes