From e7e26ce10b9d027de09c6aa5a5473a5535994b73 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 27 Feb 2017 12:06:31 -0800 Subject: [PATCH] Added experiment flag. --- src/compiler/checker.ts | 16 ++++++++++++++++ src/compiler/commandLineParser.ts | 6 ++++++ src/compiler/diagnosticMessages.json | 12 ++++++++---- src/compiler/program.ts | 8 ++++++++ src/compiler/types.ts | 1 + .../emitter.safeNavigation.es2015.ts | 1 + .../safeNavigation/emitter.safeNavigation.es3.ts | 1 + .../safeNavigation/emitter.safeNavigation.es5.ts | 1 + .../emitter.safeNavigation.esnext.ts | 1 + .../parser.safeNavigation.esnext.ts | 1 + .../types.safeNavigation.esnext.1.ts | 1 + .../types.safeNavigation.esnext.2.ts | 1 + 12 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da2b92a9406..1f379c30468 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13183,6 +13183,10 @@ namespace ts { function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) { const propagateNull = node.flags & NodeFlags.PropagateNull; + if (propagateNull && !compilerOptions.experimentalNullPropagation) { + error(node, Diagnostics.Experimental_support_for_null_propagation_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalNullPropagation_option_to_remove_this_warning); + } + const objectType = propagateNull ? checkExpression(left) : checkNonNullExpression(left); const type = propagateNull ? getNonNullableType(objectType) : objectType; const propagatingType = propagateNull ? getNullPropagatingType(objectType) : neverType; @@ -13310,6 +13314,10 @@ namespace ts { checkGrammarNullPropagation(node); const propagateNull = node.flags & NodeFlags.PropagateNull; + if (propagateNull && !compilerOptions.experimentalNullPropagation) { + error(node, Diagnostics.Experimental_support_for_null_propagation_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalNullPropagation_option_to_remove_this_warning); + } + const objectType = propagateNull ? checkExpression(node.expression) : checkNonNullExpression(node.expression); const type = propagateNull ? getNonNullableType(objectType) : objectType; const propagatingType = propagateNull ? getNullPropagatingType(objectType) : neverType; @@ -14344,6 +14352,10 @@ namespace ts { const propagateNull = node.flags & NodeFlags.PropagateNull; + if (propagateNull && !compilerOptions.experimentalNullPropagation) { + error(node, Diagnostics.Experimental_support_for_null_propagation_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalNullPropagation_option_to_remove_this_warning); + } + const funcType = propagateNull ? checkExpression(node.expression) : checkNonNullExpression(node.expression); const type = propagateNull ? getNonNullableType(funcType) : funcType; if (type === silentNeverType) { @@ -14423,6 +14435,10 @@ namespace ts { } const propagateNull = node.flags & NodeFlags.PropagateNull; + if (propagateNull && !compilerOptions.experimentalNullPropagation) { + error(node, Diagnostics.Experimental_support_for_null_propagation_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalNullPropagation_option_to_remove_this_warning); + } + const funcType = propagateNull ? checkExpression(node.expression) : checkNonNullExpression(node.expression); const type = propagateNull ? getNonNullableType(funcType) : funcType; if (type === silentNeverType) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 6b4e9ff590e..4ed9aced6a4 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -299,6 +299,12 @@ namespace ts { experimental: true, description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, + { + name: "experimentalNullPropagation", + type: "boolean", + experimental: true, + description: Diagnostics.Enables_experimental_support_for_null_propagation + }, { name: "moduleResolution", type: createMapFromTemplate({ diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6d45b53f7fe..db7b02926ab 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -827,6 +827,10 @@ "category": "Error", "code": 1254 }, + "Experimental support for null propagation is a feature that is subject to change in a future release. Set the 'experimentalNullPropagation' option to remove this warning.": { + "category": "Error", + "code": 1255 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", "code": 1300 @@ -2721,10 +2725,6 @@ "category": "Message", "code": 6066 }, - "Enables experimental support for ES7 async functions.": { - "category": "Message", - "code": 6068 - }, "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).": { "category": "Message", "code": 6069 @@ -3045,6 +3045,10 @@ "category": "Message", "code": 6149 }, + "Enables experimental support for 'null propagation'.": { + "category": "Message", + "code": 6150 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index eb9f0f0e0a1..8addc43e6fa 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -986,6 +986,14 @@ namespace ts { const typeAssertionExpression = node; diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file)); return; + case SyntaxKind.PropertyAccessExpression: + case SyntaxKind.ElementAccessExpression: + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + if (node.flags & NodeFlags.PropagateNull && !options.experimentalNullPropagation) { + diagnostics.push(createDiagnosticForNode(node, Diagnostics.Experimental_support_for_null_propagation_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalNullPropagation_option_to_remove_this_warning)); + } + break; } const prevParent = parent; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index cc6d9859f93..052433f4668 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3294,6 +3294,7 @@ emitBOM?: boolean; emitDecoratorMetadata?: boolean; experimentalDecorators?: boolean; + experimentalNullPropagation?: boolean; forceConsistentCasingInFileNames?: boolean; /*@internal*/help?: boolean; importHelpers?: boolean; diff --git a/tests/cases/conformance/emitter/es2015/safeNavigation/emitter.safeNavigation.es2015.ts b/tests/cases/conformance/emitter/es2015/safeNavigation/emitter.safeNavigation.es2015.ts index 1f9e63d0dd4..110c10ff467 100644 --- a/tests/cases/conformance/emitter/es2015/safeNavigation/emitter.safeNavigation.es2015.ts +++ b/tests/cases/conformance/emitter/es2015/safeNavigation/emitter.safeNavigation.es2015.ts @@ -2,6 +2,7 @@ // @lib: esnext // @module: commonjs // @experimentalDecorators: true +// @experimentalNullPropagation: true // @filename: declarations.d.ts declare var x: any; declare var y: any; diff --git a/tests/cases/conformance/emitter/es3/safeNavigation/emitter.safeNavigation.es3.ts b/tests/cases/conformance/emitter/es3/safeNavigation/emitter.safeNavigation.es3.ts index 89645bac4d3..c92ae51685b 100644 --- a/tests/cases/conformance/emitter/es3/safeNavigation/emitter.safeNavigation.es3.ts +++ b/tests/cases/conformance/emitter/es3/safeNavigation/emitter.safeNavigation.es3.ts @@ -2,6 +2,7 @@ // @lib: esnext // @module: commonjs // @experimentalDecorators: true +// @experimentalNullPropagation: true // @filename: declarations.d.ts declare var x: any; declare var y: any; diff --git a/tests/cases/conformance/emitter/es5/safeNavigation/emitter.safeNavigation.es5.ts b/tests/cases/conformance/emitter/es5/safeNavigation/emitter.safeNavigation.es5.ts index 17aad2559ab..b19ef730716 100644 --- a/tests/cases/conformance/emitter/es5/safeNavigation/emitter.safeNavigation.es5.ts +++ b/tests/cases/conformance/emitter/es5/safeNavigation/emitter.safeNavigation.es5.ts @@ -2,6 +2,7 @@ // @lib: esnext // @module: commonjs // @experimentalDecorators: true +// @experimentalNullPropagation: true // @filename: declarations.d.ts declare var x: any; declare var y: any; diff --git a/tests/cases/conformance/emitter/esnext/safeNavigation/emitter.safeNavigation.esnext.ts b/tests/cases/conformance/emitter/esnext/safeNavigation/emitter.safeNavigation.esnext.ts index bdabd0b0f63..12ebd680f0f 100644 --- a/tests/cases/conformance/emitter/esnext/safeNavigation/emitter.safeNavigation.esnext.ts +++ b/tests/cases/conformance/emitter/esnext/safeNavigation/emitter.safeNavigation.esnext.ts @@ -2,6 +2,7 @@ // @lib: esnext // @module: commonjs // @experimentalDecorators: true +// @experimentalNullPropagation: true // @filename: declarations.d.ts declare var x: any; declare var y: any; diff --git a/tests/cases/conformance/parser/ecmascriptnext/safeNavigation/parser.safeNavigation.esnext.ts b/tests/cases/conformance/parser/ecmascriptnext/safeNavigation/parser.safeNavigation.esnext.ts index 91b01746398..9a02a47d53d 100644 --- a/tests/cases/conformance/parser/ecmascriptnext/safeNavigation/parser.safeNavigation.esnext.ts +++ b/tests/cases/conformance/parser/ecmascriptnext/safeNavigation/parser.safeNavigation.esnext.ts @@ -3,6 +3,7 @@ // @noEmit: true // @module: commonjs // @experimentalDecorators: true +// @experimentalNullPropagation: true // @filename: declarations.d.ts declare var x: any; declare var y: any; diff --git a/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.1.ts b/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.1.ts index 3b7a74b4fbb..4e32e5607f5 100644 --- a/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.1.ts +++ b/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.1.ts @@ -3,6 +3,7 @@ // @noEmit: true // @module: commonjs // @strictNullChecks: false +// @experimentalNullPropagation: true declare const x1: (() => number) | undefined | null; declare const x2: { y: (() => number) | undefined | null; }; declare const x3: { y: (() => number) | undefined | null; } | undefined | null; diff --git a/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.2.ts b/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.2.ts index a87d3eecd14..fd995a1bcc8 100644 --- a/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.2.ts +++ b/tests/cases/conformance/types/safeNavigation/types.safeNavigation.esnext.2.ts @@ -3,6 +3,7 @@ // @noEmit: true // @module: commonjs // @strictNullChecks: true +// @experimentalNullPropagation: true declare const x1: (() => number) | undefined | null; declare const x2: { y: (() => number) | undefined | null; }; declare const x3: { y: (() => number) | undefined | null; } | undefined | null;