diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a89ef676951a6..4711d54e0b267 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2351,6 +2351,9 @@ namespace ts { case SyntaxKind.CallExpression: return computeCallExpression(node, subtreeFlags); + case SyntaxKind.NewExpression: + return computeNewExpression(node, subtreeFlags); + case SyntaxKind.ModuleDeclaration: return computeModuleDeclaration(node, subtreeFlags); @@ -2428,6 +2431,10 @@ namespace ts { const expression = node.expression; const expressionKind = expression.kind; + if (node.typeArguments) { + transformFlags |= TransformFlags.AssertTypeScript; + } + if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression || isSuperOrSuperProperty(expression, expressionKind)) { // If the this node contains a SpreadElementExpression, or is a super call, then it is an ES6 @@ -2454,6 +2461,21 @@ namespace ts { return false; } + function computeNewExpression(node: NewExpression, subtreeFlags: TransformFlags) { + let transformFlags = subtreeFlags; + if (node.typeArguments) { + transformFlags |= TransformFlags.AssertTypeScript; + } + if (subtreeFlags & TransformFlags.ContainsSpreadElementExpression) { + // If the this node contains a SpreadElementExpression then it is an ES6 + // node. + transformFlags |= TransformFlags.AssertES2015; + } + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; + return transformFlags & ~TransformFlags.ArrayLiteralOrCallOrNewExcludes; + } + + function computeBinaryExpression(node: BinaryExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; const operatorTokenKind = node.operatorToken.kind; @@ -2482,13 +2504,12 @@ namespace ts { const initializer = node.initializer; const dotDotDotToken = node.dotDotDotToken; - // If the parameter has a question token, then it is TypeScript syntax. - if (node.questionToken) { - transformFlags |= TransformFlags.AssertTypeScript; - } - - // If the parameter's name is 'this', then it is TypeScript syntax. - if (subtreeFlags & TransformFlags.ContainsDecorators || isThisIdentifier(name)) { + // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript + // syntax. + if (node.questionToken + || node.type + || subtreeFlags & TransformFlags.ContainsDecorators + || isThisIdentifier(name)) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2547,7 +2568,8 @@ namespace ts { // TypeScript syntax. // An exported declaration may be TypeScript syntax. if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) - || (modifierFlags & ModifierFlags.Export)) { + || (modifierFlags & ModifierFlags.Export) + || node.typeParameters) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2568,7 +2590,8 @@ namespace ts { // A class with a parameter property assignment, property initializer, or decorator is // TypeScript syntax. - if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask) { + if (subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask + || node.typeParameters) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2622,10 +2645,10 @@ namespace ts { function computeConstructor(node: ConstructorDeclaration, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const body = node.body; - if (body === undefined) { - // An overload constructor is TypeScript syntax. + // TypeScript-specific modifiers and overloads are TypeScript syntax + if (hasModifier(node, ModifierFlags.TypeScriptModifier) + || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2636,27 +2659,24 @@ namespace ts { function computeMethod(node: MethodDeclaration, subtreeFlags: TransformFlags) { // A MethodDeclaration is ES6 syntax. let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - const modifierFlags = getModifierFlags(node); - const body = node.body; - const typeParameters = node.typeParameters; - const asteriskToken = node.asteriskToken; - - // A MethodDeclaration is TypeScript syntax if it is either abstract, overloaded, - // generic, or has a decorator. - if (!body - || typeParameters - || (modifierFlags & ModifierFlags.Abstract) - || (subtreeFlags & TransformFlags.ContainsDecorators)) { + + // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and + // overloads are TypeScript syntax. + if (node.decorators + || hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.typeParameters + || node.type + || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } // An async method declaration is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { + if (hasModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } // Currently, we only support generators that were originally async function bodies. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } @@ -2666,14 +2686,13 @@ namespace ts { function computeAccessor(node: AccessorDeclaration, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const modifierFlags = getModifierFlags(node); - const body = node.body; - // An accessor is TypeScript syntax if it is either abstract, overloaded, - // generic, or has a decorator. - if (!body - || (modifierFlags & ModifierFlags.Abstract) - || (subtreeFlags & TransformFlags.ContainsDecorators)) { + // Decorators, TypeScript-specific modifiers, type annotations, and overloads are + // TypeScript syntax. + if (node.decorators + || hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.type + || !node.body) { transformFlags |= TransformFlags.AssertTypeScript; } @@ -2699,7 +2718,6 @@ namespace ts { let transformFlags: TransformFlags; const modifierFlags = getModifierFlags(node); const body = node.body; - const asteriskToken = node.asteriskToken; if (!body || (modifierFlags & ModifierFlags.Ambient)) { // An ambient declaration is TypeScript syntax. @@ -2714,6 +2732,14 @@ namespace ts { transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2015; } + // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript + // syntax. + if (modifierFlags & ModifierFlags.TypeScriptModifier + || node.typeParameters + || node.type) { + transformFlags |= TransformFlags.AssertTypeScript; + } + // An async function declaration is ES2017 syntax. if (modifierFlags & ModifierFlags.Async) { transformFlags |= TransformFlags.AssertES2017; @@ -2731,7 +2757,7 @@ namespace ts { // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } } @@ -2742,11 +2768,17 @@ namespace ts { function computeFunctionExpression(node: FunctionExpression, subtreeFlags: TransformFlags) { let transformFlags = subtreeFlags; - const modifierFlags = getModifierFlags(node); - const asteriskToken = node.asteriskToken; + + // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript + // syntax. + if (hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.typeParameters + || node.type) { + transformFlags |= TransformFlags.AssertTypeScript; + } // An async function expression is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { + if (hasModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } @@ -2762,7 +2794,7 @@ namespace ts { // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. - if (asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { + if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) { transformFlags |= TransformFlags.AssertGenerator; } @@ -2773,10 +2805,17 @@ namespace ts { function computeArrowFunction(node: ArrowFunction, subtreeFlags: TransformFlags) { // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. let transformFlags = subtreeFlags | TransformFlags.AssertES2015; - const modifierFlags = getModifierFlags(node); + + // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript + // syntax. + if (hasModifier(node, ModifierFlags.TypeScriptModifier) + || node.typeParameters + || node.type) { + transformFlags |= TransformFlags.AssertTypeScript; + } // An async arrow function is ES2017 syntax. - if (modifierFlags & ModifierFlags.Async) { + if (hasModifier(node, ModifierFlags.Async)) { transformFlags |= TransformFlags.AssertES2017; } @@ -2813,6 +2852,11 @@ namespace ts { transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsBindingPattern; } + // Type annotations are TypeScript syntax. + if (node.type) { + transformFlags |= TransformFlags.AssertTypeScript; + } + node.transformFlags = transformFlags | TransformFlags.HasComputedFlags; return transformFlags & ~TransformFlags.NodeExcludes; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8ece815178f5b..16f7e5a1c8a2f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -504,15 +504,29 @@ const _super = (function (geti, seti) { // Contextual keywords case SyntaxKind.AbstractKeyword: + case SyntaxKind.AsKeyword: case SyntaxKind.AnyKeyword: case SyntaxKind.AsyncKeyword: + case SyntaxKind.AwaitKeyword: case SyntaxKind.BooleanKeyword: + case SyntaxKind.ConstructorKeyword: case SyntaxKind.DeclareKeyword: - case SyntaxKind.NumberKeyword: + case SyntaxKind.GetKeyword: + case SyntaxKind.IsKeyword: + case SyntaxKind.ModuleKeyword: + case SyntaxKind.NamespaceKeyword: + case SyntaxKind.NeverKeyword: case SyntaxKind.ReadonlyKeyword: + case SyntaxKind.RequireKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.SetKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.SymbolKeyword: + case SyntaxKind.TypeKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.FromKeyword: case SyntaxKind.GlobalKeyword: + case SyntaxKind.OfKeyword: writeTokenText(kind); return; @@ -1198,12 +1212,14 @@ const _super = (function (geti, seti) { function emitCallExpression(node: CallExpression) { emitExpression(node.expression); + emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, ListFormat.CallExpressionArguments); } function emitNewExpression(node: NewExpression) { write("new "); emitExpression(node.expression); + emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, ListFormat.NewExpressionArguments); } @@ -1575,6 +1591,7 @@ const _super = (function (geti, seti) { function emitVariableDeclaration(node: VariableDeclaration) { emit(node.name); + emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 75d28a6727bcb..bb2e8ac2aa501 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -1417,6 +1417,7 @@ namespace ts { if (getAccessor) { const getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined); setSourceMapRange(getterFunction, getSourceMapRange(getAccessor)); + setEmitFlags(getterFunction, EmitFlags.NoLeadingComments); const getter = createPropertyAssignment("get", getterFunction); setCommentRange(getter, getCommentRange(getAccessor)); properties.push(getter); @@ -1425,6 +1426,7 @@ namespace ts { if (setAccessor) { const setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined); setSourceMapRange(setterFunction, getSourceMapRange(setAccessor)); + setEmitFlags(setterFunction, EmitFlags.NoLeadingComments); const setter = createPropertyAssignment("set", setterFunction); setCommentRange(setter, getCommentRange(setAccessor)); properties.push(setter); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 50d3fc26263e3..1d930c3c21e6e 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -304,8 +304,7 @@ namespace ts { // TypeScript property declarations are elided. case SyntaxKind.Constructor: - // TypeScript constructors are transformed in `visitClassDeclaration`. - return undefined; + return visitConstructor(node); case SyntaxKind.InterfaceDeclaration: // TypeScript interfaces are elided, but some comments may be preserved. @@ -393,6 +392,12 @@ namespace ts { // TypeScript type assertions are removed, but their subtrees are preserved. return visitAssertionExpression(node); + case SyntaxKind.CallExpression: + return visitCallExpression(node); + + case SyntaxKind.NewExpression: + return visitNewExpression(node); + case SyntaxKind.NonNullExpression: // TypeScript non-null expressions are removed, but their subtrees are preserved. return visitNonNullExpression(node); @@ -405,6 +410,9 @@ namespace ts { // TypeScript namespace exports for variable statements must be transformed. return visitVariableStatement(node); + case SyntaxKind.VariableDeclaration: + return visitVariableDeclaration(node); + case SyntaxKind.ModuleDeclaration: // TypeScript namespace declarations must be transformed. return visitModuleDeclaration(node); @@ -2100,6 +2108,14 @@ namespace ts { return !nodeIsMissing(node.body); } + function visitConstructor(node: ConstructorDeclaration) { + if (!shouldEmitFunctionLikeDeclaration(node)) { + return undefined; + } + + return visitEachChild(node, visitor, context); + } + /** * Visits a method declaration of a class. * @@ -2304,13 +2320,16 @@ namespace ts { function transformFunctionBodyWorker(body: Block, start = 0) { const savedCurrentScope = currentScope; + const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName; currentScope = body; + currentScopeFirstDeclarationsOfName = createMap(); startLexicalEnvironment(); const statements = visitNodes(body.statements, visitor, isStatement, start); const visited = updateBlock(body, statements); const declarations = endLexicalEnvironment(); currentScope = savedCurrentScope; + currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; return mergeFunctionBodyLexicalEnvironment(visited, declarations); } @@ -2420,6 +2439,14 @@ namespace ts { } } + function visitVariableDeclaration(node: VariableDeclaration) { + return updateVariableDeclaration( + node, + visitNode(node.name, visitor, isBindingName), + /*type*/ undefined, + visitNode(node.initializer, visitor, isExpression)); + } + /** * Visits a parenthesized expression that contains either a type assertion or an `as` * expression. @@ -2462,6 +2489,22 @@ namespace ts { return createPartiallyEmittedExpression(expression, node); } + function visitCallExpression(node: CallExpression) { + return updateCall( + node, + visitNode(node.expression, visitor, isExpression), + /*typeArguments*/ undefined, + visitNodes(node.arguments, visitor, isExpression)); + } + + function visitNewExpression(node: NewExpression) { + return updateNew( + node, + visitNode(node.expression, visitor, isExpression), + /*typeArguments*/ undefined, + visitNodes(node.arguments, visitor, isExpression)); + } + /** * Determines whether to emit an enum declaration. * diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7e17b15578307..3840401daca60 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -456,6 +456,8 @@ namespace ts { // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. ParameterPropertyModifier = AccessibilityModifier | Readonly, NonPublicAccessibilityModifier = Private | Protected, + + TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const } export const enum JsxFlags { diff --git a/tests/baselines/reference/constructorArgsErrors1.js b/tests/baselines/reference/constructorArgsErrors1.js index 15c5e64952bc2..bb0725ab8b9b3 100644 --- a/tests/baselines/reference/constructorArgsErrors1.js +++ b/tests/baselines/reference/constructorArgsErrors1.js @@ -6,7 +6,7 @@ class foo { //// [constructorArgsErrors1.js] var foo = (function () { - function foo(static a) { + function foo(a) { } return foo; }()); diff --git a/tests/baselines/reference/constructorArgsErrors5.js b/tests/baselines/reference/constructorArgsErrors5.js index 6ba68cb88b4ed..c481d6f323c6c 100644 --- a/tests/baselines/reference/constructorArgsErrors5.js +++ b/tests/baselines/reference/constructorArgsErrors5.js @@ -7,7 +7,7 @@ class foo { //// [constructorArgsErrors5.js] var foo = (function () { - function foo(export a) { + function foo(a) { } return foo; }()); diff --git a/tests/baselines/reference/parserErrorRecovery_ParameterList6.js b/tests/baselines/reference/parserErrorRecovery_ParameterList6.js index c3d5a838f88f5..7c221aaa20ac3 100644 --- a/tests/baselines/reference/parserErrorRecovery_ParameterList6.js +++ b/tests/baselines/reference/parserErrorRecovery_ParameterList6.js @@ -7,7 +7,6 @@ class Foo { var Foo = (function () { function Foo() { } - Foo.prototype.banana = function (x) { }; return Foo; }()); break ; diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.js b/tests/baselines/reference/transformsElideNullUndefinedType.js new file mode 100644 index 0000000000000..63bc77559c127 --- /dev/null +++ b/tests/baselines/reference/transformsElideNullUndefinedType.js @@ -0,0 +1,108 @@ +//// [transformsElideNullUndefinedType.ts] + +var v0: null; +var v1: undefined; + +function f0(): null { return null; } +function f1(): undefined { return undefined; } + +var f2 = function (): null { return null; } +var f3 = function (): undefined { return undefined; } + +var f4 = (): null => null; +var f5 = (): undefined => undefined; + +function f6(p0: null) { } +function f7(p1: undefined) { } + +var f8 = function (p2: null) { } +var f9 = function (p3: undefined) { } + +var f10 = (p4: null) => { } +var f11 = (p5: undefined) => { } + +class C1 { + m0(): null { return null; } + m1(): undefined { return undefined; } + + m3(p6: null) { } + m4(p7: undefined) { } + + get a0(): null { return null; } + get a1(): undefined { return undefined; } + + set a2(p8: null) { } + set a3(p9: undefined) { } +} + +class C2 { constructor(p10: null) { } } +class C3 { constructor(p11: undefined) { } } + +class C4 { + f1; + constructor(p12: null) { } +} + +class C5 { + f2; + constructor(p13: undefined) { } +} + +var C6 = class { constructor(p12: null) { } } +var C7 = class { constructor(p13: undefined) { } } + +declare function fn(); +fn(); +fn(); + +declare class D {} +new D(); +new D(); + +//// [transformsElideNullUndefinedType.js] +var v0; +var v1; +function f0() { return null; } +function f1() { return undefined; } +var f2 = function () { return null; }; +var f3 = function () { return undefined; }; +var f4 = () => null; +var f5 = () => undefined; +function f6(p0) { } +function f7(p1) { } +var f8 = function (p2) { }; +var f9 = function (p3) { }; +var f10 = (p4) => { }; +var f11 = (p5) => { }; +class C1 { + m0() { return null; } + m1() { return undefined; } + m3(p6) { } + m4(p7) { } + get a0() { return null; } + get a1() { return undefined; } + set a2(p8) { } + set a3(p9) { } +} +class C2 { + constructor(p10) { } +} +class C3 { + constructor(p11) { } +} +class C4 { + constructor(p12) { } +} +class C5 { + constructor(p13) { } +} +var C6 = class { + constructor(p12) { } +}; +var C7 = class { + constructor(p13) { } +}; +fn(); +fn(); +new D(); +new D(); diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.symbols b/tests/baselines/reference/transformsElideNullUndefinedType.symbols new file mode 100644 index 0000000000000..b651784a61ca8 --- /dev/null +++ b/tests/baselines/reference/transformsElideNullUndefinedType.symbols @@ -0,0 +1,143 @@ +=== tests/cases/compiler/transformsElideNullUndefinedType.ts === + +var v0: null; +>v0 : Symbol(v0, Decl(transformsElideNullUndefinedType.ts, 1, 3)) + +var v1: undefined; +>v1 : Symbol(v1, Decl(transformsElideNullUndefinedType.ts, 2, 3)) + +function f0(): null { return null; } +>f0 : Symbol(f0, Decl(transformsElideNullUndefinedType.ts, 2, 18)) + +function f1(): undefined { return undefined; } +>f1 : Symbol(f1, Decl(transformsElideNullUndefinedType.ts, 4, 36)) +>undefined : Symbol(undefined) + +var f2 = function (): null { return null; } +>f2 : Symbol(f2, Decl(transformsElideNullUndefinedType.ts, 7, 3)) + +var f3 = function (): undefined { return undefined; } +>f3 : Symbol(f3, Decl(transformsElideNullUndefinedType.ts, 8, 3)) +>undefined : Symbol(undefined) + +var f4 = (): null => null; +>f4 : Symbol(f4, Decl(transformsElideNullUndefinedType.ts, 10, 3)) + +var f5 = (): undefined => undefined; +>f5 : Symbol(f5, Decl(transformsElideNullUndefinedType.ts, 11, 3)) +>undefined : Symbol(undefined) + +function f6(p0: null) { } +>f6 : Symbol(f6, Decl(transformsElideNullUndefinedType.ts, 11, 36)) +>p0 : Symbol(p0, Decl(transformsElideNullUndefinedType.ts, 13, 12)) + +function f7(p1: undefined) { } +>f7 : Symbol(f7, Decl(transformsElideNullUndefinedType.ts, 13, 25)) +>p1 : Symbol(p1, Decl(transformsElideNullUndefinedType.ts, 14, 12)) + +var f8 = function (p2: null) { } +>f8 : Symbol(f8, Decl(transformsElideNullUndefinedType.ts, 16, 3)) +>p2 : Symbol(p2, Decl(transformsElideNullUndefinedType.ts, 16, 19)) + +var f9 = function (p3: undefined) { } +>f9 : Symbol(f9, Decl(transformsElideNullUndefinedType.ts, 17, 3)) +>p3 : Symbol(p3, Decl(transformsElideNullUndefinedType.ts, 17, 19)) + +var f10 = (p4: null) => { } +>f10 : Symbol(f10, Decl(transformsElideNullUndefinedType.ts, 19, 3)) +>p4 : Symbol(p4, Decl(transformsElideNullUndefinedType.ts, 19, 11)) + +var f11 = (p5: undefined) => { } +>f11 : Symbol(f11, Decl(transformsElideNullUndefinedType.ts, 20, 3)) +>p5 : Symbol(p5, Decl(transformsElideNullUndefinedType.ts, 20, 11)) + +class C1 { +>C1 : Symbol(C1, Decl(transformsElideNullUndefinedType.ts, 20, 32)) + + m0(): null { return null; } +>m0 : Symbol(C1.m0, Decl(transformsElideNullUndefinedType.ts, 22, 10)) + + m1(): undefined { return undefined; } +>m1 : Symbol(C1.m1, Decl(transformsElideNullUndefinedType.ts, 23, 31)) +>undefined : Symbol(undefined) + + m3(p6: null) { } +>m3 : Symbol(C1.m3, Decl(transformsElideNullUndefinedType.ts, 24, 41)) +>p6 : Symbol(p6, Decl(transformsElideNullUndefinedType.ts, 26, 7)) + + m4(p7: undefined) { } +>m4 : Symbol(C1.m4, Decl(transformsElideNullUndefinedType.ts, 26, 20)) +>p7 : Symbol(p7, Decl(transformsElideNullUndefinedType.ts, 27, 7)) + + get a0(): null { return null; } +>a0 : Symbol(C1.a0, Decl(transformsElideNullUndefinedType.ts, 27, 25)) + + get a1(): undefined { return undefined; } +>a1 : Symbol(C1.a1, Decl(transformsElideNullUndefinedType.ts, 29, 35)) +>undefined : Symbol(undefined) + + set a2(p8: null) { } +>a2 : Symbol(C1.a2, Decl(transformsElideNullUndefinedType.ts, 30, 45)) +>p8 : Symbol(p8, Decl(transformsElideNullUndefinedType.ts, 32, 11)) + + set a3(p9: undefined) { } +>a3 : Symbol(C1.a3, Decl(transformsElideNullUndefinedType.ts, 32, 24)) +>p9 : Symbol(p9, Decl(transformsElideNullUndefinedType.ts, 33, 11)) +} + +class C2 { constructor(p10: null) { } } +>C2 : Symbol(C2, Decl(transformsElideNullUndefinedType.ts, 34, 1)) +>p10 : Symbol(p10, Decl(transformsElideNullUndefinedType.ts, 36, 23)) + +class C3 { constructor(p11: undefined) { } } +>C3 : Symbol(C3, Decl(transformsElideNullUndefinedType.ts, 36, 39)) +>p11 : Symbol(p11, Decl(transformsElideNullUndefinedType.ts, 37, 23)) + +class C4 { +>C4 : Symbol(C4, Decl(transformsElideNullUndefinedType.ts, 37, 44)) + + f1; +>f1 : Symbol(C4.f1, Decl(transformsElideNullUndefinedType.ts, 39, 10)) + + constructor(p12: null) { } +>p12 : Symbol(p12, Decl(transformsElideNullUndefinedType.ts, 41, 16)) +} + +class C5 { +>C5 : Symbol(C5, Decl(transformsElideNullUndefinedType.ts, 42, 1)) + + f2; +>f2 : Symbol(C5.f2, Decl(transformsElideNullUndefinedType.ts, 44, 10)) + + constructor(p13: undefined) { } +>p13 : Symbol(p13, Decl(transformsElideNullUndefinedType.ts, 46, 16)) +} + +var C6 = class { constructor(p12: null) { } } +>C6 : Symbol(C6, Decl(transformsElideNullUndefinedType.ts, 49, 3)) +>p12 : Symbol(p12, Decl(transformsElideNullUndefinedType.ts, 49, 29)) + +var C7 = class { constructor(p13: undefined) { } } +>C7 : Symbol(C7, Decl(transformsElideNullUndefinedType.ts, 50, 3)) +>p13 : Symbol(p13, Decl(transformsElideNullUndefinedType.ts, 50, 29)) + +declare function fn(); +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 50, 50)) +>T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 52, 20)) + +fn(); +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 50, 50)) + +fn(); +>fn : Symbol(fn, Decl(transformsElideNullUndefinedType.ts, 50, 50)) + +declare class D {} +>D : Symbol(D, Decl(transformsElideNullUndefinedType.ts, 54, 16)) +>T : Symbol(T, Decl(transformsElideNullUndefinedType.ts, 56, 16)) + +new D(); +>D : Symbol(D, Decl(transformsElideNullUndefinedType.ts, 54, 16)) + +new D(); +>D : Symbol(D, Decl(transformsElideNullUndefinedType.ts, 54, 16)) + diff --git a/tests/baselines/reference/transformsElideNullUndefinedType.types b/tests/baselines/reference/transformsElideNullUndefinedType.types new file mode 100644 index 0000000000000..7f48d8a00e96f --- /dev/null +++ b/tests/baselines/reference/transformsElideNullUndefinedType.types @@ -0,0 +1,178 @@ +=== tests/cases/compiler/transformsElideNullUndefinedType.ts === + +var v0: null; +>v0 : null +>null : null + +var v1: undefined; +>v1 : undefined + +function f0(): null { return null; } +>f0 : () => null +>null : null +>null : null + +function f1(): undefined { return undefined; } +>f1 : () => undefined +>undefined : undefined + +var f2 = function (): null { return null; } +>f2 : () => null +>function (): null { return null; } : () => null +>null : null +>null : null + +var f3 = function (): undefined { return undefined; } +>f3 : () => undefined +>function (): undefined { return undefined; } : () => undefined +>undefined : undefined + +var f4 = (): null => null; +>f4 : () => null +>(): null => null : () => null +>null : null +>null : null + +var f5 = (): undefined => undefined; +>f5 : () => undefined +>(): undefined => undefined : () => undefined +>undefined : undefined + +function f6(p0: null) { } +>f6 : (p0: null) => void +>p0 : null +>null : null + +function f7(p1: undefined) { } +>f7 : (p1: undefined) => void +>p1 : undefined + +var f8 = function (p2: null) { } +>f8 : (p2: null) => void +>function (p2: null) { } : (p2: null) => void +>p2 : null +>null : null + +var f9 = function (p3: undefined) { } +>f9 : (p3: undefined) => void +>function (p3: undefined) { } : (p3: undefined) => void +>p3 : undefined + +var f10 = (p4: null) => { } +>f10 : (p4: null) => void +>(p4: null) => { } : (p4: null) => void +>p4 : null +>null : null + +var f11 = (p5: undefined) => { } +>f11 : (p5: undefined) => void +>(p5: undefined) => { } : (p5: undefined) => void +>p5 : undefined + +class C1 { +>C1 : C1 + + m0(): null { return null; } +>m0 : () => null +>null : null +>null : null + + m1(): undefined { return undefined; } +>m1 : () => undefined +>undefined : undefined + + m3(p6: null) { } +>m3 : (p6: null) => void +>p6 : null +>null : null + + m4(p7: undefined) { } +>m4 : (p7: undefined) => void +>p7 : undefined + + get a0(): null { return null; } +>a0 : null +>null : null +>null : null + + get a1(): undefined { return undefined; } +>a1 : undefined +>undefined : undefined + + set a2(p8: null) { } +>a2 : null +>p8 : null +>null : null + + set a3(p9: undefined) { } +>a3 : undefined +>p9 : undefined +} + +class C2 { constructor(p10: null) { } } +>C2 : C2 +>p10 : null +>null : null + +class C3 { constructor(p11: undefined) { } } +>C3 : C3 +>p11 : undefined + +class C4 { +>C4 : C4 + + f1; +>f1 : any + + constructor(p12: null) { } +>p12 : null +>null : null +} + +class C5 { +>C5 : C5 + + f2; +>f2 : any + + constructor(p13: undefined) { } +>p13 : undefined +} + +var C6 = class { constructor(p12: null) { } } +>C6 : typeof (Anonymous class) +>class { constructor(p12: null) { } } : typeof (Anonymous class) +>p12 : null +>null : null + +var C7 = class { constructor(p13: undefined) { } } +>C7 : typeof (Anonymous class) +>class { constructor(p13: undefined) { } } : typeof (Anonymous class) +>p13 : undefined + +declare function fn(); +>fn : () => any +>T : T + +fn(); +>fn() : any +>fn : () => any +>null : null + +fn(); +>fn() : any +>fn : () => any + +declare class D {} +>D : D +>T : T + +new D(); +>new D() : D +>D : typeof D +>null : null + +new D(); +>new D() : D +>D : typeof D + diff --git a/tests/baselines/reference/typeGuardFunctionErrors.js b/tests/baselines/reference/typeGuardFunctionErrors.js index 6f0880ad7f59a..244b0df3333db 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.js +++ b/tests/baselines/reference/typeGuardFunctionErrors.js @@ -171,7 +171,6 @@ var C = (function (_super) { function hasANonBooleanReturnStatement(x) { return ''; } -function hasTypeGuardTypeInsideTypeGuardType(x) { } is; A; { @@ -232,7 +231,6 @@ function b2(a, A) { if (a === void 0) { a = is; } } ; -function b3() { } is; A; { diff --git a/tests/cases/compiler/transformsElideNullUndefinedType.ts b/tests/cases/compiler/transformsElideNullUndefinedType.ts new file mode 100644 index 0000000000000..4a493a91d8824 --- /dev/null +++ b/tests/cases/compiler/transformsElideNullUndefinedType.ts @@ -0,0 +1,60 @@ +// @target: es6 + +var v0: null; +var v1: undefined; + +function f0(): null { return null; } +function f1(): undefined { return undefined; } + +var f2 = function (): null { return null; } +var f3 = function (): undefined { return undefined; } + +var f4 = (): null => null; +var f5 = (): undefined => undefined; + +function f6(p0: null) { } +function f7(p1: undefined) { } + +var f8 = function (p2: null) { } +var f9 = function (p3: undefined) { } + +var f10 = (p4: null) => { } +var f11 = (p5: undefined) => { } + +class C1 { + m0(): null { return null; } + m1(): undefined { return undefined; } + + m3(p6: null) { } + m4(p7: undefined) { } + + get a0(): null { return null; } + get a1(): undefined { return undefined; } + + set a2(p8: null) { } + set a3(p9: undefined) { } +} + +class C2 { constructor(p10: null) { } } +class C3 { constructor(p11: undefined) { } } + +class C4 { + f1; + constructor(p12: null) { } +} + +class C5 { + f2; + constructor(p13: undefined) { } +} + +var C6 = class { constructor(p12: null) { } } +var C7 = class { constructor(p13: undefined) { } } + +declare function fn(); +fn(); +fn(); + +declare class D {} +new D(); +new D(); \ No newline at end of file