From 5b1469aece62f30c2c8c0c0341e6c81609aa8b4c Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 10 Feb 2016 10:41:52 -0800 Subject: [PATCH 1/4] Add undefined checks for malformed type tags Fixes #7002 --- src/compiler/checker.ts | 4 ++-- src/harness/harness.ts | 3 +++ tests/baselines/reference/malformedTags.js | 17 +++++++++++++++++ tests/baselines/reference/malformedTags.symbols | 13 +++++++++++++ tests/baselines/reference/malformedTags.types | 13 +++++++++++++ tests/cases/conformance/salsa/malformedTags.ts | 10 ++++++++++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/malformedTags.js create mode 100644 tests/baselines/reference/malformedTags.symbols create mode 100644 tests/baselines/reference/malformedTags.types create mode 100644 tests/cases/conformance/salsa/malformedTags.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 61fe8f3a794..a3555eca745 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2613,7 +2613,7 @@ namespace ts { function getJSDocTypeForVariableLikeDeclarationFromJSDocComment(declaration: VariableLikeDeclaration): JSDocType { // First, see if this node has an @type annotation on it directly. const typeTag = getJSDocTypeTag(declaration); - if (typeTag) { + if (typeTag && typeTag.typeExpression) { return typeTag.typeExpression.type; } @@ -2623,7 +2623,7 @@ namespace ts { // @type annotation might have been on the variable statement, try that instead. const annotation = getJSDocTypeTag(declaration.parent.parent); - if (annotation) { + if (annotation && annotation.typeExpression) { return annotation.typeExpression.type; } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 848b0d4e063..6b9ae6a15db 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -938,6 +938,9 @@ namespace Harness { } } } + else if (name === 'suppressOutputPathCheck') { + options.suppressOutputPathCheck = true; + } else { throw new Error(`Unknown compiler option '${name}'.`); } diff --git a/tests/baselines/reference/malformedTags.js b/tests/baselines/reference/malformedTags.js new file mode 100644 index 00000000000..33b2c1e6f41 --- /dev/null +++ b/tests/baselines/reference/malformedTags.js @@ -0,0 +1,17 @@ +//// [myFile02.js] + +/** + * Checks if `value` is classified as an `Array` object. + * + * @type Function + */ +var isArray = Array.isArray; + + +//// [myFile02.js] +/** + * Checks if `value` is classified as an `Array` object. + * + * @type Function + */ +var isArray = Array.isArray; diff --git a/tests/baselines/reference/malformedTags.symbols b/tests/baselines/reference/malformedTags.symbols new file mode 100644 index 00000000000..df953a82497 --- /dev/null +++ b/tests/baselines/reference/malformedTags.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/salsa/myFile02.js === + +/** + * Checks if `value` is classified as an `Array` object. + * + * @type Function + */ +var isArray = Array.isArray; +>isArray : Symbol(isArray, Decl(myFile02.js, 6, 3)) +>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/malformedTags.types b/tests/baselines/reference/malformedTags.types new file mode 100644 index 00000000000..acf442f7cba --- /dev/null +++ b/tests/baselines/reference/malformedTags.types @@ -0,0 +1,13 @@ +=== tests/cases/conformance/salsa/myFile02.js === + +/** + * Checks if `value` is classified as an `Array` object. + * + * @type Function + */ +var isArray = Array.isArray; +>isArray : (arg: any) => arg is any[] +>Array.isArray : (arg: any) => arg is any[] +>Array : ArrayConstructor +>isArray : (arg: any) => arg is any[] + diff --git a/tests/cases/conformance/salsa/malformedTags.ts b/tests/cases/conformance/salsa/malformedTags.ts new file mode 100644 index 00000000000..1128ce73f15 --- /dev/null +++ b/tests/cases/conformance/salsa/malformedTags.ts @@ -0,0 +1,10 @@ +// @allowJS: true +// @suppressOutputPathCheck: true + +// @filename: myFile02.js +/** + * Checks if `value` is classified as an `Array` object. + * + * @type Function + */ +var isArray = Array.isArray; From d64bbc0becc7c4390692f712646ca784a42c2671 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 10 Feb 2016 11:18:02 -0800 Subject: [PATCH 2/4] :heart: linter --- src/harness/harness.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 6b9ae6a15db..230b680eab7 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -938,7 +938,7 @@ namespace Harness { } } } - else if (name === 'suppressOutputPathCheck') { + else if (name === "suppressOutputPathCheck") { options.suppressOutputPathCheck = true; } else { From 8c9baf81c53b44ca7551adf7a64405827708c0eb Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 10 Feb 2016 11:30:21 -0800 Subject: [PATCH 3/4] Check in other places too --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a3555eca745..76323f83e08 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7414,7 +7414,7 @@ namespace ts { function getTypeForThisExpressionFromJSDoc(node: Node) { const typeTag = getJSDocTypeTag(node); - if (typeTag && typeTag.typeExpression.type.kind === SyntaxKind.JSDocFunctionType) { + if (typeTag && typeTag.typeExpression && typeTag.typeExpression.type && typeTag.typeExpression.type.kind === SyntaxKind.JSDocFunctionType) { const jsDocFunctionType = typeTag.typeExpression.type; if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].type.kind === SyntaxKind.JSDocThisType) { return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type); From 259a89e2cfdfe730c1ad4463970d8f213983cf9e Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 10 Feb 2016 12:51:21 -0800 Subject: [PATCH 4/4] Move suppress option to appropriate place --- src/harness/harness.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 230b680eab7..4d48537a911 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -895,7 +895,8 @@ namespace Harness { { name: "includeBuiltFile", type: "string" }, { name: "fileName", type: "string" }, { name: "libFiles", type: "string" }, - { name: "noErrorTruncation", type: "boolean" } + { name: "noErrorTruncation", type: "boolean" }, + { name: "suppressOutputPathCheck", type: "boolean" } ]; let optionsIndex: ts.Map; @@ -938,9 +939,6 @@ namespace Harness { } } } - else if (name === "suppressOutputPathCheck") { - options.suppressOutputPathCheck = true; - } else { throw new Error(`Unknown compiler option '${name}'.`); }