From 0bb897273fe1e4844f16e341700911e4e730fd82 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 21 Jun 2018 16:12:55 -0700 Subject: [PATCH] Parse nested prop and param tags the same way (#25139) That is, only nest them if their name matches the provided parent name. Otherwise do not nest them. Note that this commit changes the behaviour of an incorrect typedef that contains both an `@type` child tag and `@property` child tags. Previously, the `@type` would be incorrectly nested under a `@property` tag with type `object`, just like `@property` tags would be. Now, the `@type` tag causes the entire typedef to ignore the `@property` tags and treat the typedef as if it were an instance of the typedef-and-nested-type pattern: ```js /** * @typedef {Object} name * @type {{ the, actual, type }} */ ``` --- src/compiler/parser.ts | 4 +- .../reference/typedefTagNested.symbols | 32 +++++++++++++++- .../reference/typedefTagNested.types | 37 ++++++++++++++++++- .../conformance/jsdoc/typedefTagNested.ts | 13 +++++++ 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c7b01b9b804..ea0ec323798 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6922,9 +6922,9 @@ namespace ts { case SyntaxKind.AtToken: if (canParseTag) { const child = tryParseChildTag(target); - if (child && child.kind === SyntaxKind.JSDocParameterTag && + if (child && (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) && target !== PropertyLikeParse.CallbackParameter && - (ts.isIdentifier(child.name) || !escapedTextsEqual(name!, child.name.left))) { // TODO: GH#18217 + name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) { return false; } return child; diff --git a/tests/baselines/reference/typedefTagNested.symbols b/tests/baselines/reference/typedefTagNested.symbols index 41ea2faf0b0..f6a34679306 100644 --- a/tests/baselines/reference/typedefTagNested.symbols +++ b/tests/baselines/reference/typedefTagNested.symbols @@ -32,8 +32,38 @@ const app = { * @property {string} horrible * @type {string} idea */ +var intercessor = 1 +>intercessor : Symbol(intercessor, Decl(a.js, 23, 3)) /** @type {Opp} */ var mistake; ->mistake : Symbol(mistake, Decl(a.js, 25, 3)) +>mistake : Symbol(mistake, Decl(a.js, 26, 3)) + +/** @typedef {Object} Upp + * @property {string} name + * @property {Object} not + * @property {string} nested + */ + +/** @type {Upp} */ +var sala = { name: 'uppsala', not: 0, nested: "ok" }; +>sala : Symbol(sala, Decl(a.js, 35, 3)) +>name : Symbol(name, Decl(a.js, 35, 12)) +>not : Symbol(not, Decl(a.js, 35, 29)) +>nested : Symbol(nested, Decl(a.js, 35, 37)) + +sala.name +>sala.name : Symbol(name, Decl(a.js, 29, 3)) +>sala : Symbol(sala, Decl(a.js, 35, 3)) +>name : Symbol(name, Decl(a.js, 29, 3)) + +sala.not +>sala.not : Symbol(not, Decl(a.js, 30, 3)) +>sala : Symbol(sala, Decl(a.js, 35, 3)) +>not : Symbol(not, Decl(a.js, 30, 3)) + +sala.nested +>sala.nested : Symbol(nested, Decl(a.js, 31, 3)) +>sala : Symbol(sala, Decl(a.js, 35, 3)) +>nested : Symbol(nested, Decl(a.js, 31, 3)) diff --git a/tests/baselines/reference/typedefTagNested.types b/tests/baselines/reference/typedefTagNested.types index 52707d55cec..9216796869e 100644 --- a/tests/baselines/reference/typedefTagNested.types +++ b/tests/baselines/reference/typedefTagNested.types @@ -37,8 +37,43 @@ const app = { * @property {string} horrible * @type {string} idea */ +var intercessor = 1 +>intercessor : number +>1 : 1 /** @type {Opp} */ var mistake; ->mistake : Opp +>mistake : string + +/** @typedef {Object} Upp + * @property {string} name + * @property {Object} not + * @property {string} nested + */ + +/** @type {Upp} */ +var sala = { name: 'uppsala', not: 0, nested: "ok" }; +>sala : Upp +>{ name: 'uppsala', not: 0, nested: "ok" } : { name: string; not: number; nested: string; } +>name : string +>'uppsala' : "uppsala" +>not : number +>0 : 0 +>nested : string +>"ok" : "ok" + +sala.name +>sala.name : string +>sala : Upp +>name : string + +sala.not +>sala.not : any +>sala : Upp +>not : any + +sala.nested +>sala.nested : string +>sala : Upp +>nested : string diff --git a/tests/cases/conformance/jsdoc/typedefTagNested.ts b/tests/cases/conformance/jsdoc/typedefTagNested.ts index a66ff7aa424..b1f51c1b6f1 100644 --- a/tests/cases/conformance/jsdoc/typedefTagNested.ts +++ b/tests/cases/conformance/jsdoc/typedefTagNested.ts @@ -27,6 +27,19 @@ const app = { * @property {string} horrible * @type {string} idea */ +var intercessor = 1 /** @type {Opp} */ var mistake; + +/** @typedef {Object} Upp + * @property {string} name + * @property {Object} not + * @property {string} nested + */ + +/** @type {Upp} */ +var sala = { name: 'uppsala', not: 0, nested: "ok" }; +sala.name +sala.not +sala.nested