From 4838eff2d7b0833c62b6e9e667fd3d5e006cf070 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 29 May 2017 20:37:01 -0700 Subject: [PATCH 1/6] "function" without followed by "(" should be considered as Global function type --- src/compiler/checker.ts | 1 + src/compiler/parser.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 125e492cc3..9ff1c4b41b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6855,6 +6855,7 @@ namespace ts { case "Object": return anyType; case "Function": + case "function": return globalFunctionType; case "Array": case "array": diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 07d4a9ada4..04d70639e1 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6075,7 +6075,10 @@ namespace ts { case SyntaxKind.OpenBraceToken: return parseJSDocRecordType(); case SyntaxKind.FunctionKeyword: - return parseJSDocFunctionType(); + if (lookAhead(nextTokenIsOpenParen)) { + return parseJSDocFunctionType(); + } + break; case SyntaxKind.DotDotDotToken: return parseJSDocVariadicType(); case SyntaxKind.NewKeyword: From 0ead501c86203d3c5473acaaf98e1c61ad0c5bab Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 29 May 2017 20:37:15 -0700 Subject: [PATCH 2/6] Update tests and baselines --- tests/baselines/reference/jsDocTypeTag2.js | 24 ++---------------- tests/baselines/reference/jsDocTypes2.js | 7 ++++++ tests/baselines/reference/jsDocTypes2.symbols | 25 +++++++++++++------ tests/baselines/reference/jsDocTypes2.types | 14 +++++++++++ tests/cases/conformance/salsa/jsDocTypes2.ts | 4 +++ 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/tests/baselines/reference/jsDocTypeTag2.js b/tests/baselines/reference/jsDocTypeTag2.js index 07535dcee0..d54b4557f0 100644 --- a/tests/baselines/reference/jsDocTypeTag2.js +++ b/tests/baselines/reference/jsDocTypeTag2.js @@ -431,28 +431,8 @@ "kind": "space" }, { - "text": "(", - "kind": "punctuation" - }, - { - "text": ")", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "=>", - "kind": "punctuation" - }, - { - "text": " ", - "kind": "space" - }, - { - "text": "any", - "kind": "keyword" + "text": "Function", + "kind": "localName" } ], "documentation": [], diff --git a/tests/baselines/reference/jsDocTypes2.js b/tests/baselines/reference/jsDocTypes2.js index a3848704fa..ba59043978 100644 --- a/tests/baselines/reference/jsDocTypes2.js +++ b/tests/baselines/reference/jsDocTypes2.js @@ -11,6 +11,10 @@ anyT1 = "hi"; const x = (a) => a + 1; x(1); +/** @type {function} */ +const y = (a) => a + 1; +x(1); + /** @type {function (number)} */ const x1 = (a) => a + 1; x1(0); @@ -29,6 +33,9 @@ anyT1 = "hi"; /** @type {Function} */ var x = function (a) { return a + 1; }; x(1); +/** @type {function} */ +var y = function (a) { return a + 1; }; +x(1); /** @type {function (number)} */ var x1 = function (a) { return a + 1; }; x1(0); diff --git a/tests/baselines/reference/jsDocTypes2.symbols b/tests/baselines/reference/jsDocTypes2.symbols index 96b32b9ad9..8f4dc4e7b4 100644 --- a/tests/baselines/reference/jsDocTypes2.symbols +++ b/tests/baselines/reference/jsDocTypes2.symbols @@ -20,21 +20,30 @@ const x = (a) => a + 1; x(1); >x : Symbol(x, Decl(0.js, 9, 5)) +/** @type {function} */ +const y = (a) => a + 1; +>y : Symbol(y, Decl(0.js, 13, 5)) +>a : Symbol(a, Decl(0.js, 13, 11)) +>a : Symbol(a, Decl(0.js, 13, 11)) + +x(1); +>x : Symbol(x, Decl(0.js, 9, 5)) + /** @type {function (number)} */ const x1 = (a) => a + 1; ->x1 : Symbol(x1, Decl(0.js, 13, 5)) ->a : Symbol(a, Decl(0.js, 13, 12)) ->a : Symbol(a, Decl(0.js, 13, 12)) +>x1 : Symbol(x1, Decl(0.js, 17, 5)) +>a : Symbol(a, Decl(0.js, 17, 12)) +>a : Symbol(a, Decl(0.js, 17, 12)) x1(0); ->x1 : Symbol(x1, Decl(0.js, 13, 5)) +>x1 : Symbol(x1, Decl(0.js, 17, 5)) /** @type {function (number): number} */ const x2 = (a) => a + 1; ->x2 : Symbol(x2, Decl(0.js, 17, 5)) ->a : Symbol(a, Decl(0.js, 17, 12)) ->a : Symbol(a, Decl(0.js, 17, 12)) +>x2 : Symbol(x2, Decl(0.js, 21, 5)) +>a : Symbol(a, Decl(0.js, 21, 12)) +>a : Symbol(a, Decl(0.js, 21, 12)) x2(0); ->x2 : Symbol(x2, Decl(0.js, 17, 5)) +>x2 : Symbol(x2, Decl(0.js, 21, 5)) diff --git a/tests/baselines/reference/jsDocTypes2.types b/tests/baselines/reference/jsDocTypes2.types index db5a5902d1..599c19c7ff 100644 --- a/tests/baselines/reference/jsDocTypes2.types +++ b/tests/baselines/reference/jsDocTypes2.types @@ -29,6 +29,20 @@ x(1); >x : Function >1 : 1 +/** @type {function} */ +const y = (a) => a + 1; +>y : Function +>(a) => a + 1 : (a: any) => any +>a : any +>a + 1 : any +>a : any +>1 : 1 + +x(1); +>x(1) : any +>x : Function +>1 : 1 + /** @type {function (number)} */ const x1 = (a) => a + 1; >x1 : (arg0: number) => any diff --git a/tests/cases/conformance/salsa/jsDocTypes2.ts b/tests/cases/conformance/salsa/jsDocTypes2.ts index 612804b91d..21107f87cc 100644 --- a/tests/cases/conformance/salsa/jsDocTypes2.ts +++ b/tests/cases/conformance/salsa/jsDocTypes2.ts @@ -14,6 +14,10 @@ anyT1 = "hi"; const x = (a) => a + 1; x(1); +/** @type {function} */ +const y = (a) => a + 1; +x(1); + /** @type {function (number)} */ const x1 = (a) => a + 1; x1(0); From 10eae61aca469a590b80260e894b1816721cf9f4 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 29 May 2017 21:47:39 -0700 Subject: [PATCH 3/6] Handle "object" as "Object" in JSDoc type expression --- src/compiler/parser.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 07d4a9ada4..2d44f2eed7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6091,7 +6091,6 @@ namespace ts { case SyntaxKind.NullKeyword: case SyntaxKind.UndefinedKeyword: case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: return parseTokenNode(); case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: @@ -6769,7 +6768,7 @@ namespace ts { const jsDocTypeReference = typeExpression.type; if (jsDocTypeReference.name.kind === SyntaxKind.Identifier) { const name = jsDocTypeReference.name; - if (name.text === "Object") { + if (name.text === "Object" || name.text === "object") { typedefTag.jsDocTypeLiteral = scanChildTags(); } } From 5c7c113203a82c10f99834403eb166ab81a2ae4c Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 29 May 2017 21:48:34 -0700 Subject: [PATCH 4/6] Update tests and baselines --- .../reference/checkJsdocTypedefInParamTag1.js | 38 +++++++++++++++++-- .../checkJsdocTypedefInParamTag1.symbols | 32 +++++++++++++++- .../checkJsdocTypedefInParamTag1.types | 33 +++++++++++++++- .../jsdoc/checkJsdocTypedefInParamTag1.ts | 22 +++++++++-- 4 files changed, 116 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.js b/tests/baselines/reference/checkJsdocTypedefInParamTag1.js index d4983bfd58..7ce5cdd6f3 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.js +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.js @@ -9,9 +9,26 @@ * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { + opts.x; +} -foo({x: 'abc'}); +foo({x: 'abc'}); + +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { + opts.x; +} +foo1({x: 'abc'}); + //// [0.js] // @ts-check @@ -24,5 +41,20 @@ foo({x: 'abc'}); * * @param {Opts} opts */ -function foo(opts) { } +function foo(opts) { + opts.x; +} foo({ x: 'abc' }); +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { + opts.x; +} +foo1({ x: 'abc' }); diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols b/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols index cd2455797b..be4c40643d 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols @@ -9,11 +9,39 @@ * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { >foo : Symbol(foo, Decl(0.js, 0, 0)) >opts : Symbol(opts, Decl(0.js, 10, 13)) + opts.x; +>opts.x : Symbol(x, Decl(0.js, 3, 3)) +>opts : Symbol(opts, Decl(0.js, 10, 13)) +>x : Symbol(x, Decl(0.js, 3, 3)) +} + foo({x: 'abc'}); >foo : Symbol(foo, Decl(0.js, 0, 0)) ->x : Symbol(x, Decl(0.js, 12, 5)) +>x : Symbol(x, Decl(0.js, 14, 5)) + +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { +>foo1 : Symbol(foo1, Decl(0.js, 14, 16)) +>opts : Symbol(opts, Decl(0.js, 25, 14)) + + opts.x; +>opts.x : Symbol(x, Decl(0.js, 18, 3)) +>opts : Symbol(opts, Decl(0.js, 25, 14)) +>x : Symbol(x, Decl(0.js, 18, 3)) +} +foo1({x: 'abc'}); +>foo1 : Symbol(foo1, Decl(0.js, 14, 16)) +>x : Symbol(x, Decl(0.js, 28, 6)) diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.types b/tests/baselines/reference/checkJsdocTypedefInParamTag1.types index cc923e3303..a82b125a2b 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.types +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.types @@ -9,10 +9,16 @@ * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { >foo : (opts: { x: string; y?: string; z?: string; w?: string; }) => void >opts : { x: string; y?: string; z?: string; w?: string; } + opts.x; +>opts.x : string +>opts : { x: string; y?: string; z?: string; w?: string; } +>x : string +} + foo({x: 'abc'}); >foo({x: 'abc'}) : void >foo : (opts: { x: string; y?: string; z?: string; w?: string; }) => void @@ -20,3 +26,28 @@ foo({x: 'abc'}); >x : string >'abc' : "abc" +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { +>foo1 : (opts: { x: string; y?: string; z?: string; w?: string; }) => void +>opts : { x: string; y?: string; z?: string; w?: string; } + + opts.x; +>opts.x : string +>opts : { x: string; y?: string; z?: string; w?: string; } +>x : string +} +foo1({x: 'abc'}); +>foo1({x: 'abc'}) : void +>foo1 : (opts: { x: string; y?: string; z?: string; w?: string; }) => void +>{x: 'abc'} : { x: string; } +>x : string +>'abc' : "abc" + diff --git a/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts b/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts index 80ca21bd4f..fa885b9f31 100644 --- a/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts +++ b/tests/cases/conformance/jsdoc/checkJsdocTypedefInParamTag1.ts @@ -9,9 +9,25 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ -function foo(opts) {} +function foo(opts) { + opts.x; +} -foo({x: 'abc'}); \ No newline at end of file +foo({x: 'abc'}); + +/** + * @typedef {object} Opts1 + * @property {string} x + * @property {string=} y + * @property {string} [z] + * @property {string} [w="hi"] + * + * @param {Opts1} opts + */ +function foo1(opts) { + opts.x; +} +foo1({x: 'abc'}); From d35e538123ecfd6cde1fe3b4872d8fe6a47c73dd Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 29 May 2017 21:48:43 -0700 Subject: [PATCH 5/6] Add fourslash tests --- tests/baselines/reference/jsDocTypedef1.js | 234 ++++++++++++++++++ .../cases/fourslash/jsDocTypedefQuickInfo1.ts | 33 +++ 2 files changed, 267 insertions(+) create mode 100644 tests/baselines/reference/jsDocTypedef1.js create mode 100644 tests/cases/fourslash/jsDocTypedefQuickInfo1.ts diff --git a/tests/baselines/reference/jsDocTypedef1.js b/tests/baselines/reference/jsDocTypedef1.js new file mode 100644 index 0000000000..28410ee879 --- /dev/null +++ b/tests/baselines/reference/jsDocTypedef1.js @@ -0,0 +1,234 @@ +[ + { + "marker": { + "fileName": "/tests/cases/fourslash/jsDocTypedef1.js", + "position": 189 + }, + "quickInfo": { + "kind": "parameter", + "kindModifiers": "", + "textSpan": { + "start": 189, + "length": 4 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "parameter", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "opts", + "kind": "parameterName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "x", + "kind": "propertyName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "y", + "kind": "propertyName" + }, + { + "text": "?", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "z", + "kind": "propertyName" + }, + { + "text": "?", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "w", + "kind": "propertyName" + }, + { + "text": "?", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": "\n", + "kind": "lineBreak" + }, + { + "text": "}", + "kind": "punctuation" + } + ], + "documentation": [], + "tags": [] + } + }, + { + "marker": { + "fileName": "/tests/cases/fourslash/jsDocTypedef1.js", + "position": 424 + }, + "quickInfo": { + "kind": "parameter", + "kindModifiers": "", + "textSpan": { + "start": 424, + "length": 5 + }, + "displayParts": [ + { + "text": "(", + "kind": "punctuation" + }, + { + "text": "parameter", + "kind": "text" + }, + { + "text": ")", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "opts1", + "kind": "parameterName" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "any", + "kind": "keyword" + } + ], + "documentation": [], + "tags": [] + } + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/jsDocTypedefQuickInfo1.ts b/tests/cases/fourslash/jsDocTypedefQuickInfo1.ts new file mode 100644 index 0000000000..eea17f182e --- /dev/null +++ b/tests/cases/fourslash/jsDocTypedefQuickInfo1.ts @@ -0,0 +1,33 @@ +/// +// @allowJs: true +// @Filename: jsDocTypedef1.js +//// /** +//// * @typedef {Object} Opts +//// * @property {string} x +//// * @property {string=} y +//// * @property {string} [z] +//// * @property {string} [w="hi"] +//// * +//// * @param {Opts} opts +//// */ +//// function foo(/*1*/opts) { +//// opts.x; +///// } + +//// foo({x: 'abc'}); + +//// /** +//// * @typedef {object} Opts1 +//// * @property {string} x +//// * @property {string=} y +//// * @property {string} [z] +//// * @property {string} [w="hi"] +//// * +//// * @param {Opts1} opts +//// */ +//// function foo1(/*2*/opts1) { +//// opts1.x; +//// } +//// foo1({x: 'abc'}); + +verify.baselineQuickInfo(); \ No newline at end of file From 1e8edcbad44223d2b11f72e3eace211c12f32ff2 Mon Sep 17 00:00:00 2001 From: Yui T Date: Mon, 29 May 2017 21:55:55 -0700 Subject: [PATCH 6/6] remove whitespace --- tests/baselines/reference/checkJsdocTypedefInParamTag1.js | 4 ++-- .../baselines/reference/checkJsdocTypedefInParamTag1.symbols | 4 ++-- tests/baselines/reference/checkJsdocTypedefInParamTag1.types | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.js b/tests/baselines/reference/checkJsdocTypedefInParamTag1.js index 7ce5cdd6f3..cc2e302ffc 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.js +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.js @@ -6,7 +6,7 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ function foo(opts) { @@ -21,7 +21,7 @@ foo({x: 'abc'}); * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts1} opts */ function foo1(opts) { diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols b/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols index be4c40643d..844c4c045a 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.symbols @@ -6,7 +6,7 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ function foo(opts) { @@ -29,7 +29,7 @@ foo({x: 'abc'}); * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts1} opts */ function foo1(opts) { diff --git a/tests/baselines/reference/checkJsdocTypedefInParamTag1.types b/tests/baselines/reference/checkJsdocTypedefInParamTag1.types index a82b125a2b..cb21ea2ef0 100644 --- a/tests/baselines/reference/checkJsdocTypedefInParamTag1.types +++ b/tests/baselines/reference/checkJsdocTypedefInParamTag1.types @@ -6,7 +6,7 @@ * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts} opts */ function foo(opts) { @@ -32,7 +32,7 @@ foo({x: 'abc'}); * @property {string=} y * @property {string} [z] * @property {string} [w="hi"] - * + * * @param {Opts1} opts */ function foo1(opts) {