diff --git a/syntaxes/expression.json b/syntaxes/expression.json index b528aa2925..32ef7a8bdd 100644 --- a/syntaxes/expression.json +++ b/syntaxes/expression.json @@ -558,6 +558,120 @@ } ] }, + "templateLiteral": { + "patterns": [ + { + "include": "#templateLiteralCall" + }, + { + "contentName": "string.template.ts", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)?(`)", + "beginCaptures": { + "1": { + "name": "entity.name.function.tagged-template.ts" + }, + "2": { + "name": "string.template.ts punctuation.definition.string.template.begin.ts" + } + }, + "end": "`", + "endCaptures": { + "0": { + "name": "string.template.ts punctuation.definition.string.template.end.ts" + } + }, + "patterns": [ + { + "include": "#templateLiteralSubstitutionElement" + }, + { + "include": "#stringCharacterEscape" + } + ] + } + ] + }, + "templateLiteralCall": { + "patterns": [ + { + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", + "end": "(?=`)", + "patterns": [ + { + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", + "end": "(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)?`)", + "patterns": [ + { + "include": "#support-function-call-identifiers" + }, + { + "name": "entity.name.function.tagged-template.ts", + "match": "([_$[:alpha:]][_$[:alnum:]]*)" + } + ] + }, + { + "include": "#typeArguments" + } + ] + }, + { + "begin": "([_$[:alpha:]][_$[:alnum:]]*)?\\s*(?=(<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))(([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer|typeof|readonly)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{([^\\{\\}]|\\{[^\\{\\}]*\\})*\\}))*\\})|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(\\[([^\\[\\]]|(\\[([^\\[\\]]|\\[[^\\[\\]]*\\])*\\]))*\\])|(\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\(([^\\(\\)]|\\([^\\(\\)]*\\))*\\)))*\\))|(?<==)\\>)*(?))*(?)*(?\\s*)`)", + "beginCaptures": { + "1": { + "name": "entity.name.function.tagged-template.ts" + } + }, + "end": "(?=`)", + "patterns": [ + { + "include": "#typeArguments" + } + ] + } + ] + }, + "templateLiteralSubstitutionElement": { + "name": "meta.template.expression.ts", + "begin": "\\${", + "beginCaptures": { + "0": { + "name": "punctuation.definition.template-expression.begin.ts" + } + }, + "end": "}", + "endCaptures": { + "0": { + "name": "punctuation.definition.template-expression.end.ts" + } + }, + "patterns": [ + { + "include": "#ngExpression" + } + ], + "contentName": "meta.embedded.line.ts" + }, + "typeArguments": { + "name": "meta.type.parameters.ts", + "begin": "<", + "beginCaptures": { + "0": { + "name": "punctuation.definition.typeparameters.begin.ts" + } + }, + "end": ">", + "endCaptures": { + "0": { + "name": "punctuation.definition.typeparameters.end.ts" + } + }, + "patterns": [ + { + "include": "#typeArgumentsBody" + } + ] + }, "stringCharacterEscape": { "name": "constant.character.escape.ts", "match": "\\\\(x\\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)" @@ -592,6 +706,9 @@ }, { "include": "#qstringDouble" + }, + { + "include": "#templateLiteral" } ] }, @@ -776,6 +893,24 @@ } ] }, + "typeArgumentsBody": { + "patterns": [ + { + "match": "(?>=|>>>=|\|=/, - }, - { - name: 'keyword.operator.bitwise.shift.ts', - match: /<<|>>>|>>/, - }, - { - name: 'keyword.operator.comparison.ts', - match: /===|!==|==|!=/, - }, - { - name: 'keyword.operator.relational.ts', - match: /<=|>=|<>|<|>/, - }, - { - name: 'keyword.operator.logical.ts', - match: /\!|&&|\?\?|\|\|/, - }, - { - name: 'keyword.operator.bitwise.ts', - match: /\&|~|\^|\|/, - }, - { - name: 'keyword.operator.assignment.ts', - match: /\=/, - }, - { - name: 'keyword.operator.decrement.ts', - match: /--/, - }, - { - name: 'keyword.operator.increment.ts', - match: /\+\+/, - }, - { - name: 'keyword.operator.arithmetic.ts', - match: /\%|\*|\/|-|\+/, - }, - { - match: /(?<=[_$[:alnum:]])\s*(\/)(?![\/*])/, - captures: { - 1: { - name: 'keyword.operator.arithmetic.ts', + { + include: '#functionCall', }, - }, - }, - { - include: '#typeofOperator', - }, - ], - }, - - functionCall: { - begin: /(?=(\??\.\s*)?([_$[:alpha:]][_$[:alnum:]]*)\s*(<([^<>]|\<[^<>]+\>)+>\s*)?\()/, - end: /(?<=\))(?!(\??\.\s*)?([_$[:alpha:]][_$[:alnum:]]*)\s*(<([^<>]|\<[^<>]+\>)+>\s*)?\()/, - patterns: [ - { - name: 'punctuation.accessor.ts', - match: /\?/, - }, - { - name: 'punctuation.accessor.ts', - match: /\./, - }, - { - name: 'entity.name.function.ts', - match: /([_$[:alpha:]][_$[:alnum:]]*)/, + { + include: '#identifiers', + }, + { + include: '#parenExpression', + }, + { + include: '#punctuationComma', + }, + { + include: '#punctuationAccessor', + }, + ], }, - { - name: 'meta.type.parameters.ts', - begin: /\/, + end: /\]/, endCaptures: { 0: { - name: 'punctuation.definition.typeparameters.end.ts', + name: 'meta.brace.square.ts', }, }, patterns: [ { - include: '#type', + include: '#ngExpression', }, { include: '#punctuationComma', }, ], }, - { - include: '#parenExpression', - }, - ], - }, - - functionParameters: { - name: 'meta.parameters.ts', - begin: /\(/, - beginCaptures: { - 0: { - name: 'punctuation.definition.parameters.begin.ts', - }, - }, - end: /\)/, - endCaptures: { - 0: { - name: 'punctuation.definition.parameters.end.ts', - }, - }, - patterns: [ - { - include: '#decorator', - }, - { - include: '#parameterName', - }, - { - include: '#variableInitializer', - }, - { - name: 'punctuation.separator.parameter.ts', - match: /,/, - }, - ], - }, - - identifiers: { - patterns: [ - { - name: 'support.class.ts', - match: /([_$[:alpha:]][_$[:alnum:]]*)(?=\s*\.\s*prototype\b(?!\$))/, + + booleanLiteral: { + patterns: [ + { + name: 'constant.language.boolean.true.ts', + match: /(?)|((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))', - captures: { - 1: { - name: 'punctuation.accessor.ts', + { + name: 'keyword.operator.expression.delete.ts', + match: /(?>=|>>>=|\|=/, }, - 3: { - name: 'meta.delimiter.decimal.period.ts', + { + name: 'keyword.operator.bitwise.shift.ts', + match: /<<|>>>|>>/, }, - 4: { - name: 'meta.delimiter.decimal.period.ts', + { + name: 'keyword.operator.comparison.ts', + match: /===|!==|==|!=/, }, - 5: { - name: 'meta.delimiter.decimal.period.ts', + { + name: 'keyword.operator.relational.ts', + match: /<=|>=|<>|<|>/, }, - 6: { - name: 'meta.delimiter.decimal.period.ts', + { + name: 'keyword.operator.logical.ts', + match: /\!|&&|\?\?|\|\|/, }, - }, - }, - ], - }, - - numericConstantLiteral: { - patterns: [ - { - name: 'constant.language.nan.ts', - match: /(?]|\<[^<>]+\>)+>\s*)?\()/, + end: + /(?<=\))(?!(\??\.\s*)?([_$[:alpha:]][_$[:alnum:]]*)\s*(<([^<>]|\<[^<>]+\>)+>\s*)?\()/, + patterns: + [ + { + name: 'punctuation.accessor.ts', + match: /\?/, + }, + { + name: 'punctuation.accessor.ts', + match: /\./, + }, + { + name: 'entity.name.function.ts', + match: /([_$[:alpha:]][_$[:alnum:]]*)/, + }, + { + name: 'meta.type.parameters.ts', + begin: /\/, + endCaptures: + { + 0: + { + name: 'punctuation.definition.typeparameters.end.ts', + }, + }, + patterns: + [ + { + include: '#type', + }, + { + include: '#punctuationComma', + }, + ], + }, + { + include: '#parenExpression', + }, + ], }, - ], - }, - - parameterName: { - patterns: [ - { - match: - '(?x)(?:\\s*\\b(readonly)\\s+)?(?:\\s*\\b(public|private|protected)\\s+)?(\\.\\.\\.)?\\s*(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))', - captures: { - 1: { - name: 'storage.modifier.ts', + + functionParameters: + { + name: 'meta.parameters.ts', + begin: /\(/, + beginCaptures: + { + 0: + { + name: 'punctuation.definition.parameters.begin.ts', + }, + }, + end: /\)/, + endCaptures: + { + 0: + { + name: 'punctuation.definition.parameters.end.ts', + }, + }, + patterns: + [ + { + include: '#decorator', + }, + { + include: '#parameterName', + }, + { + include: '#variableInitializer', + }, + { + name: 'punctuation.separator.parameter.ts', + match: /,/, + }, + ], }, - 2: { - name: 'storage.modifier.ts', + + identifiers: + { + patterns: + [ + { + name: 'support.class.ts', + match: /([_$[:alpha:]][_$[:alnum:]]*)(?=\s*\.\s*prototype\b(?!\$))/, + }, + { + match: + '(?x)([?!]?\\.)\\s*(?:\n([[:upper:]][_$[:digit:][:upper:]]*)|\n([_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*)', + captures: + { + 1: + { + name: 'punctuation.accessor.ts', + }, + 2: + { + name: 'constant.other.object.property.ts', + }, + 3: + { + name: 'variable.other.object.property.ts', + }, + }, + }, + { + match: + '(?x)(?:([?!]?\\.)\\s*)?([_$[:alpha:]][_$[:alnum:]]*)(?=\\s*=\\s*((async\\s+)|(function\\s*[(<])|(function\\s+)|([_$[:alpha:]][_$[:alnum:]]*\\s*=>)|((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)))', + captures: + { + 1: + { + name: 'punctuation.accessor.ts', + }, + 2: + { + name: 'entity.name.function.ts', + }, + }, + }, + { + match: '([?!]?\\.)\\s*([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])', + captures: + { + 1: + { + name: 'punctuation.accessor.ts', + }, + 2: + { + name: 'constant.other.property.ts', + }, + }, + }, + { + match: '([?!]?\\.)\\s*([_$[:alpha:]][_$[:alnum:]]*)', + captures: + { + 1: + { + name: 'punctuation.accessor.ts', + }, + 2: + { + name: 'variable.other.property.ts', + }, + }, + }, + { + match: + '(?x)(?:\n([[:upper:]][_$[:digit:][:upper:]]*)|\n([_$[:alpha:]][_$[:alnum:]]*)\n)(?=\\s*\\.\\s*[_$[:alpha:]][_$[:alnum:]]*)', + captures: + { + 1: + { + name: 'constant.other.object.ts', + }, + 2: + { + name: 'variable.other.object.ts', + }, + }, + }, + { + name: 'constant.character.other', + match: '([[:upper:]][_$[:digit:][:upper:]]*)(?![_$[:alnum:]])', + }, + { + name: 'variable.other.readwrite.ts', + match: '[_$[:alpha:]][_$[:alnum:]]*', + }, + ], }, - 3: { - name: 'keyword.operator.rest.ts', + + literal: + { + name: 'literal.ts', + patterns: + [ + { + include: '#numericLiteral', + }, + { + include: '#booleanLiteral', + }, + { + include: '#nullLiteral', + }, + { + include: '#undefinedLiteral', + }, + { + include: '#numericConstantLiteral', + }, + { + include: '#arrayLiteral', + }, + { + include: '#thisLiteral', + }, + ], }, - 4: { - name: 'entity.name.function.ts', + + nullLiteral: + { + name: 'constant.language.null.ts', + match: /(?) | ((<([^<>]|\\<[^<>]+\\>)+>\\s*)?\\(([^()]|\\([^()]*\\))*\\)(\\s*:\\s*(.)*)?\\s*=>)) ) | (:\\s*( (<) | ([(]\\s*( ([)]) | (\\.\\.\\.) | ([_$[:alnum:]]+\\s*( ([:,?=])| ([)]\\s*=>) )) ))) ))', + captures: + { + 1: + { + name: 'storage.modifier.ts', + }, + 2: + { + name: 'storage.modifier.ts', + }, + 3: + { + name: 'keyword.operator.rest.ts', + }, + 4: + { + name: 'entity.name.function.ts', + }, + 5: + { + name: 'keyword.operator.optional.ts', + }, + }, + }, + { + match: + /(?:\s*\b(readonly)\s+)?(?:\s*\b(public|private|protected)\s+)?(\.\.\.)?\s*(?\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>)*(?))*(?)*(?\s*)?`)/, + end: /(?=`)/, + patterns: [ + { + begin: + /(?=(([_$[:alpha:]][_$[:alnum:]]*\s*\??\.\s*)*|(\??\.\s*)?)([_$[:alpha:]][_$[:alnum:]]*))/, + end: + /(?=(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>)*(?))*(?)*(?\s*)?`)/, + patterns: [ + {include: '#support-function-call-identifiers'}, + { + name: 'entity.name.function.tagged-template.ts', + match: /([_$[:alpha:]][_$[:alnum:]]*)/, + }, + ], + }, + {include: '#typeArguments'}, + ], + }, + { + begin: + /([_$[:alpha:]][_$[:alnum:]]*)?\s*(?=(<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))(([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>|\<\s*(((keyof|infer|typeof|readonly)\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\{([^\{\}]|(\{([^\{\}]|\{[^\{\}]*\})*\}))*\})|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(\[([^\[\]]|(\[([^\[\]]|\[[^\[\]]*\])*\]))*\])|(\'([^\'\\]|\\.)*\')|(\"([^\"\\]|\\.)*\")|(\`([^\`\\]|\\.)*\`))(?=\s*([\<\>\,\.\[]|=>|&(?!&)|\|(?!\|)))))([^<>\(]|(\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\))|(?<==)\>)*(?))*(?)*(?\s*)`)/, + beginCaptures: {1: {name: 'entity.name.function.tagged-template.ts'}}, + end: /(?=`)/, + patterns: [{include: '#typeArguments'}], + }, + ], + }, + + templateLiteralSubstitutionElement: { + name: 'meta.template.expression.ts', + begin: /\${/, + beginCaptures: {0: {name: 'punctuation.definition.template-expression.begin.ts'}}, + end: /}/, + endCaptures: {0: {name: 'punctuation.definition.template-expression.end.ts'}}, + patterns: [{include: '#ngExpression'}], + contentName: 'meta.embedded.line.ts', }, - 2: { - name: 'invalid.illegal.newline.ts', + + typeArguments: { + name: 'meta.type.parameters.ts', + begin: //, + endCaptures: {0: {name: 'punctuation.definition.typeparameters.end.ts'}}, + patterns: [{include: '#typeArgumentsBody'}], }, - }, - patterns: [ - { - include: '#stringCharacterEscape', + + stringCharacterEscape: { + name: 'constant.character.escape.ts', + match: /\\(x\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)/, }, - ], - }, - - stringCharacterEscape: { - name: 'constant.character.escape.ts', - match: /\\(x\h{2}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)/, - }, - - // Derived from - // https://github.com/microsoft/vscode-typescript-next/blob/849bce9ce68c4b87e6e1de0c31573ff376c7078d/syntaxes/TypeScript.tmLanguage.json#L2855-L2873 - ternaryExpression: { - // 1. negative lookahead (?!\?\.\s*[^[:digit:]]) ensures safe navigation does not match - // 2. match the ternary question mark with (\?) - // 3. negative lookahead (?!\?) ensures nullish coalesce does not match - begin: /(?!\?\.\s*[^[:digit:]])(\?)(?!\?)/, - beginCaptures: { - 1: { - name: 'keyword.operator.ternary.ts', + + // Derived from + // https://github.com/microsoft/vscode-typescript-next/blob/849bce9ce68c4b87e6e1de0c31573ff376c7078d/syntaxes/TypeScript.tmLanguage.json#L2855-L2873 + ternaryExpression: { + // 1. negative lookahead (?!\?\.\s*[^[:digit:]]) ensures safe navigation does not match + // 2. match the ternary question mark with (\?) + // 3. negative lookahead (?!\?) ensures nullish coalesce does not match + begin: /(?!\?\.\s*[^[:digit:]])(\?)(?!\?)/, + beginCaptures: { + 1: { + name: 'keyword.operator.ternary.ts', + }, + }, + end: /\s*(:)/, + endCaptures: { + 1: { + name: 'keyword.operator.ternary.ts', + }, + }, + patterns: [ + { + include: '#ngExpression', + }, + ], }, - }, - end: /\s*(:)/, - endCaptures: { - 1: { - name: 'keyword.operator.ternary.ts', + + thisLiteral: { + name: 'variable.language.this.ts', + match: /(?])|(?<=[\}>\]\)]|[_$[:alpha:]])\s*(?=\{)/, + patterns: [ + { + include: '#type', + }, + ], }, - { - include: '#qstringDouble', + + typeBuiltinLiterals: { + name: 'support.type.builtin.ts', + match: /(?)\s*(?=\()/, + end: /(?<=\))/, + patterns: [ + { + include: '#functionParameters', + }, + ], + }, + { + name: 'meta.type.function.ts', + begin: + '(?x)((?=[(]\\s*(([)])|(\\.\\.\\.)|([_$[:alnum:]]+\\s*(([:,?=])|([)]\\s*=>))))))', + end: /(?<=\))/, + patterns: [ + { + include: '#functionParameters', + }, + ], + }, + ], }, - }, - end: /(?=$|[,);\}\]]|\/\/|")|(?==[^>])|(?<=[\}>\]\)]|[_$[:alpha:]])\s*(?=\{)/, - patterns: [ - { - include: '#type', + + typeName: { + patterns: [ + { + match: /([_$[:alpha:]][_$[:alnum:]]*)\s*([?!]?\.)/, + captures: { + 1: { + name: 'entity.name.type.module.ts', + }, + 2: { + name: 'punctuation.accessor.ts', + }, + }, + }, + { + name: 'entity.name.type.ts', + match: /[_$[:alpha:]][_$[:alnum:]]*/, + }, + ], }, - ], - }, - - typeBuiltinLiterals: { - name: 'support.type.builtin.ts', - match: /(?)\s*(?=\()/, - end: /(?<=\))/, + + typeOperators: { patterns: [ { - include: '#functionParameters', + include: '#typeofOperator', + }, + { + name: 'keyword.operator.type.ts', + match: /[&|]/, + }, + { + name: 'keyword.operator.expression.keyof.ts', + match: /(?))))))', - end: /(?<=\))/, + + typeParenOrFunctionParameters: { + name: 'meta.type.paren.cover.ts', + begin: /\(/, + beginCaptures: { + 0: { + name: 'meta.brace.round.ts', + }, + }, + end: /\)/, + endCaptures: { + 0: { + name: 'meta.brace.round.ts', + }, + }, patterns: [ + { + include: '#type', + }, { include: '#functionParameters', }, ], }, - ], - }, - - typeName: { - patterns: [ - { - match: /([_$[:alpha:]][_$[:alnum:]]*)\s*([?!]?\.)/, - captures: { - 1: { - name: 'entity.name.type.module.ts', + + typeTuple: { + name: 'meta.type.tuple.ts', + begin: /\[/, + beginCaptures: { + 0: { + name: 'meta.brace.square.ts', }, - 2: { - name: 'punctuation.accessor.ts', + }, + end: /\]/, + endCaptures: { + 0: { + name: 'meta.brace.square.ts', }, }, + patterns: [ + { + include: '#type', + }, + { + include: '#punctuationComma', + }, + ], }, - { - name: 'entity.name.type.ts', - match: /[_$[:alpha:]][_$[:alnum:]]*/, - }, - ], - }, - typeObjectMembers: { - patterns: [ - { - include: '#typeAnnotation', - }, - { - include: '#punctuationComma', - }, - { - include: '#punctuationSemicolon', - }, - ], - }, - - typeObject: { - name: 'meta.object.type.ts', - begin: /\{/, - beginCaptures: { - 0: { - name: 'punctuation.definition.block.ts', - }, - }, - end: /\}/, - endCaptures: { - 0: { - name: 'punctuation.definition.block.ts', - }, - }, - patterns: [ - { - include: '#typeObjectMembers', + typeArgumentsBody: { + patterns: [ + { + match: + /(? +{{ `hello world` }} +{{ tag`hello world` }} +{{ `before ${123} - ${fn()} after` }} +{{ tag`before ${123} - ${fn()} after` }} + {{ (let param of params?.get('value')!.property | async).anotherProperty | translate: ['language1', 'language2']; index as i }} diff --git a/syntaxes/test/data/expression.html.snap b/syntaxes/test/data/expression.html.snap index de3e3f6789..70abf88143 100644 --- a/syntaxes/test/data/expression.html.snap +++ b/syntaxes/test/data/expression.html.snap @@ -975,6 +975,63 @@ # ^ template.ng expression.ng # ^^ template.ng punctuation.definition.block.ts > +> +#^^^^^^^^^^^^^^^^^^^^^^^^^^^ template.ng +>{{ `hello world` }} +#^^ template.ng punctuation.definition.block.ts +# ^ template.ng expression.ng +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.begin.ts +# ^^^^^^^^^^^ template.ng expression.ng string.template.ts +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.end.ts +# ^ template.ng expression.ng +# ^^ template.ng punctuation.definition.block.ts +>{{ tag`hello world` }} +#^^ template.ng punctuation.definition.block.ts +# ^ template.ng expression.ng +# ^^^ template.ng expression.ng entity.name.function.tagged-template.ts +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.begin.ts +# ^^^^^^^^^^^ template.ng expression.ng string.template.ts +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.end.ts +# ^ template.ng expression.ng +# ^^ template.ng punctuation.definition.block.ts +>{{ `before ${123} - ${fn()} after` }} +#^^ template.ng punctuation.definition.block.ts +# ^ template.ng expression.ng +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.begin.ts +# ^^^^^^^ template.ng expression.ng string.template.ts +# ^^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts +# ^^^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts constant.numeric.decimal.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts +# ^^^ template.ng expression.ng string.template.ts +# ^^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts +# ^^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts entity.name.function.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts meta.brace.round.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts meta.brace.round.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts +# ^^^^^^ template.ng expression.ng string.template.ts +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.end.ts +# ^ template.ng expression.ng +# ^^ template.ng punctuation.definition.block.ts +>{{ tag`before ${123} - ${fn()} after` }} +#^^ template.ng punctuation.definition.block.ts +# ^ template.ng expression.ng +# ^^^ template.ng expression.ng entity.name.function.tagged-template.ts +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.begin.ts +# ^^^^^^^ template.ng expression.ng string.template.ts +# ^^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts +# ^^^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts constant.numeric.decimal.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts +# ^^^ template.ng expression.ng string.template.ts +# ^^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.begin.ts +# ^^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts entity.name.function.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts meta.brace.round.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts meta.embedded.line.ts meta.brace.round.ts +# ^ template.ng expression.ng string.template.ts meta.template.expression.ts punctuation.definition.template-expression.end.ts +# ^^^^^^ template.ng expression.ng string.template.ts +# ^ template.ng expression.ng string.template.ts punctuation.definition.string.template.end.ts +# ^ template.ng expression.ng +# ^^ template.ng punctuation.definition.block.ts +> > #^^^^^^^^^^^^^^^ template.ng >{{ (let param of params?.get('value')!.property | async).anotherProperty | translate: ['language1', 'language2']; index