From d2f500292f8cb885ec8e379944ae272af911210d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 10 Dec 2014 16:02:39 -0800 Subject: [PATCH 1/5] Make initial inferences from parameterless function expressions (#1186) --- src/compiler/checker.ts | 2 +- ...lTypingWithFixedTypeParameters1.errors.txt | 9 +---- .../inferenceFromParameterlessLambda.js | 17 +++++++++ .../inferenceFromParameterlessLambda.types | 37 +++++++++++++++++++ .../inferenceFromParameterlessLambda.ts | 9 +++++ 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/inferenceFromParameterlessLambda.js create mode 100644 tests/baselines/reference/inferenceFromParameterlessLambda.types create mode 100644 tests/cases/compiler/inferenceFromParameterlessLambda.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1e8a87bc4d4..41a0a3c4ec2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3372,7 +3372,7 @@ module ts { } function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration) { - return !node.typeParameters && !forEach(node.parameters, p => p.type); + return !node.typeParameters && node.parameters.length && !forEach(node.parameters, p => p.type); } function getTypeWithoutConstructors(type: Type): Type { diff --git a/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt b/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt index b668468eac3..972b4bb9188 100644 --- a/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt +++ b/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt @@ -1,14 +1,9 @@ tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(2,22): error TS2339: Property 'foo' does not exist on type 'string'. -tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(3,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'number'. -==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (2 errors) ==== +==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (1 errors) ==== var f10: (x: T, b: () => (a: T) => void, y: T) => T; f10('', () => a => a.foo, ''); // a is string ~~~ !!! error TS2339: Property 'foo' does not exist on type 'string'. - var r9 = f10('', () => (a => a.foo), 1); // error - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'number'. \ No newline at end of file + var r9 = f10('', () => (a => a.foo), 1); // error \ No newline at end of file diff --git a/tests/baselines/reference/inferenceFromParameterlessLambda.js b/tests/baselines/reference/inferenceFromParameterlessLambda.js new file mode 100644 index 00000000000..ad9a18b7549 --- /dev/null +++ b/tests/baselines/reference/inferenceFromParameterlessLambda.js @@ -0,0 +1,17 @@ +//// [inferenceFromParameterlessLambda.ts] +function foo(o: Take, i: Make) { } +interface Make { + (): T; +} +interface Take { + (n: T): void; +} +// Infer string from second argument because it isn't context sensitive +foo(n => n.length, () => 'hi'); + + +//// [inferenceFromParameterlessLambda.js] +function foo(o, i) { +} +// Infer string from second argument because it isn't context sensitive +foo(function (n) { return n.length; }, function () { return 'hi'; }); diff --git a/tests/baselines/reference/inferenceFromParameterlessLambda.types b/tests/baselines/reference/inferenceFromParameterlessLambda.types new file mode 100644 index 00000000000..8dbb8c5967c --- /dev/null +++ b/tests/baselines/reference/inferenceFromParameterlessLambda.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/inferenceFromParameterlessLambda.ts === +function foo(o: Take, i: Make) { } +>foo : (o: Take, i: Make) => void +>T : T +>o : Take +>Take : Take +>T : T +>i : Make +>Make : Make +>T : T + +interface Make { +>Make : Make +>T : T + + (): T; +>T : T +} +interface Take { +>Take : Take +>T : T + + (n: T): void; +>n : T +>T : T +} +// Infer string from second argument because it isn't context sensitive +foo(n => n.length, () => 'hi'); +>foo(n => n.length, () => 'hi') : void +>foo : (o: Take, i: Make) => void +>n => n.length : (n: string) => number +>n : string +>n.length : number +>n : string +>length : number +>() => 'hi' : () => string + diff --git a/tests/cases/compiler/inferenceFromParameterlessLambda.ts b/tests/cases/compiler/inferenceFromParameterlessLambda.ts new file mode 100644 index 00000000000..8585d4451fd --- /dev/null +++ b/tests/cases/compiler/inferenceFromParameterlessLambda.ts @@ -0,0 +1,9 @@ +function foo(o: Take, i: Make) { } +interface Make { + (): T; +} +interface Take { + (n: T): void; +} +// Infer string from second argument because it isn't context sensitive +foo(n => n.length, () => 'hi'); From dbe5cd0459299bd54b0b3b5339ea6fe159ed5584 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Tue, 16 Dec 2014 20:25:19 -0800 Subject: [PATCH 2/5] Add -noEmit compiler flag. --- src/compiler/commandLineParser.ts | 5 +++++ src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/types.ts | 1 + 4 files changed, 11 insertions(+) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index fabc897a355..9fe59b1ba27 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -54,6 +54,11 @@ module ts { paramType: Diagnostics.KIND, error: Diagnostics.Argument_for_module_option_must_be_commonjs_or_amd }, + { + name: "noEmit", + type: "boolean", + description: Diagnostics.Do_not_emit_outputs, + }, { name: "noEmitOnError", type: "boolean", diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 9c4ccfb5215..3db00700022 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -387,6 +387,7 @@ module ts { Do_not_erase_const_enum_declarations_in_generated_code: { code: 6007, category: DiagnosticCategory.Message, key: "Do not erase const enum declarations in generated code." }, Do_not_emit_outputs_if_any_type_checking_errors_were_reported: { code: 6008, category: DiagnosticCategory.Message, key: "Do not emit outputs if any type checking errors were reported." }, Do_not_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." }, + Do_not_emit_outputs: { code: 6010, category: DiagnosticCategory.Message, key: "Do not emit outputs." }, Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)" }, Specify_module_code_generation_Colon_commonjs_or_amd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs' or 'amd'" }, Print_this_message: { code: 6017, category: DiagnosticCategory.Message, key: "Print this message." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 89b5d645ad1..bd808edc9a4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1547,6 +1547,10 @@ "category": "Message", "code": 6009 }, + "Do not emit outputs.": { + "category": "Message", + "code": 6010 + }, "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)": { "category": "Message", "code": 6015 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 66a2ff25eee..9ed58746922 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1413,6 +1413,7 @@ module ts { locale?: string; mapRoot?: string; module?: ModuleKind; + noEmit?: boolean; noEmitOnError?: boolean; noErrorTruncation?: boolean; noImplicitAny?: boolean; From cd6eb180c6a87a91a0d0d0fc6310b2088be42f2e Mon Sep 17 00:00:00 2001 From: Arnavion Date: Tue, 16 Dec 2014 20:25:19 -0800 Subject: [PATCH 3/5] Don't emit outputs when -noEmit is specified. --- src/compiler/tsc.ts | 3 +++ src/compiler/types.ts | 2 +- tests/cases/fourslash/fourslash.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index bc4d48b7513..32725bfe0fc 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -296,6 +296,9 @@ module ts { if (checker.isEmitBlocked()) { exitStatus = EmitReturnStatus.AllOutputGenerationSkipped; } + else if (compilerOptions.noEmit) { + exitStatus = EmitReturnStatus.Succeeded; + } else { var emitStart = new Date().getTime(); var emitOutput = checker.emitFiles(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9ed58746922..c44c148c6ae 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -943,7 +943,7 @@ module ts { // Return code used by getEmitOutput function to indicate status of the function export enum EmitReturnStatus { - Succeeded = 0, // All outputs generated as requested (.js, .map, .d.ts), no errors reported + Succeeded = 0, // All outputs generated if requested (.js, .map, .d.ts), no errors reported AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, nothing generated JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index f5a582868e5..9ad1734178d 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -34,7 +34,7 @@ declare var FourSlash; // Return code used by getEmitOutput function to indicate status of the function // It is a duplicate of the one in types.ts to expose it to testcases in fourslash enum EmitReturnStatus { - Succeeded = 0, // All outputs generated as requested (.js, .map, .d.ts), no errors reported + Succeeded = 0, // All outputs generated if requested (.js, .map, .d.ts), no errors reported AllOutputGenerationSkipped = 1, // No .js generated because of syntax errors, or compiler options errors, nothing generated JSGeneratedWithSemanticErrors = 2, // .js and .map generated with semantic errors DeclarationGenerationSkipped = 3, // .d.ts generation skipped because of semantic errors or declaration emitter specific errors; Output .js with semantic errors From df6aa85d4f2a47253cec436e53c799d397bb587b Mon Sep 17 00:00:00 2001 From: Arnavion Date: Tue, 16 Dec 2014 20:25:20 -0800 Subject: [PATCH 4/5] Don't allow -noEmit with -out or -outDir --- src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/parser.ts | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 3db00700022..16d055725ca 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -378,6 +378,7 @@ module ts { Could_not_write_file_0_Colon_1: { code: 5033, category: DiagnosticCategory.Error, key: "Could not write file '{0}': {1}" }, Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5038, category: DiagnosticCategory.Error, key: "Option mapRoot cannot be specified without specifying sourcemap option." }, Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5039, category: DiagnosticCategory.Error, key: "Option sourceRoot cannot be specified without specifying sourcemap option." }, + Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option noEmit cannot be specified with option out or outDir." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index bd808edc9a4..cd9476b4747 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1511,6 +1511,10 @@ "category": "Error", "code": 5039 }, + "Option noEmit cannot be specified with option out or outDir.": { + "category": "Error", + "code": 5040 + }, "Concatenate and emit output to single file.": { "category": "Message", "code": 6001 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 14319b28257..77c11c709bd 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5539,6 +5539,12 @@ module ts { commonSourceDirectory += directorySeparator; } } + + if (options.noEmit) { + if (options.out || options.outDir) { + errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_out_or_outDir)); + } + } } } } From 880e5c50d726b3a05f2c75c26139992822b3a349 Mon Sep 17 00:00:00 2001 From: Arnavion Date: Tue, 16 Dec 2014 20:25:20 -0800 Subject: [PATCH 5/5] Don't allow -noEmit with -declaration --- src/compiler/diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ src/compiler/parser.ts | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 16d055725ca..1a437938a5a 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -379,6 +379,7 @@ module ts { Option_mapRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5038, category: DiagnosticCategory.Error, key: "Option mapRoot cannot be specified without specifying sourcemap option." }, Option_sourceRoot_cannot_be_specified_without_specifying_sourcemap_option: { code: 5039, category: DiagnosticCategory.Error, key: "Option sourceRoot cannot be specified without specifying sourcemap option." }, Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option noEmit cannot be specified with option out or outDir." }, + Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option noEmit cannot be specified with option declaration." }, Concatenate_and_emit_output_to_single_file: { code: 6001, category: DiagnosticCategory.Message, key: "Concatenate and emit output to single file." }, Generates_corresponding_d_ts_file: { code: 6002, category: DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." }, Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cd9476b4747..d49ae01220c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1515,6 +1515,10 @@ "category": "Error", "code": 5040 }, + "Option noEmit cannot be specified with option declaration.": { + "category": "Error", + "code": 5041 + }, "Concatenate and emit output to single file.": { "category": "Message", "code": 6001 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 77c11c709bd..b653e1e024c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5544,6 +5544,10 @@ module ts { if (options.out || options.outDir) { errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_out_or_outDir)); } + + if (options.declaration) { + errors.push(createCompilerDiagnostic(Diagnostics.Option_noEmit_cannot_be_specified_with_option_declaration)); + } } } }