Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3d7ec8a

Browse filesBrowse files
authored
Improve @template lookup and resilience (microsoft#42851)
* Improve @template lookup and resilience 1. @template parsing may produce a template tag with a type parameter whose name is the missing identifier. These tags should be skipped in the checker because they receive an error in the parser. 2. The fix in microsoft#37819 was incorrect; there's no such thing as a type parameter declared on a variable declaration. Instead, there needs to be a type parameter declared on a jsdoc comment, because that's the scope for tags like `@return` and `@typedef`. There are 3 tests because either fix (1) and (2) fix the first test's failure, but both are required to fix the last two tests' failures. * remove containsParseError call
1 parent c3d7a56 commit 3d7ec8a
Copy full SHA for 3d7ec8a

13 files changed

+269-5Lines changed: 269 additions & 5 deletions
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+8-5Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9185,7 +9185,6 @@ namespace ts {
91859185
return undefined;
91869186
}
91879187
switch (node.kind) {
9188-
case SyntaxKind.VariableStatement:
91899188
case SyntaxKind.ClassDeclaration:
91909189
case SyntaxKind.ClassExpression:
91919190
case SyntaxKind.InterfaceDeclaration:
@@ -9205,28 +9204,32 @@ namespace ts {
92059204
case SyntaxKind.JSDocEnumTag:
92069205
case SyntaxKind.JSDocCallbackTag:
92079206
case SyntaxKind.MappedType:
9208-
case SyntaxKind.ConditionalType:
9207+
case SyntaxKind.ConditionalType: {
92099208
const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
92109209
if (node.kind === SyntaxKind.MappedType) {
92119210
return append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((<MappedTypeNode>node).typeParameter)));
92129211
}
92139212
else if (node.kind === SyntaxKind.ConditionalType) {
92149213
return concatenate(outerTypeParameters, getInferTypeParameters(<ConditionalTypeNode>node));
92159214
}
9216-
else if (node.kind === SyntaxKind.VariableStatement && !isInJSFile(node)) {
9217-
break;
9218-
}
92199215
const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(<DeclarationWithTypeParameters>node));
92209216
const thisType = includeThisTypes &&
92219217
(node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) &&
92229218
getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType;
92239219
return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
9220+
}
92249221
case SyntaxKind.JSDocParameterTag:
92259222
const paramSymbol = getParameterSymbolFromJSDoc(node as JSDocParameterTag);
92269223
if (paramSymbol) {
92279224
node = paramSymbol.valueDeclaration;
92289225
}
92299226
break;
9227+
case SyntaxKind.JSDocComment: {
9228+
const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
9229+
return (node as JSDoc).tags
9230+
? appendTypeParameters(outerTypeParameters, flatMap((node as JSDoc).tags, t => isJSDocTemplateTag(t) ? t.typeParameters : undefined))
9231+
: outerTypeParameters;
9232+
}
92309233
}
92319234
}
92329235
}
Collapse file
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error TS5055: Cannot write file 'tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js' because it would overwrite input file.
2+
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
3+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js(1,14): error TS2304: Cannot find name 'T'.
4+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js(4,17): error TS2304: Cannot find name 'T'.
5+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js(4,19): error TS1069: Unexpected token. A type parameter name was expected without curly braces.
6+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js(7,35): error TS2339: Property 'foo' does not exist on type 'Bar'.
7+
8+
9+
!!! error TS5055: Cannot write file 'tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js' because it would overwrite input file.
10+
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
11+
==== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js (4 errors) ====
12+
/** @return {T} */
13+
~
14+
!!! error TS2304: Cannot find name 'T'.
15+
const dedupingMixin = function(mixin) {};
16+
17+
/** @template {T} */
18+
~
19+
!!! error TS2304: Cannot find name 'T'.
20+
~
21+
!!! error TS1069: Unexpected token. A type parameter name was expected without curly braces.
22+
const PropertyAccessors = dedupingMixin(() => {
23+
class Bar {
24+
static bar() { this.prototype.foo(); }
25+
~~~
26+
!!! error TS2339: Property 'foo' does not exist on type 'Bar'.
27+
}
28+
});
29+
30+
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js ===
2+
/** @return {T} */
3+
const dedupingMixin = function(mixin) {};
4+
>dedupingMixin : Symbol(dedupingMixin, Decl(jsdocOuterTypeParameters1.js, 1, 5))
5+
>mixin : Symbol(mixin, Decl(jsdocOuterTypeParameters1.js, 1, 31))
6+
7+
/** @template {T} */
8+
const PropertyAccessors = dedupingMixin(() => {
9+
>PropertyAccessors : Symbol(PropertyAccessors, Decl(jsdocOuterTypeParameters1.js, 4, 5))
10+
>dedupingMixin : Symbol(dedupingMixin, Decl(jsdocOuterTypeParameters1.js, 1, 5))
11+
12+
class Bar {
13+
>Bar : Symbol(Bar, Decl(jsdocOuterTypeParameters1.js, 4, 47))
14+
15+
static bar() { this.prototype.foo(); }
16+
>bar : Symbol(Bar.bar, Decl(jsdocOuterTypeParameters1.js, 5, 13))
17+
>this.prototype : Symbol(Bar.prototype)
18+
>this : Symbol(Bar, Decl(jsdocOuterTypeParameters1.js, 4, 47))
19+
>prototype : Symbol(Bar.prototype)
20+
}
21+
});
22+
23+
Collapse file
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js ===
2+
/** @return {T} */
3+
const dedupingMixin = function(mixin) {};
4+
>dedupingMixin : (mixin: any) => any
5+
>function(mixin) {} : (mixin: any) => any
6+
>mixin : any
7+
8+
/** @template {T} */
9+
const PropertyAccessors = dedupingMixin(() => {
10+
>PropertyAccessors : any
11+
>dedupingMixin(() => { class Bar { static bar() { this.prototype.foo(); } }}) : any
12+
>dedupingMixin : (mixin: any) => any
13+
>() => { class Bar { static bar() { this.prototype.foo(); } }} : () => void
14+
15+
class Bar {
16+
>Bar : Bar
17+
18+
static bar() { this.prototype.foo(); }
19+
>bar : () => void
20+
>this.prototype.foo() : any
21+
>this.prototype.foo : any
22+
>this.prototype : Bar
23+
>this : typeof Bar
24+
>prototype : Bar
25+
>foo : any
26+
}
27+
});
28+
29+
Collapse file
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error TS5055: Cannot write file 'tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js' because it would overwrite input file.
2+
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
3+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js(1,14): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
4+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js(7,35): error TS2339: Property 'foo' does not exist on type 'Bar'.
5+
6+
7+
!!! error TS5055: Cannot write file 'tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js' because it would overwrite input file.
8+
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
9+
==== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js (2 errors) ====
10+
/** @return {T} */
11+
~
12+
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
13+
const dedupingMixin = function(mixin) {};
14+
15+
/** @template T */
16+
const PropertyAccessors = dedupingMixin(() => {
17+
class Bar {
18+
static bar() { this.prototype.foo(); }
19+
~~~
20+
!!! error TS2339: Property 'foo' does not exist on type 'Bar'.
21+
}
22+
});
23+
24+
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js ===
2+
/** @return {T} */
3+
const dedupingMixin = function(mixin) {};
4+
>dedupingMixin : Symbol(dedupingMixin, Decl(jsdocOuterTypeParameters1.js, 1, 5))
5+
>mixin : Symbol(mixin, Decl(jsdocOuterTypeParameters1.js, 1, 31))
6+
7+
/** @template T */
8+
const PropertyAccessors = dedupingMixin(() => {
9+
>PropertyAccessors : Symbol(PropertyAccessors, Decl(jsdocOuterTypeParameters1.js, 4, 5))
10+
>dedupingMixin : Symbol(dedupingMixin, Decl(jsdocOuterTypeParameters1.js, 1, 5))
11+
12+
class Bar {
13+
>Bar : Symbol(Bar, Decl(jsdocOuterTypeParameters1.js, 4, 47))
14+
15+
static bar() { this.prototype.foo(); }
16+
>bar : Symbol(Bar.bar, Decl(jsdocOuterTypeParameters1.js, 5, 13))
17+
>this.prototype : Symbol(Bar.prototype)
18+
>this : Symbol(Bar, Decl(jsdocOuterTypeParameters1.js, 4, 47))
19+
>prototype : Symbol(Bar.prototype)
20+
}
21+
});
22+
23+
Collapse file
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters1.js ===
2+
/** @return {T} */
3+
const dedupingMixin = function(mixin) {};
4+
>dedupingMixin : (mixin: any) => T
5+
>function(mixin) {} : (mixin: any) => T
6+
>mixin : any
7+
8+
/** @template T */
9+
const PropertyAccessors = dedupingMixin(() => {
10+
>PropertyAccessors : T
11+
>dedupingMixin(() => { class Bar { static bar() { this.prototype.foo(); } }}) : T
12+
>dedupingMixin : (mixin: any) => T
13+
>() => { class Bar { static bar() { this.prototype.foo(); } }} : () => void
14+
15+
class Bar {
16+
>Bar : Bar
17+
18+
static bar() { this.prototype.foo(); }
19+
>bar : () => void
20+
>this.prototype.foo() : any
21+
>this.prototype.foo : any
22+
>this.prototype : Bar
23+
>this : typeof Bar
24+
>prototype : Bar
25+
>foo : any
26+
}
27+
});
28+
29+
Collapse file
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error TS5055: Cannot write file 'tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js' because it would overwrite input file.
2+
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
3+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js(1,16): error TS2304: Cannot find name 'T'.
4+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js(1,18): error TS1069: Unexpected token. A type parameter name was expected without curly braces.
5+
tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js(5,43): error TS2339: Property 'foo' does not exist on type 'Bar'.
6+
7+
8+
!!! error TS5055: Cannot write file 'tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js' because it would overwrite input file.
9+
!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
10+
==== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js (3 errors) ====
11+
/** @template {T} */
12+
~
13+
!!! error TS2304: Cannot find name 'T'.
14+
~
15+
!!! error TS1069: Unexpected token. A type parameter name was expected without curly braces.
16+
class Baz {
17+
m() {
18+
class Bar {
19+
static bar() { this.prototype.foo(); }
20+
~~~
21+
!!! error TS2339: Property 'foo' does not exist on type 'Bar'.
22+
}
23+
}
24+
}
25+
Collapse file
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js ===
2+
/** @template {T} */
3+
class Baz {
4+
>Baz : Symbol(Baz, Decl(jsdocOuterTypeParameters3.js, 0, 0))
5+
6+
m() {
7+
>m : Symbol(Baz.m, Decl(jsdocOuterTypeParameters3.js, 1, 11))
8+
9+
class Bar {
10+
>Bar : Symbol(Bar, Decl(jsdocOuterTypeParameters3.js, 2, 9))
11+
12+
static bar() { this.prototype.foo(); }
13+
>bar : Symbol(Bar.bar, Decl(jsdocOuterTypeParameters3.js, 3, 19))
14+
>this.prototype : Symbol(Bar.prototype)
15+
>this : Symbol(Bar, Decl(jsdocOuterTypeParameters3.js, 2, 9))
16+
>prototype : Symbol(Bar.prototype)
17+
}
18+
}
19+
}
20+
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/conformance/jsdoc/jsdocOuterTypeParameters3.js ===
2+
/** @template {T} */
3+
class Baz {
4+
>Baz : Baz
5+
6+
m() {
7+
>m : () => void
8+
9+
class Bar {
10+
>Bar : Bar
11+
12+
static bar() { this.prototype.foo(); }
13+
>bar : () => void
14+
>this.prototype.foo() : any
15+
>this.prototype.foo : any
16+
>this.prototype : Bar
17+
>this : typeof Bar
18+
>prototype : Bar
19+
>foo : any
20+
}
21+
}
22+
}
23+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.