From df2caa8248c26ffdad5f56c8ad9a32f78674ebcf Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 18 Mar 2022 16:43:35 -0700 Subject: [PATCH] Updated to support 'infer..extends' --- TypeScript.YAML-tmLanguage | 26 ++++++- TypeScript.tmLanguage | 73 +++++++++++++++++-- TypeScriptReact.tmLanguage | 73 +++++++++++++++++-- package-lock.json | 66 +++++++++++++++++ package.json | 1 + tests/baselines/inferTypes.baseline.txt | 96 ++++++++++++++++++++++++- tests/cases/inferTypes.ts | 3 +- 7 files changed, 319 insertions(+), 19 deletions(-) diff --git a/TypeScript.YAML-tmLanguage b/TypeScript.YAML-tmLanguage index fd02e2ba..5a4fbb8a 100644 --- a/TypeScript.YAML-tmLanguage +++ b/TypeScript.YAML-tmLanguage @@ -2332,8 +2332,8 @@ repository: - include: '#type-parameters' - include: '#type-tuple' - include: '#type-object' - - include: '#type-conditional' - include: '#type-operators' + - include: '#type-conditional' - include: '#type-fn-type-parameters' - include: '#type-paren-or-function-parameters' - include: '#type-function-return-type' @@ -2519,6 +2519,7 @@ repository: type-operators: patterns: - include: '#typeof-operator' + - include: '#type-infer' # Handle the object types followed by | or & operator as { can be used as end of Type in many places and this avoids tripping that - begin: ([&|])(?=\s*\{) beginCaptures: @@ -2536,11 +2537,30 @@ repository: match: '{{startOfIdentifier}}keyof{{endOfIdentifier}}' - name: keyword.operator.ternary.ts match: (\?|\:) - - name: keyword.operator.expression.infer.ts - match: '{{startOfIdentifier}}infer(?=\s+[_$[:alpha:]])' - name: keyword.operator.expression.import.ts match: '{{startOfIdentifier}}import(?=\s*\()' + type-infer: + patterns: + # try to match infer..extends on a single line + - match: '{{startOfIdentifier}}(infer)\s+({{identifier}})\s+(extends){{endOfIdentifier}}' + name: meta.type.infer.ts + captures: + '1': { name: keyword.operator.expression.infer.ts } + '2': { name: entity.name.type.ts } + '3': { name: keyword.operator.expression.extends.ts } + # alternatively, match across multiple lines + - begin: '{{startOfIdentifier}}infer(?=\s+[_$[:alpha:]])' + beginCaptures: + '0': { name: keyword.operator.expression.infer.ts } + end: '(?={{lookAheadEndOfType}}|[''"`|&])' + name: meta.type.infer.ts + patterns: + - name: keyword.operator.expression.extends.ts + match: '{{startOfIdentifier}}extends{{endOfIdentifier}}' + - name: entity.name.type.ts + match: '{{startOfIdentifier}}{{identifier}}{{endOfIdentifier}}' + type-predicate-operator: patterns: - match: '{{startOfIdentifier}}(?:(asserts)\s+)?(?!asserts)(?:(this)|({{identifier}}))\s(is){{endOfIdentifier}}' diff --git a/TypeScript.tmLanguage b/TypeScript.tmLanguage index 78bfc806..6c994421 100644 --- a/TypeScript.tmLanguage +++ b/TypeScript.tmLanguage @@ -7076,11 +7076,11 @@ include - #type-conditional + #type-operators include - #type-operators + #type-conditional include @@ -7630,6 +7630,10 @@ include #typeof-operator + + include + #type-infer + begin ([&|])(?=\s*\{) @@ -7679,15 +7683,70 @@ name - keyword.operator.expression.infer.ts + keyword.operator.expression.import.ts match - (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))infer(?=\s+[_$[:alpha:]]) + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))import(?=\s*\() + + + type-infer + + patterns + - name - keyword.operator.expression.import.ts match - (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))import(?=\s*\() + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(infer)\s+([_$[:alpha:]][_$[:alnum:]]*)\s+(extends)(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)) + name + meta.type.infer.ts + captures + + 1 + + name + keyword.operator.expression.infer.ts + + 2 + + name + entity.name.type.ts + + 3 + + name + keyword.operator.expression.extends.ts + + + + + begin + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))infer(?=\s+[_$[:alpha:]]) + beginCaptures + + 0 + + name + keyword.operator.expression.infer.ts + + + end + (?=[;),}\]:?\-\+\>]|\|\||\&\&|\!\=\=|$|['"`|&]) + name + meta.type.infer.ts + patterns + + + name + keyword.operator.expression.extends.ts + match + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))extends(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)) + + + name + entity.name.type.ts + match + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))[_$[:alpha:]][_$[:alnum:]]*(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)) + + diff --git a/TypeScriptReact.tmLanguage b/TypeScriptReact.tmLanguage index 43477c9e..6d630699 100644 --- a/TypeScriptReact.tmLanguage +++ b/TypeScriptReact.tmLanguage @@ -7024,11 +7024,11 @@ include - #type-conditional + #type-operators include - #type-operators + #type-conditional include @@ -7578,6 +7578,10 @@ include #typeof-operator + + include + #type-infer + begin ([&|])(?=\s*\{) @@ -7627,15 +7631,70 @@ name - keyword.operator.expression.infer.tsx + keyword.operator.expression.import.tsx match - (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))infer(?=\s+[_$[:alpha:]]) + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))import(?=\s*\() + + + type-infer + + patterns + - name - keyword.operator.expression.import.tsx match - (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))import(?=\s*\() + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))(infer)\s+([_$[:alpha:]][_$[:alnum:]]*)\s+(extends)(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)) + name + meta.type.infer.tsx + captures + + 1 + + name + keyword.operator.expression.infer.tsx + + 2 + + name + entity.name.type.tsx + + 3 + + name + keyword.operator.expression.extends.tsx + + + + + begin + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))infer(?=\s+[_$[:alpha:]]) + beginCaptures + + 0 + + name + keyword.operator.expression.infer.tsx + + + end + (?=[;),}\]:?\-\+\>]|\|\||\&\&|\!\=\=|$|['"`|&]) + name + meta.type.infer.tsx + patterns + + + name + keyword.operator.expression.extends.tsx + match + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))extends(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)) + + + name + entity.name.type.tsx + match + (?<![_$[:alnum:]])(?:(?<=\.\.\.)|(?<!\.))[_$[:alpha:]][_$[:alnum:]]*(?![_$[:alnum:]])(?:(?=\.\.\.)|(?!\.)) + + diff --git a/package-lock.json b/package-lock.json index 170a8ab6..2dbe35c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "mocha": "latest", "plist": "latest", "typescript": "latest", + "vscode-grammar-updater": "^1.0.4", "vscode-textmate": "^4.1.1" }, "devDependencies": { @@ -264,6 +265,19 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==", + "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)", + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -486,6 +500,14 @@ "node": ">=4.8" } }, + "node_modules/cson-parser": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", + "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", + "dependencies": { + "coffee-script": "^1.10.0" + } + }, "node_modules/debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -548,6 +570,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/fast-plist": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/fast-plist/-/fast-plist-0.1.2.tgz", + "integrity": "sha1-pFr/NFGWAG1AbKbNzQX2kFHvNbg=" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1398,6 +1425,18 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "node_modules/vscode-grammar-updater": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vscode-grammar-updater/-/vscode-grammar-updater-1.0.4.tgz", + "integrity": "sha512-WjmpFo+jlnxOfHNeSrO3nJx8S2u3f926UL0AHJhDMQghCwEfkMvf37aafF83xvtLW2G9ywhifLbq4caxDQm+wQ==", + "dependencies": { + "cson-parser": "^1.3.3", + "fast-plist": "0.1.2" + }, + "bin": { + "vscode-grammar-updater": "bin.js" + } + }, "node_modules/vscode-textmate": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-4.1.1.tgz", @@ -1729,6 +1768,11 @@ "wrap-ansi": "^7.0.0" } }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1906,6 +1950,14 @@ "which": "^1.2.9" } }, + "cson-parser": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/cson-parser/-/cson-parser-1.3.5.tgz", + "integrity": "sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ=", + "requires": { + "coffee-script": "^1.10.0" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -1949,6 +2001,11 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, + "fast-plist": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/fast-plist/-/fast-plist-0.1.2.tgz", + "integrity": "sha1-pFr/NFGWAG1AbKbNzQX2kFHvNbg=" + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2573,6 +2630,15 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "vscode-grammar-updater": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vscode-grammar-updater/-/vscode-grammar-updater-1.0.4.tgz", + "integrity": "sha512-WjmpFo+jlnxOfHNeSrO3nJx8S2u3f926UL0AHJhDMQghCwEfkMvf37aafF83xvtLW2G9ywhifLbq4caxDQm+wQ==", + "requires": { + "cson-parser": "^1.3.3", + "fast-plist": "0.1.2" + } + }, "vscode-textmate": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-4.1.1.tgz", diff --git a/package.json b/package.json index 5d76c215..a418ab18 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "mocha": "latest", "plist": "latest", "typescript": "latest", + "vscode-grammar-updater": "^1.0.4", "vscode-textmate": "^4.1.1" }, "devDependencies": { diff --git a/tests/baselines/inferTypes.baseline.txt b/tests/baselines/inferTypes.baseline.txt index 706c2d09..081220ed 100644 --- a/tests/baselines/inferTypes.baseline.txt +++ b/tests/baselines/inferTypes.baseline.txt @@ -4,6 +4,7 @@ type ReturnType = T extends ((...args: any[]) => infer R) | type ArgumentType any> = T extends (a: infer A) => any ? A : any; type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; type B1 = S extends A1 ? [T, U] : never; +type C1 = S extends A1 ? [T, U] : never; ----------------------------------- Grammar: TypeScript.tmLanguage @@ -435,4 +436,97 @@ Grammar: TypeScript.tmLanguage ^^^^^ source.ts meta.type.declaration.ts support.type.primitive.ts ^ - source.ts punctuation.terminator.statement.ts \ No newline at end of file + source.ts punctuation.terminator.statement.ts +>type C1 = S extends A1 ? [T, U] : never; + ^^^^ + source.ts meta.type.declaration.ts storage.type.type.ts + ^ + source.ts meta.type.declaration.ts + ^^ + source.ts meta.type.declaration.ts entity.name.type.alias.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts punctuation.definition.typeparameters.begin.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts punctuation.definition.typeparameters.end.ts + ^ + source.ts meta.type.declaration.ts + ^ + source.ts meta.type.declaration.ts keyword.operator.assignment.ts + ^ + source.ts meta.type.declaration.ts + ^ + source.ts meta.type.declaration.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts + ^^^^^^^ + source.ts meta.type.declaration.ts storage.modifier.ts + ^ + source.ts meta.type.declaration.ts + ^^ + source.ts meta.type.declaration.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts punctuation.definition.typeparameters.begin.ts + ^^^^^ + source.ts meta.type.declaration.ts meta.type.parameters.ts keyword.operator.expression.infer.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^^^^^^^ + source.ts meta.type.declaration.ts meta.type.parameters.ts keyword.operator.expression.extends.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^^^^^^ + source.ts meta.type.declaration.ts meta.type.parameters.ts support.type.primitive.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts punctuation.separator.comma.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^^^^^ + source.ts meta.type.declaration.ts meta.type.parameters.ts keyword.operator.expression.infer.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^^^^^^^ + source.ts meta.type.declaration.ts meta.type.parameters.ts keyword.operator.expression.extends.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts + ^^^^^^ + source.ts meta.type.declaration.ts meta.type.parameters.ts support.type.primitive.ts + ^ + source.ts meta.type.declaration.ts meta.type.parameters.ts punctuation.definition.typeparameters.end.ts + ^ + source.ts meta.type.declaration.ts + ^ + source.ts meta.type.declaration.ts keyword.operator.ternary.ts + ^ + source.ts meta.type.declaration.ts + ^ + source.ts meta.type.declaration.ts meta.type.tuple.ts meta.brace.square.ts + ^ + source.ts meta.type.declaration.ts meta.type.tuple.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts meta.type.tuple.ts punctuation.separator.comma.ts + ^ + source.ts meta.type.declaration.ts meta.type.tuple.ts + ^ + source.ts meta.type.declaration.ts meta.type.tuple.ts entity.name.type.ts + ^ + source.ts meta.type.declaration.ts meta.type.tuple.ts meta.brace.square.ts + ^ + source.ts meta.type.declaration.ts + ^ + source.ts meta.type.declaration.ts keyword.operator.ternary.ts + ^ + source.ts meta.type.declaration.ts + ^^^^^ + source.ts meta.type.declaration.ts support.type.primitive.ts + ^ + source.ts punctuation.terminator.statement.ts \ No newline at end of file diff --git a/tests/cases/inferTypes.ts b/tests/cases/inferTypes.ts index 7a74507b..64410da3 100644 --- a/tests/cases/inferTypes.ts +++ b/tests/cases/inferTypes.ts @@ -1,4 +1,5 @@ type ReturnType = T extends ((...args: any[]) => infer R) | (new (...args: any[]) => infer R) ? R : any; type ArgumentType any> = T extends (a: infer A) => any ? A : any; type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; -type B1 = S extends A1 ? [T, U] : never; \ No newline at end of file +type B1 = S extends A1 ? [T, U] : never; +type C1 = S extends A1 ? [T, U] : never;