fix(41818): use last JSDoc comment related to host (#41858)
This commit is contained in:
parent
c3ff0d4c17
commit
a763600cc4
|
@ -2147,8 +2147,8 @@ namespace ts {
|
|||
const saveCurrentFlow = currentFlow;
|
||||
for (const typeAlias of delayedTypeAliases) {
|
||||
const host = getJSDocHost(typeAlias);
|
||||
container = findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer)) || file;
|
||||
blockScopeContainer = getEnclosingBlockScopeContainer(host) || file;
|
||||
container = (host && findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer))) || file;
|
||||
blockScopeContainer = (host && getEnclosingBlockScopeContainer(host)) || file;
|
||||
currentFlow = initFlowNode({ flags: FlowFlags.Start });
|
||||
parent = typeAlias;
|
||||
bind(typeAlias.typeExpression);
|
||||
|
|
|
@ -1948,7 +1948,10 @@ namespace ts {
|
|||
case SyntaxKind.JSDocCallbackTag:
|
||||
case SyntaxKind.JSDocEnumTag:
|
||||
// js type aliases do not resolve names from their host, so skip past it
|
||||
location = getJSDocHost(location);
|
||||
const root = getJSDocRoot(location);
|
||||
if (root) {
|
||||
location = root.parent;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
if (lastLocation && (
|
||||
|
@ -3160,7 +3163,8 @@ namespace ts {
|
|||
return;
|
||||
}
|
||||
const host = getJSDocHost(node);
|
||||
if (isExpressionStatement(host) &&
|
||||
if (host &&
|
||||
isExpressionStatement(host) &&
|
||||
isBinaryExpression(host.expression) &&
|
||||
getAssignmentDeclarationKind(host.expression) === AssignmentDeclarationKind.PrototypeProperty) {
|
||||
// X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration
|
||||
|
@ -3169,7 +3173,7 @@ namespace ts {
|
|||
return getDeclarationOfJSPrototypeContainer(symbol);
|
||||
}
|
||||
}
|
||||
if ((isObjectLiteralMethod(host) || isPropertyAssignment(host)) &&
|
||||
if (host && (isObjectLiteralMethod(host) || isPropertyAssignment(host)) &&
|
||||
isBinaryExpression(host.parent.parent) &&
|
||||
getAssignmentDeclarationKind(host.parent.parent) === AssignmentDeclarationKind.Prototype) {
|
||||
// X.prototype = { /** @param {K} p */m() { } } <-- look for K on X's declaration
|
||||
|
|
|
@ -2622,18 +2622,31 @@ namespace ts {
|
|||
|
||||
export function getEffectiveJSDocHost(node: Node): Node | undefined {
|
||||
const host = getJSDocHost(node);
|
||||
const decl = getSourceOfDefaultedAssignment(host) ||
|
||||
getSourceOfAssignment(host) ||
|
||||
getSingleInitializerOfVariableStatementOrPropertyDeclaration(host) ||
|
||||
getSingleVariableOfVariableStatement(host) ||
|
||||
getNestedModuleDeclaration(host) ||
|
||||
host;
|
||||
return decl;
|
||||
if (host) {
|
||||
return getSourceOfDefaultedAssignment(host)
|
||||
|| getSourceOfAssignment(host)
|
||||
|| getSingleInitializerOfVariableStatementOrPropertyDeclaration(host)
|
||||
|| getSingleVariableOfVariableStatement(host)
|
||||
|| getNestedModuleDeclaration(host)
|
||||
|| host;
|
||||
}
|
||||
}
|
||||
|
||||
/** Use getEffectiveJSDocHost if you additionally need to look for jsdoc on parent nodes, like assignments. */
|
||||
export function getJSDocHost(node: Node): HasJSDoc {
|
||||
return Debug.checkDefined(findAncestor(node.parent, isJSDoc)).parent;
|
||||
/** Use getEffectiveJSDocHost if you additionally need to look for jsdoc on parent nodes, like assignments. */
|
||||
export function getJSDocHost(node: Node): HasJSDoc | undefined {
|
||||
const jsDoc = getJSDocRoot(node);
|
||||
if (!jsDoc) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const host = jsDoc.parent;
|
||||
if (host && host.jsDoc && jsDoc === lastOrUndefined(host.jsDoc)) {
|
||||
return host;
|
||||
}
|
||||
}
|
||||
|
||||
export function getJSDocRoot(node: Node): JSDoc | undefined {
|
||||
return findAncestor(node.parent, isJSDoc);
|
||||
}
|
||||
|
||||
export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined {
|
||||
|
|
25
tests/baselines/reference/extendsTag2.errors.txt
Normal file
25
tests/baselines/reference/extendsTag2.errors.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
error TS8022: JSDoc '@extends' is not attached to a class.
|
||||
|
||||
|
||||
!!! error TS8022: JSDoc '@extends' is not attached to a class.
|
||||
==== tests/cases/conformance/jsdoc/foo.js (0 errors) ====
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
40
tests/baselines/reference/extendsTag2.js
Normal file
40
tests/baselines/reference/extendsTag2.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
//// [foo.js]
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [foo.js]
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() { }
|
||||
}
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
27
tests/baselines/reference/extendsTag2.symbols
Normal file
27
tests/baselines/reference/extendsTag2.symbols
Normal file
|
@ -0,0 +1,27 @@
|
|||
=== tests/cases/conformance/jsdoc/foo.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
>A : Symbol(A, Decl(foo.js, 0, 0))
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
>B : Symbol(B, Decl(foo.js, 5, 1))
|
||||
>A : Symbol(A, Decl(foo.js, 0, 0))
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super : Symbol(A, Decl(foo.js, 0, 0))
|
||||
}
|
||||
}
|
||||
|
28
tests/baselines/reference/extendsTag2.types
Normal file
28
tests/baselines/reference/extendsTag2.types
Normal file
|
@ -0,0 +1,28 @@
|
|||
=== tests/cases/conformance/jsdoc/foo.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
>B : B
|
||||
>A : A
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super() : void
|
||||
>super : typeof A
|
||||
}
|
||||
}
|
||||
|
35
tests/baselines/reference/extendsTag3.js
Normal file
35
tests/baselines/reference/extendsTag3.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
//// [foo.js]
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [foo.js]
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() { }
|
||||
}
|
||||
/**
|
||||
* @extends {A}
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
24
tests/baselines/reference/extendsTag3.symbols
Normal file
24
tests/baselines/reference/extendsTag3.symbols
Normal file
|
@ -0,0 +1,24 @@
|
|||
=== tests/cases/conformance/jsdoc/foo.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
>A : Symbol(A, Decl(foo.js, 0, 0))
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
>B : Symbol(B, Decl(foo.js, 5, 1))
|
||||
>A : Symbol(A, Decl(foo.js, 0, 0))
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super : Symbol(A, Decl(foo.js, 0, 0))
|
||||
}
|
||||
}
|
||||
|
25
tests/baselines/reference/extendsTag3.types
Normal file
25
tests/baselines/reference/extendsTag3.types
Normal file
|
@ -0,0 +1,25 @@
|
|||
=== tests/cases/conformance/jsdoc/foo.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
>B : B
|
||||
>A : A
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super() : void
|
||||
>super : typeof A
|
||||
}
|
||||
}
|
||||
|
17
tests/baselines/reference/extendsTag4.errors.txt
Normal file
17
tests/baselines/reference/extendsTag4.errors.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
tests/cases/conformance/jsdoc/foo.js(11,1): error TS8022: JSDoc '@extends' is not attached to a class.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/foo.js (1 errors) ====
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
|
||||
!!! error TS8022: JSDoc '@extends' is not attached to a class.
|
23
tests/baselines/reference/extendsTag4.js
Normal file
23
tests/baselines/reference/extendsTag4.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
//// [foo.js]
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
|
||||
//// [foo.js]
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() { }
|
||||
}
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
14
tests/baselines/reference/extendsTag4.symbols
Normal file
14
tests/baselines/reference/extendsTag4.symbols
Normal file
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/conformance/jsdoc/foo.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
>A : Symbol(A, Decl(foo.js, 0, 0))
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
14
tests/baselines/reference/extendsTag4.types
Normal file
14
tests/baselines/reference/extendsTag4.types
Normal file
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/conformance/jsdoc/foo.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
25
tests/cases/conformance/jsdoc/extendsTag2.ts
Normal file
25
tests/cases/conformance/jsdoc/extendsTag2.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: esnext
|
||||
// @outDir: out
|
||||
// @Filename: foo.js
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
22
tests/cases/conformance/jsdoc/extendsTag3.ts
Normal file
22
tests/cases/conformance/jsdoc/extendsTag3.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: esnext
|
||||
// @outDir: out
|
||||
// @Filename: foo.js
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
* @constructor
|
||||
*/
|
||||
class B extends A {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
16
tests/cases/conformance/jsdoc/extendsTag4.ts
Normal file
16
tests/cases/conformance/jsdoc/extendsTag4.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: esnext
|
||||
// @outDir: out
|
||||
// @Filename: foo.js
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
class A {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @extends {A}
|
||||
*/
|
Loading…
Reference in a new issue