From 873c1df74b7c7dcba59eaccc1bb4bd4b0da18a35 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Sat, 11 Oct 2014 12:52:42 -0700 Subject: [PATCH 01/25] Add es6 target --- src/compiler/commandLineParser.ts | 6 +- .../diagnosticInformationMap.generated.ts | 4 +- src/compiler/diagnosticMessages.json | 4 +- src/compiler/types.ts | 2 + src/harness/fourslash.ts | 2 +- src/harness/harness.ts | 4 +- src/harness/harnessLanguageService.ts | 2 +- src/services/compiler/precompile.ts | 2 +- src/services/services.ts | 12 +- src/services/shims.ts | 3 + src/services/syntax/scanner.ts | 2 +- src/services/syntax/unicode.ts | 4 +- tests/baselines/reference/es6-amd.js | 31 +++++ tests/baselines/reference/es6-amd.js.map | 2 + .../baselines/reference/es6-amd.sourcemap.txt | 128 ++++++++++++++++++ tests/baselines/reference/es6-amd.types | 16 +++ .../reference/es6-declaration-amd.js | 31 +++++ .../reference/es6-declaration-amd.js.map | 2 + .../es6-declaration-amd.sourcemap.txt | 128 ++++++++++++++++++ .../reference/es6-declaration-amd.types | 16 +++ .../baselines/reference/es6-sourcemap-amd.js | 25 ++++ .../reference/es6-sourcemap-amd.js.map | 2 + .../reference/es6-sourcemap-amd.sourcemap.txt | 128 ++++++++++++++++++ .../reference/es6-sourcemap-amd.types | 16 +++ tests/cases/compiler/es6-amd.ts | 17 +++ tests/cases/compiler/es6-declaration-amd.ts | 17 +++ tests/cases/compiler/es6-sourcemap-amd.ts | 16 +++ 27 files changed, 602 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/es6-amd.js create mode 100644 tests/baselines/reference/es6-amd.js.map create mode 100644 tests/baselines/reference/es6-amd.sourcemap.txt create mode 100644 tests/baselines/reference/es6-amd.types create mode 100644 tests/baselines/reference/es6-declaration-amd.js create mode 100644 tests/baselines/reference/es6-declaration-amd.js.map create mode 100644 tests/baselines/reference/es6-declaration-amd.sourcemap.txt create mode 100644 tests/baselines/reference/es6-declaration-amd.types create mode 100644 tests/baselines/reference/es6-sourcemap-amd.js create mode 100644 tests/baselines/reference/es6-sourcemap-amd.js.map create mode 100644 tests/baselines/reference/es6-sourcemap-amd.sourcemap.txt create mode 100644 tests/baselines/reference/es6-sourcemap-amd.types create mode 100644 tests/cases/compiler/es6-amd.ts create mode 100644 tests/cases/compiler/es6-declaration-amd.ts create mode 100644 tests/cases/compiler/es6-sourcemap-amd.ts diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 0e48953eaa7d5..a7993484c647d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -102,10 +102,10 @@ module ts { { name: "target", shortName: "t", - type: { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5 }, - description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_or_ES5, + type: { "es3": ScriptTarget.ES3, "es5": ScriptTarget.ES5 , "es6": ScriptTarget.ES6 }, + description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental, paramType: Diagnostics.VERSION, - error: Diagnostics.Argument_for_target_option_must_be_es3_or_es5 + error: Diagnostics.Argument_for_target_option_must_be_es3_es5_or_es6 }, { name: "version", diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index f6e8275786d29..627fb202c18aa 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -357,7 +357,7 @@ module ts { Watch_input_files: { code: 6005, category: DiagnosticCategory.Message, key: "Watch input files." }, Redirect_output_structure_to_the_directory: { code: 6006, category: DiagnosticCategory.Message, key: "Redirect output structure to the directory." }, Do_not_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." }, - Specify_ECMAScript_target_version_Colon_ES3_default_or_ES5: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), or 'ES5'" }, + 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." }, Print_the_compiler_s_version: { code: 6019, category: DiagnosticCategory.Message, key: "Print the compiler's version." }, @@ -379,7 +379,7 @@ module ts { Compiler_option_0_expects_an_argument: { code: 6044, category: DiagnosticCategory.Error, key: "Compiler option '{0}' expects an argument." }, Unterminated_quoted_string_in_response_file_0: { code: 6045, category: DiagnosticCategory.Error, key: "Unterminated quoted string in response file '{0}'." }, Argument_for_module_option_must_be_commonjs_or_amd: { code: 6046, category: DiagnosticCategory.Error, key: "Argument for '--module' option must be 'commonjs' or 'amd'." }, - Argument_for_target_option_must_be_es3_or_es5: { code: 6047, category: DiagnosticCategory.Error, key: "Argument for '--target' option must be 'es3' or 'es5'." }, + Argument_for_target_option_must_be_es3_es5_or_es6: { code: 6047, category: DiagnosticCategory.Error, key: "Argument for '--target' option must be 'es3', 'es5', or 'es6'." }, Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: { code: 6048, category: DiagnosticCategory.Error, key: "Locale must be of the form or -. For example '{0}' or '{1}'." }, Unsupported_locale_0: { code: 6049, category: DiagnosticCategory.Error, key: "Unsupported locale '{0}'." }, Unable_to_open_file_0: { code: 6050, category: DiagnosticCategory.Error, key: "Unable to open file '{0}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 97c82a0a71869..26a8c51cccc0b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1424,7 +1424,7 @@ "category": "Message", "code": 6009 }, - "Specify ECMAScript target version: 'ES3' (default), or 'ES5'": { + "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)": { "category": "Message", "code": 6015 }, @@ -1512,7 +1512,7 @@ "category": "Error", "code": 6046 }, - "Argument for '--target' option must be 'es3' or 'es5'.": { + "Argument for '--target' option must be 'es3', 'es5', or 'es6'.": { "category": "Error", "code": 6047 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2a291c828cdab..38b69e23dee10 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1062,6 +1062,8 @@ module ts { export enum ScriptTarget { ES3, ES5, + ES6, + Latest = ES6, } export interface ParsedCommandLine { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 6a4e13b22e33f..0e605a854e2df 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2139,7 +2139,7 @@ module FourSlash { var host = Harness.Compiler.createCompilerHost([{ unitName: Harness.Compiler.fourslashFilename, content: undefined }, { unitName: fileName, content: content }], (fn, contents) => result = contents, - ts.ScriptTarget.ES5, + ts.ScriptTarget.Latest, sys.useCaseSensitiveFileNames); var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js" }, host); var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true); diff --git a/src/harness/harness.ts b/src/harness/harness.ts index e35fe83f9b265..728c4cc08e0ab 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -532,7 +532,7 @@ module Harness { } export var defaultLibFileName = 'lib.d.ts'; - export var defaultLibSourceFile = ts.createSourceFile(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.ES5, /*version:*/ "0"); + export var defaultLibSourceFile = ts.createSourceFile(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest, /*version:*/ "0"); // Cache these between executions so we don't have to re-parse them for every test export var fourslashFilename = 'fourslash.ts'; @@ -685,6 +685,8 @@ module Harness { options.target = ts.ScriptTarget.ES3; } else if (setting.value.toLowerCase() === 'es5') { options.target = ts.ScriptTarget.ES5; + } else if (setting.value.toLowerCase() === 'es6') { + options.target = ts.ScriptTarget.ES6; } else { throw new Error('Unknown compile target ' + setting.value); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 647d0729cbb5f..6307c4d1e78ff 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -260,7 +260,7 @@ module Harness.LanguageService { /** Parse file given its source text */ public parseSourceText(fileName: string, sourceText: TypeScript.IScriptSnapshot): TypeScript.SourceUnitSyntax { - return TypeScript.Parser.parse(fileName, TypeScript.SimpleText.fromScriptSnapshot(sourceText), ts.ScriptTarget.ES5, TypeScript.isDTSFile(fileName)).sourceUnit(); + return TypeScript.Parser.parse(fileName, TypeScript.SimpleText.fromScriptSnapshot(sourceText), ts.ScriptTarget.Latest, TypeScript.isDTSFile(fileName)).sourceUnit(); } /** Parse a file on disk given its fileName */ diff --git a/src/services/compiler/precompile.ts b/src/services/compiler/precompile.ts index 3ff23d85bea1c..08a919a65b58a 100644 --- a/src/services/compiler/precompile.ts +++ b/src/services/compiler/precompile.ts @@ -184,7 +184,7 @@ module TypeScript { export function preProcessFile(fileName: string, sourceText: IScriptSnapshot, readImportFiles = true): IPreProcessedFileInfo { var text = SimpleText.fromScriptSnapshot(sourceText); - var scanner = Scanner.createScanner(ts.ScriptTarget.ES5, text, reportDiagnostic); + var scanner = Scanner.createScanner(ts.ScriptTarget.Latest, text, reportDiagnostic); var firstToken = scanner.scan(/*allowRegularExpression:*/ false); diff --git a/src/services/services.ts b/src/services/services.ts index 42f6160bd3e4b..d7c5dc2d897cc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -77,7 +77,7 @@ module ts { update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile; } - var scanner: Scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true); + var scanner: Scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); var emptyArray: any[] = []; @@ -1456,9 +1456,9 @@ module ts { } export function getDefaultCompilerOptions(): CompilerOptions { - // Set "ES5" target by default for language service + // Set "ScriptTarget.Latest" target by default for language service return { - target: ScriptTarget.ES5, + target: ScriptTarget.Latest, module: ModuleKind.None, }; } @@ -3794,8 +3794,8 @@ module ts { // before and after it have to be a non-identifier char). var endPosition = position + symbolNameLength; - if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.ES5)) && - (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.ES5))) { + if ((position === 0 || !isIdentifierPart(text.charCodeAt(position - 1), ScriptTarget.Latest)) && + (endPosition === sourceLength || !isIdentifierPart(text.charCodeAt(endPosition), ScriptTarget.Latest))) { // Found a real match. Keep searching. positions.push(position); } @@ -5217,7 +5217,7 @@ module ts { /// Classifier export function createClassifier(host: Logger): Classifier { - var scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ false); + var scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false); /// We do not have a full parser support to know when we should parse a regex or not /// If we consider every slash token to be a regex, we could be missing cases like "1/2/3", where diff --git a/src/services/shims.ts b/src/services/shims.ts index fdea0202323fb..a6bf421b09566 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -174,6 +174,7 @@ module ts { export enum LanguageVersion { EcmaScript3 = 0, EcmaScript5 = 1, + EcmaScript6 = 2, } export enum ModuleGenTarget { @@ -213,6 +214,7 @@ module ts { switch (languageVersion) { case LanguageVersion.EcmaScript3: return ScriptTarget.ES3 case LanguageVersion.EcmaScript5: return ScriptTarget.ES5; + case LanguageVersion.EcmaScript6: return ScriptTarget.ES6; default: throw Error("unsupported LanguageVersion value: " + languageVersion); } } @@ -234,6 +236,7 @@ module ts { switch (scriptTarget) { case ScriptTarget.ES3: return LanguageVersion.EcmaScript3; case ScriptTarget.ES5: return LanguageVersion.EcmaScript5; + case ScriptTarget.ES6: return LanguageVersion.EcmaScript6; default: throw Error("unsupported ScriptTarget value: " + scriptTarget); } } diff --git a/src/services/syntax/scanner.ts b/src/services/syntax/scanner.ts index 45cc151e2d5ba..29ced029f1cca 100644 --- a/src/services/syntax/scanner.ts +++ b/src/services/syntax/scanner.ts @@ -186,7 +186,7 @@ module TypeScript.Scanner { var lastTokenInfo = { leadingTriviaWidth: -1, width: -1 }; var lastTokenInfoTokenID: number = -1; - var triviaScanner = createScannerInternal(ts.ScriptTarget.ES5, SimpleText.fromString(""), () => { }); + var triviaScanner = createScannerInternal(ts.ScriptTarget.Latest, SimpleText.fromString(""), () => { }); interface IScannerToken extends ISyntaxToken { } diff --git a/src/services/syntax/unicode.ts b/src/services/syntax/unicode.ts index df2f88b74c576..b1e94090de743 100644 --- a/src/services/syntax/unicode.ts +++ b/src/services/syntax/unicode.ts @@ -84,7 +84,7 @@ module TypeScript { if (languageVersion === ts.ScriptTarget.ES3) { return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES3IdentifierStart); } - else if (languageVersion === ts.ScriptTarget.ES5) { + else if (languageVersion >= ts.ScriptTarget.ES5) { return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES5IdentifierStart); } else { @@ -96,7 +96,7 @@ module TypeScript { if (languageVersion === ts.ScriptTarget.ES3) { return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES3IdentifierPart); } - else if (languageVersion === ts.ScriptTarget.ES5) { + else if (languageVersion >= ts.ScriptTarget.ES5) { return Unicode.lookupInUnicodeMap(code, Unicode.unicodeES5IdentifierPart); } else { diff --git a/tests/baselines/reference/es6-amd.js b/tests/baselines/reference/es6-amd.js new file mode 100644 index 0000000000000..0cce3af04463a --- /dev/null +++ b/tests/baselines/reference/es6-amd.js @@ -0,0 +1,31 @@ +//// [es6-amd.ts] + +class A +{ + constructor () + { + + } + + public B() + { + return 42; + } +} + +//// [es6-amd.js] +var A = (function () { + function A() { + } + A.prototype.B = function () { + return 42; + }; + return A; +})(); +//# sourceMappingURL=es6-amd.js.map + +//// [es6-amd.d.ts] +declare class A { + constructor(); + B(): number; +} diff --git a/tests/baselines/reference/es6-amd.js.map b/tests/baselines/reference/es6-amd.js.map new file mode 100644 index 0000000000000..7371ba578bd1d --- /dev/null +++ b/tests/baselines/reference/es6-amd.js.map @@ -0,0 +1,2 @@ +//// [es6-amd.js.map] +{"version":3,"file":"es6-amd.js","sourceRoot":"","sources":["es6-amd.ts"],"names":["A","A.constructor","A.B"],"mappings":"AACA,IAAM,CAAC;IAEHA,SAFEA,CAACA;IAKHC,CAACA;IAEMD,aAACA,GAARA;QAEIE,MAAMA,CAACA,EAAEA,CAACA;IACdA,CAACA;IACLF,QAACA;AAADA,CAACA,AAXD,IAWC"} \ No newline at end of file diff --git a/tests/baselines/reference/es6-amd.sourcemap.txt b/tests/baselines/reference/es6-amd.sourcemap.txt new file mode 100644 index 0000000000000..070a35703e173 --- /dev/null +++ b/tests/baselines/reference/es6-amd.sourcemap.txt @@ -0,0 +1,128 @@ +=================================================================== +JsFile: es6-amd.js +mapUrl: es6-amd.js.map +sourceRoot: +sources: es6-amd.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:tests/cases/compiler/es6-amd.js +sourceFile:es6-amd.ts +------------------------------------------------------------------- +>>>var A = (function () { +1 > +2 >^^^^ +3 > ^ +4 > ^^^^^^^^^^^^^^-> +1 > + > +2 >class +3 > A +1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0) +2 >Emitted(1, 5) Source(2, 7) + SourceIndex(0) +3 >Emitted(1, 6) Source(2, 8) + SourceIndex(0) +--- +>>> function A() { +1->^^^^ +2 > ^^^^^^^^^ +3 > ^ +1-> + >{ + > +2 > +3 > A +1->Emitted(2, 5) Source(4, 5) + SourceIndex(0) name (A) +2 >Emitted(2, 14) Source(2, 7) + SourceIndex(0) name (A) +3 >Emitted(2, 15) Source(2, 8) + SourceIndex(0) name (A) +--- +>>> } +1 >^^^^ +2 > ^ +3 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > + >{ + > constructor () + > { + > + > +2 > } +1 >Emitted(3, 5) Source(7, 5) + SourceIndex(0) name (A.constructor) +2 >Emitted(3, 6) Source(7, 6) + SourceIndex(0) name (A.constructor) +--- +>>> A.prototype.B = function () { +1->^^^^ +2 > ^^^^^^^^^^^^^ +3 > ^^^ +1-> + > + > public +2 > B +3 > +1->Emitted(4, 5) Source(9, 12) + SourceIndex(0) name (A) +2 >Emitted(4, 18) Source(9, 13) + SourceIndex(0) name (A) +3 >Emitted(4, 21) Source(9, 5) + SourceIndex(0) name (A) +--- +>>> return 42; +1 >^^^^^^^^ +2 > ^^^^^^ +3 > ^ +4 > ^^ +5 > ^ +1 >public B() + > { + > +2 > return +3 > +4 > 42 +5 > ; +1 >Emitted(5, 9) Source(11, 9) + SourceIndex(0) name (A.B) +2 >Emitted(5, 15) Source(11, 15) + SourceIndex(0) name (A.B) +3 >Emitted(5, 16) Source(11, 16) + SourceIndex(0) name (A.B) +4 >Emitted(5, 18) Source(11, 18) + SourceIndex(0) name (A.B) +5 >Emitted(5, 19) Source(11, 19) + SourceIndex(0) name (A.B) +--- +>>> }; +1 >^^^^ +2 > ^ +3 > ^^^^^^^^^-> +1 > + > +2 > } +1 >Emitted(6, 5) Source(12, 5) + SourceIndex(0) name (A.B) +2 >Emitted(6, 6) Source(12, 6) + SourceIndex(0) name (A.B) +--- +>>> return A; +1->^^^^ +2 > ^^^^^^^^ +1-> + > +2 > } +1->Emitted(7, 5) Source(13, 1) + SourceIndex(0) name (A) +2 >Emitted(7, 13) Source(13, 2) + SourceIndex(0) name (A) +--- +>>>})(); +1 > +2 >^ +3 > +4 > ^^^^ +5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > +2 >} +3 > +4 > class A + > { + > constructor () + > { + > + > } + > + > public B() + > { + > return 42; + > } + > } +1 >Emitted(8, 1) Source(13, 1) + SourceIndex(0) name (A) +2 >Emitted(8, 2) Source(13, 2) + SourceIndex(0) name (A) +3 >Emitted(8, 2) Source(2, 1) + SourceIndex(0) +4 >Emitted(8, 6) Source(13, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=es6-amd.js.map \ No newline at end of file diff --git a/tests/baselines/reference/es6-amd.types b/tests/baselines/reference/es6-amd.types new file mode 100644 index 0000000000000..62815911f7f97 --- /dev/null +++ b/tests/baselines/reference/es6-amd.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/es6-amd.ts === + +class A +>A : A +{ + constructor () + { + + } + + public B() +>B : () => number + { + return 42; + } +} diff --git a/tests/baselines/reference/es6-declaration-amd.js b/tests/baselines/reference/es6-declaration-amd.js new file mode 100644 index 0000000000000..471f96b223d1a --- /dev/null +++ b/tests/baselines/reference/es6-declaration-amd.js @@ -0,0 +1,31 @@ +//// [es6-declaration-amd.ts] + +class A +{ + constructor () + { + + } + + public B() + { + return 42; + } +} + +//// [es6-declaration-amd.js] +var A = (function () { + function A() { + } + A.prototype.B = function () { + return 42; + }; + return A; +})(); +//# sourceMappingURL=es6-declaration-amd.js.map + +//// [es6-declaration-amd.d.ts] +declare class A { + constructor(); + B(): number; +} diff --git a/tests/baselines/reference/es6-declaration-amd.js.map b/tests/baselines/reference/es6-declaration-amd.js.map new file mode 100644 index 0000000000000..0987f9478e99e --- /dev/null +++ b/tests/baselines/reference/es6-declaration-amd.js.map @@ -0,0 +1,2 @@ +//// [es6-declaration-amd.js.map] +{"version":3,"file":"es6-declaration-amd.js","sourceRoot":"","sources":["es6-declaration-amd.ts"],"names":["A","A.constructor","A.B"],"mappings":"AACA,IAAM,CAAC;IAEHA,SAFEA,CAACA;IAKHC,CAACA;IAEMD,aAACA,GAARA;QAEIE,MAAMA,CAACA,EAAEA,CAACA;IACdA,CAACA;IACLF,QAACA;AAADA,CAACA,AAXD,IAWC"} \ No newline at end of file diff --git a/tests/baselines/reference/es6-declaration-amd.sourcemap.txt b/tests/baselines/reference/es6-declaration-amd.sourcemap.txt new file mode 100644 index 0000000000000..1fc0b5f05fead --- /dev/null +++ b/tests/baselines/reference/es6-declaration-amd.sourcemap.txt @@ -0,0 +1,128 @@ +=================================================================== +JsFile: es6-declaration-amd.js +mapUrl: es6-declaration-amd.js.map +sourceRoot: +sources: es6-declaration-amd.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:tests/cases/compiler/es6-declaration-amd.js +sourceFile:es6-declaration-amd.ts +------------------------------------------------------------------- +>>>var A = (function () { +1 > +2 >^^^^ +3 > ^ +4 > ^^^^^^^^^^^^^^-> +1 > + > +2 >class +3 > A +1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0) +2 >Emitted(1, 5) Source(2, 7) + SourceIndex(0) +3 >Emitted(1, 6) Source(2, 8) + SourceIndex(0) +--- +>>> function A() { +1->^^^^ +2 > ^^^^^^^^^ +3 > ^ +1-> + >{ + > +2 > +3 > A +1->Emitted(2, 5) Source(4, 5) + SourceIndex(0) name (A) +2 >Emitted(2, 14) Source(2, 7) + SourceIndex(0) name (A) +3 >Emitted(2, 15) Source(2, 8) + SourceIndex(0) name (A) +--- +>>> } +1 >^^^^ +2 > ^ +3 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > + >{ + > constructor () + > { + > + > +2 > } +1 >Emitted(3, 5) Source(7, 5) + SourceIndex(0) name (A.constructor) +2 >Emitted(3, 6) Source(7, 6) + SourceIndex(0) name (A.constructor) +--- +>>> A.prototype.B = function () { +1->^^^^ +2 > ^^^^^^^^^^^^^ +3 > ^^^ +1-> + > + > public +2 > B +3 > +1->Emitted(4, 5) Source(9, 12) + SourceIndex(0) name (A) +2 >Emitted(4, 18) Source(9, 13) + SourceIndex(0) name (A) +3 >Emitted(4, 21) Source(9, 5) + SourceIndex(0) name (A) +--- +>>> return 42; +1 >^^^^^^^^ +2 > ^^^^^^ +3 > ^ +4 > ^^ +5 > ^ +1 >public B() + > { + > +2 > return +3 > +4 > 42 +5 > ; +1 >Emitted(5, 9) Source(11, 9) + SourceIndex(0) name (A.B) +2 >Emitted(5, 15) Source(11, 15) + SourceIndex(0) name (A.B) +3 >Emitted(5, 16) Source(11, 16) + SourceIndex(0) name (A.B) +4 >Emitted(5, 18) Source(11, 18) + SourceIndex(0) name (A.B) +5 >Emitted(5, 19) Source(11, 19) + SourceIndex(0) name (A.B) +--- +>>> }; +1 >^^^^ +2 > ^ +3 > ^^^^^^^^^-> +1 > + > +2 > } +1 >Emitted(6, 5) Source(12, 5) + SourceIndex(0) name (A.B) +2 >Emitted(6, 6) Source(12, 6) + SourceIndex(0) name (A.B) +--- +>>> return A; +1->^^^^ +2 > ^^^^^^^^ +1-> + > +2 > } +1->Emitted(7, 5) Source(13, 1) + SourceIndex(0) name (A) +2 >Emitted(7, 13) Source(13, 2) + SourceIndex(0) name (A) +--- +>>>})(); +1 > +2 >^ +3 > +4 > ^^^^ +5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > +2 >} +3 > +4 > class A + > { + > constructor () + > { + > + > } + > + > public B() + > { + > return 42; + > } + > } +1 >Emitted(8, 1) Source(13, 1) + SourceIndex(0) name (A) +2 >Emitted(8, 2) Source(13, 2) + SourceIndex(0) name (A) +3 >Emitted(8, 2) Source(2, 1) + SourceIndex(0) +4 >Emitted(8, 6) Source(13, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=es6-declaration-amd.js.map \ No newline at end of file diff --git a/tests/baselines/reference/es6-declaration-amd.types b/tests/baselines/reference/es6-declaration-amd.types new file mode 100644 index 0000000000000..e275fc5243961 --- /dev/null +++ b/tests/baselines/reference/es6-declaration-amd.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/es6-declaration-amd.ts === + +class A +>A : A +{ + constructor () + { + + } + + public B() +>B : () => number + { + return 42; + } +} diff --git a/tests/baselines/reference/es6-sourcemap-amd.js b/tests/baselines/reference/es6-sourcemap-amd.js new file mode 100644 index 0000000000000..805e56cf830d0 --- /dev/null +++ b/tests/baselines/reference/es6-sourcemap-amd.js @@ -0,0 +1,25 @@ +//// [es6-sourcemap-amd.ts] + +class A +{ + constructor () + { + + } + + public B() + { + return 42; + } +} + +//// [es6-sourcemap-amd.js] +var A = (function () { + function A() { + } + A.prototype.B = function () { + return 42; + }; + return A; +})(); +//# sourceMappingURL=es6-sourcemap-amd.js.map \ No newline at end of file diff --git a/tests/baselines/reference/es6-sourcemap-amd.js.map b/tests/baselines/reference/es6-sourcemap-amd.js.map new file mode 100644 index 0000000000000..689f0447fa8db --- /dev/null +++ b/tests/baselines/reference/es6-sourcemap-amd.js.map @@ -0,0 +1,2 @@ +//// [es6-sourcemap-amd.js.map] +{"version":3,"file":"es6-sourcemap-amd.js","sourceRoot":"","sources":["es6-sourcemap-amd.ts"],"names":["A","A.constructor","A.B"],"mappings":"AACA,IAAM,CAAC;IAEHA,SAFEA,CAACA;IAKHC,CAACA;IAEMD,aAACA,GAARA;QAEIE,MAAMA,CAACA,EAAEA,CAACA;IACdA,CAACA;IACLF,QAACA;AAADA,CAACA,AAXD,IAWC"} \ No newline at end of file diff --git a/tests/baselines/reference/es6-sourcemap-amd.sourcemap.txt b/tests/baselines/reference/es6-sourcemap-amd.sourcemap.txt new file mode 100644 index 0000000000000..09abb195987c1 --- /dev/null +++ b/tests/baselines/reference/es6-sourcemap-amd.sourcemap.txt @@ -0,0 +1,128 @@ +=================================================================== +JsFile: es6-sourcemap-amd.js +mapUrl: es6-sourcemap-amd.js.map +sourceRoot: +sources: es6-sourcemap-amd.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:tests/cases/compiler/es6-sourcemap-amd.js +sourceFile:es6-sourcemap-amd.ts +------------------------------------------------------------------- +>>>var A = (function () { +1 > +2 >^^^^ +3 > ^ +4 > ^^^^^^^^^^^^^^-> +1 > + > +2 >class +3 > A +1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0) +2 >Emitted(1, 5) Source(2, 7) + SourceIndex(0) +3 >Emitted(1, 6) Source(2, 8) + SourceIndex(0) +--- +>>> function A() { +1->^^^^ +2 > ^^^^^^^^^ +3 > ^ +1-> + >{ + > +2 > +3 > A +1->Emitted(2, 5) Source(4, 5) + SourceIndex(0) name (A) +2 >Emitted(2, 14) Source(2, 7) + SourceIndex(0) name (A) +3 >Emitted(2, 15) Source(2, 8) + SourceIndex(0) name (A) +--- +>>> } +1 >^^^^ +2 > ^ +3 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > + >{ + > constructor () + > { + > + > +2 > } +1 >Emitted(3, 5) Source(7, 5) + SourceIndex(0) name (A.constructor) +2 >Emitted(3, 6) Source(7, 6) + SourceIndex(0) name (A.constructor) +--- +>>> A.prototype.B = function () { +1->^^^^ +2 > ^^^^^^^^^^^^^ +3 > ^^^ +1-> + > + > public +2 > B +3 > +1->Emitted(4, 5) Source(9, 12) + SourceIndex(0) name (A) +2 >Emitted(4, 18) Source(9, 13) + SourceIndex(0) name (A) +3 >Emitted(4, 21) Source(9, 5) + SourceIndex(0) name (A) +--- +>>> return 42; +1 >^^^^^^^^ +2 > ^^^^^^ +3 > ^ +4 > ^^ +5 > ^ +1 >public B() + > { + > +2 > return +3 > +4 > 42 +5 > ; +1 >Emitted(5, 9) Source(11, 9) + SourceIndex(0) name (A.B) +2 >Emitted(5, 15) Source(11, 15) + SourceIndex(0) name (A.B) +3 >Emitted(5, 16) Source(11, 16) + SourceIndex(0) name (A.B) +4 >Emitted(5, 18) Source(11, 18) + SourceIndex(0) name (A.B) +5 >Emitted(5, 19) Source(11, 19) + SourceIndex(0) name (A.B) +--- +>>> }; +1 >^^^^ +2 > ^ +3 > ^^^^^^^^^-> +1 > + > +2 > } +1 >Emitted(6, 5) Source(12, 5) + SourceIndex(0) name (A.B) +2 >Emitted(6, 6) Source(12, 6) + SourceIndex(0) name (A.B) +--- +>>> return A; +1->^^^^ +2 > ^^^^^^^^ +1-> + > +2 > } +1->Emitted(7, 5) Source(13, 1) + SourceIndex(0) name (A) +2 >Emitted(7, 13) Source(13, 2) + SourceIndex(0) name (A) +--- +>>>})(); +1 > +2 >^ +3 > +4 > ^^^^ +5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > +2 >} +3 > +4 > class A + > { + > constructor () + > { + > + > } + > + > public B() + > { + > return 42; + > } + > } +1 >Emitted(8, 1) Source(13, 1) + SourceIndex(0) name (A) +2 >Emitted(8, 2) Source(13, 2) + SourceIndex(0) name (A) +3 >Emitted(8, 2) Source(2, 1) + SourceIndex(0) +4 >Emitted(8, 6) Source(13, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=es6-sourcemap-amd.js.map \ No newline at end of file diff --git a/tests/baselines/reference/es6-sourcemap-amd.types b/tests/baselines/reference/es6-sourcemap-amd.types new file mode 100644 index 0000000000000..661ab2e7cddfc --- /dev/null +++ b/tests/baselines/reference/es6-sourcemap-amd.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/es6-sourcemap-amd.ts === + +class A +>A : A +{ + constructor () + { + + } + + public B() +>B : () => number + { + return 42; + } +} diff --git a/tests/cases/compiler/es6-amd.ts b/tests/cases/compiler/es6-amd.ts new file mode 100644 index 0000000000000..a5fb99a86051d --- /dev/null +++ b/tests/cases/compiler/es6-amd.ts @@ -0,0 +1,17 @@ +// @target: ES6 +// @sourcemap: false +// @declaration: false +// @module: amd + +class A +{ + constructor () + { + + } + + public B() + { + return 42; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/es6-declaration-amd.ts b/tests/cases/compiler/es6-declaration-amd.ts new file mode 100644 index 0000000000000..1dcfeca84979e --- /dev/null +++ b/tests/cases/compiler/es6-declaration-amd.ts @@ -0,0 +1,17 @@ +// @target: ES6 +// @sourcemap: false +// @declaration: true +// @module: amd + +class A +{ + constructor () + { + + } + + public B() + { + return 42; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/es6-sourcemap-amd.ts b/tests/cases/compiler/es6-sourcemap-amd.ts new file mode 100644 index 0000000000000..c00a697de940b --- /dev/null +++ b/tests/cases/compiler/es6-sourcemap-amd.ts @@ -0,0 +1,16 @@ +// @target: ES6 +// @sourcemap: true +// @module: amd + +class A +{ + constructor () + { + + } + + public B() + { + return 42; + } +} \ No newline at end of file From 778f101dea279a97349261a802158bd1055b77f9 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Sun, 12 Oct 2014 21:10:04 -0700 Subject: [PATCH 02/25] Add basic parsing support for let and const --- .../diagnosticInformationMap.generated.ts | 4 ++ src/compiler/diagnosticMessages.json | 16 +++++ src/compiler/emitter.ts | 46 ++++++++++++-- src/compiler/parser.ts | 41 +++++++++++- src/compiler/types.ts | 2 + ...onstDeclarations-ambient-errors.errors.txt | 34 ++++++++++ .../reference/constDeclarations-ambient.js | 13 ++++ .../reference/constDeclarations-ambient.types | 23 +++++++ .../constDeclarations-errors.errors.txt | 62 +++++++++++++++++++ .../constDeclarations-es5.errors.txt | 17 +++++ .../baselines/reference/constDeclarations.js | 19 ++++++ .../reference/constDeclarations.types | 14 +++++ .../baselines/reference/constDeclarations2.js | 26 ++++++++ .../reference/constDeclarations2.types | 18 ++++++ .../reference/letDeclarations-es5.errors.txt | 40 ++++++++++++ tests/baselines/reference/letDeclarations.js | 35 +++++++++++ .../baselines/reference/letDeclarations.types | 36 +++++++++++ tests/baselines/reference/letDeclarations2.js | 19 ++++++ .../reference/letDeclarations2.types | 11 ++++ .../constDeclarations-ambient-errors.ts | 11 ++++ .../compiler/constDeclarations-ambient.ts | 11 ++++ .../compiler/constDeclarations-errors.ts | 11 ++++ tests/cases/compiler/constDeclarations-es5.ts | 5 ++ tests/cases/compiler/constDeclarations.ts | 7 +++ tests/cases/compiler/constDeclarations2.ts | 9 +++ tests/cases/compiler/letDeclarations-es5.ts | 13 ++++ tests/cases/compiler/letDeclarations.ts | 14 +++++ tests/cases/compiler/letDeclarations2.ts | 7 +++ 28 files changed, 557 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-ambient-errors.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-ambient.js create mode 100644 tests/baselines/reference/constDeclarations-ambient.types create mode 100644 tests/baselines/reference/constDeclarations-errors.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-es5.errors.txt create mode 100644 tests/baselines/reference/constDeclarations.js create mode 100644 tests/baselines/reference/constDeclarations.types create mode 100644 tests/baselines/reference/constDeclarations2.js create mode 100644 tests/baselines/reference/constDeclarations2.types create mode 100644 tests/baselines/reference/letDeclarations-es5.errors.txt create mode 100644 tests/baselines/reference/letDeclarations.js create mode 100644 tests/baselines/reference/letDeclarations.types create mode 100644 tests/baselines/reference/letDeclarations2.js create mode 100644 tests/baselines/reference/letDeclarations2.types create mode 100644 tests/cases/compiler/constDeclarations-ambient-errors.ts create mode 100644 tests/cases/compiler/constDeclarations-ambient.ts create mode 100644 tests/cases/compiler/constDeclarations-errors.ts create mode 100644 tests/cases/compiler/constDeclarations-es5.ts create mode 100644 tests/cases/compiler/constDeclarations.ts create mode 100644 tests/cases/compiler/constDeclarations2.ts create mode 100644 tests/cases/compiler/letDeclarations-es5.ts create mode 100644 tests/cases/compiler/letDeclarations.ts create mode 100644 tests/cases/compiler/letDeclarations2.ts diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 627fb202c18aa..fe0071c130232 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -115,6 +115,10 @@ module ts { Filename_0_differs_from_already_included_filename_1_only_in_casing: { code: 1149, category: DiagnosticCategory.Error, key: "Filename '{0}' differs from already included filename '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, An_enum_member_cannot_have_a_numeric_name: { code: 1151, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." }, + var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." }, + let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' variable declarations are only available when targeting ECMAScript 6 and higher." }, + const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' variable declarations are only available when targeting ECMAScript 6 and higher." }, + Const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "Const must be intialized." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 26a8c51cccc0b..39c38b06938aa 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -451,6 +451,22 @@ "category": "Error", "code": 1151 }, + "'var', 'let' or 'const' expected.": { + "category": "Error", + "code": 1152 + }, + "'let' variable declarations are only available when targeting ECMAScript 6 and higher.": { + "category": "Error", + "code": 1153 + }, + "'const' variable declarations are only available when targeting ECMAScript 6 and higher.": { + "category": "Error", + "code": 1154 + }, + "Const must be intialized.": { + "category": "Error", + "code": 1155 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c038cf3986895..81022d04e3170 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1149,7 +1149,12 @@ module ts { write(" "); endPos = emitToken(SyntaxKind.OpenParenToken, endPos); if (node.declarations) { - emitToken(SyntaxKind.VarKeyword, endPos); + if (node.declarations[0] && node.declarations[0].flags & NodeFlags.Let) { + emitToken(SyntaxKind.LetKeyword, endPos); + } + else { + emitToken(SyntaxKind.VarKeyword, endPos); + } write(" "); emitCommaList(node.declarations, /*includeTrailingComma*/ false); } @@ -1169,7 +1174,12 @@ module ts { write(" "); endPos = emitToken(SyntaxKind.OpenParenToken, endPos); if (node.declaration) { - emitToken(SyntaxKind.VarKeyword, endPos); + if (node.declaration.flags & NodeFlags.Let) { + emitToken(SyntaxKind.LetKeyword, endPos); + } + else { + emitToken(SyntaxKind.VarKeyword, endPos); + } write(" "); emit(node.declaration); } @@ -1298,7 +1308,17 @@ module ts { function emitVariableStatement(node: VariableStatement) { emitLeadingComments(node); - if (!(node.flags & NodeFlags.Export)) write("var "); + if (!(node.flags & NodeFlags.Export)) { + if (node.flags & NodeFlags.Let) { + write("let "); + } + else if (node.flags & NodeFlags.Const) { + write("const "); + } + else { + write("var "); + } + } emitCommaList(node.declarations, /*includeTrailingComma*/ false); write(";"); emitTrailingComments(node); @@ -1774,7 +1794,15 @@ module ts { if (node.flags & NodeFlags.Export) { writeLine(); emitStart(node); - write("var "); + if (node.flags & NodeFlags.Let) { + write("let "); + } + else if (node.flags & NodeFlags.Const) { + write("const "); + } + else { + write("var "); + } emit(node.name); write(" = "); emitModuleMemberName(node); @@ -2822,7 +2850,15 @@ module ts { if (hasDeclarationWithEmit) { emitJsDocComments(node); emitDeclarationFlags(node); - write("var "); + if (node.flags & NodeFlags.Let) { + write("let "); + } + else if (node.flags & NodeFlags.Const) { + write("const "); + } + else { + write("var "); + } emitCommaList(node.declarations, emitVariableDeclaration); write(";"); writeLine(); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8a78500db8d49..c39780087f2f4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2645,6 +2645,15 @@ module ts { error(Diagnostics.Variable_declaration_list_cannot_be_empty); } } + else if (parseOptional(SyntaxKind.LetKeyword)) { + var declarations = parseVariableDeclarationList(NodeFlags.Let, true); + if (!declarations.length) { + error(Diagnostics.Variable_declaration_list_cannot_be_empty); + } + if (languageVersion < ScriptTarget.ES6) { + grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + } + } else { var varOrInit = parseExpression(true); } @@ -2970,6 +2979,8 @@ module ts { return !inErrorRecovery; case SyntaxKind.OpenBraceToken: case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: case SyntaxKind.FunctionKeyword: case SyntaxKind.IfKeyword: case SyntaxKind.DoKeyword: @@ -3016,6 +3027,8 @@ module ts { case SyntaxKind.OpenBraceToken: return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: return parseVariableStatement(); case SyntaxKind.FunctionKeyword: return parseFunctionDeclaration(); @@ -3095,6 +3108,9 @@ module ts { if (inAmbientContext && node.initializer && errorCountBeforeVariableDeclaration === file.syntacticErrors.length) { grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } + if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { + grammarErrorOnNode(node, Diagnostics.Const_must_be_intialized); + } if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) { // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code // and its Identifier is eval or arguments @@ -3112,13 +3128,30 @@ module ts { var node = createNode(SyntaxKind.VariableStatement, pos); if (flags) node.flags = flags; var errorCountBeforeVarStatement = file.syntacticErrors.length; - parseExpected(SyntaxKind.VarKeyword); - node.declarations = parseVariableDeclarationList(flags, /*noIn*/false); + if (token === SyntaxKind.LetKeyword) { + node.flags |= NodeFlags.Let; + } + else if (token === SyntaxKind.ConstKeyword) { + node.flags |= NodeFlags.Const; + } + else if (token !== SyntaxKind.VarKeyword) { + error(Diagnostics.var_let_or_const_expected); + } + nextToken(); + node.declarations = parseVariableDeclarationList(node.flags, /*noIn*/false); parseSemicolon(); finishNode(node); if (!node.declarations.length && file.syntacticErrors.length === errorCountBeforeVarStatement) { grammarErrorOnNode(node, Diagnostics.Variable_declaration_list_cannot_be_empty); } + if (languageVersion < ScriptTarget.ES6) { + if (node.flags & NodeFlags.Let) { + grammarErrorOnNode(node, Diagnostics.let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + } + else if (node.flags & NodeFlags.Const) { + grammarErrorOnNode(node, Diagnostics.const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + } + } return node; } @@ -3697,6 +3730,8 @@ module ts { function isDeclaration(): boolean { switch (token) { case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: case SyntaxKind.FunctionKeyword: return true; case SyntaxKind.ClassKeyword: @@ -3747,6 +3782,8 @@ module ts { var result: Declaration; switch (token) { case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: result = parseVariableStatement(pos, flags); break; case SyntaxKind.FunctionKeyword: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 38b69e23dee10..4218d4f401121 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -245,6 +245,8 @@ module ts { MultiLine = 0x00000100, // Multi-line array or object literal Synthetic = 0x00000200, // Synthetic node (for full fidelity) DeclarationFile = 0x00000400, // Node is a .d.ts file + Let = 0x00000800, + Const = 0x00001000, Modifier = Export | Ambient | Public | Private | Protected | Static, AccessibilityModifier = Public | Private | Protected diff --git a/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt b/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt new file mode 100644 index 0000000000000..6e2d00dc4c42c --- /dev/null +++ b/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt @@ -0,0 +1,34 @@ +tests/cases/compiler/constDeclarations-ambient-errors.ts(3,27): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(4,26): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(5,18): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(5,37): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(5,51): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(8,14): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(9,22): error TS1039: Initializers are not allowed in ambient contexts. + + +==== tests/cases/compiler/constDeclarations-ambient-errors.ts (7 errors) ==== + + // error: no intialization expected in ambient declarations + declare const c1: boolean = true; + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + declare const c2: number = 0; + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + declare const c3 = null, c4 :string = "", c5: any = 0; + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + + declare module M { + const c6 = 0; + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + const c7: number = 7; + ~ +!!! error TS1039: Initializers are not allowed in ambient contexts. + } \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-ambient.js b/tests/baselines/reference/constDeclarations-ambient.js new file mode 100644 index 0000000000000..dd78f73051aa4 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-ambient.js @@ -0,0 +1,13 @@ +//// [constDeclarations-ambient.ts] + +// No error +declare const c1: boolean; +declare const c2: number; +declare const c3, c4 :string, c5: any; + +declare module M { + const c6; + const c7: number; +} + +//// [constDeclarations-ambient.js] diff --git a/tests/baselines/reference/constDeclarations-ambient.types b/tests/baselines/reference/constDeclarations-ambient.types new file mode 100644 index 0000000000000..0ab2d4b700a69 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-ambient.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/constDeclarations-ambient.ts === + +// No error +declare const c1: boolean; +>c1 : boolean + +declare const c2: number; +>c2 : number + +declare const c3, c4 :string, c5: any; +>c3 : any +>c4 : string +>c5 : any + +declare module M { +>M : typeof M + + const c6; +>c6 : any + + const c7: number; +>c7 : number +} diff --git a/tests/baselines/reference/constDeclarations-errors.errors.txt b/tests/baselines/reference/constDeclarations-errors.errors.txt new file mode 100644 index 0000000000000..79d56ade878a4 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-errors.errors.txt @@ -0,0 +1,62 @@ +tests/cases/compiler/constDeclarations-errors.ts(3,7): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(4,7): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(5,7): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(5,11): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(5,15): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(5,27): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(8,5): error TS1109: Expression expected. +tests/cases/compiler/constDeclarations-errors.ts(8,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-errors.ts(8,11): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(8,13): error TS1005: ';' expected. +tests/cases/compiler/constDeclarations-errors.ts(8,13): error TS1128: Declaration or statement expected. +tests/cases/compiler/constDeclarations-errors.ts(8,18): error TS1128: Declaration or statement expected. +tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1109: Expression expected. +tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-errors.ts(10,28): error TS1005: ';' expected. +tests/cases/compiler/constDeclarations-errors.ts(10,11): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. + + +==== tests/cases/compiler/constDeclarations-errors.ts (16 errors) ==== + + // error, missing intialicer + const c1; + ~~ +!!! error TS1155: const must be intialized. + const c2: number; + ~~ +!!! error TS1155: const must be intialized. + const c3, c4, c5 :string, c6; // error, missing initialicer + ~~ +!!! error TS1155: const must be intialized. + ~~ +!!! error TS1155: const must be intialized. + ~~ +!!! error TS1155: const must be intialized. + ~~ +!!! error TS1155: const must be intialized. + + // error, wrong context + for(const c in {}) { } + ~~~~~ +!!! error TS1109: Expression expected. + ~~~~~~~ +!!! error TS1156: const must be declared inside a block. + ~ +!!! error TS1155: const must be intialized. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS1128: Declaration or statement expected. + ~ +!!! error TS1128: Declaration or statement expected. + + for(const c = 0; c < 9; c++) { } + ~~~~~ +!!! error TS1109: Expression expected. + ~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + ~ +!!! error TS1005: ';' expected. + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-es5.errors.txt b/tests/baselines/reference/constDeclarations-es5.errors.txt new file mode 100644 index 0000000000000..a941b826ed084 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-es5.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/constDeclarations-es5.ts(2,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/constDeclarations-es5.ts(3,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/constDeclarations-es5.ts(4,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. + + +==== tests/cases/compiler/constDeclarations-es5.ts (3 errors) ==== + + const z7 = false; + ~~~~~~~~~~~~~~~~~ +!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. + const z8: number = 23; + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. + const z9 = 0, z10 :string = "", z11 = null; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations.js b/tests/baselines/reference/constDeclarations.js new file mode 100644 index 0000000000000..23d87d2c2a788 --- /dev/null +++ b/tests/baselines/reference/constDeclarations.js @@ -0,0 +1,19 @@ +//// [constDeclarations.ts] + +// No error +const c1 = false; +const c2: number = 23; +const c3 = 0, c4 :string = "", c5 = null; + + +//// [constDeclarations.js] +// No error +const c1 = false; +const c2 = 23; +const c3 = 0, c4 = "", c5 = null; + + +//// [constDeclarations.d.ts] +declare const c1: boolean; +declare const c2: number; +declare const c3: number, c4: string, c5: any; diff --git a/tests/baselines/reference/constDeclarations.types b/tests/baselines/reference/constDeclarations.types new file mode 100644 index 0000000000000..7faa37f85bcfe --- /dev/null +++ b/tests/baselines/reference/constDeclarations.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/constDeclarations.ts === + +// No error +const c1 = false; +>c1 : boolean + +const c2: number = 23; +>c2 : number + +const c3 = 0, c4 :string = "", c5 = null; +>c3 : number +>c4 : string +>c5 : any + diff --git a/tests/baselines/reference/constDeclarations2.js b/tests/baselines/reference/constDeclarations2.js new file mode 100644 index 0000000000000..e4ee67ebdcdd0 --- /dev/null +++ b/tests/baselines/reference/constDeclarations2.js @@ -0,0 +1,26 @@ +//// [constDeclarations2.ts] + +// No error +module M { + export const c1 = false; + export const c2: number = 23; + export const c3 = 0, c4 :string = "", c5 = null; +} + + +//// [constDeclarations2.js] +// No error +var M; +(function (M) { + M.c1 = false; + M.c2 = 23; + M.c3 = 0, M.c4 = "", M.c5 = null; +})(M || (M = {})); + + +//// [constDeclarations2.d.ts] +declare module M { + const c1: boolean; + const c2: number; + const c3: number, c4: string, c5: any; +} diff --git a/tests/baselines/reference/constDeclarations2.types b/tests/baselines/reference/constDeclarations2.types new file mode 100644 index 0000000000000..c81eca96b0dd0 --- /dev/null +++ b/tests/baselines/reference/constDeclarations2.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/constDeclarations2.ts === + +// No error +module M { +>M : typeof M + + export const c1 = false; +>c1 : boolean + + export const c2: number = 23; +>c2 : number + + export const c3 = 0, c4 :string = "", c5 = null; +>c3 : number +>c4 : string +>c5 : any +} + diff --git a/tests/baselines/reference/letDeclarations-es5.errors.txt b/tests/baselines/reference/letDeclarations-es5.errors.txt new file mode 100644 index 0000000000000..2a5858350cdba --- /dev/null +++ b/tests/baselines/reference/letDeclarations-es5.errors.txt @@ -0,0 +1,40 @@ +tests/cases/compiler/letDeclarations-es5.ts(2,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(3,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(4,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(6,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(7,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(8,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(10,8): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(12,8): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + + +==== tests/cases/compiler/letDeclarations-es5.ts (8 errors) ==== + + let l1; + ~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + let l2: number; + ~~~~~~~~~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + let l3, l4, l5 :string, l6; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + + let l7 = false; + ~~~~~~~~~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + let l8: number = 23; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + let l9 = 0, l10 :string = "", l11 = null; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + + for(let l11 in {}) { } + ~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + + for(let l12 = 0; l12 < 9; l12++) { } + ~~~~~~~~ +!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. + \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations.js b/tests/baselines/reference/letDeclarations.js new file mode 100644 index 0000000000000..bc186b732f559 --- /dev/null +++ b/tests/baselines/reference/letDeclarations.js @@ -0,0 +1,35 @@ +//// [letDeclarations.ts] + +let l1; +let l2: number; +let l3, l4, l5 :string, l6; + +let l7 = false; +let l8: number = 23; +let l9 = 0, l10 :string = "", l11 = null; + +for(let l11 in {}) { } + +for(let l12 = 0; l12 < 9; l12++) { } + + +//// [letDeclarations.js] +let l1; +let l2; +let l3, l4, l5, l6; +let l7 = false; +let l8 = 23; +let l9 = 0, l10 = "", l11 = null; +for (let l11 in {}) { +} +for (let l12 = 0; l12 < 9; l12++) { +} + + +//// [letDeclarations.d.ts] +declare let l1: any; +declare let l2: number; +declare let l3: any, l4: any, l5: string, l6: any; +declare let l7: boolean; +declare let l8: number; +declare let l9: number, l10: string, l11: any; diff --git a/tests/baselines/reference/letDeclarations.types b/tests/baselines/reference/letDeclarations.types new file mode 100644 index 0000000000000..aa47a7f000645 --- /dev/null +++ b/tests/baselines/reference/letDeclarations.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/letDeclarations.ts === + +let l1; +>l1 : any + +let l2: number; +>l2 : number + +let l3, l4, l5 :string, l6; +>l3 : any +>l4 : any +>l5 : string +>l6 : any + +let l7 = false; +>l7 : boolean + +let l8: number = 23; +>l8 : number + +let l9 = 0, l10 :string = "", l11 = null; +>l9 : number +>l10 : string +>l11 : any + +for(let l11 in {}) { } +>l11 : any +>{} : {} + +for(let l12 = 0; l12 < 9; l12++) { } +>l12 : number +>l12 < 9 : boolean +>l12 : number +>l12++ : number +>l12 : number + diff --git a/tests/baselines/reference/letDeclarations2.js b/tests/baselines/reference/letDeclarations2.js new file mode 100644 index 0000000000000..8a6f039f2ca93 --- /dev/null +++ b/tests/baselines/reference/letDeclarations2.js @@ -0,0 +1,19 @@ +//// [letDeclarations2.ts] + +module M { + let l1 = "s"; + export let l2 = 0; +} + +//// [letDeclarations2.js] +var M; +(function (M) { + let l1 = "s"; + M.l2 = 0; +})(M || (M = {})); + + +//// [letDeclarations2.d.ts] +declare module M { + let l2: number; +} diff --git a/tests/baselines/reference/letDeclarations2.types b/tests/baselines/reference/letDeclarations2.types new file mode 100644 index 0000000000000..2fa08b6d9400b --- /dev/null +++ b/tests/baselines/reference/letDeclarations2.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/letDeclarations2.ts === + +module M { +>M : typeof M + + let l1 = "s"; +>l1 : string + + export let l2 = 0; +>l2 : number +} diff --git a/tests/cases/compiler/constDeclarations-ambient-errors.ts b/tests/cases/compiler/constDeclarations-ambient-errors.ts new file mode 100644 index 0000000000000..c07bfb01810a5 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-ambient-errors.ts @@ -0,0 +1,11 @@ +// @target: ES6 + +// error: no intialization expected in ambient declarations +declare const c1: boolean = true; +declare const c2: number = 0; +declare const c3 = null, c4 :string = "", c5: any = 0; + +declare module M { + const c6 = 0; + const c7: number = 7; +} \ No newline at end of file diff --git a/tests/cases/compiler/constDeclarations-ambient.ts b/tests/cases/compiler/constDeclarations-ambient.ts new file mode 100644 index 0000000000000..dcd4cb9fc726d --- /dev/null +++ b/tests/cases/compiler/constDeclarations-ambient.ts @@ -0,0 +1,11 @@ +// @target: ES6 + +// No error +declare const c1: boolean; +declare const c2: number; +declare const c3, c4 :string, c5: any; + +declare module M { + const c6; + const c7: number; +} \ No newline at end of file diff --git a/tests/cases/compiler/constDeclarations-errors.ts b/tests/cases/compiler/constDeclarations-errors.ts new file mode 100644 index 0000000000000..08ccaf7fe18c4 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-errors.ts @@ -0,0 +1,11 @@ +// @target: ES6 + +// error, missing intialicer +const c1; +const c2: number; +const c3, c4, c5 :string, c6; // error, missing initialicer + +// error, wrong context +for(const c in {}) { } + +for(const c = 0; c < 9; c++) { } diff --git a/tests/cases/compiler/constDeclarations-es5.ts b/tests/cases/compiler/constDeclarations-es5.ts new file mode 100644 index 0000000000000..0da824a7396d8 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-es5.ts @@ -0,0 +1,5 @@ +// @target: ES5 + +const z7 = false; +const z8: number = 23; +const z9 = 0, z10 :string = "", z11 = null; diff --git a/tests/cases/compiler/constDeclarations.ts b/tests/cases/compiler/constDeclarations.ts new file mode 100644 index 0000000000000..36e01551a66c0 --- /dev/null +++ b/tests/cases/compiler/constDeclarations.ts @@ -0,0 +1,7 @@ +// @target: ES6 +// @declaration: true + +// No error +const c1 = false; +const c2: number = 23; +const c3 = 0, c4 :string = "", c5 = null; diff --git a/tests/cases/compiler/constDeclarations2.ts b/tests/cases/compiler/constDeclarations2.ts new file mode 100644 index 0000000000000..a221c3563bae0 --- /dev/null +++ b/tests/cases/compiler/constDeclarations2.ts @@ -0,0 +1,9 @@ +// @target: ES6 +// @declaration: true + +// No error +module M { + export const c1 = false; + export const c2: number = 23; + export const c3 = 0, c4 :string = "", c5 = null; +} diff --git a/tests/cases/compiler/letDeclarations-es5.ts b/tests/cases/compiler/letDeclarations-es5.ts new file mode 100644 index 0000000000000..b115c260a915c --- /dev/null +++ b/tests/cases/compiler/letDeclarations-es5.ts @@ -0,0 +1,13 @@ +// @target: ES5 + +let l1; +let l2: number; +let l3, l4, l5 :string, l6; + +let l7 = false; +let l8: number = 23; +let l9 = 0, l10 :string = "", l11 = null; + +for(let l11 in {}) { } + +for(let l12 = 0; l12 < 9; l12++) { } diff --git a/tests/cases/compiler/letDeclarations.ts b/tests/cases/compiler/letDeclarations.ts new file mode 100644 index 0000000000000..e90e355ba68ac --- /dev/null +++ b/tests/cases/compiler/letDeclarations.ts @@ -0,0 +1,14 @@ +// @target: ES6 +// @declaration: true + +let l1; +let l2: number; +let l3, l4, l5 :string, l6; + +let l7 = false; +let l8: number = 23; +let l9 = 0, l10 :string = "", l11 = null; + +for(let l11 in {}) { } + +for(let l12 = 0; l12 < 9; l12++) { } diff --git a/tests/cases/compiler/letDeclarations2.ts b/tests/cases/compiler/letDeclarations2.ts new file mode 100644 index 0000000000000..e7e09f0849a3a --- /dev/null +++ b/tests/cases/compiler/letDeclarations2.ts @@ -0,0 +1,7 @@ +// @target: ES6 +// @declaration: true + +module M { + let l1 = "s"; + export let l2 = 0; +} \ No newline at end of file From 979d45eb670ebc1e68f4029e1d055c28c73430f6 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Sun, 12 Oct 2014 21:43:09 -0700 Subject: [PATCH 03/25] Disallow let and const declarations outside blocks --- .../diagnosticInformationMap.generated.ts | 4 +- src/compiler/diagnosticMessages.json | 10 +- src/compiler/parser.ts | 55 +++-- ...nstDeclarations-invalidContexts.errors.txt | 66 +++++ ...constDeclarations-validContexts.errors.txt | 129 ++++++++++ .../constDeclarations-validContexts.js | 229 ++++++++++++++++++ ...letDeclarations-invalidContexts.errors.txt | 66 +++++ .../letDeclarations-validContexts.errors.txt | 129 ++++++++++ .../letDeclarations-validContexts.js | 229 ++++++++++++++++++ .../constDeclarations-invalidContexts.ts | 33 +++ .../constDeclarations-validContexts.ts | 124 ++++++++++ .../letDeclarations-invalidContexts.ts | 33 +++ .../compiler/letDeclarations-validContexts.ts | 124 ++++++++++ 13 files changed, 1205 insertions(+), 26 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-invalidContexts.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-validContexts.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-validContexts.js create mode 100644 tests/baselines/reference/letDeclarations-invalidContexts.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-validContexts.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-validContexts.js create mode 100644 tests/cases/compiler/constDeclarations-invalidContexts.ts create mode 100644 tests/cases/compiler/constDeclarations-validContexts.ts create mode 100644 tests/cases/compiler/letDeclarations-invalidContexts.ts create mode 100644 tests/cases/compiler/letDeclarations-validContexts.ts diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index fe0071c130232..84e10cfec581d 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -118,7 +118,9 @@ module ts { var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." }, let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' variable declarations are only available when targeting ECMAScript 6 and higher." }, const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' variable declarations are only available when targeting ECMAScript 6 and higher." }, - Const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "Const must be intialized." }, + const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "const must be intialized." }, + const_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "const must be declared inside a block." }, + let_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "let must be declared inside a block." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 39c38b06938aa..fa433e0e772ca 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -463,10 +463,18 @@ "category": "Error", "code": 1154 }, - "Const must be intialized.": { + "const must be intialized.": { "category": "Error", "code": 1155 }, + "const must be declared inside a block.": { + "category": "Error", + "code": 1156 + }, + "let must be declared inside a block.": { + "category": "Error", + "code": 1157 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c39780087f2f4..d8d1d24a97eff 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2542,11 +2542,14 @@ module ts { } // STATEMENTS + function parseStatementAllowingLetDeclaration() { + return parseStatement(/*allowLetDeclarations*/ true); + } function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block { var node = createNode(SyntaxKind.Block); if (parseExpected(SyntaxKind.OpenBraceToken) || ignoreMissingOpenBrace) { - node.statements = parseList(ParsingContext.BlockStatements,checkForStrictMode, parseStatement); + node.statements = parseList(ParsingContext.BlockStatements, checkForStrictMode, parseStatementAllowingLetDeclaration); parseExpected(SyntaxKind.CloseBraceToken); } else { @@ -2592,8 +2595,8 @@ module ts { parseExpected(SyntaxKind.OpenParenToken); node.expression = parseExpression(); parseExpected(SyntaxKind.CloseParenToken); - node.thenStatement = parseStatement(); - node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; + node.thenStatement = parseStatement(/*allowLetDeclarations*/ false); + node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement(/*allowLetDeclarations*/ false) : undefined; return finishNode(node); } @@ -2603,7 +2606,7 @@ module ts { var saveInIterationStatement = inIterationStatement; inIterationStatement = ControlBlockContext.Nested; - node.statement = parseStatement(); + node.statement = parseStatement(/*allowLetDeclarations*/ false); inIterationStatement = saveInIterationStatement; parseExpected(SyntaxKind.WhileKeyword); @@ -2628,7 +2631,7 @@ module ts { var saveInIterationStatement = inIterationStatement; inIterationStatement = ControlBlockContext.Nested; - node.statement = parseStatement(); + node.statement = parseStatement(/*allowLetDeclarations*/ false); inIterationStatement = saveInIterationStatement; return finishNode(node); @@ -2692,7 +2695,7 @@ module ts { var saveInIterationStatement = inIterationStatement; inIterationStatement = ControlBlockContext.Nested; - forOrForInStatement.statement = parseStatement(); + forOrForInStatement.statement = parseStatement(/*allowLetDeclarations*/ false); inIterationStatement = saveInIterationStatement; return finishNode(forOrForInStatement); @@ -2803,7 +2806,7 @@ module ts { parseExpected(SyntaxKind.OpenParenToken); node.expression = parseExpression(); parseExpected(SyntaxKind.CloseParenToken); - node.statement = parseStatement(); + node.statement = parseStatement(/*allowLetDeclarations*/ false); node = finishNode(node); if (isInStrictMode) { // Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such @@ -2818,7 +2821,7 @@ module ts { parseExpected(SyntaxKind.CaseKeyword); node.expression = parseExpression(); parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); + node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatementAllowingLetDeclaration); return finishNode(node); } @@ -2826,7 +2829,7 @@ module ts { var node = createNode(SyntaxKind.DefaultClause); parseExpected(SyntaxKind.DefaultKeyword); parseExpected(SyntaxKind.ColonToken); - node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); + node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatementAllowingLetDeclaration); return finishNode(node); } @@ -2933,9 +2936,9 @@ module ts { return token === SyntaxKind.WhileKeyword || token === SyntaxKind.DoKeyword || token === SyntaxKind.ForKeyword; } - function parseStatementWithLabelSet(): Statement { + function parseStatementWithLabelSet(allowLetDeclarations: boolean): Statement { labelledStatementInfo.pushCurrentLabelSet(isIterationStatementStart()); - var statement = parseStatement(); + var statement = parseStatement(allowLetDeclarations); labelledStatementInfo.pop(); return statement; } @@ -2944,7 +2947,7 @@ module ts { return isIdentifier() && lookAhead(() => nextToken() === SyntaxKind.ColonToken); } - function parseLabelledStatement(): LabeledStatement { + function parseLabelledStatement(allowLetDeclarations: boolean): LabeledStatement { var node = createNode(SyntaxKind.LabeledStatement); node.label = parseIdentifier(); parseExpected(SyntaxKind.ColonToken); @@ -2956,7 +2959,7 @@ module ts { // We only want to call parseStatementWithLabelSet when the label set is complete // Therefore, keep parsing labels until we know we're done. - node.statement = isLabel() ? parseLabelledStatement() : parseStatementWithLabelSet(); + node.statement = isLabel() ? parseLabelledStatement(allowLetDeclarations) : parseStatementWithLabelSet(allowLetDeclarations); return finishNode(node); } @@ -3022,14 +3025,14 @@ module ts { } } - function parseStatement(): Statement { + function parseStatement(allowLetDeclarations: boolean): Statement { switch (token) { case SyntaxKind.OpenBraceToken: return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: - return parseVariableStatement(); + return parseVariableStatement(allowLetDeclarations); case SyntaxKind.FunctionKeyword: return parseFunctionDeclaration(); case SyntaxKind.SemicolonToken: @@ -3063,16 +3066,12 @@ module ts { return parseDebuggerStatement(); default: if (isLabel()) { - return parseLabelledStatement(); + return parseLabelledStatement(allowLetDeclarations); } return parseExpressionStatement(); } } - function parseStatementOrFunction(): Statement { - return token === SyntaxKind.FunctionKeyword ? parseFunctionDeclaration() : parseStatement(); - } - function parseAndCheckFunctionBody(isConstructor: boolean): Block { var initialPosition = scanner.getTokenPos(); var errorCountBeforeBody = file.syntacticErrors.length; @@ -3109,7 +3108,7 @@ module ts { grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.Const_must_be_intialized); + grammarErrorOnNode(node, Diagnostics.const_must_be_intialized); } if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) { // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code @@ -3124,7 +3123,7 @@ module ts { () => parseVariableDeclaration(flags, noIn), /*allowTrailingComma*/ false); } - function parseVariableStatement(pos?: number, flags?: NodeFlags): VariableStatement { + function parseVariableStatement(allowLetDeclarations: boolean, pos?: number, flags?: NodeFlags): VariableStatement { var node = createNode(SyntaxKind.VariableStatement, pos); if (flags) node.flags = flags; var errorCountBeforeVarStatement = file.syntacticErrors.length; @@ -3152,6 +3151,14 @@ module ts { grammarErrorOnNode(node, Diagnostics.const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); } } + else if (!allowLetDeclarations){ + if (node.flags & NodeFlags.Let) { + grammarErrorOnNode(node, Diagnostics.let_must_be_declared_inside_a_block); + } + else if (node.flags & NodeFlags.Const) { + grammarErrorOnNode(node, Diagnostics.const_must_be_declared_inside_a_block); + } + } return node; } @@ -3784,7 +3791,7 @@ module ts { case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: - result = parseVariableStatement(pos, flags); + result = parseVariableStatement(/*allowLetDeclarations*/ true, pos, flags); break; case SyntaxKind.FunctionKeyword: result = parseFunctionDeclaration(pos, flags); @@ -3832,7 +3839,7 @@ module ts { var statementStart = scanner.getTokenPos(); var statementFirstTokenLength = scanner.getTextPos() - statementStart; var errorCountBeforeStatement = file.syntacticErrors.length; - var statement = parseStatement(); + var statement = parseStatement(/*allowLetDeclarations*/ false); if (inAmbientContext && file.syntacticErrors.length === errorCountBeforeStatement) { grammarErrorAtPos(statementStart, statementFirstTokenLength, Diagnostics.Statements_are_not_allowed_in_ambient_contexts); diff --git a/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt b/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt new file mode 100644 index 0000000000000..b7aef3dabbef6 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt @@ -0,0 +1,66 @@ +tests/cases/compiler/constDeclarations-invalidContexts.ts(4,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(6,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(9,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(12,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(17,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(20,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(23,5): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(26,12): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(29,29): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. + + +==== tests/cases/compiler/constDeclarations-invalidContexts.ts (10 errors) ==== + + // Errors, const must be defined inside a block + if (true) + const c1 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + else + const c2 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + while (true) + const c3 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + do + const c4 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + while (true); + + var obj; + with (obj) + ~~~ +!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. + const c5 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + for (var i = 0; i < 10; i++) + const c6 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + for (var i2 in {}) + const c7 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + if (true) + label: const c8 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + while (false) + label2: label3: label4: const c9 = 0; + ~~~~~~~~~~~~~ +!!! error TS1156: const must be declared inside a block. + + + + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-validContexts.errors.txt b/tests/baselines/reference/constDeclarations-validContexts.errors.txt new file mode 100644 index 0000000000000..7af16a53cbe7e --- /dev/null +++ b/tests/baselines/reference/constDeclarations-validContexts.errors.txt @@ -0,0 +1,129 @@ +tests/cases/compiler/constDeclarations-validContexts.ts(20,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. + + +==== tests/cases/compiler/constDeclarations-validContexts.ts (1 errors) ==== + + + // Control flow statements with blocks + if (true) { + const c1 = 0; + } + else { + const c2 = 0; + } + + while (true) { + const c3 = 0; + } + + do { + const c4 = 0; + } while (true); + + var obj; + with (obj) { + ~~~ +!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. + const c5 = 0; + } + + for (var i = 0; i < 10; i++) { + const c6 = 0; + } + + for (var i2 in {}) { + const c7 = 0; + } + + if (true) { + label: const c8 = 0; + } + + while (false) { + label2: label3: label4: const c9 = 0; + } + + // Try/catch/finally + try { + const c10 = 0; + } + catch (e) { + const c11 = 0; + } + finally { + const c12 = 0; + } + + // Switch + switch (0) { + case 0: + const c13 = 0; + break; + default: + const c14 = 0; + break; + } + + // blocks + { + const c15 = 0; + { + const c16 = 0 + label17: const c17 = 0; + } + } + + // global + const c18 = 0; + + // functions + function F() { + const c19 = 0; + } + + var F2 = () => { + const c20 = 0; + }; + + var F3 = function () { + const c21 = 0; + }; + + // modules + module m { + const c22 = 0; + + { + const c23 = 0; + } + } + + // methods + class C { + constructor() { + const c24 = 0; + } + + method() { + const c25 = 0; + } + + get v() { + const c26 = 0; + return c26; + } + + set v(value) { + const c27 = value; + } + } + + // object literals + var o = { + f() { + const c28 = 0; + }, + f2: () => { + const c29 = 0; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-validContexts.js b/tests/baselines/reference/constDeclarations-validContexts.js new file mode 100644 index 0000000000000..355f39af2f2f9 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-validContexts.js @@ -0,0 +1,229 @@ +//// [constDeclarations-validContexts.ts] + + +// Control flow statements with blocks +if (true) { + const c1 = 0; +} +else { + const c2 = 0; +} + +while (true) { + const c3 = 0; +} + +do { + const c4 = 0; +} while (true); + +var obj; +with (obj) { + const c5 = 0; +} + +for (var i = 0; i < 10; i++) { + const c6 = 0; +} + +for (var i2 in {}) { + const c7 = 0; +} + +if (true) { + label: const c8 = 0; +} + +while (false) { + label2: label3: label4: const c9 = 0; +} + +// Try/catch/finally +try { + const c10 = 0; +} +catch (e) { + const c11 = 0; +} +finally { + const c12 = 0; +} + +// Switch +switch (0) { + case 0: + const c13 = 0; + break; + default: + const c14 = 0; + break; +} + +// blocks +{ + const c15 = 0; + { + const c16 = 0 + label17: const c17 = 0; + } +} + +// global +const c18 = 0; + +// functions +function F() { + const c19 = 0; +} + +var F2 = () => { + const c20 = 0; +}; + +var F3 = function () { + const c21 = 0; +}; + +// modules +module m { + const c22 = 0; + + { + const c23 = 0; + } +} + +// methods +class C { + constructor() { + const c24 = 0; + } + + method() { + const c25 = 0; + } + + get v() { + const c26 = 0; + return c26; + } + + set v(value) { + const c27 = value; + } +} + +// object literals +var o = { + f() { + const c28 = 0; + }, + f2: () => { + const c29 = 0; + } +} + +//// [constDeclarations-validContexts.js] +// Control flow statements with blocks +if (true) { + const c1 = 0; +} +else { + const c2 = 0; +} +while (true) { + const c3 = 0; +} +do { + const c4 = 0; +} while (true); +var obj; +with (obj) { + const c5 = 0; +} +for (var i = 0; i < 10; i++) { + const c6 = 0; +} +for (var i2 in {}) { + const c7 = 0; +} +if (true) { + label: const c8 = 0; +} +while (false) { + label2: label3: label4: const c9 = 0; +} +try { + const c10 = 0; +} +catch (e) { + const c11 = 0; +} +finally { + const c12 = 0; +} +switch (0) { + case 0: + const c13 = 0; + break; + default: + const c14 = 0; + break; +} +{ + const c15 = 0; + { + const c16 = 0; + label17: const c17 = 0; + } +} +// global +const c18 = 0; +// functions +function F() { + const c19 = 0; +} +var F2 = function () { + const c20 = 0; +}; +var F3 = function () { + const c21 = 0; +}; +// modules +var m; +(function (m) { + const c22 = 0; + { + const c23 = 0; + } +})(m || (m = {})); +// methods +var C = (function () { + function C() { + const c24 = 0; + } + C.prototype.method = function () { + const c25 = 0; + }; + Object.defineProperty(C.prototype, "v", { + get: function () { + const c26 = 0; + return c26; + }, + set: function (value) { + const c27 = value; + }, + enumerable: true, + configurable: true + }); + return C; +})(); +// object literals +var o = { + f: function () { + const c28 = 0; + }, + f2: function () { + const c29 = 0; + } +}; diff --git a/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt b/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt new file mode 100644 index 0000000000000..3877f61641aaa --- /dev/null +++ b/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt @@ -0,0 +1,66 @@ +tests/cases/compiler/letDeclarations-invalidContexts.ts(4,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(6,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(9,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(12,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(17,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(20,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(23,5): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(26,12): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(29,29): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. + + +==== tests/cases/compiler/letDeclarations-invalidContexts.ts (10 errors) ==== + + // Errors, let must be defined inside a block + if (true) + let l1 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + else + let l2 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + while (true) + let l3 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + do + let l4 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + while (true); + + var obj; + with (obj) + ~~~ +!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. + let l5 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + for (var i = 0; i < 10; i++) + let l6 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + for (var i2 in {}) + let l7 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + if (true) + label: let l8 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + while (false) + label2: label3: label4: let l9 = 0; + ~~~~~~~~~~~ +!!! error TS1157: let must be declared inside a block. + + + + \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-validContexts.errors.txt b/tests/baselines/reference/letDeclarations-validContexts.errors.txt new file mode 100644 index 0000000000000..de6cf7beef417 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-validContexts.errors.txt @@ -0,0 +1,129 @@ +tests/cases/compiler/letDeclarations-validContexts.ts(20,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. + + +==== tests/cases/compiler/letDeclarations-validContexts.ts (1 errors) ==== + + + // Control flow statements with blocks + if (true) { + let l1 = 0; + } + else { + let l2 = 0; + } + + while (true) { + let l3 = 0; + } + + do { + let l4 = 0; + } while (true); + + var obj; + with (obj) { + ~~~ +!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. + let l5 = 0; + } + + for (var i = 0; i < 10; i++) { + let l6 = 0; + } + + for (var i2 in {}) { + let l7 = 0; + } + + if (true) { + label: let l8 = 0; + } + + while (false) { + label2: label3: label4: let l9 = 0; + } + + // Try/catch/finally + try { + let l10 = 0; + } + catch (e) { + let l11 = 0; + } + finally { + let l12 = 0; + } + + // Switch + switch (0) { + case 0: + let l13 = 0; + break; + default: + let l14 = 0; + break; + } + + // blocks + { + let l15 = 0; + { + let l16 = 0 + label17: let l17 = 0; + } + } + + // global + let l18 = 0; + + // functions + function F() { + let l19 = 0; + } + + var F2 = () => { + let l20 = 0; + }; + + var F3 = function () { + let l21 = 0; + }; + + // modules + module m { + let l22 = 0; + + { + let l23 = 0; + } + } + + // methods + class C { + constructor() { + let l24 = 0; + } + + method() { + let l25 = 0; + } + + get v() { + let l26 = 0; + return l26; + } + + set v(value) { + let l27 = value; + } + } + + // object literals + var o = { + f() { + let l28 = 0; + }, + f2: () => { + let l29 = 0; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-validContexts.js b/tests/baselines/reference/letDeclarations-validContexts.js new file mode 100644 index 0000000000000..daa25014ab33a --- /dev/null +++ b/tests/baselines/reference/letDeclarations-validContexts.js @@ -0,0 +1,229 @@ +//// [letDeclarations-validContexts.ts] + + +// Control flow statements with blocks +if (true) { + let l1 = 0; +} +else { + let l2 = 0; +} + +while (true) { + let l3 = 0; +} + +do { + let l4 = 0; +} while (true); + +var obj; +with (obj) { + let l5 = 0; +} + +for (var i = 0; i < 10; i++) { + let l6 = 0; +} + +for (var i2 in {}) { + let l7 = 0; +} + +if (true) { + label: let l8 = 0; +} + +while (false) { + label2: label3: label4: let l9 = 0; +} + +// Try/catch/finally +try { + let l10 = 0; +} +catch (e) { + let l11 = 0; +} +finally { + let l12 = 0; +} + +// Switch +switch (0) { + case 0: + let l13 = 0; + break; + default: + let l14 = 0; + break; +} + +// blocks +{ + let l15 = 0; + { + let l16 = 0 + label17: let l17 = 0; + } +} + +// global +let l18 = 0; + +// functions +function F() { + let l19 = 0; +} + +var F2 = () => { + let l20 = 0; +}; + +var F3 = function () { + let l21 = 0; +}; + +// modules +module m { + let l22 = 0; + + { + let l23 = 0; + } +} + +// methods +class C { + constructor() { + let l24 = 0; + } + + method() { + let l25 = 0; + } + + get v() { + let l26 = 0; + return l26; + } + + set v(value) { + let l27 = value; + } +} + +// object literals +var o = { + f() { + let l28 = 0; + }, + f2: () => { + let l29 = 0; + } +} + +//// [letDeclarations-validContexts.js] +// Control flow statements with blocks +if (true) { + let l1 = 0; +} +else { + let l2 = 0; +} +while (true) { + let l3 = 0; +} +do { + let l4 = 0; +} while (true); +var obj; +with (obj) { + let l5 = 0; +} +for (var i = 0; i < 10; i++) { + let l6 = 0; +} +for (var i2 in {}) { + let l7 = 0; +} +if (true) { + label: let l8 = 0; +} +while (false) { + label2: label3: label4: let l9 = 0; +} +try { + let l10 = 0; +} +catch (e) { + let l11 = 0; +} +finally { + let l12 = 0; +} +switch (0) { + case 0: + let l13 = 0; + break; + default: + let l14 = 0; + break; +} +{ + let l15 = 0; + { + let l16 = 0; + label17: let l17 = 0; + } +} +// global +let l18 = 0; +// functions +function F() { + let l19 = 0; +} +var F2 = function () { + let l20 = 0; +}; +var F3 = function () { + let l21 = 0; +}; +// modules +var m; +(function (m) { + let l22 = 0; + { + let l23 = 0; + } +})(m || (m = {})); +// methods +var C = (function () { + function C() { + let l24 = 0; + } + C.prototype.method = function () { + let l25 = 0; + }; + Object.defineProperty(C.prototype, "v", { + get: function () { + let l26 = 0; + return l26; + }, + set: function (value) { + let l27 = value; + }, + enumerable: true, + configurable: true + }); + return C; +})(); +// object literals +var o = { + f: function () { + let l28 = 0; + }, + f2: function () { + let l29 = 0; + } +}; diff --git a/tests/cases/compiler/constDeclarations-invalidContexts.ts b/tests/cases/compiler/constDeclarations-invalidContexts.ts new file mode 100644 index 0000000000000..3da91a7d1d75c --- /dev/null +++ b/tests/cases/compiler/constDeclarations-invalidContexts.ts @@ -0,0 +1,33 @@ +// @target: ES6 + +// Errors, const must be defined inside a block +if (true) + const c1 = 0; +else + const c2 = 0; + +while (true) + const c3 = 0; + +do + const c4 = 0; +while (true); + +var obj; +with (obj) + const c5 = 0; + +for (var i = 0; i < 10; i++) + const c6 = 0; + +for (var i2 in {}) + const c7 = 0; + +if (true) + label: const c8 = 0; + +while (false) + label2: label3: label4: const c9 = 0; + + + diff --git a/tests/cases/compiler/constDeclarations-validContexts.ts b/tests/cases/compiler/constDeclarations-validContexts.ts new file mode 100644 index 0000000000000..ffde8e45d6fa1 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-validContexts.ts @@ -0,0 +1,124 @@ +// @target: ES6 + + +// Control flow statements with blocks +if (true) { + const c1 = 0; +} +else { + const c2 = 0; +} + +while (true) { + const c3 = 0; +} + +do { + const c4 = 0; +} while (true); + +var obj; +with (obj) { + const c5 = 0; +} + +for (var i = 0; i < 10; i++) { + const c6 = 0; +} + +for (var i2 in {}) { + const c7 = 0; +} + +if (true) { + label: const c8 = 0; +} + +while (false) { + label2: label3: label4: const c9 = 0; +} + +// Try/catch/finally +try { + const c10 = 0; +} +catch (e) { + const c11 = 0; +} +finally { + const c12 = 0; +} + +// Switch +switch (0) { + case 0: + const c13 = 0; + break; + default: + const c14 = 0; + break; +} + +// blocks +{ + const c15 = 0; + { + const c16 = 0 + label17: const c17 = 0; + } +} + +// global +const c18 = 0; + +// functions +function F() { + const c19 = 0; +} + +var F2 = () => { + const c20 = 0; +}; + +var F3 = function () { + const c21 = 0; +}; + +// modules +module m { + const c22 = 0; + + { + const c23 = 0; + } +} + +// methods +class C { + constructor() { + const c24 = 0; + } + + method() { + const c25 = 0; + } + + get v() { + const c26 = 0; + return c26; + } + + set v(value) { + const c27 = value; + } +} + +// object literals +var o = { + f() { + const c28 = 0; + }, + f2: () => { + const c29 = 0; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-invalidContexts.ts b/tests/cases/compiler/letDeclarations-invalidContexts.ts new file mode 100644 index 0000000000000..4d165ba2cda0e --- /dev/null +++ b/tests/cases/compiler/letDeclarations-invalidContexts.ts @@ -0,0 +1,33 @@ +// @target: ES6 + +// Errors, let must be defined inside a block +if (true) + let l1 = 0; +else + let l2 = 0; + +while (true) + let l3 = 0; + +do + let l4 = 0; +while (true); + +var obj; +with (obj) + let l5 = 0; + +for (var i = 0; i < 10; i++) + let l6 = 0; + +for (var i2 in {}) + let l7 = 0; + +if (true) + label: let l8 = 0; + +while (false) + label2: label3: label4: let l9 = 0; + + + diff --git a/tests/cases/compiler/letDeclarations-validContexts.ts b/tests/cases/compiler/letDeclarations-validContexts.ts new file mode 100644 index 0000000000000..32801f2d00966 --- /dev/null +++ b/tests/cases/compiler/letDeclarations-validContexts.ts @@ -0,0 +1,124 @@ +// @target: ES6 + + +// Control flow statements with blocks +if (true) { + let l1 = 0; +} +else { + let l2 = 0; +} + +while (true) { + let l3 = 0; +} + +do { + let l4 = 0; +} while (true); + +var obj; +with (obj) { + let l5 = 0; +} + +for (var i = 0; i < 10; i++) { + let l6 = 0; +} + +for (var i2 in {}) { + let l7 = 0; +} + +if (true) { + label: let l8 = 0; +} + +while (false) { + label2: label3: label4: let l9 = 0; +} + +// Try/catch/finally +try { + let l10 = 0; +} +catch (e) { + let l11 = 0; +} +finally { + let l12 = 0; +} + +// Switch +switch (0) { + case 0: + let l13 = 0; + break; + default: + let l14 = 0; + break; +} + +// blocks +{ + let l15 = 0; + { + let l16 = 0 + label17: let l17 = 0; + } +} + +// global +let l18 = 0; + +// functions +function F() { + let l19 = 0; +} + +var F2 = () => { + let l20 = 0; +}; + +var F3 = function () { + let l21 = 0; +}; + +// modules +module m { + let l22 = 0; + + { + let l23 = 0; + } +} + +// methods +class C { + constructor() { + let l24 = 0; + } + + method() { + let l25 = 0; + } + + get v() { + let l26 = 0; + return l26; + } + + set v(value) { + let l27 = value; + } +} + +// object literals +var o = { + f() { + let l28 = 0; + }, + f2: () => { + let l29 = 0; + } +} \ No newline at end of file From 6f6f4afeb1cd0e5be322d8de371e7b5db03bda2a Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Sun, 12 Oct 2014 21:44:29 -0700 Subject: [PATCH 04/25] Fix line endings --- .../decrementOperatorWithEnumType.errors.txt | 46 +++++++++--------- .../enumIdentifierLiterals.errors.txt | 48 +++++++++---------- .../reference/enumIdentifierLiterals.js | 24 +++++----- .../incrementOperatorWithEnumType.errors.txt | 40 ++++++++-------- .../reference/parserEnum7.errors.txt | 28 +++++------ tests/baselines/reference/parserEnum7.js | 20 ++++---- 6 files changed, 103 insertions(+), 103 deletions(-) diff --git a/tests/baselines/reference/decrementOperatorWithEnumType.errors.txt b/tests/baselines/reference/decrementOperatorWithEnumType.errors.txt index d43515e84ef6e..a0c30e9dc93fa 100644 --- a/tests/baselines/reference/decrementOperatorWithEnumType.errors.txt +++ b/tests/baselines/reference/decrementOperatorWithEnumType.errors.txt @@ -1,24 +1,24 @@ -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts(7,23): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts(12,1): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts(12,7): error TS2304: Cannot find name 'A'. - - -==== tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts (3 errors) ==== - // -- operator on enum type - - enum ENUM1 { A, B, "" }; - - // expression - var ResultIsNumber1 = --ENUM1["A"]; - var ResultIsNumber2 = ENUM1.A--; - ~~~~~~~ -!!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. - - // miss assignment operator - --ENUM1["A"]; - - ENUM1[A]--; - ~~~~~~~~ -!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. - ~ +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts(7,23): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts(12,1): error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts(12,7): error TS2304: Cannot find name 'A'. + + +==== tests/cases/conformance/expressions/unaryOperators/decrementOperator/decrementOperatorWithEnumType.ts (3 errors) ==== + // -- operator on enum type + + enum ENUM1 { A, B, "" }; + + // expression + var ResultIsNumber1 = --ENUM1["A"]; + var ResultIsNumber2 = ENUM1.A--; + ~~~~~~~ +!!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. + + // miss assignment operator + --ENUM1["A"]; + + ENUM1[A]--; + ~~~~~~~~ +!!! error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type. + ~ !!! error TS2304: Cannot find name 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/enumIdentifierLiterals.errors.txt b/tests/baselines/reference/enumIdentifierLiterals.errors.txt index 721a6bd29ff11..6327e40289ac0 100644 --- a/tests/baselines/reference/enumIdentifierLiterals.errors.txt +++ b/tests/baselines/reference/enumIdentifierLiterals.errors.txt @@ -1,25 +1,25 @@ -tests/cases/compiler/enumIdentifierLiterals.ts(2,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(3,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(4,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(5,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(6,5): error TS1151: An enum member cannot have a numeric name. - - -==== tests/cases/compiler/enumIdentifierLiterals.ts (5 errors) ==== - enum Nums { - 1.0, - ~~~ -!!! error TS1151: An enum member cannot have a numeric name. - 11e-1, - ~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. - 0.12e1, - ~~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. - "13e-1", - ~~~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. - 0xF00D - ~~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(2,5): error TS1151: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(3,5): error TS1151: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(4,5): error TS1151: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(5,5): error TS1151: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(6,5): error TS1151: An enum member cannot have a numeric name. + + +==== tests/cases/compiler/enumIdentifierLiterals.ts (5 errors) ==== + enum Nums { + 1.0, + ~~~ +!!! error TS1151: An enum member cannot have a numeric name. + 11e-1, + ~~~~~ +!!! error TS1151: An enum member cannot have a numeric name. + 0.12e1, + ~~~~~~ +!!! error TS1151: An enum member cannot have a numeric name. + "13e-1", + ~~~~~~~ +!!! error TS1151: An enum member cannot have a numeric name. + 0xF00D + ~~~~~~ +!!! error TS1151: An enum member cannot have a numeric name. } \ No newline at end of file diff --git a/tests/baselines/reference/enumIdentifierLiterals.js b/tests/baselines/reference/enumIdentifierLiterals.js index 06cb76dd21d83..72a8a56570c8b 100644 --- a/tests/baselines/reference/enumIdentifierLiterals.js +++ b/tests/baselines/reference/enumIdentifierLiterals.js @@ -1,18 +1,18 @@ -//// [enumIdentifierLiterals.ts] +//// [enumIdentifierLiterals.ts] enum Nums { 1.0, 11e-1, 0.12e1, "13e-1", 0xF00D -} - -//// [enumIdentifierLiterals.js] -var Nums; -(function (Nums) { - Nums[Nums["1"] = 0] = "1"; - Nums[Nums["1.1"] = 1] = "1.1"; - Nums[Nums["1.2"] = 2] = "1.2"; - Nums[Nums["13e-1"] = 3] = "13e-1"; - Nums[Nums["61453"] = 4] = "61453"; -})(Nums || (Nums = {})); +} + +//// [enumIdentifierLiterals.js] +var Nums; +(function (Nums) { + Nums[Nums["1"] = 0] = "1"; + Nums[Nums["1.1"] = 1] = "1.1"; + Nums[Nums["1.2"] = 2] = "1.2"; + Nums[Nums["13e-1"] = 3] = "13e-1"; + Nums[Nums["61453"] = 4] = "61453"; +})(Nums || (Nums = {})); diff --git a/tests/baselines/reference/incrementOperatorWithEnumType.errors.txt b/tests/baselines/reference/incrementOperatorWithEnumType.errors.txt index 7617dbba379b3..9bcf6c7612f66 100644 --- a/tests/baselines/reference/incrementOperatorWithEnumType.errors.txt +++ b/tests/baselines/reference/incrementOperatorWithEnumType.errors.txt @@ -1,21 +1,21 @@ -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithEnumType.ts(7,23): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. -tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithEnumType.ts(12,1): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. - - -==== tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithEnumType.ts (2 errors) ==== - // ++ operator on enum type - - enum ENUM1 { A, B, "" }; - - // expression - var ResultIsNumber1 = ++ENUM1["B"]; - var ResultIsNumber2 = ENUM1.B++; - ~~~~~~~ -!!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. - - // miss assignment operator - ++ENUM1["B"]; - - ENUM1.B++; - ~~~~~~~ +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithEnumType.ts(7,23): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. +tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithEnumType.ts(12,1): error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. + + +==== tests/cases/conformance/expressions/unaryOperators/incrementOperator/incrementOperatorWithEnumType.ts (2 errors) ==== + // ++ operator on enum type + + enum ENUM1 { A, B, "" }; + + // expression + var ResultIsNumber1 = ++ENUM1["B"]; + var ResultIsNumber2 = ENUM1.B++; + ~~~~~~~ +!!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. + + // miss assignment operator + ++ENUM1["B"]; + + ENUM1.B++; + ~~~~~~~ !!! error TS2357: The operand of an increment or decrement operator must be a variable, property or indexer. \ No newline at end of file diff --git a/tests/baselines/reference/parserEnum7.errors.txt b/tests/baselines/reference/parserEnum7.errors.txt index 48c938e02de55..a4a2326546a05 100644 --- a/tests/baselines/reference/parserEnum7.errors.txt +++ b/tests/baselines/reference/parserEnum7.errors.txt @@ -1,15 +1,15 @@ -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,3): error TS1151: An enum member cannot have a numeric name. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,6): error TS1151: An enum member cannot have a numeric name. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,9): error TS1151: An enum member cannot have a numeric name. - - -==== tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts (3 errors) ==== - enum E { - 1, 2, 3 - ~ -!!! error TS1151: An enum member cannot have a numeric name. - ~ -!!! error TS1151: An enum member cannot have a numeric name. - ~ -!!! error TS1151: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,3): error TS1151: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,6): error TS1151: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,9): error TS1151: An enum member cannot have a numeric name. + + +==== tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts (3 errors) ==== + enum E { + 1, 2, 3 + ~ +!!! error TS1151: An enum member cannot have a numeric name. + ~ +!!! error TS1151: An enum member cannot have a numeric name. + ~ +!!! error TS1151: An enum member cannot have a numeric name. } \ No newline at end of file diff --git a/tests/baselines/reference/parserEnum7.js b/tests/baselines/reference/parserEnum7.js index 831090f4ce782..3781167bbbaff 100644 --- a/tests/baselines/reference/parserEnum7.js +++ b/tests/baselines/reference/parserEnum7.js @@ -1,12 +1,12 @@ -//// [parserEnum7.ts] +//// [parserEnum7.ts] enum E { 1, 2, 3 -} - -//// [parserEnum7.js] -var E; -(function (E) { - E[E["1"] = 0] = "1"; - E[E["2"] = 1] = "2"; - E[E["3"] = 2] = "3"; -})(E || (E = {})); +} + +//// [parserEnum7.js] +var E; +(function (E) { + E[E["1"] = 0] = "1"; + E[E["2"] = 1] = "2"; + E[E["3"] = 2] = "3"; +})(E || (E = {})); From cf89f5cf589213510ab9b30f67050592118b60be Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Oct 2014 20:54:26 -0700 Subject: [PATCH 05/25] Add binder support for block scoped variable declarations --- src/compiler/binder.ts | 112 +++++-- src/compiler/types.ts | 12 +- .../constDeclarations-errors.errors.txt | 11 +- .../constDeclarations-scopes.errors.txt | 153 +++++++++ .../reference/constDeclarations-scopes.js | 276 +++++++++++++++++ ...tDeclarations-scopes-duplicates.errors.txt | 152 +++++++++ .../letDeclarations-scopes-duplicates.js | 140 +++++++++ .../letDeclarations-scopes.errors.txt | 161 ++++++++++ .../reference/letDeclarations-scopes.js | 290 ++++++++++++++++++ .../letDeclarations-scopes2.errors.txt | 42 +++ .../reference/letDeclarations-scopes2.js | 49 +++ .../compiler/constDeclarations-scopes.ts | 148 +++++++++ .../letDeclarations-scopes-duplicates.ts | 77 +++++ .../cases/compiler/letDeclarations-scopes.ts | 156 ++++++++++ .../cases/compiler/letDeclarations-scopes2.ts | 27 ++ 15 files changed, 1766 insertions(+), 40 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-scopes.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-scopes.js create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates.js create mode 100644 tests/baselines/reference/letDeclarations-scopes.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes.js create mode 100644 tests/baselines/reference/letDeclarations-scopes2.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes2.js create mode 100644 tests/cases/compiler/constDeclarations-scopes.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes2.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index c9f9d6bf6e3de..0760f33ce6795 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -31,13 +31,14 @@ module ts { var parent: Node; var container: Declaration; + var blockScopeContainer: Node; var lastContainer: Declaration; var symbolCount = 0; var Symbol = objectAllocator.getSymbolConstructor(); if (!file.locals) { file.locals = {}; - container = file; + container = blockScopeContainer = file; bind(file); file.symbolCount = symbolCount; } @@ -167,12 +168,13 @@ module ts { // All container nodes are kept on a linked list in declaration order. This list is used by the getLocalNameOfContainer function // in the type checker to validate that the local name used for a container is unique. - function bindChildren(node: Declaration, symbolKind: SymbolFlags) { + function bindChildren(node: Declaration, symbolKind: SymbolFlags, isBlockScopeContainer: boolean) { if (symbolKind & SymbolFlags.HasLocals) { node.locals = {}; } var saveParent = parent; var saveContainer = container; + var savedBlockScopeContainer = blockScopeContainer; parent = node; if (symbolKind & SymbolFlags.IsContainer) { container = node; @@ -184,12 +186,16 @@ module ts { lastContainer = container; } } + if (isBlockScopeContainer) { + blockScopeContainer = node; + } forEachChild(node, bind); container = saveContainer; parent = saveParent; + blockScopeContainer = savedBlockScopeContainer; } - function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) { + function bindDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags, isBlockScopeContainer: boolean) { switch (container.kind) { case SyntaxKind.ModuleDeclaration: declareModuleMember(node, symbolKind, symbolExcludes); @@ -225,126 +231,168 @@ module ts { declareSymbol(container.symbol.exports, container.symbol, node, symbolKind, symbolExcludes); break; } - bindChildren(node, symbolKind); + bindChildren(node, symbolKind, isBlockScopeContainer); } function bindConstructorDeclaration(node: ConstructorDeclaration) { - bindDeclaration(node, SymbolFlags.Constructor, 0); + bindDeclaration(node, SymbolFlags.Constructor, 0, /*isBlockScopeContainer*/ true); forEach(node.parameters, p => { if (p.flags & (NodeFlags.Public | NodeFlags.Private | NodeFlags.Protected)) { - bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + bindDeclaration(p, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); } }); } function bindModuleDeclaration(node: ModuleDeclaration) { if (node.name.kind === SyntaxKind.StringLiteral) { - bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); } else if (isInstantiated(node)) { - bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes); + bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true); } else { - bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes); + bindDeclaration(node, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes, /*isBlockScopeContainer*/ true); } } - function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string) { + function bindAnonymousDeclaration(node: Node, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) { var symbol = createSymbol(symbolKind, name); addDeclarationToSymbol(symbol, node, symbolKind); - bindChildren(node, symbolKind); + bindChildren(node, symbolKind, isBlockScopeContainer); } function bindCatchVariableDeclaration(node: CatchBlock) { var symbol = createSymbol(SymbolFlags.Variable, node.variable.text || "__missing"); addDeclarationToSymbol(symbol, node, SymbolFlags.Variable); var saveParent = parent; - parent = node; + var savedBlockScopeContainer = blockScopeContainer; + parent = blockScopeContainer = node; forEachChild(node, bind); parent = saveParent; + blockScopeContainer = savedBlockScopeContainer; + } + + function bindBlockScopedVariableDeclaration(node: Declaration) { + var symbolKind = SymbolFlags.Variable | SymbolFlags.BlockScoped; + switch (blockScopeContainer.kind) { + case SyntaxKind.ModuleDeclaration: + declareModuleMember(node, symbolKind, SymbolFlags.BlockScopedExcludes); + break; + case SyntaxKind.SourceFile: + if (isExternalModule(container)) { + declareModuleMember(node, symbolKind, SymbolFlags.BlockScopedExcludes); + break; + } + default: + if (!blockScopeContainer.locals) { + blockScopeContainer.locals = {}; + } + declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, SymbolFlags.BlockScopedExcludes); + } + + bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false); } function bind(node: Node) { + var isBlockScopeContainer: boolean; node.parent = parent; switch (node.kind) { case SyntaxKind.TypeParameter: - bindDeclaration(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + bindDeclaration(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.Parameter: - bindDeclaration(node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes); + bindDeclaration(node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.VariableDeclaration: - bindDeclaration(node, SymbolFlags.Variable, SymbolFlags.VariableExcludes); + if (node.flags & NodeFlags.BlockScoped) { + bindBlockScopedVariableDeclaration(node); + } + else { + bindDeclaration(node, SymbolFlags.Variable, SymbolFlags.VariableExcludes, /*isBlockScopeContainer*/ false); + } break; case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: - bindDeclaration(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes); + bindDeclaration(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.EnumMember: - bindDeclaration(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes); + bindDeclaration(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.CallSignature: - bindDeclaration(node, SymbolFlags.CallSignature, 0); + bindDeclaration(node, SymbolFlags.CallSignature, 0, /*isBlockScopeContainer*/ false); break; case SyntaxKind.Method: - bindDeclaration(node, SymbolFlags.Method, SymbolFlags.MethodExcludes); + bindDeclaration(node, SymbolFlags.Method, SymbolFlags.MethodExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.ConstructSignature: - bindDeclaration(node, SymbolFlags.ConstructSignature, 0); + bindDeclaration(node, SymbolFlags.ConstructSignature, 0, /*isBlockScopeContainer*/ true); break; case SyntaxKind.IndexSignature: - bindDeclaration(node, SymbolFlags.IndexSignature, 0); + bindDeclaration(node, SymbolFlags.IndexSignature, 0, /*isBlockScopeContainer*/ false); break; case SyntaxKind.FunctionDeclaration: - bindDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes); + bindDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.Constructor: bindConstructorDeclaration(node); break; case SyntaxKind.GetAccessor: - bindDeclaration(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes); + bindDeclaration(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.SetAccessor: - bindDeclaration(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes); + bindDeclaration(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes, /*isBlockScopeContainer*/ true); break; case SyntaxKind.TypeLiteral: - bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type"); + bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, "__type", /*isBlockScopeContainer*/ false); break; case SyntaxKind.ObjectLiteral: - bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object"); + bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object", /*isBlockScopeContainer*/ false); break; case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - bindAnonymousDeclaration(node, SymbolFlags.Function, "__function"); + bindAnonymousDeclaration(node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true); break; case SyntaxKind.CatchBlock: bindCatchVariableDeclaration(node); break; case SyntaxKind.ClassDeclaration: - bindDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes); + bindDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.InterfaceDeclaration: - bindDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes); + bindDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.EnumDeclaration: - bindDeclaration(node, SymbolFlags.Enum, SymbolFlags.EnumExcludes); + bindDeclaration(node, SymbolFlags.Enum, SymbolFlags.EnumExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.ModuleDeclaration: bindModuleDeclaration(node); break; case SyntaxKind.ImportDeclaration: - bindDeclaration(node, SymbolFlags.Import, SymbolFlags.ImportExcludes); + bindDeclaration(node, SymbolFlags.Import, SymbolFlags.ImportExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.SourceFile: if (isExternalModule(node)) { - bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).filename) + '"'); + bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).filename) + '"', /*isBlockScopeContainer*/ true); break; } + + case SyntaxKind.Block: + case SyntaxKind.TryBlock: + case SyntaxKind.CatchBlock: + case SyntaxKind.FinallyBlock: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.SwitchStatement: + isBlockScopeContainer = true; + default: var saveParent = parent; + var savedBlockScopeContainer = blockScopeContainer; parent = node; + if (isBlockScopeContainer) blockScopeContainer = node; forEachChild(node, bind); parent = saveParent; + blockScopeContainer = savedBlockScopeContainer; } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4218d4f401121..09cd613e8f341 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -245,11 +245,12 @@ module ts { MultiLine = 0x00000100, // Multi-line array or object literal Synthetic = 0x00000200, // Synthetic node (for full fidelity) DeclarationFile = 0x00000400, // Node is a .d.ts file - Let = 0x00000800, - Const = 0x00001000, + Let = 0x00000800, // Variable declaration + Const = 0x00001000, // Variable declaration Modifier = Export | Ambient | Public | Private | Protected | Static, - AccessibilityModifier = Public | Private | Protected + AccessibilityModifier = Public | Private | Protected, + BlockScoped = Let | Const } export interface Node extends TextRange { @@ -768,6 +769,8 @@ module ts { Undefined = 0x08000000, // Symbol for the undefined + BlockScoped = 0x10000000, + Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor, Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter, Namespace = ValueModule | NamespaceModule, @@ -776,7 +779,8 @@ module ts { Signature = CallSignature | ConstructSignature | IndexSignature, ParameterExcludes = Value, - VariableExcludes = Value & ~Variable, + VariableExcludes = (Value | BlockScoped) & ~Variable, + BlockScopedExcludes = Value, PropertyExcludes = Value, EnumMemberExcludes = Value, FunctionExcludes = Value & ~(Function | ValueModule), diff --git a/tests/baselines/reference/constDeclarations-errors.errors.txt b/tests/baselines/reference/constDeclarations-errors.errors.txt index 79d56ade878a4..9a922ac93a916 100644 --- a/tests/baselines/reference/constDeclarations-errors.errors.txt +++ b/tests/baselines/reference/constDeclarations-errors.errors.txt @@ -13,10 +13,11 @@ tests/cases/compiler/constDeclarations-errors.ts(8,18): error TS1128: Declaratio tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1109: Expression expected. tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1156: const must be declared inside a block. tests/cases/compiler/constDeclarations-errors.ts(10,28): error TS1005: ';' expected. -tests/cases/compiler/constDeclarations-errors.ts(10,11): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. +tests/cases/compiler/constDeclarations-errors.ts(10,18): error TS2304: Cannot find name 'c'. +tests/cases/compiler/constDeclarations-errors.ts(10,25): error TS2304: Cannot find name 'c'. -==== tests/cases/compiler/constDeclarations-errors.ts (16 errors) ==== +==== tests/cases/compiler/constDeclarations-errors.ts (17 errors) ==== // error, missing intialicer const c1; @@ -57,6 +58,8 @@ tests/cases/compiler/constDeclarations-errors.ts(10,11): error TS2403: Subsequen !!! error TS1156: const must be declared inside a block. ~ !!! error TS1005: ';' expected. - ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. + ~ +!!! error TS2304: Cannot find name 'c'. + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-scopes.errors.txt b/tests/baselines/reference/constDeclarations-scopes.errors.txt new file mode 100644 index 0000000000000..138acd9b16d1c --- /dev/null +++ b/tests/baselines/reference/constDeclarations-scopes.errors.txt @@ -0,0 +1,153 @@ +tests/cases/compiler/constDeclarations-scopes.ts(28,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. + + +==== tests/cases/compiler/constDeclarations-scopes.ts (1 errors) ==== + + // global + const c = "string"; + + var n: number; + + // Control flow statements with blocks + if (true) { + const c = 0; + n = c; + } + else { + const c = 0; + n = c; + } + + while (true) { + const c = 0; + n = c; + } + + do { + const c = 0; + n = c; + } while (true); + + var obj; + with (obj) { + ~~~ +!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. + const c = 0; + n = c; + } + + for (var i = 0; i < 10; i++) { + const c = 0; + n = c; + } + + for (var i2 in {}) { + const c = 0; + n = c; + } + + if (true) { + label: const c = 0; + n = c; + } + + while (false) { + label2: label3: label4: const c = 0; + n = c; + } + + // Try/catch/finally + try { + const c = 0; + n = c; + } + catch (e) { + const c = 0; + n = c; + } + finally { + const c = 0; + n = c; + } + + // Switch + switch (0) { + case 0: + const c = 0; + n = c; + break; + } + + // blocks + { + const c = 0; + n = c; + { + const c = false; + var b: boolean = c; + } + } + + // functions + + function F() { + const c = 0; + n = c; + } + + var F2 = () => { + const c = 0; + n = c; + }; + + var F3 = function () { + const c = 0; + n = c; + }; + + // modules + module m { + const c = 0; + n = c; + + { + const c = false; + var b2: boolean = c; + } + } + + // methods + class C { + constructor() { + const c = 0; + n = c; + } + + method() { + const c = 0; + n = c; + } + + get v() { + const c = 0; + n = c; + return n; + } + + set v(value) { + const c = 0; + n = c; + } + } + + // object literals + var o = { + f() { + const c = 0; + n = c; + }, + f2: () => { + const c = 0; + n = c; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-scopes.js b/tests/baselines/reference/constDeclarations-scopes.js new file mode 100644 index 0000000000000..800dd856422ea --- /dev/null +++ b/tests/baselines/reference/constDeclarations-scopes.js @@ -0,0 +1,276 @@ +//// [constDeclarations-scopes.ts] + +// global +const c = "string"; + +var n: number; + +// Control flow statements with blocks +if (true) { + const c = 0; + n = c; +} +else { + const c = 0; + n = c; +} + +while (true) { + const c = 0; + n = c; +} + +do { + const c = 0; + n = c; +} while (true); + +var obj; +with (obj) { + const c = 0; + n = c; +} + +for (var i = 0; i < 10; i++) { + const c = 0; + n = c; +} + +for (var i2 in {}) { + const c = 0; + n = c; +} + +if (true) { + label: const c = 0; + n = c; +} + +while (false) { + label2: label3: label4: const c = 0; + n = c; +} + +// Try/catch/finally +try { + const c = 0; + n = c; +} +catch (e) { + const c = 0; + n = c; +} +finally { + const c = 0; + n = c; +} + +// Switch +switch (0) { + case 0: + const c = 0; + n = c; + break; +} + +// blocks +{ + const c = 0; + n = c; + { + const c = false; + var b: boolean = c; + } +} + +// functions + +function F() { + const c = 0; + n = c; +} + +var F2 = () => { + const c = 0; + n = c; +}; + +var F3 = function () { + const c = 0; + n = c; +}; + +// modules +module m { + const c = 0; + n = c; + + { + const c = false; + var b2: boolean = c; + } +} + +// methods +class C { + constructor() { + const c = 0; + n = c; + } + + method() { + const c = 0; + n = c; + } + + get v() { + const c = 0; + n = c; + return n; + } + + set v(value) { + const c = 0; + n = c; + } +} + +// object literals +var o = { + f() { + const c = 0; + n = c; + }, + f2: () => { + const c = 0; + n = c; + } +} + +//// [constDeclarations-scopes.js] +// global +const c = "string"; +var n; +// Control flow statements with blocks +if (true) { + const c = 0; + n = c; +} +else { + const c = 0; + n = c; +} +while (true) { + const c = 0; + n = c; +} +do { + const c = 0; + n = c; +} while (true); +var obj; +with (obj) { + const c = 0; + n = c; +} +for (var i = 0; i < 10; i++) { + const c = 0; + n = c; +} +for (var i2 in {}) { + const c = 0; + n = c; +} +if (true) { + label: const c = 0; + n = c; +} +while (false) { + label2: label3: label4: const c = 0; + n = c; +} +try { + const c = 0; + n = c; +} +catch (e) { + const c = 0; + n = c; +} +finally { + const c = 0; + n = c; +} +switch (0) { + case 0: + const c = 0; + n = c; + break; +} +{ + const c = 0; + n = c; + { + const c = false; + var b = c; + } +} +// functions +function F() { + const c = 0; + n = c; +} +var F2 = function () { + const c = 0; + n = c; +}; +var F3 = function () { + const c = 0; + n = c; +}; +// modules +var m; +(function (m) { + const c = 0; + n = c; + { + const c = false; + var b2 = c; + } +})(m || (m = {})); +// methods +var C = (function () { + function C() { + const c = 0; + n = c; + } + C.prototype.method = function () { + const c = 0; + n = c; + }; + Object.defineProperty(C.prototype, "v", { + get: function () { + const c = 0; + n = c; + return n; + }, + set: function (value) { + const c = 0; + n = c; + }, + enumerable: true, + configurable: true + }); + return C; +})(); +// object literals +var o = { + f: function () { + const c = 0; + n = c; + }, + f2: function () { + const c = 0; + n = c; + } +}; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt new file mode 100644 index 0000000000000..41d2813f7c440 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt @@ -0,0 +1,152 @@ +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(3,5): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(4,5): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(6,5): error TS2300: Duplicate identifier 'var2'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(7,7): error TS2300: Duplicate identifier 'var2'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(9,7): error TS2300: Duplicate identifier 'var3'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(10,5): error TS2300: Duplicate identifier 'var3'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(12,7): error TS2300: Duplicate identifier 'var4'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(13,7): error TS2300: Duplicate identifier 'var4'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(15,5): error TS2300: Duplicate identifier 'var5'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(16,5): error TS2300: Duplicate identifier 'var5'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(18,5): error TS2300: Duplicate identifier 'var6'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(19,5): error TS2300: Duplicate identifier 'var6'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(22,9): error TS2300: Duplicate identifier 'var7'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(23,9): error TS2300: Duplicate identifier 'var7'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(25,13): error TS2300: Duplicate identifier 'var8'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(26,15): error TS2300: Duplicate identifier 'var8'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(32,13): error TS2300: Duplicate identifier 'var9'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(33,13): error TS2300: Duplicate identifier 'var9'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(37,11): error TS2300: Duplicate identifier 'var10'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(38,11): error TS2300: Duplicate identifier 'var10'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(41,9): error TS2300: Duplicate identifier 'var11'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(42,9): error TS2300: Duplicate identifier 'var11'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(46,9): error TS2300: Duplicate identifier 'var12'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2300: Duplicate identifier 'var12'. + + +==== tests/cases/compiler/letDeclarations-scopes-duplicates.ts (24 errors) ==== + + // Errors: redeclaration + let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. + let var1 = 0; // error + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. + + let var2 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var2'. + const var2 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var2'. + + const var3 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var3'. + let var3 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var3'. + + const var4 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var4'. + const var4 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var4'. + + var var5 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var5'. + let var5 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var5'. + + let var6 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var6'. + var var6 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var6'. + + { + let var7 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var7'. + let var7 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var7'. + { + let var8 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var8'. + const var8 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var8'. + } + } + + switch (0) { + default: + let var9 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var9'. + let var9 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var9'. + } + + try { + const var10 = 0; + ~~~~~ +!!! error TS2300: Duplicate identifier 'var10'. + const var10 = 0; + ~~~~~ +!!! error TS2300: Duplicate identifier 'var10'. + } + catch (e) { + let var11 = 0; + ~~~~~ +!!! error TS2300: Duplicate identifier 'var11'. + let var11 = 0; + ~~~~~ +!!! error TS2300: Duplicate identifier 'var11'. + } + + function F1() { + let var12; + ~~~~~ +!!! error TS2300: Duplicate identifier 'var12'. + let var12; + ~~~~~ +!!! error TS2300: Duplicate identifier 'var12'. + } + + // OK + var var20 = 0; + + var var20 = 0 + { + let var20 = 0; + { + let var20 = 0; + } + } + + switch (0) { + default: + let var20 = 0; + } + + try { + let var20 = 0; + } + catch (e) { + let var20 = 0; + } + + function F() { + let var20; + } + + \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates.js b/tests/baselines/reference/letDeclarations-scopes-duplicates.js new file mode 100644 index 0000000000000..c7d2ef9863a04 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates.js @@ -0,0 +1,140 @@ +//// [letDeclarations-scopes-duplicates.ts] + +// Errors: redeclaration +let var1 = 0; +let var1 = 0; // error + +let var2 = 0; +const var2 = 0; + +const var3 = 0; +let var3 = 0; + +const var4 = 0; +const var4 = 0; + +var var5 = 0; +let var5 = 0; + +let var6 = 0; +var var6 = 0; + +{ + let var7 = 0; + let var7 = 0; + { + let var8 = 0; + const var8 = 0; + } +} + +switch (0) { + default: + let var9 = 0; + let var9 = 0; +} + +try { + const var10 = 0; + const var10 = 0; +} +catch (e) { + let var11 = 0; + let var11 = 0; +} + +function F1() { + let var12; + let var12; +} + +// OK +var var20 = 0; + +var var20 = 0 +{ + let var20 = 0; + { + let var20 = 0; + } +} + +switch (0) { + default: + let var20 = 0; +} + +try { + let var20 = 0; +} +catch (e) { + let var20 = 0; +} + +function F() { + let var20; +} + + + +//// [letDeclarations-scopes-duplicates.js] +// Errors: redeclaration +let var1 = 0; +let var1 = 0; // error +let var2 = 0; +const var2 = 0; +const var3 = 0; +let var3 = 0; +const var4 = 0; +const var4 = 0; +var var5 = 0; +let var5 = 0; +let var6 = 0; +var var6 = 0; +{ + let var7 = 0; + let var7 = 0; + { + let var8 = 0; + const var8 = 0; + } +} +switch (0) { + default: + let var9 = 0; + let var9 = 0; +} +try { + const var10 = 0; + const var10 = 0; +} +catch (e) { + let var11 = 0; + let var11 = 0; +} +function F1() { + let var12; + let var12; +} +// OK +var var20 = 0; +var var20 = 0; +{ + let var20 = 0; + { + let var20 = 0; + } +} +switch (0) { + default: + let var20 = 0; +} +try { + let var20 = 0; +} +catch (e) { + let var20 = 0; +} +function F() { + let var20; +} diff --git a/tests/baselines/reference/letDeclarations-scopes.errors.txt b/tests/baselines/reference/letDeclarations-scopes.errors.txt new file mode 100644 index 0000000000000..df54e0fc3c474 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes.errors.txt @@ -0,0 +1,161 @@ +tests/cases/compiler/letDeclarations-scopes.ts(28,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. + + +==== tests/cases/compiler/letDeclarations-scopes.ts (1 errors) ==== + + // global + let l = "string"; + + var n: number; + + // Control flow statements with blocks + if (true) { + let l = 0; + n = l; + } + else { + let l = 0; + n = l; + } + + while (true) { + let l = 0; + n = l; + } + + do { + let l = 0; + n = l; + } while (true); + + var obj; + with (obj) { + ~~~ +!!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. + let l = 0; + n = l; + } + + for (var i = 0; i < 10; i++) { + let l = 0; + n = l; + } + + for (var i2 in {}) { + let l = 0; + n = l; + } + + if (true) { + label: let l = 0; + n = l; + } + + while (false) { + label2: label3: label4: let l = 0; + n = l; + } + + for (let l = 0; n = l; l++) { + let l = true; + var b3: boolean = l; + } + + for (let l in {}) { + + } + + // Try/catch/finally + try { + let l = 0; + n = l; + } + catch (e) { + let l = 0; + n = l; + } + finally { + let l = 0; + n = l; + } + + // Switch + switch (0) { + case 0: + let l = 0; + n = l; + break; + } + + // blocks + { + let l = 0; + n = l; + { + let l = false; + var b: boolean = l; + } + } + + // functions + function F() { + let l = 0; + n = l; + } + + var F2 = () => { + let l = 0; + n = l; + }; + + var F3 = function () { + let l = 0; + n = l; + }; + + // modules + module m { + let l = 0; + n = l; + + { + let l = false; + var b2: boolean = l; + } + } + + // methods + class C { + constructor() { + let l = 0; + n = l; + } + + method() { + let l = 0; + n = l; + } + + get v() { + let l = 0; + n = l; + return n; + } + + set v(value) { + let l = 0; + n = l; + } + } + + // object literals + var o = { + f() { + let l = 0; + n = l; + }, + f2: () => { + let l = 0; + n = l; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes.js b/tests/baselines/reference/letDeclarations-scopes.js new file mode 100644 index 0000000000000..59d42368b6c0c --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes.js @@ -0,0 +1,290 @@ +//// [letDeclarations-scopes.ts] + +// global +let l = "string"; + +var n: number; + +// Control flow statements with blocks +if (true) { + let l = 0; + n = l; +} +else { + let l = 0; + n = l; +} + +while (true) { + let l = 0; + n = l; +} + +do { + let l = 0; + n = l; +} while (true); + +var obj; +with (obj) { + let l = 0; + n = l; +} + +for (var i = 0; i < 10; i++) { + let l = 0; + n = l; +} + +for (var i2 in {}) { + let l = 0; + n = l; +} + +if (true) { + label: let l = 0; + n = l; +} + +while (false) { + label2: label3: label4: let l = 0; + n = l; +} + +for (let l = 0; n = l; l++) { + let l = true; + var b3: boolean = l; +} + +for (let l in {}) { + +} + +// Try/catch/finally +try { + let l = 0; + n = l; +} +catch (e) { + let l = 0; + n = l; +} +finally { + let l = 0; + n = l; +} + +// Switch +switch (0) { + case 0: + let l = 0; + n = l; + break; +} + +// blocks +{ + let l = 0; + n = l; + { + let l = false; + var b: boolean = l; + } +} + +// functions +function F() { + let l = 0; + n = l; +} + +var F2 = () => { + let l = 0; +n = l; +}; + +var F3 = function () { + let l = 0; +n = l; +}; + +// modules +module m { + let l = 0; + n = l; + + { + let l = false; + var b2: boolean = l; + } +} + +// methods +class C { + constructor() { + let l = 0; + n = l; + } + + method() { + let l = 0; + n = l; + } + + get v() { + let l = 0; + n = l; + return n; + } + + set v(value) { + let l = 0; + n = l; + } +} + +// object literals +var o = { + f() { + let l = 0; +n = l; + }, +f2: () => { + let l = 0; + n = l; + } +} + +//// [letDeclarations-scopes.js] +// global +let l = "string"; +var n; +// Control flow statements with blocks +if (true) { + let l = 0; + n = l; +} +else { + let l = 0; + n = l; +} +while (true) { + let l = 0; + n = l; +} +do { + let l = 0; + n = l; +} while (true); +var obj; +with (obj) { + let l = 0; + n = l; +} +for (var i = 0; i < 10; i++) { + let l = 0; + n = l; +} +for (var i2 in {}) { + let l = 0; + n = l; +} +if (true) { + label: let l = 0; + n = l; +} +while (false) { + label2: label3: label4: let l = 0; + n = l; +} +for (let l = 0; n = l; l++) { + let l = true; + var b3 = l; +} +for (let l in {}) { +} +try { + let l = 0; + n = l; +} +catch (e) { + let l = 0; + n = l; +} +finally { + let l = 0; + n = l; +} +switch (0) { + case 0: + let l = 0; + n = l; + break; +} +{ + let l = 0; + n = l; + { + let l = false; + var b = l; + } +} +// functions +function F() { + let l = 0; + n = l; +} +var F2 = function () { + let l = 0; + n = l; +}; +var F3 = function () { + let l = 0; + n = l; +}; +// modules +var m; +(function (m) { + let l = 0; + n = l; + { + let l = false; + var b2 = l; + } +})(m || (m = {})); +// methods +var C = (function () { + function C() { + let l = 0; + n = l; + } + C.prototype.method = function () { + let l = 0; + n = l; + }; + Object.defineProperty(C.prototype, "v", { + get: function () { + let l = 0; + n = l; + return n; + }, + set: function (value) { + let l = 0; + n = l; + }, + enumerable: true, + configurable: true + }); + return C; +})(); +// object literals +var o = { + f: function () { + let l = 0; + n = l; + }, + f2: function () { + let l = 0; + n = l; + } +}; diff --git a/tests/baselines/reference/letDeclarations-scopes2.errors.txt b/tests/baselines/reference/letDeclarations-scopes2.errors.txt new file mode 100644 index 0000000000000..a786db1104b79 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes2.errors.txt @@ -0,0 +1,42 @@ +tests/cases/compiler/letDeclarations-scopes2.ts(9,5): error TS2304: Cannot find name 'local2'. +tests/cases/compiler/letDeclarations-scopes2.ts(21,5): error TS2304: Cannot find name 'local2'. +tests/cases/compiler/letDeclarations-scopes2.ts(24,1): error TS2304: Cannot find name 'local'. +tests/cases/compiler/letDeclarations-scopes2.ts(26,1): error TS2304: Cannot find name 'local2'. + + +==== tests/cases/compiler/letDeclarations-scopes2.ts (4 errors) ==== + + let global = 0; + + { + let local = 0; + + local; // OK + global; // OK + local2; // Error + ~~~~~~ +!!! error TS2304: Cannot find name 'local2'. + + { + let local2 = 0; + + local; // OK + global; // OK + local2; // OK + } + + local; // OK + global; // OK + local2; // Error + ~~~~~~ +!!! error TS2304: Cannot find name 'local2'. + } + + local; // Error + ~~~~~ +!!! error TS2304: Cannot find name 'local'. + global; // OK + local2; // Error + ~~~~~~ +!!! error TS2304: Cannot find name 'local2'. + \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes2.js b/tests/baselines/reference/letDeclarations-scopes2.js new file mode 100644 index 0000000000000..98d0e791832e0 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes2.js @@ -0,0 +1,49 @@ +//// [letDeclarations-scopes2.ts] + +let global = 0; + +{ + let local = 0; + + local; // OK + global; // OK + local2; // Error + + { + let local2 = 0; + + local; // OK + global; // OK + local2; // OK + } + + local; // OK + global; // OK + local2; // Error +} + +local; // Error +global; // OK +local2; // Error + + +//// [letDeclarations-scopes2.js] +let global = 0; +{ + let local = 0; + local; // OK + global; // OK + local2; // Error + { + let local2 = 0; + local; // OK + global; // OK + local2; // OK + } + local; // OK + global; // OK + local2; // Error +} +local; // Error +global; // OK +local2; // Error diff --git a/tests/cases/compiler/constDeclarations-scopes.ts b/tests/cases/compiler/constDeclarations-scopes.ts new file mode 100644 index 0000000000000..d0c1df425b618 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-scopes.ts @@ -0,0 +1,148 @@ +// @target: ES6 + +// global +const c = "string"; + +var n: number; + +// Control flow statements with blocks +if (true) { + const c = 0; + n = c; +} +else { + const c = 0; + n = c; +} + +while (true) { + const c = 0; + n = c; +} + +do { + const c = 0; + n = c; +} while (true); + +var obj; +with (obj) { + const c = 0; + n = c; +} + +for (var i = 0; i < 10; i++) { + const c = 0; + n = c; +} + +for (var i2 in {}) { + const c = 0; + n = c; +} + +if (true) { + label: const c = 0; + n = c; +} + +while (false) { + label2: label3: label4: const c = 0; + n = c; +} + +// Try/catch/finally +try { + const c = 0; + n = c; +} +catch (e) { + const c = 0; + n = c; +} +finally { + const c = 0; + n = c; +} + +// Switch +switch (0) { + case 0: + const c = 0; + n = c; + break; +} + +// blocks +{ + const c = 0; + n = c; + { + const c = false; + var b: boolean = c; + } +} + +// functions + +function F() { + const c = 0; + n = c; +} + +var F2 = () => { + const c = 0; + n = c; +}; + +var F3 = function () { + const c = 0; + n = c; +}; + +// modules +module m { + const c = 0; + n = c; + + { + const c = false; + var b2: boolean = c; + } +} + +// methods +class C { + constructor() { + const c = 0; + n = c; + } + + method() { + const c = 0; + n = c; + } + + get v() { + const c = 0; + n = c; + return n; + } + + set v(value) { + const c = 0; + n = c; + } +} + +// object literals +var o = { + f() { + const c = 0; + n = c; + }, + f2: () => { + const c = 0; + n = c; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates.ts new file mode 100644 index 0000000000000..841b55af1685b --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates.ts @@ -0,0 +1,77 @@ +// @target: ES6 + +// Errors: redeclaration +let var1 = 0; +let var1 = 0; // error + +let var2 = 0; +const var2 = 0; + +const var3 = 0; +let var3 = 0; + +const var4 = 0; +const var4 = 0; + +var var5 = 0; +let var5 = 0; + +let var6 = 0; +var var6 = 0; + +{ + let var7 = 0; + let var7 = 0; + { + let var8 = 0; + const var8 = 0; + } +} + +switch (0) { + default: + let var9 = 0; + let var9 = 0; +} + +try { + const var10 = 0; + const var10 = 0; +} +catch (e) { + let var11 = 0; + let var11 = 0; +} + +function F1() { + let var12; + let var12; +} + +// OK +var var20 = 0; + +var var20 = 0 +{ + let var20 = 0; + { + let var20 = 0; + } +} + +switch (0) { + default: + let var20 = 0; +} + +try { + let var20 = 0; +} +catch (e) { + let var20 = 0; +} + +function F() { + let var20; +} + diff --git a/tests/cases/compiler/letDeclarations-scopes.ts b/tests/cases/compiler/letDeclarations-scopes.ts new file mode 100644 index 0000000000000..0393f0f295b60 --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes.ts @@ -0,0 +1,156 @@ +// @target: ES6 + +// global +let l = "string"; + +var n: number; + +// Control flow statements with blocks +if (true) { + let l = 0; + n = l; +} +else { + let l = 0; + n = l; +} + +while (true) { + let l = 0; + n = l; +} + +do { + let l = 0; + n = l; +} while (true); + +var obj; +with (obj) { + let l = 0; + n = l; +} + +for (var i = 0; i < 10; i++) { + let l = 0; + n = l; +} + +for (var i2 in {}) { + let l = 0; + n = l; +} + +if (true) { + label: let l = 0; + n = l; +} + +while (false) { + label2: label3: label4: let l = 0; + n = l; +} + +for (let l = 0; n = l; l++) { + let l = true; + var b3: boolean = l; +} + +for (let l in {}) { + +} + +// Try/catch/finally +try { + let l = 0; + n = l; +} +catch (e) { + let l = 0; + n = l; +} +finally { + let l = 0; + n = l; +} + +// Switch +switch (0) { + case 0: + let l = 0; + n = l; + break; +} + +// blocks +{ + let l = 0; + n = l; + { + let l = false; + var b: boolean = l; + } +} + +// functions +function F() { + let l = 0; + n = l; +} + +var F2 = () => { + let l = 0; +n = l; +}; + +var F3 = function () { + let l = 0; +n = l; +}; + +// modules +module m { + let l = 0; + n = l; + + { + let l = false; + var b2: boolean = l; + } +} + +// methods +class C { + constructor() { + let l = 0; + n = l; + } + + method() { + let l = 0; + n = l; + } + + get v() { + let l = 0; + n = l; + return n; + } + + set v(value) { + let l = 0; + n = l; + } +} + +// object literals +var o = { + f() { + let l = 0; +n = l; + }, +f2: () => { + let l = 0; + n = l; + } +} \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes2.ts b/tests/cases/compiler/letDeclarations-scopes2.ts new file mode 100644 index 0000000000000..6f1200a0cb237 --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes2.ts @@ -0,0 +1,27 @@ +// @target: ES6 + +let global = 0; + +{ + let local = 0; + + local; // OK + global; // OK + local2; // Error + + { + let local2 = 0; + + local; // OK + global; // OK + local2; // OK + } + + local; // OK + global; // OK + local2; // Error +} + +local; // Error +global; // OK +local2; // Error From 1dde985f1d66459c079ca84271d951b9aa770ec0 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 13 Oct 2014 22:19:19 -0700 Subject: [PATCH 06/25] Do not allow use of block-scoped variable before its definition --- src/compiler/checker.ts | 15 ++++++++++++ .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 16 ++++++++----- ...eclarations-useBeforeDefinition.errors.txt | 21 ++++++++++++++++ .../constDeclarations-useBeforeDefinition.js | 24 +++++++++++++++++++ ...clarations-useBeforeDefinition2.errors.txt | 11 +++++++++ .../constDeclarations-useBeforeDefinition2.js | 12 ++++++++++ ...eclarations-useBeforeDefinition.errors.txt | 21 ++++++++++++++++ .../letDeclarations-useBeforeDefinition.js | 24 +++++++++++++++++++ ...clarations-useBeforeDefinition2.errors.txt | 11 +++++++++ .../letDeclarations-useBeforeDefinition2.js | 12 ++++++++++ .../reference/letDeclarations3.errors.txt | 18 ++++++++++++++ .../constDeclarations-useBeforeDefinition.ts | 12 ++++++++++ .../constDeclarations-useBeforeDefinition2.ts | 8 +++++++ .../letDeclarations-useBeforeDefinition.ts | 12 ++++++++++ .../letDeclarations-useBeforeDefinition2.ts | 8 +++++++ 16 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition.js create mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition2.js create mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition.js create mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition2.js create mode 100644 tests/baselines/reference/letDeclarations3.errors.txt create mode 100644 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts create mode 100644 tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts create mode 100644 tests/cases/compiler/letDeclarations-useBeforeDefinition.ts create mode 100644 tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 927cc050e2085..08f2654d4d238 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -314,6 +314,21 @@ module ts { if (!s && nameNotFoundMessage) { error(errorLocation, nameNotFoundMessage, nameArg); } + if (s && s.flags & SymbolFlags.BlockScoped) { + var declaration = forEach(s.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined); + Debug.assert(declaration, "Bock-scoped variable declaration is undefined"); + var declarationSourceFile = getSourceFileOfNode(declaration); + var referenceSourceFile = getSourceFileOfNode(errorLocation); + if (declarationSourceFile === referenceSourceFile && declaration.pos > errorLocation.pos) { + error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name)); + } + else if (compilerOptions.out) { + var sourceFiles = program.getSourceFiles(); + if (sourceFiles.indexOf(referenceSourceFile) < sourceFiles.indexOf(declarationSourceFile)) { + error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name)); + } + } + } return s; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 84e10cfec581d..f2a1f6abc033a 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -269,6 +269,7 @@ module ts { Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." }, Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." }, The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." }, + Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fa433e0e772ca..dddd3ddb3d2a8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -451,27 +451,27 @@ "category": "Error", "code": 1151 }, - "'var', 'let' or 'const' expected.": { + "'var', 'let' or 'const' expected.": { "category": "Error", "code": 1152 }, - "'let' variable declarations are only available when targeting ECMAScript 6 and higher.": { + "'let' variable declarations are only available when targeting ECMAScript 6 and higher.": { "category": "Error", "code": 1153 }, - "'const' variable declarations are only available when targeting ECMAScript 6 and higher.": { + "'const' variable declarations are only available when targeting ECMAScript 6 and higher.": { "category": "Error", "code": 1154 }, - "const must be intialized.": { + "const must be intialized.": { "category": "Error", "code": 1155 }, - "const must be declared inside a block.": { + "const must be declared inside a block.": { "category": "Error", "code": 1156 }, - "let must be declared inside a block.": { + "let must be declared inside a block.": { "category": "Error", "code": 1157 }, @@ -1068,6 +1068,10 @@ "category": "Error", "code": 2447 }, + "Block-scoped variable '{0}' used before its declaration.": { + "category": "Error", + "code": 2448 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition.errors.txt b/tests/baselines/reference/constDeclarations-useBeforeDefinition.errors.txt new file mode 100644 index 0000000000000..97cf58c6e9d23 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(3,5): error TS2448: Block-scoped variable 'c1' used before its declaration. +tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(9,5): error TS2448: Block-scoped variable 'v1' used before its declaration. + + +==== tests/cases/compiler/constDeclarations-useBeforeDefinition.ts (2 errors) ==== + + { + c1; + ~~ +!!! error TS2448: Block-scoped variable 'c1' used before its declaration. + const c1 = 0; + } + + var v1; + { + v1; + ~~ +!!! error TS2448: Block-scoped variable 'v1' used before its declaration. + const v1 = 0; + } + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition.js b/tests/baselines/reference/constDeclarations-useBeforeDefinition.js new file mode 100644 index 0000000000000..4fe0e64f27542 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition.js @@ -0,0 +1,24 @@ +//// [constDeclarations-useBeforeDefinition.ts] + +{ + c1; + const c1 = 0; +} + +var v1; +{ + v1; + const v1 = 0; +} + + +//// [constDeclarations-useBeforeDefinition.js] +{ + c1; + const c1 = 0; +} +var v1; +{ + v1; + const v1 = 0; +} diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt new file mode 100644 index 0000000000000..a4d28f5187857 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'c' used before its declaration. + + +==== tests/cases/compiler/file1.ts (1 errors) ==== + + c; + ~ +!!! error TS2448: Block-scoped variable 'c' used before its declaration. + +==== tests/cases/compiler/file2.ts (0 errors) ==== + const c = 0; \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.js b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.js new file mode 100644 index 0000000000000..7d1f4cf572584 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts] //// + +//// [file1.ts] + +c; + +//// [file2.ts] +const c = 0; + +//// [out.js] +c; +const c = 0; diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition.errors.txt b/tests/baselines/reference/letDeclarations-useBeforeDefinition.errors.txt new file mode 100644 index 0000000000000..74c354f4ff26f --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/letDeclarations-useBeforeDefinition.ts(3,5): error TS2448: Block-scoped variable 'l1' used before its declaration. +tests/cases/compiler/letDeclarations-useBeforeDefinition.ts(9,5): error TS2448: Block-scoped variable 'v1' used before its declaration. + + +==== tests/cases/compiler/letDeclarations-useBeforeDefinition.ts (2 errors) ==== + + { + l1; + ~~ +!!! error TS2448: Block-scoped variable 'l1' used before its declaration. + let l1; + } + + var v1; + { + v1; + ~~ +!!! error TS2448: Block-scoped variable 'v1' used before its declaration. + let v1 = 0; + } + \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition.js b/tests/baselines/reference/letDeclarations-useBeforeDefinition.js new file mode 100644 index 0000000000000..be1f9a127f49a --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition.js @@ -0,0 +1,24 @@ +//// [letDeclarations-useBeforeDefinition.ts] + +{ + l1; + let l1; +} + +var v1; +{ + v1; + let v1 = 0; +} + + +//// [letDeclarations-useBeforeDefinition.js] +{ + l1; + let l1; +} +var v1; +{ + v1; + let v1 = 0; +} diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt new file mode 100644 index 0000000000000..5b8633312d9a9 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'l' used before its declaration. + + +==== tests/cases/compiler/file1.ts (1 errors) ==== + + l; + ~ +!!! error TS2448: Block-scoped variable 'l' used before its declaration. + +==== tests/cases/compiler/file2.ts (0 errors) ==== + const l = 0; \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.js b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.js new file mode 100644 index 0000000000000..35560edd1c887 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts] //// + +//// [file1.ts] + +l; + +//// [file2.ts] +const l = 0; + +//// [out.js] +l; +const l = 0; diff --git a/tests/baselines/reference/letDeclarations3.errors.txt b/tests/baselines/reference/letDeclarations3.errors.txt new file mode 100644 index 0000000000000..8c4d925ce133f --- /dev/null +++ b/tests/baselines/reference/letDeclarations3.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/letDeclarations3.ts(3,5): error TS2300: Duplicate identifier 'l1'. +tests/cases/compiler/letDeclarations3.ts(3,9): error TS2300: Duplicate identifier 'l1'. +tests/cases/compiler/letDeclarations3.ts(3,13): error TS2300: Duplicate identifier 'l1'. + + +==== tests/cases/compiler/letDeclarations3.ts (3 errors) ==== + + // Duplicate variables + let l1, l1, l1; + ~~ +!!! error TS2300: Duplicate identifier 'l1'. + ~~ +!!! error TS2300: Duplicate identifier 'l1'. + ~~ +!!! error TS2300: Duplicate identifier 'l1'. + + // unexpected 'let' + let l2, let, l3; \ No newline at end of file diff --git a/tests/cases/compiler/constDeclarations-useBeforeDefinition.ts b/tests/cases/compiler/constDeclarations-useBeforeDefinition.ts new file mode 100644 index 0000000000000..ec793fda4846f --- /dev/null +++ b/tests/cases/compiler/constDeclarations-useBeforeDefinition.ts @@ -0,0 +1,12 @@ +// @target: ES6 + +{ + c1; + const c1 = 0; +} + +var v1; +{ + v1; + const v1 = 0; +} diff --git a/tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts b/tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts new file mode 100644 index 0000000000000..c34bb4012bfc2 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts @@ -0,0 +1,8 @@ +// @target: ES6 +// @out: out.js + +// @Filename: file1.ts +c; + +// @Filename: file2.ts +const c = 0; \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-useBeforeDefinition.ts b/tests/cases/compiler/letDeclarations-useBeforeDefinition.ts new file mode 100644 index 0000000000000..671762d4a45ea --- /dev/null +++ b/tests/cases/compiler/letDeclarations-useBeforeDefinition.ts @@ -0,0 +1,12 @@ +// @target: ES6 + +{ + l1; + let l1; +} + +var v1; +{ + v1; + let v1 = 0; +} diff --git a/tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts b/tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts new file mode 100644 index 0000000000000..a6cbc729b94c4 --- /dev/null +++ b/tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts @@ -0,0 +1,8 @@ +// @target: ES6 +// @out: out.js + +// @Filename: file1.ts +l; + +// @Filename: file2.ts +const l = 0; \ No newline at end of file From 318575ce75c2c10e714336a9326405c63f49affd Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 14 Oct 2014 14:51:28 -0700 Subject: [PATCH 07/25] Ensure duplicate let/const declarations accross files are reported --- src/compiler/checker.ts | 1 + .../letDeclarations-scopes-duplicates2.errors.txt | 11 +++++++++++ .../reference/letDeclarations-scopes-duplicates2.js | 13 +++++++++++++ .../letDeclarations-scopes-duplicates3.errors.txt | 11 +++++++++++ .../reference/letDeclarations-scopes-duplicates3.js | 13 +++++++++++++ .../letDeclarations-scopes-duplicates4.errors.txt | 11 +++++++++++ .../reference/letDeclarations-scopes-duplicates4.js | 13 +++++++++++++ .../letDeclarations-scopes-duplicates5.errors.txt | 11 +++++++++++ .../reference/letDeclarations-scopes-duplicates5.js | 13 +++++++++++++ .../letDeclarations-scopes-duplicates6.errors.txt | 11 +++++++++++ .../reference/letDeclarations-scopes-duplicates6.js | 13 +++++++++++++ .../letDeclarations-scopes-duplicates7.errors.txt | 11 +++++++++++ .../reference/letDeclarations-scopes-duplicates7.js | 13 +++++++++++++ .../compiler/letDeclarations-scopes-duplicates2.ts | 7 +++++++ .../compiler/letDeclarations-scopes-duplicates3.ts | 7 +++++++ .../compiler/letDeclarations-scopes-duplicates4.ts | 7 +++++++ .../compiler/letDeclarations-scopes-duplicates5.ts | 7 +++++++ .../compiler/letDeclarations-scopes-duplicates6.ts | 7 +++++++ .../compiler/letDeclarations-scopes-duplicates7.ts | 7 +++++++ 19 files changed, 187 insertions(+) create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates2.js create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates3.js create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates4.js create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates5.js create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates6.js create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt create mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates7.js create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates2.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates3.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates4.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates5.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates6.ts create mode 100644 tests/cases/compiler/letDeclarations-scopes-duplicates7.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 08f2654d4d238..76533abf50c8b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -172,6 +172,7 @@ module ts { function getExcludedSymbolFlags(flags: SymbolFlags): SymbolFlags { var result: SymbolFlags = 0; + if (flags & SymbolFlags.BlockScoped) result |= SymbolFlags.BlockScopedExcludes; if (flags & SymbolFlags.Variable) result |= SymbolFlags.VariableExcludes; if (flags & SymbolFlags.Property) result |= SymbolFlags.PropertyExcludes; if (flags & SymbolFlags.EnumMember) result |= SymbolFlags.EnumMemberExcludes; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt new file mode 100644 index 0000000000000..324385b406e9c --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + let var1 = 0; + +==== tests/cases/compiler/file2.ts (1 errors) ==== + let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates2.js b/tests/baselines/reference/letDeclarations-scopes-duplicates2.js new file mode 100644 index 0000000000000..9b35bd81c76fa --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates2.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/letDeclarations-scopes-duplicates2.ts] //// + +//// [file1.ts] + +let var1 = 0; + +//// [file2.ts] +let var1 = 0; + +//// [file1.js] +let var1 = 0; +//// [file2.js] +let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt new file mode 100644 index 0000000000000..a85ca8bad046b --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,7): error TS2300: Duplicate identifier 'var1'. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + let var1 = 0; + +==== tests/cases/compiler/file2.ts (1 errors) ==== + const var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates3.js b/tests/baselines/reference/letDeclarations-scopes-duplicates3.js new file mode 100644 index 0000000000000..e74caf37219a1 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates3.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/letDeclarations-scopes-duplicates3.ts] //// + +//// [file1.ts] + +let var1 = 0; + +//// [file2.ts] +const var1 = 0; + +//// [file1.js] +let var1 = 0; +//// [file2.js] +const var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt new file mode 100644 index 0000000000000..1a43932040f6e --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + const var1 = 0; + +==== tests/cases/compiler/file2.ts (1 errors) ==== + let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates4.js b/tests/baselines/reference/letDeclarations-scopes-duplicates4.js new file mode 100644 index 0000000000000..ac338e31c7291 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates4.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/letDeclarations-scopes-duplicates4.ts] //// + +//// [file1.ts] + +const var1 = 0; + +//// [file2.ts] +let var1 = 0; + +//// [file1.js] +const var1 = 0; +//// [file2.js] +let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt new file mode 100644 index 0000000000000..49737b1774091 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,7): error TS2300: Duplicate identifier 'var1'. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + const var1 = 0; + +==== tests/cases/compiler/file2.ts (1 errors) ==== + const var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates5.js b/tests/baselines/reference/letDeclarations-scopes-duplicates5.js new file mode 100644 index 0000000000000..2424c91ab90dd --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates5.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/letDeclarations-scopes-duplicates5.ts] //// + +//// [file1.ts] + +const var1 = 0; + +//// [file2.ts] +const var1 = 0; + +//// [file1.js] +const var1 = 0; +//// [file2.js] +const var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt new file mode 100644 index 0000000000000..2904227c8f8a3 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + var var1 = 0; + +==== tests/cases/compiler/file2.ts (1 errors) ==== + let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates6.js b/tests/baselines/reference/letDeclarations-scopes-duplicates6.js new file mode 100644 index 0000000000000..24edc0b7bde49 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates6.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/letDeclarations-scopes-duplicates6.ts] //// + +//// [file1.ts] + +var var1 = 0; + +//// [file2.ts] +let var1 = 0; + +//// [file1.js] +var var1 = 0; +//// [file2.js] +let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt new file mode 100644 index 0000000000000..8dd0418b60277 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + let var1 = 0; + +==== tests/cases/compiler/file2.ts (1 errors) ==== + var var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates7.js b/tests/baselines/reference/letDeclarations-scopes-duplicates7.js new file mode 100644 index 0000000000000..4cbc359e2c255 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates7.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/letDeclarations-scopes-duplicates7.ts] //// + +//// [file1.ts] + +let var1 = 0; + +//// [file2.ts] +var var1 = 0; + +//// [file1.js] +let var1 = 0; +//// [file2.js] +var var1 = 0; diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates2.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates2.ts new file mode 100644 index 0000000000000..40ddc14fc3f1a --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates2.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +let var1 = 0; + +// @Filename: file2.ts +let var1 = 0; \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates3.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates3.ts new file mode 100644 index 0000000000000..1f10efa53850c --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates3.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +let var1 = 0; + +// @Filename: file2.ts +const var1 = 0; \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates4.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates4.ts new file mode 100644 index 0000000000000..150d434a2bc14 --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates4.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +const var1 = 0; + +// @Filename: file2.ts +let var1 = 0; \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates5.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates5.ts new file mode 100644 index 0000000000000..da24985349910 --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates5.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +const var1 = 0; + +// @Filename: file2.ts +const var1 = 0; \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates6.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates6.ts new file mode 100644 index 0000000000000..f71b7623790cc --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates6.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +var var1 = 0; + +// @Filename: file2.ts +let var1 = 0; \ No newline at end of file diff --git a/tests/cases/compiler/letDeclarations-scopes-duplicates7.ts b/tests/cases/compiler/letDeclarations-scopes-duplicates7.ts new file mode 100644 index 0000000000000..829fda0c927bc --- /dev/null +++ b/tests/cases/compiler/letDeclarations-scopes-duplicates7.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +let var1 = 0; + +// @Filename: file2.ts +var var1 = 0; \ No newline at end of file From cffc62aa1bc9b1282707365475e18bd6af200775 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 14 Oct 2014 15:18:44 -0700 Subject: [PATCH 08/25] Report duplicate identifier errors on all locations for merged declarations to align with local declarations --- src/compiler/checker.ts | 3 + ...tionTypeArgumentArrayAssignment.errors.txt | 15 ----- .../functionTypeArgumentArrayAssignment.js | 23 +++++--- .../functionTypeArgumentArrayAssignment.types | 27 +++++++++ .../reference/instanceofOperator.errors.txt | 47 ++++++++-------- .../baselines/reference/instanceofOperator.js | 53 ++++++++++-------- ...Declarations-scopes-duplicates2.errors.txt | 5 +- ...Declarations-scopes-duplicates3.errors.txt | 5 +- ...Declarations-scopes-duplicates4.errors.txt | 5 +- ...Declarations-scopes-duplicates5.errors.txt | 5 +- ...Declarations-scopes-duplicates6.errors.txt | 5 +- ...Declarations-scopes-duplicates7.errors.txt | 5 +- .../reference/letDeclarations3.errors.txt | 18 ------ .../parserOptionalTypeMembers1.errors.txt | 23 -------- .../reference/parserOptionalTypeMembers1.js | 2 +- .../parserOptionalTypeMembers1.types | 23 ++++++++ .../amd/declareVariableCollision.errors.txt | 5 +- .../node/declareVariableCollision.errors.txt | 5 +- .../functionTypeArgumentArrayAssignment.ts | 14 +++-- tests/cases/compiler/instanceofOperator.ts | Bin 1006 -> 1120 bytes .../ecmascript5/parserOptionalTypeMembers1.ts | 2 +- 21 files changed, 161 insertions(+), 129 deletions(-) delete mode 100644 tests/baselines/reference/functionTypeArgumentArrayAssignment.errors.txt create mode 100644 tests/baselines/reference/functionTypeArgumentArrayAssignment.types delete mode 100644 tests/baselines/reference/letDeclarations3.errors.txt delete mode 100644 tests/baselines/reference/parserOptionalTypeMembers1.errors.txt create mode 100644 tests/baselines/reference/parserOptionalTypeMembers1.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76533abf50c8b..f7d20733aa9b1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -226,6 +226,9 @@ module ts { forEach(source.declarations, node => { error(node.name ? node.name : node, Diagnostics.Duplicate_identifier_0, symbolToString(source)); }); + forEach(target.declarations, node => { + error(node.name ? node.name : node, Diagnostics.Duplicate_identifier_0, symbolToString(source)); + }); } } diff --git a/tests/baselines/reference/functionTypeArgumentArrayAssignment.errors.txt b/tests/baselines/reference/functionTypeArgumentArrayAssignment.errors.txt deleted file mode 100644 index 9897286a62438..0000000000000 --- a/tests/baselines/reference/functionTypeArgumentArrayAssignment.errors.txt +++ /dev/null @@ -1,15 +0,0 @@ -tests/cases/compiler/functionTypeArgumentArrayAssignment.ts(3,2): error TS2300: Duplicate identifier 'length'. - - -==== tests/cases/compiler/functionTypeArgumentArrayAssignment.ts (1 errors) ==== - interface Array { - foo: T; - length: number; - ~~~~~~ -!!! error TS2300: Duplicate identifier 'length'. - } - - function map() { - var ys: U[] = []; - } - \ No newline at end of file diff --git a/tests/baselines/reference/functionTypeArgumentArrayAssignment.js b/tests/baselines/reference/functionTypeArgumentArrayAssignment.js index 9569c4566d818..38188c3505a83 100644 --- a/tests/baselines/reference/functionTypeArgumentArrayAssignment.js +++ b/tests/baselines/reference/functionTypeArgumentArrayAssignment.js @@ -1,15 +1,20 @@ //// [functionTypeArgumentArrayAssignment.ts] -interface Array { - foo: T; - length: number; -} +module test { + interface Array { + foo: T; + length: number; + } -function map() { -var ys: U[] = []; + function map() { + var ys: U[] = []; + } } //// [functionTypeArgumentArrayAssignment.js] -function map() { - var ys = []; -} +var test; +(function (test) { + function map() { + var ys = []; + } +})(test || (test = {})); diff --git a/tests/baselines/reference/functionTypeArgumentArrayAssignment.types b/tests/baselines/reference/functionTypeArgumentArrayAssignment.types new file mode 100644 index 0000000000000..73375ac5e21f0 --- /dev/null +++ b/tests/baselines/reference/functionTypeArgumentArrayAssignment.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/functionTypeArgumentArrayAssignment.ts === +module test { +>test : typeof test + + interface Array { +>Array : Array +>T : T + + foo: T; +>foo : T +>T : T + + length: number; +>length : number + } + + function map() { +>map : () => void +>U : U + + var ys: U[] = []; +>ys : U[] +>U : U +>[] : U[] + } +} + diff --git a/tests/baselines/reference/instanceofOperator.errors.txt b/tests/baselines/reference/instanceofOperator.errors.txt index 15d5518874141..2fa517c53be8b 100644 --- a/tests/baselines/reference/instanceofOperator.errors.txt +++ b/tests/baselines/reference/instanceofOperator.errors.txt @@ -1,43 +1,42 @@ -tests/cases/compiler/instanceofOperator.ts(6,7): error TS2300: Duplicate identifier 'Object'. -tests/cases/compiler/instanceofOperator.ts(11,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -tests/cases/compiler/instanceofOperator.ts(14,16): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -tests/cases/compiler/instanceofOperator.ts(15,19): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. -tests/cases/compiler/instanceofOperator.ts(18,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -tests/cases/compiler/instanceofOperator.ts(20,1): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +tests/cases/compiler/instanceofOperator.ts(12,5): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +tests/cases/compiler/instanceofOperator.ts(15,20): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +tests/cases/compiler/instanceofOperator.ts(16,23): error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. +tests/cases/compiler/instanceofOperator.ts(19,5): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. +tests/cases/compiler/instanceofOperator.ts(21,5): error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. -==== tests/cases/compiler/instanceofOperator.ts (6 errors) ==== +==== tests/cases/compiler/instanceofOperator.ts (5 errors) ==== // Spec: // The instanceof operator requires the left operand to be of type Any or an object type, and the right // operand to be of type Any or a subtype of the ‘Function’ interface type. The result is always of the // Boolean primitive type. - class Object { } - ~~~~~~ -!!! error TS2300: Duplicate identifier 'Object'. - var obj: Object; + module test { + class Object { } + var obj: Object; - 4 instanceof null; - ~ + 4 instanceof null; + ~ !!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. - // Error and should be error - obj instanceof 4; - ~ + // Error and should be error + obj instanceof 4; + ~ !!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. - Object instanceof obj; - ~~~ + Object instanceof obj; + ~~~ !!! error TS2359: The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type. - // Error on left hand side - null instanceof null; - ~~~~ + // Error on left hand side + null instanceof null; + ~~~~ !!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. - obj instanceof Object; - undefined instanceof undefined; - ~~~~~~~~~ + obj instanceof Object; + undefined instanceof undefined; + ~~~~~~~~~ !!! error TS2358: The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter. + } \ No newline at end of file diff --git a/tests/baselines/reference/instanceofOperator.js b/tests/baselines/reference/instanceofOperator.js index 7620c3e83f4fc..3c6970b66a4f1 100644 --- a/tests/baselines/reference/instanceofOperator.js +++ b/tests/baselines/reference/instanceofOperator.js @@ -4,21 +4,23 @@ // operand to be of type Any or a subtype of the ‘Function’ interface type. The result is always of the // Boolean primitive type. -class Object { } -var obj: Object; +module test { + class Object { } + var obj: Object; -4 instanceof null; + 4 instanceof null; -// Error and should be error -obj instanceof 4; -Object instanceof obj; + // Error and should be error + obj instanceof 4; + Object instanceof obj; -// Error on left hand side -null instanceof null; -obj instanceof Object; -undefined instanceof undefined; + // Error on left hand side + null instanceof null; + obj instanceof Object; + undefined instanceof undefined; +} @@ -27,17 +29,20 @@ undefined instanceof undefined; // The instanceof operator requires the left operand to be of type Any or an object type, and the right // operand to be of type Any or a subtype of the ‘Function’ interface type. The result is always of the // Boolean primitive type. -var Object = (function () { - function Object() { - } - return Object; -})(); -var obj; -4 instanceof null; -// Error and should be error -obj instanceof 4; -Object instanceof obj; -// Error on left hand side -null instanceof null; -obj instanceof Object; -undefined instanceof undefined; +var test; +(function (test) { + var Object = (function () { + function Object() { + } + return Object; + })(); + var obj; + 4 instanceof null; + // Error and should be error + obj instanceof 4; + Object instanceof obj; + // Error on left hand side + null instanceof null; + obj instanceof Object; + undefined instanceof undefined; +})(test || (test = {})); diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt index 324385b406e9c..b948b1b7a1440 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt @@ -1,9 +1,12 @@ +tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. -==== tests/cases/compiler/file1.ts (0 errors) ==== +==== tests/cases/compiler/file1.ts (1 errors) ==== let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt index a85ca8bad046b..7222fb9bf22fa 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt @@ -1,9 +1,12 @@ +tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. tests/cases/compiler/file2.ts(1,7): error TS2300: Duplicate identifier 'var1'. -==== tests/cases/compiler/file1.ts (0 errors) ==== +==== tests/cases/compiler/file1.ts (1 errors) ==== let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== const var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt index 1a43932040f6e..e626af7e52a56 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt @@ -1,9 +1,12 @@ +tests/cases/compiler/file1.ts(2,7): error TS2300: Duplicate identifier 'var1'. tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. -==== tests/cases/compiler/file1.ts (0 errors) ==== +==== tests/cases/compiler/file1.ts (1 errors) ==== const var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt index 49737b1774091..ac5f79dd5a8d4 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt @@ -1,9 +1,12 @@ +tests/cases/compiler/file1.ts(2,7): error TS2300: Duplicate identifier 'var1'. tests/cases/compiler/file2.ts(1,7): error TS2300: Duplicate identifier 'var1'. -==== tests/cases/compiler/file1.ts (0 errors) ==== +==== tests/cases/compiler/file1.ts (1 errors) ==== const var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== const var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt index 2904227c8f8a3..0d3a4726bd3f4 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt @@ -1,9 +1,12 @@ +tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. -==== tests/cases/compiler/file1.ts (0 errors) ==== +==== tests/cases/compiler/file1.ts (1 errors) ==== var var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt index 8dd0418b60277..dafbae9708030 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt @@ -1,9 +1,12 @@ +tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. -==== tests/cases/compiler/file1.ts (0 errors) ==== +==== tests/cases/compiler/file1.ts (1 errors) ==== let var1 = 0; + ~~~~ +!!! error TS2300: Duplicate identifier 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== var var1 = 0; diff --git a/tests/baselines/reference/letDeclarations3.errors.txt b/tests/baselines/reference/letDeclarations3.errors.txt deleted file mode 100644 index 8c4d925ce133f..0000000000000 --- a/tests/baselines/reference/letDeclarations3.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -tests/cases/compiler/letDeclarations3.ts(3,5): error TS2300: Duplicate identifier 'l1'. -tests/cases/compiler/letDeclarations3.ts(3,9): error TS2300: Duplicate identifier 'l1'. -tests/cases/compiler/letDeclarations3.ts(3,13): error TS2300: Duplicate identifier 'l1'. - - -==== tests/cases/compiler/letDeclarations3.ts (3 errors) ==== - - // Duplicate variables - let l1, l1, l1; - ~~ -!!! error TS2300: Duplicate identifier 'l1'. - ~~ -!!! error TS2300: Duplicate identifier 'l1'. - ~~ -!!! error TS2300: Duplicate identifier 'l1'. - - // unexpected 'let' - let l2, let, l3; \ No newline at end of file diff --git a/tests/baselines/reference/parserOptionalTypeMembers1.errors.txt b/tests/baselines/reference/parserOptionalTypeMembers1.errors.txt deleted file mode 100644 index 0279ad37777ef..0000000000000 --- a/tests/baselines/reference/parserOptionalTypeMembers1.errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts(2,5): error TS2300: Duplicate identifier 'configurable'. -tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts(3,5): error TS2300: Duplicate identifier 'enumerable'. -tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts(4,5): error TS2300: Duplicate identifier 'value'. -tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts(5,5): error TS2300: Duplicate identifier 'writable'. - - -==== tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts (4 errors) ==== - interface PropertyDescriptor { - configurable?: boolean; - ~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier 'configurable'. - enumerable?: boolean; - ~~~~~~~~~~ -!!! error TS2300: Duplicate identifier 'enumerable'. - value?: any; - ~~~~~ -!!! error TS2300: Duplicate identifier 'value'. - writable?: boolean; - ~~~~~~~~ -!!! error TS2300: Duplicate identifier 'writable'. - get?(): any; - set?(v: any): void; - } \ No newline at end of file diff --git a/tests/baselines/reference/parserOptionalTypeMembers1.js b/tests/baselines/reference/parserOptionalTypeMembers1.js index 5dfb0adfe8260..757887e540966 100644 --- a/tests/baselines/reference/parserOptionalTypeMembers1.js +++ b/tests/baselines/reference/parserOptionalTypeMembers1.js @@ -1,5 +1,5 @@ //// [parserOptionalTypeMembers1.ts] -interface PropertyDescriptor { +interface PropertyDescriptor2 { configurable?: boolean; enumerable?: boolean; value?: any; diff --git a/tests/baselines/reference/parserOptionalTypeMembers1.types b/tests/baselines/reference/parserOptionalTypeMembers1.types new file mode 100644 index 0000000000000..7ede18a1d9246 --- /dev/null +++ b/tests/baselines/reference/parserOptionalTypeMembers1.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts === +interface PropertyDescriptor2 { +>PropertyDescriptor2 : PropertyDescriptor2 + + configurable?: boolean; +>configurable : boolean + + enumerable?: boolean; +>enumerable : boolean + + value?: any; +>value : any + + writable?: boolean; +>writable : boolean + + get?(): any; +>get : () => any + + set?(v: any): void; +>set : (v: any) => void +>v : any +} diff --git a/tests/baselines/reference/project/declareVariableCollision/amd/declareVariableCollision.errors.txt b/tests/baselines/reference/project/declareVariableCollision/amd/declareVariableCollision.errors.txt index 5dc0a63d7eb11..64ec399fabf71 100644 --- a/tests/baselines/reference/project/declareVariableCollision/amd/declareVariableCollision.errors.txt +++ b/tests/baselines/reference/project/declareVariableCollision/amd/declareVariableCollision.errors.txt @@ -1,3 +1,4 @@ +in1.d.ts(1,8): error TS2300: Duplicate identifier 'a'. in2.d.ts(1,8): error TS2300: Duplicate identifier 'a'. @@ -14,8 +15,10 @@ in2.d.ts(1,8): error TS2300: Duplicate identifier 'a'. class MyClass{ } } } -==== in1.d.ts (0 errors) ==== +==== in1.d.ts (1 errors) ==== import a = A; + ~ +!!! error TS2300: Duplicate identifier 'a'. ==== in2.d.ts (1 errors) ==== import a = A; ~ diff --git a/tests/baselines/reference/project/declareVariableCollision/node/declareVariableCollision.errors.txt b/tests/baselines/reference/project/declareVariableCollision/node/declareVariableCollision.errors.txt index 5dc0a63d7eb11..64ec399fabf71 100644 --- a/tests/baselines/reference/project/declareVariableCollision/node/declareVariableCollision.errors.txt +++ b/tests/baselines/reference/project/declareVariableCollision/node/declareVariableCollision.errors.txt @@ -1,3 +1,4 @@ +in1.d.ts(1,8): error TS2300: Duplicate identifier 'a'. in2.d.ts(1,8): error TS2300: Duplicate identifier 'a'. @@ -14,8 +15,10 @@ in2.d.ts(1,8): error TS2300: Duplicate identifier 'a'. class MyClass{ } } } -==== in1.d.ts (0 errors) ==== +==== in1.d.ts (1 errors) ==== import a = A; + ~ +!!! error TS2300: Duplicate identifier 'a'. ==== in2.d.ts (1 errors) ==== import a = A; ~ diff --git a/tests/cases/compiler/functionTypeArgumentArrayAssignment.ts b/tests/cases/compiler/functionTypeArgumentArrayAssignment.ts index 77fbb74d7ad3e..91cf2d551b9d4 100644 --- a/tests/cases/compiler/functionTypeArgumentArrayAssignment.ts +++ b/tests/cases/compiler/functionTypeArgumentArrayAssignment.ts @@ -1,8 +1,10 @@ -interface Array { - foo: T; - length: number; -} +module test { + interface Array { + foo: T; + length: number; + } -function map() { -var ys: U[] = []; + function map() { + var ys: U[] = []; + } } diff --git a/tests/cases/compiler/instanceofOperator.ts b/tests/cases/compiler/instanceofOperator.ts index 60b724149ce5d8769df19128b9542a359313f421..f9b304de1136787f2307ea99fe8feebba1f74b1a 100644 GIT binary patch delta 202 zcmaFI{(xh{FGkf|hJ1z;hEj$chExUxh7urI3?vm8su_40xPUYmPX5WL$_``8G8uA0 z*$gI=1DVyikyQ#Z3s3H2(&B}w$Y)4m$eO4q$#247jbh|oCR4bPg3Ok1wkNYbhUUrB Xn1xs&E;-LEI(Zkf0aq>9Fp$jv^I#zc delta 78 zcmaFB@s54NFUH9VOe&Lom<$+ACMrr!p2x(+sldR?zy-pSw=>yJ{==j;S&P|ZavHM* admck6Lk>d@L?PegJIn@?MOd6zK*|AE%@gMU diff --git a/tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts b/tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts index fb3b96952feb3..331d0faed9e41 100644 --- a/tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts +++ b/tests/cases/conformance/parser/ecmascript5/parserOptionalTypeMembers1.ts @@ -1,4 +1,4 @@ -interface PropertyDescriptor { +interface PropertyDescriptor2 { configurable?: boolean; enumerable?: boolean; value?: any; From f5c27400939ee5584a2f18575ad7d6c9f75ef2a3 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 14 Oct 2014 16:52:12 -0700 Subject: [PATCH 09/25] Flag assignments to a const --- src/compiler/checker.ts | 30 ++++- .../diagnosticInformationMap.generated.ts | 2 + src/compiler/diagnosticMessages.json | 8 ++ .../constDeclarations-access.errors.txt | 11 ++ .../reference/constDeclarations-access.js | 13 +++ .../constDeclarations-access2.errors.txt | 89 ++++++++++++++ .../reference/constDeclarations-access2.js | 71 ++++++++++++ .../reference/letDeclarations-access.js | 70 +++++++++++ .../reference/letDeclarations-access.types | 109 ++++++++++++++++++ .../compiler/constDeclarations-access.ts | 7 ++ .../compiler/constDeclarations-access2.ts | 38 ++++++ .../cases/compiler/letDeclarations-access.ts | 38 ++++++ 12 files changed, 480 insertions(+), 6 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-access.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-access.js create mode 100644 tests/baselines/reference/constDeclarations-access2.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-access2.js create mode 100644 tests/baselines/reference/letDeclarations-access.js create mode 100644 tests/baselines/reference/letDeclarations-access.types create mode 100644 tests/cases/compiler/constDeclarations-access.ts create mode 100644 tests/cases/compiler/constDeclarations-access2.ts create mode 100644 tests/cases/compiler/letDeclarations-access.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f7d20733aa9b1..5bba99c6d439c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -318,7 +318,9 @@ module ts { if (!s && nameNotFoundMessage) { error(errorLocation, nameNotFoundMessage, nameArg); } + if (s && s.flags & SymbolFlags.BlockScoped) { + // Block-scoped variables can not be used before thier definition var declaration = forEach(s.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined); Debug.assert(declaration, "Bock-scoped variable declaration is undefined"); var declarationSourceFile = getSourceFileOfNode(declaration); @@ -4923,7 +4925,7 @@ module ts { return true; } - function checkReferenceExpression(n: Node, message: DiagnosticMessage): boolean { + function checkReferenceExpression(n: Node, invalidReferenceMessage: DiagnosticMessage, constantVarianleMessage: DiagnosticMessage): boolean { function findSymbol(n: Node): Symbol { var symbol = getNodeLinks(n).resolvedSymbol; // Because we got the symbol from the resolvedSymbol property, it might be of kind @@ -4962,8 +4964,20 @@ module ts { } } + function isConstVariableReference(n: Node) { + if (n.kind === SyntaxKind.Identifier) { + var symbol = findSymbol(n); + return symbol && (symbol.flags & SymbolFlags.Variable) !== 0 && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0; + } + return false; + } + if (!isReferenceOrErrorExpression(n)) { - error(n, message); + error(n, invalidReferenceMessage); + return false; + } + if (isConstVariableReference(n)) { + error(n, constantVarianleMessage); return false; } return true; @@ -4988,7 +5002,9 @@ module ts { var ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors - checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer); + checkReferenceExpression(node.operand, + Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer, + Diagnostics.The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant); } return numberType; } @@ -5000,7 +5016,9 @@ module ts { var ok = checkArithmeticOperandType(node.operand, operandType, Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors - checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer); + checkReferenceExpression(node.operand, + Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_property_or_indexer, + Diagnostics.The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant); } return numberType; } @@ -5177,7 +5195,7 @@ module ts { // requires VarExpr to be classified as a reference // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1) // and the type of the non - compound operation to be assignable to the type of VarExpr. - var ok = checkReferenceExpression(node.left, Diagnostics.Invalid_left_hand_side_of_assignment_expression); + var ok = checkReferenceExpression(node.left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant); // Use default messages if (ok) { // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported @@ -6252,7 +6270,7 @@ module ts { } else { // run check only former check succeeded to avoid cascading errors - checkReferenceExpression(node.variable, Diagnostics.Invalid_left_hand_side_in_for_in_statement); + checkReferenceExpression(node.variable, Diagnostics.Invalid_left_hand_side_in_for_in_statement, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant); } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index f2a1f6abc033a..5d4acbbc67b5c 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -270,6 +270,8 @@ module ts { Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." }, The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." }, Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration." }, + The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: { code: 2449, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator cannot be a constant." }, + Left_hand_side_of_assignment_expression_cannot_be_a_constant: { code: 2450, category: DiagnosticCategory.Error, key: "Left-hand side of assignment expression cannot be a constant." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index dddd3ddb3d2a8..937d6cdd614a1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1072,6 +1072,14 @@ "category": "Error", "code": 2448 }, + "The operand of an increment or decrement operator cannot be a constant.": { + "category": "Error", + "code": 2449 + }, + "Left-hand side of assignment expression cannot be a constant.": { + "category": "Error", + "code": 2450 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/constDeclarations-access.errors.txt b/tests/baselines/reference/constDeclarations-access.errors.txt new file mode 100644 index 0000000000000..04b942aec09ef --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file2.ts(1,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. + + +==== tests/cases/compiler/file1.ts (0 errors) ==== + + const x = 0 + +==== tests/cases/compiler/file2.ts (1 errors) ==== + x++; + ~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-access.js b/tests/baselines/reference/constDeclarations-access.js new file mode 100644 index 0000000000000..ba913f2d5fce9 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/constDeclarations-access.ts] //// + +//// [file1.ts] + +const x = 0 + +//// [file2.ts] +x++; + +//// [file1.js] +const x = 0; +//// [file2.js] +x++; diff --git a/tests/baselines/reference/constDeclarations-access2.errors.txt b/tests/baselines/reference/constDeclarations-access2.errors.txt new file mode 100644 index 0000000000000..f3bf7d1d750ce --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access2.errors.txt @@ -0,0 +1,89 @@ +tests/cases/compiler/constDeclarations-access2.ts(5,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(6,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(7,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(8,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(9,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(10,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(11,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(12,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(13,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(14,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(15,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(16,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(18,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(19,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(20,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(21,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. + + +==== tests/cases/compiler/constDeclarations-access2.ts (16 errors) ==== + + const x = 0 + + // Errors + x = 1; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x += 2; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x -= 3; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x *= 4; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x /= 5; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x %= 6; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x <<= 7; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x >>= 8; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x >>>= 9; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x &= 10; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x |= 11; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + x ^= 12; + ~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + + x++; + ~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + x--; + ~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + ++x; + ~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + --x; + ~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + // OK + var a = x + 1; + + function f(v: number) { } + f(x); + + if (x) { } + + x; + (x); + + -x; + +x; + + x.toString(); + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-access2.js b/tests/baselines/reference/constDeclarations-access2.js new file mode 100644 index 0000000000000..e2a1bcd9fa573 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access2.js @@ -0,0 +1,71 @@ +//// [constDeclarations-access2.ts] + +const x = 0 + +// Errors +x = 1; +x += 2; +x -= 3; +x *= 4; +x /= 5; +x %= 6; +x <<= 7; +x >>= 8; +x >>>= 9; +x &= 10; +x |= 11; +x ^= 12; + +x++; +x--; +++x; +--x; + +// OK +var a = x + 1; + +function f(v: number) { } +f(x); + +if (x) { } + +x; +(x); + +-x; ++x; + +x.toString(); + + +//// [constDeclarations-access2.js] +const x = 0; +// Errors +x = 1; +x += 2; +x -= 3; +x *= 4; +x /= 5; +x %= 6; +x <<= 7; +x >>= 8; +x >>>= 9; +x &= 10; +x |= 11; +x ^= 12; +x++; +x--; +++x; +--x; +// OK +var a = x + 1; +function f(v) { +} +f(x); +if (x) { +} +x; +(x); +-x; ++x; +x.toString(); diff --git a/tests/baselines/reference/letDeclarations-access.js b/tests/baselines/reference/letDeclarations-access.js new file mode 100644 index 0000000000000..404c287631079 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-access.js @@ -0,0 +1,70 @@ +//// [letDeclarations-access.ts] + +let x = 0 + +// No errors + +x = 1; +x += 2; +x -= 3; +x *= 4; +x /= 5; +x %= 6; +x <<= 7; +x >>= 8; +x >>>= 9; +x &= 10; +x |= 11; +x ^= 12; + +x++; +x--; +++x; +--x; + +var a = x + 1; + +function f(v: number) { } +f(x); + +if (x) { } + +x; +(x); + +-x; ++x; + +x.toString(); + + +//// [letDeclarations-access.js] +let x = 0; +// No errors +x = 1; +x += 2; +x -= 3; +x *= 4; +x /= 5; +x %= 6; +x <<= 7; +x >>= 8; +x >>>= 9; +x &= 10; +x |= 11; +x ^= 12; +x++; +x--; +++x; +--x; +var a = x + 1; +function f(v) { +} +f(x); +if (x) { +} +x; +(x); +-x; ++x; +x.toString(); diff --git a/tests/baselines/reference/letDeclarations-access.types b/tests/baselines/reference/letDeclarations-access.types new file mode 100644 index 0000000000000..f26d07ca5f8e8 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-access.types @@ -0,0 +1,109 @@ +=== tests/cases/compiler/letDeclarations-access.ts === + +let x = 0 +>x : number + +// No errors + +x = 1; +>x = 1 : number +>x : number + +x += 2; +>x += 2 : number +>x : number + +x -= 3; +>x -= 3 : number +>x : number + +x *= 4; +>x *= 4 : number +>x : number + +x /= 5; +>x /= 5 : number +>x : number + +x %= 6; +>x %= 6 : number +>x : number + +x <<= 7; +>x <<= 7 : number +>x : number + +x >>= 8; +>x >>= 8 : number +>x : number + +x >>>= 9; +>x >>>= 9 : number +>x : number + +x &= 10; +>x &= 10 : number +>x : number + +x |= 11; +>x |= 11 : number +>x : number + +x ^= 12; +>x ^= 12 : number +>x : number + +x++; +>x++ : number +>x : number + +x--; +>x-- : number +>x : number + +++x; +>++x : number +>x : number + +--x; +>--x : number +>x : number + +var a = x + 1; +>a : number +>x + 1 : number +>x : number + +function f(v: number) { } +>f : (v: number) => void +>v : number + +f(x); +>f(x) : void +>f : (v: number) => void +>x : number + +if (x) { } +>x : number + +x; +>x : number + +(x); +>(x) : number +>x : number + +-x; +>-x : number +>x : number + ++x; +>+x : number +>x : number + +x.toString(); +>x.toString() : string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string + diff --git a/tests/cases/compiler/constDeclarations-access.ts b/tests/cases/compiler/constDeclarations-access.ts new file mode 100644 index 0000000000000..665d6753a6df6 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-access.ts @@ -0,0 +1,7 @@ +// @target: ES6 + +// @Filename: file1.ts +const x = 0 + +// @Filename: file2.ts +x++; \ No newline at end of file diff --git a/tests/cases/compiler/constDeclarations-access2.ts b/tests/cases/compiler/constDeclarations-access2.ts new file mode 100644 index 0000000000000..e46889c11261c --- /dev/null +++ b/tests/cases/compiler/constDeclarations-access2.ts @@ -0,0 +1,38 @@ +// @target: ES6 + +const x = 0 + +// Errors +x = 1; +x += 2; +x -= 3; +x *= 4; +x /= 5; +x %= 6; +x <<= 7; +x >>= 8; +x >>>= 9; +x &= 10; +x |= 11; +x ^= 12; + +x++; +x--; +++x; +--x; + +// OK +var a = x + 1; + +function f(v: number) { } +f(x); + +if (x) { } + +x; +(x); + +-x; ++x; + +x.toString(); diff --git a/tests/cases/compiler/letDeclarations-access.ts b/tests/cases/compiler/letDeclarations-access.ts new file mode 100644 index 0000000000000..6ed655f1cb25c --- /dev/null +++ b/tests/cases/compiler/letDeclarations-access.ts @@ -0,0 +1,38 @@ +// @target: ES6 + +let x = 0 + +// No errors + +x = 1; +x += 2; +x -= 3; +x *= 4; +x /= 5; +x %= 6; +x <<= 7; +x >>= 8; +x >>>= 9; +x &= 10; +x |= 11; +x ^= 12; + +x++; +x--; +++x; +--x; + +var a = x + 1; + +function f(v: number) { } +f(x); + +if (x) { } + +x; +(x); + +-x; ++x; + +x.toString(); From 82f5fb4055c98ded41f6d6d275cc06c2f286ab2b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 14 Oct 2014 17:15:11 -0700 Subject: [PATCH 10/25] Flag const declarations shodowed by var redeclarations --- src/compiler/checker.ts | 32 ++++++++++++++ .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++ ...arationShadowedByVarDeclaration.errors.txt | 35 +++++++++++++++ ...onstDeclarationShadowedByVarDeclaration.js | 43 +++++++++++++++++++ ...onstDeclarationShadowedByVarDeclaration.ts | 24 +++++++++++ 6 files changed, 139 insertions(+) create mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt create mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js create mode 100644 tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5bba99c6d439c..6927be355a86f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6174,6 +6174,36 @@ module ts { } } + function checkCollisionsWithConstDeclarations(node: VariableDeclaration) { + // Variable declarations are hoisted to the top of their function scope. They can shadow + // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition + // by the binder as the declaration scope is different. + // A non-initialized declaration is a no-op as the block declaration will resolve before the var + // declaration. the problem is if the declaration has an initializer. this will act as a write to the + // block declared value. this is fine for let, but not const. + // + // Only consider declarations with initializers, uninitialized var declarations will not + // step on a const variable. + // Do not consider let and const declarations, as duplicate block-scoped declarations + // are handled by the binder. + // We are only looking for var declarations that step on const declarations from a + // different scope. e.g.: + // var x = 0; + // { + // const x = 0; + // var x = 0; + // } + if (node.initializer && (node.flags & NodeFlags.BlockScoped) === 0) { + var symbol = getSymbolOfNode(node); + var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.BlockScoped, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); + if (localDeclarationSymbol && localDeclarationSymbol !== symbol) { + if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { + error(node, Diagnostics.Cannot_redeclare_constant_0, symbolToString(localDeclarationSymbol)); + } + } + } + } + function checkVariableDeclaration(node: VariableDeclaration) { checkSourceElement(node.type); checkExportsOnMergedDeclarations(node); @@ -6197,6 +6227,8 @@ module ts { // Use default messages checkTypeAssignableTo(checkAndMarkExpression(node.initializer), type, node, /*chainedMessage*/ undefined, /*terminalMessage*/ undefined); } + + checkCollisionsWithConstDeclarations(node); } checkCollisionWithCapturedSuperVariable(node, node.name); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 5d4acbbc67b5c..86a66c468abaf 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -272,6 +272,7 @@ module ts { Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration." }, The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: { code: 2449, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator cannot be a constant." }, Left_hand_side_of_assignment_expression_cannot_be_a_constant: { code: 2450, category: DiagnosticCategory.Error, key: "Left-hand side of assignment expression cannot be a constant." }, + Cannot_redeclare_constant_0: { code: 2451, category: DiagnosticCategory.Error, key: "Cannot redeclare constant '{0}'." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 937d6cdd614a1..ebe9a815b5064 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1080,6 +1080,10 @@ "category": "Error", "code": 2450 }, + "Cannot redeclare constant '{0}'.": { + "category": "Error", + "code": 2451 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt new file mode 100644 index 0000000000000..662628e0692c1 --- /dev/null +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt @@ -0,0 +1,35 @@ +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(7,9): error TS2451: Cannot redeclare constant 'x'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(15,13): error TS2451: Cannot redeclare constant 'y'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS2451: Cannot redeclare constant 'z'. + + +==== tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts (3 errors) ==== + + // Error as declaration of var would cause a write to the const value + var x = 0; + { + const x = 0; + + var x = 0; + ~ +!!! error TS2451: Cannot redeclare constant 'x'. + } + + + var y = 0; + { + const y = 0; + { + var y = 0; + ~ +!!! error TS2451: Cannot redeclare constant 'y'. + } + } + + + { + const z = 0; + var z = 0 + ~ +!!! error TS2451: Cannot redeclare constant 'z'. + } \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js new file mode 100644 index 0000000000000..9fcc9f8f568f2 --- /dev/null +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js @@ -0,0 +1,43 @@ +//// [constDeclarationShadowedByVarDeclaration.ts] + +// Error as declaration of var would cause a write to the const value +var x = 0; +{ + const x = 0; + + var x = 0; +} + + +var y = 0; +{ + const y = 0; + { + var y = 0; + } +} + + +{ + const z = 0; + var z = 0 +} + +//// [constDeclarationShadowedByVarDeclaration.js] +// Error as declaration of var would cause a write to the const value +var x = 0; +{ + const x = 0; + var x = 0; +} +var y = 0; +{ + const y = 0; + { + var y = 0; + } +} +{ + const z = 0; + var z = 0; +} diff --git a/tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts b/tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts new file mode 100644 index 0000000000000..a4d392338477a --- /dev/null +++ b/tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts @@ -0,0 +1,24 @@ +// @target: ES6 + +// Error as declaration of var would cause a write to the const value +var x = 0; +{ + const x = 0; + + var x = 0; +} + + +var y = 0; +{ + const y = 0; + { + var y = 0; + } +} + + +{ + const z = 0; + var z = 0 +} \ No newline at end of file From 3e4560147bb03a7ad471ebc8487a11d8adcfe66c Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 14 Oct 2014 17:37:46 -0700 Subject: [PATCH 11/25] Allow const in for statements --- .../diagnosticInformationMap.generated.ts | 4 +- src/compiler/diagnosticMessages.json | 4 +- src/compiler/parser.ts | 15 ++++-- .../constDeclarations-errors.errors.txt | 53 +++++++------------ .../constDeclarations-es5.errors.txt | 12 ++--- .../reference/constDeclarations-scopes2.js | 27 ++++++++++ .../reference/constDeclarations-scopes2.types | 32 +++++++++++ .../baselines/reference/constDeclarations.js | 13 ++++- .../reference/constDeclarations.types | 14 +++++ .../compiler/constDeclarations-errors.ts | 11 +++- .../compiler/constDeclarations-scopes2.ts | 15 ++++++ tests/cases/compiler/constDeclarations.ts | 6 +++ 12 files changed, 156 insertions(+), 50 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-scopes2.js create mode 100644 tests/baselines/reference/constDeclarations-scopes2.types create mode 100644 tests/cases/compiler/constDeclarations-scopes2.ts diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 86a66c468abaf..2fde444dff2d7 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -116,8 +116,8 @@ module ts { new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, An_enum_member_cannot_have_a_numeric_name: { code: 1151, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." }, var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." }, - let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' variable declarations are only available when targeting ECMAScript 6 and higher." }, - const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' variable declarations are only available when targeting ECMAScript 6 and higher." }, + let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." }, + const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." }, const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "const must be intialized." }, const_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "const must be declared inside a block." }, let_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "let must be declared inside a block." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ebe9a815b5064..b2f98559ed888 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -455,11 +455,11 @@ "category": "Error", "code": 1152 }, - "'let' variable declarations are only available when targeting ECMAScript 6 and higher.": { + "'let' declarations are only available when targeting ECMAScript 6 and higher.": { "category": "Error", "code": 1153 }, - "'const' variable declarations are only available when targeting ECMAScript 6 and higher.": { + "'const' declarations are only available when targeting ECMAScript 6 and higher.": { "category": "Error", "code": 1154 }, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d8d1d24a97eff..ad514adebeda1 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2654,7 +2654,16 @@ module ts { error(Diagnostics.Variable_declaration_list_cannot_be_empty); } if (languageVersion < ScriptTarget.ES6) { - grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + } + } + else if (parseOptional(SyntaxKind.ConstKeyword)) { + var declarations = parseVariableDeclarationList(NodeFlags.Const, true); + if (!declarations.length) { + error(Diagnostics.Variable_declaration_list_cannot_be_empty); + } + if (languageVersion < ScriptTarget.ES6) { + grammarErrorAtPos(declarations.pos, declarations.end - declarations.pos, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); } } else { @@ -3145,10 +3154,10 @@ module ts { } if (languageVersion < ScriptTarget.ES6) { if (node.flags & NodeFlags.Let) { - grammarErrorOnNode(node, Diagnostics.let_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + grammarErrorOnNode(node, Diagnostics.let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); } else if (node.flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.const_variable_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); + grammarErrorOnNode(node, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); } } else if (!allowLetDeclarations){ diff --git a/tests/baselines/reference/constDeclarations-errors.errors.txt b/tests/baselines/reference/constDeclarations-errors.errors.txt index 9a922ac93a916..1766fb4937412 100644 --- a/tests/baselines/reference/constDeclarations-errors.errors.txt +++ b/tests/baselines/reference/constDeclarations-errors.errors.txt @@ -4,20 +4,13 @@ tests/cases/compiler/constDeclarations-errors.ts(5,7): error TS1155: const must tests/cases/compiler/constDeclarations-errors.ts(5,11): error TS1155: const must be intialized. tests/cases/compiler/constDeclarations-errors.ts(5,15): error TS1155: const must be intialized. tests/cases/compiler/constDeclarations-errors.ts(5,27): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(8,5): error TS1109: Expression expected. -tests/cases/compiler/constDeclarations-errors.ts(8,5): error TS1156: const must be declared inside a block. tests/cases/compiler/constDeclarations-errors.ts(8,11): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(8,13): error TS1005: ';' expected. -tests/cases/compiler/constDeclarations-errors.ts(8,13): error TS1128: Declaration or statement expected. -tests/cases/compiler/constDeclarations-errors.ts(8,18): error TS1128: Declaration or statement expected. -tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1109: Expression expected. -tests/cases/compiler/constDeclarations-errors.ts(10,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-errors.ts(10,28): error TS1005: ';' expected. -tests/cases/compiler/constDeclarations-errors.ts(10,18): error TS2304: Cannot find name 'c'. -tests/cases/compiler/constDeclarations-errors.ts(10,25): error TS2304: Cannot find name 'c'. +tests/cases/compiler/constDeclarations-errors.ts(14,11): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(17,20): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(11,27): error TS2449: The operand of an increment or decrement operator cannot be a constant. -==== tests/cases/compiler/constDeclarations-errors.ts (17 errors) ==== +==== tests/cases/compiler/constDeclarations-errors.ts (10 errors) ==== // error, missing intialicer const c1; @@ -36,30 +29,22 @@ tests/cases/compiler/constDeclarations-errors.ts(10,25): error TS2304: Cannot fi ~~ !!! error TS1155: const must be intialized. - // error, wrong context + // error, can not be unintalized for(const c in {}) { } - ~~~~~ -!!! error TS1109: Expression expected. - ~~~~~~~ -!!! error TS1156: const must be declared inside a block. ~ !!! error TS1155: const must be intialized. - ~~ -!!! error TS1005: ';' expected. - ~~ -!!! error TS1128: Declaration or statement expected. - ~ -!!! error TS1128: Declaration or statement expected. - for(const c = 0; c < 9; c++) { } - ~~~~~ -!!! error TS1109: Expression expected. - ~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. - ~ -!!! error TS1005: ';' expected. - ~ -!!! error TS2304: Cannot find name 'c'. - ~ -!!! error TS2304: Cannot find name 'c'. - \ No newline at end of file + // error, assigning to a const + for(const c8 = 0; c8 < 1; c8++) { } + ~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + // error, can not be unintalized + for(const c9; c9 < 1;) { } + ~~ +!!! error TS1155: const must be intialized. + + // error, can not be unintalized + for(const c10 = 0, c11; c10 < 1;) { } + ~~~ +!!! error TS1155: const must be intialized. \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-es5.errors.txt b/tests/baselines/reference/constDeclarations-es5.errors.txt index a941b826ed084..0b830eab05a82 100644 --- a/tests/baselines/reference/constDeclarations-es5.errors.txt +++ b/tests/baselines/reference/constDeclarations-es5.errors.txt @@ -1,17 +1,17 @@ -tests/cases/compiler/constDeclarations-es5.ts(2,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/constDeclarations-es5.ts(3,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/constDeclarations-es5.ts(4,1): error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/constDeclarations-es5.ts(2,1): error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/constDeclarations-es5.ts(3,1): error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/constDeclarations-es5.ts(4,1): error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher. ==== tests/cases/compiler/constDeclarations-es5.ts (3 errors) ==== const z7 = false; ~~~~~~~~~~~~~~~~~ -!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher. const z8: number = 23; ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher. const z9 = 0, z10 :string = "", z11 = null; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1154: 'const' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1154: 'const' declarations are only available when targeting ECMAScript 6 and higher. \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-scopes2.js b/tests/baselines/reference/constDeclarations-scopes2.js new file mode 100644 index 0000000000000..be9514e18a722 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-scopes2.js @@ -0,0 +1,27 @@ +//// [constDeclarations-scopes2.ts] + +// global +const c = "string"; + +var n: number; +var b: boolean; + +// for scope +for (const c = 0; c < 10; n = c ) { + // for block + const c = false; + b = c; +} + + + +//// [constDeclarations-scopes2.js] +// global +const c = "string"; +var n; +var b; +for (var c = 0; c < 10; n = c) { + // for block + const c = false; + b = c; +} diff --git a/tests/baselines/reference/constDeclarations-scopes2.types b/tests/baselines/reference/constDeclarations-scopes2.types new file mode 100644 index 0000000000000..9609ef8f44b1e --- /dev/null +++ b/tests/baselines/reference/constDeclarations-scopes2.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/constDeclarations-scopes2.ts === + +// global +const c = "string"; +>c : string + +var n: number; +>n : number + +var b: boolean; +>b : boolean + +// for scope +for (const c = 0; c < 10; n = c ) { +>c : number +>c < 10 : boolean +>c : number +>n = c : number +>n : number +>c : number + + // for block + const c = false; +>c : boolean + + b = c; +>b = c : boolean +>b : boolean +>c : boolean +} + + diff --git a/tests/baselines/reference/constDeclarations.js b/tests/baselines/reference/constDeclarations.js index 23d87d2c2a788..d6371da863e1b 100644 --- a/tests/baselines/reference/constDeclarations.js +++ b/tests/baselines/reference/constDeclarations.js @@ -4,13 +4,24 @@ const c1 = false; const c2: number = 23; const c3 = 0, c4 :string = "", c5 = null; - + + +for(const c4 = 0; c4 < 9; ) { break; } + + +for(const c5 = 0, c6 = 0; c5 < c6; ) { break; } //// [constDeclarations.js] // No error const c1 = false; const c2 = 23; const c3 = 0, c4 = "", c5 = null; +for (var c4 = 0; c4 < 9;) { + break; +} +for (var c5 = 0, c6 = 0; c5 < c6;) { + break; +} //// [constDeclarations.d.ts] diff --git a/tests/baselines/reference/constDeclarations.types b/tests/baselines/reference/constDeclarations.types index 7faa37f85bcfe..e82a2f0035f50 100644 --- a/tests/baselines/reference/constDeclarations.types +++ b/tests/baselines/reference/constDeclarations.types @@ -12,3 +12,17 @@ const c3 = 0, c4 :string = "", c5 = null; >c4 : string >c5 : any + +for(const c4 = 0; c4 < 9; ) { break; } +>c4 : number +>c4 < 9 : boolean +>c4 : number + + +for(const c5 = 0, c6 = 0; c5 < c6; ) { break; } +>c5 : number +>c6 : number +>c5 < c6 : boolean +>c5 : number +>c6 : number + diff --git a/tests/cases/compiler/constDeclarations-errors.ts b/tests/cases/compiler/constDeclarations-errors.ts index 08ccaf7fe18c4..09dc0e9679068 100644 --- a/tests/cases/compiler/constDeclarations-errors.ts +++ b/tests/cases/compiler/constDeclarations-errors.ts @@ -5,7 +5,14 @@ const c1; const c2: number; const c3, c4, c5 :string, c6; // error, missing initialicer -// error, wrong context +// error, can not be unintalized for(const c in {}) { } -for(const c = 0; c < 9; c++) { } +// error, assigning to a const +for(const c8 = 0; c8 < 1; c8++) { } + +// error, can not be unintalized +for(const c9; c9 < 1;) { } + +// error, can not be unintalized +for(const c10 = 0, c11; c10 < 1;) { } \ No newline at end of file diff --git a/tests/cases/compiler/constDeclarations-scopes2.ts b/tests/cases/compiler/constDeclarations-scopes2.ts new file mode 100644 index 0000000000000..fe0ab16409a98 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-scopes2.ts @@ -0,0 +1,15 @@ +// @target: ES6 + +// global +const c = "string"; + +var n: number; +var b: boolean; + +// for scope +for (const c = 0; c < 10; n = c ) { + // for block + const c = false; + b = c; +} + diff --git a/tests/cases/compiler/constDeclarations.ts b/tests/cases/compiler/constDeclarations.ts index 36e01551a66c0..2b8563b340a21 100644 --- a/tests/cases/compiler/constDeclarations.ts +++ b/tests/cases/compiler/constDeclarations.ts @@ -5,3 +5,9 @@ const c1 = false; const c2: number = 23; const c3 = 0, c4 :string = "", c5 = null; + + +for(const c4 = 0; c4 < 9; ) { break; } + + +for(const c5 = 0, c6 = 0; c5 < c6; ) { break; } \ No newline at end of file From 03a100d03921b659b2c6b6eeaf284d0685c57d46 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Oct 2014 09:15:00 -0700 Subject: [PATCH 12/25] Do not allow let and const declarations to be exported from a module --- .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 +++ src/compiler/parser.ts | 5 ++- .../reference/constDeclarations2.errors.txt | 20 ++++++++++++ .../baselines/reference/constDeclarations2.js | 26 --------------- .../reference/constDeclarations2.types | 18 ----------- .../reference/letDeclarations-es5.errors.txt | 32 +++++++++---------- .../reference/letDeclarations2.errors.txt | 11 +++++++ tests/baselines/reference/letDeclarations2.js | 19 ----------- .../reference/letDeclarations2.types | 11 ------- 10 files changed, 56 insertions(+), 91 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations2.errors.txt delete mode 100644 tests/baselines/reference/constDeclarations2.js delete mode 100644 tests/baselines/reference/constDeclarations2.types create mode 100644 tests/baselines/reference/letDeclarations2.errors.txt delete mode 100644 tests/baselines/reference/letDeclarations2.js delete mode 100644 tests/baselines/reference/letDeclarations2.types diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 2fde444dff2d7..c9d296d8bccca 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -121,6 +121,7 @@ module ts { const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "const must be intialized." }, const_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "const must be declared inside a block." }, let_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "let must be declared inside a block." }, + Only_var_declarations_can_be_exported: { code: 1158, category: DiagnosticCategory.Error, key: "Only var declarations can be exported." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b2f98559ed888..68b5395224a51 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -475,6 +475,10 @@ "category": "Error", "code": 1157 }, + "Only var declarations can be exported.": { + "category": "Error", + "code": 1158 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ad514adebeda1..b011220095c1c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3160,7 +3160,7 @@ module ts { grammarErrorOnNode(node, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); } } - else if (!allowLetDeclarations){ + else if (!allowLetDeclarations) { if (node.flags & NodeFlags.Let) { grammarErrorOnNode(node, Diagnostics.let_must_be_declared_inside_a_block); } @@ -3168,6 +3168,9 @@ module ts { grammarErrorOnNode(node, Diagnostics.const_must_be_declared_inside_a_block); } } + else if (node.flags & NodeFlags.Export && node.flags & NodeFlags.BlockScoped) { + grammarErrorOnNode(node, Diagnostics.Only_var_declarations_can_be_exported); + } return node; } diff --git a/tests/baselines/reference/constDeclarations2.errors.txt b/tests/baselines/reference/constDeclarations2.errors.txt new file mode 100644 index 0000000000000..39317b599f9ba --- /dev/null +++ b/tests/baselines/reference/constDeclarations2.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/constDeclarations2.ts(4,5): error TS1158: Only var declarations can be exported. +tests/cases/compiler/constDeclarations2.ts(5,5): error TS1158: Only var declarations can be exported. +tests/cases/compiler/constDeclarations2.ts(6,5): error TS1158: Only var declarations can be exported. + + +==== tests/cases/compiler/constDeclarations2.ts (3 errors) ==== + + // No error + module M { + export const c1 = false; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1158: Only var declarations can be exported. + export const c2: number = 23; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1158: Only var declarations can be exported. + export const c3 = 0, c4 :string = "", c5 = null; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1158: Only var declarations can be exported. + } + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations2.js b/tests/baselines/reference/constDeclarations2.js deleted file mode 100644 index e4ee67ebdcdd0..0000000000000 --- a/tests/baselines/reference/constDeclarations2.js +++ /dev/null @@ -1,26 +0,0 @@ -//// [constDeclarations2.ts] - -// No error -module M { - export const c1 = false; - export const c2: number = 23; - export const c3 = 0, c4 :string = "", c5 = null; -} - - -//// [constDeclarations2.js] -// No error -var M; -(function (M) { - M.c1 = false; - M.c2 = 23; - M.c3 = 0, M.c4 = "", M.c5 = null; -})(M || (M = {})); - - -//// [constDeclarations2.d.ts] -declare module M { - const c1: boolean; - const c2: number; - const c3: number, c4: string, c5: any; -} diff --git a/tests/baselines/reference/constDeclarations2.types b/tests/baselines/reference/constDeclarations2.types deleted file mode 100644 index c81eca96b0dd0..0000000000000 --- a/tests/baselines/reference/constDeclarations2.types +++ /dev/null @@ -1,18 +0,0 @@ -=== tests/cases/compiler/constDeclarations2.ts === - -// No error -module M { ->M : typeof M - - export const c1 = false; ->c1 : boolean - - export const c2: number = 23; ->c2 : number - - export const c3 = 0, c4 :string = "", c5 = null; ->c3 : number ->c4 : string ->c5 : any -} - diff --git a/tests/baselines/reference/letDeclarations-es5.errors.txt b/tests/baselines/reference/letDeclarations-es5.errors.txt index 2a5858350cdba..be1a56a8b7fa5 100644 --- a/tests/baselines/reference/letDeclarations-es5.errors.txt +++ b/tests/baselines/reference/letDeclarations-es5.errors.txt @@ -1,40 +1,40 @@ -tests/cases/compiler/letDeclarations-es5.ts(2,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(3,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(4,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(6,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(7,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(8,1): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(10,8): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/letDeclarations-es5.ts(12,8): error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(2,1): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(3,1): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(4,1): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(6,1): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(7,1): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(8,1): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(10,8): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. +tests/cases/compiler/letDeclarations-es5.ts(12,8): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. ==== tests/cases/compiler/letDeclarations-es5.ts (8 errors) ==== let l1; ~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. let l2: number; ~~~~~~~~~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. let l3, l4, l5 :string, l6; ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. let l7 = false; ~~~~~~~~~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. let l8: number = 23; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. let l9 = 0, l10 :string = "", l11 = null; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. for(let l11 in {}) { } ~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. for(let l12 = 0; l12 < 9; l12++) { } ~~~~~~~~ -!!! error TS1153: 'let' variable declarations are only available when targeting ECMAScript 6 and higher. +!!! error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations2.errors.txt b/tests/baselines/reference/letDeclarations2.errors.txt new file mode 100644 index 0000000000000..384912a2bb439 --- /dev/null +++ b/tests/baselines/reference/letDeclarations2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/letDeclarations2.ts(4,5): error TS1158: Only var declarations can be exported. + + +==== tests/cases/compiler/letDeclarations2.ts (1 errors) ==== + + module M { + let l1 = "s"; + export let l2 = 0; + ~~~~~~~~~~~~~~~~~~ +!!! error TS1158: Only var declarations can be exported. + } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations2.js b/tests/baselines/reference/letDeclarations2.js deleted file mode 100644 index 8a6f039f2ca93..0000000000000 --- a/tests/baselines/reference/letDeclarations2.js +++ /dev/null @@ -1,19 +0,0 @@ -//// [letDeclarations2.ts] - -module M { - let l1 = "s"; - export let l2 = 0; -} - -//// [letDeclarations2.js] -var M; -(function (M) { - let l1 = "s"; - M.l2 = 0; -})(M || (M = {})); - - -//// [letDeclarations2.d.ts] -declare module M { - let l2: number; -} diff --git a/tests/baselines/reference/letDeclarations2.types b/tests/baselines/reference/letDeclarations2.types deleted file mode 100644 index 2fa08b6d9400b..0000000000000 --- a/tests/baselines/reference/letDeclarations2.types +++ /dev/null @@ -1,11 +0,0 @@ -=== tests/cases/compiler/letDeclarations2.ts === - -module M { ->M : typeof M - - let l1 = "s"; ->l1 : string - - export let l2 = 0; ->l2 : number -} From 61549239d85e554d36eb85050fbae5d4edc3f0f8 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 15 Oct 2014 09:20:46 -0700 Subject: [PATCH 13/25] Fix emitting for const in for loops --- src/compiler/emitter.ts | 13 ++++--------- .../reference/constDeclarations-scopes2.js | 2 +- tests/baselines/reference/constDeclarations.js | 4 ++-- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 81022d04e3170..8c0dd818d32be 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1152,6 +1152,9 @@ module ts { if (node.declarations[0] && node.declarations[0].flags & NodeFlags.Let) { emitToken(SyntaxKind.LetKeyword, endPos); } + else if (node.declarations[0] && node.declarations[0].flags & NodeFlags.Const) { + emitToken(SyntaxKind.ConstKeyword, endPos); + } else { emitToken(SyntaxKind.VarKeyword, endPos); } @@ -1794,15 +1797,7 @@ module ts { if (node.flags & NodeFlags.Export) { writeLine(); emitStart(node); - if (node.flags & NodeFlags.Let) { - write("let "); - } - else if (node.flags & NodeFlags.Const) { - write("const "); - } - else { - write("var "); - } + write("var "); emit(node.name); write(" = "); emitModuleMemberName(node); diff --git a/tests/baselines/reference/constDeclarations-scopes2.js b/tests/baselines/reference/constDeclarations-scopes2.js index be9514e18a722..1d0f252ab4f2d 100644 --- a/tests/baselines/reference/constDeclarations-scopes2.js +++ b/tests/baselines/reference/constDeclarations-scopes2.js @@ -20,7 +20,7 @@ for (const c = 0; c < 10; n = c ) { const c = "string"; var n; var b; -for (var c = 0; c < 10; n = c) { +for (const c = 0; c < 10; n = c) { // for block const c = false; b = c; diff --git a/tests/baselines/reference/constDeclarations.js b/tests/baselines/reference/constDeclarations.js index d6371da863e1b..060c0aba61cd6 100644 --- a/tests/baselines/reference/constDeclarations.js +++ b/tests/baselines/reference/constDeclarations.js @@ -16,10 +16,10 @@ for(const c5 = 0, c6 = 0; c5 < c6; ) { break; } const c1 = false; const c2 = 23; const c3 = 0, c4 = "", c5 = null; -for (var c4 = 0; c4 < 9;) { +for (const c4 = 0; c4 < 9;) { break; } -for (var c5 = 0, c6 = 0; c5 < c6;) { +for (const c5 = 0, c6 = 0; c5 < c6;) { break; } From 60bb37be60c6e7388ca1e346def14ce281a023f0 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 16 Oct 2014 10:28:00 -0700 Subject: [PATCH 14/25] Add language service support for const --- src/services/navigationBar.ts | 7 ++++++- src/services/services.ts | 10 ++++++++-- tests/cases/fourslash/completionEntryForConst.ts | 7 +++++++ tests/cases/fourslash/navbar_const.ts | 13 +++++++++++++ .../cases/fourslash/quickInfoForConstDeclaration.ts | 6 ++++++ 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionEntryForConst.ts create mode 100644 tests/cases/fourslash/navbar_const.ts create mode 100644 tests/cases/fourslash/quickInfoForConstDeclaration.ts diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 9f16fa57741d9..6918097412035 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -233,7 +233,12 @@ module ts.NavigationBar { return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.functionElement); case SyntaxKind.VariableDeclaration: - return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.variableElement); + if (node.flags & NodeFlags.Const) { + return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.constantElement); + } + else { + return createItem(node, getTextOfNode((node).name), ts.ScriptElementKind.variableElement); + } case SyntaxKind.Constructor: return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); diff --git a/src/services/services.ts b/src/services/services.ts index 0222a448aeb53..c52bdb347713b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1235,7 +1235,9 @@ module ts { static label = "label"; - static alias = "alias" + static alias = "alias"; + + static constantElement = "constant"; } export class ScriptElementKindModifier { @@ -2720,6 +2722,9 @@ module ts { if (isFirstDeclarationOfSymbolParameter(symbol)) { return ScriptElementKind.parameterElement; } + else if(forEach(symbol.declarations, d => d.flags & NodeFlags.Const)) { + return ScriptElementKind.constantElement; + } return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement; } if (flags & SymbolFlags.Function) return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localFunctionElement : ScriptElementKind.functionElement; @@ -2751,7 +2756,7 @@ module ts { case SyntaxKind.ClassDeclaration: return ScriptElementKind.classElement; case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement; case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement; - case SyntaxKind.VariableDeclaration: return ScriptElementKind.variableElement; + case SyntaxKind.VariableDeclaration: return node.flags & NodeFlags.Const ? ScriptElementKind.constantElement: ScriptElementKind.variableElement; case SyntaxKind.FunctionDeclaration: return ScriptElementKind.functionElement; case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement; case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement; @@ -2840,6 +2845,7 @@ module ts { switch (symbolKind) { case ScriptElementKind.memberVariableElement: case ScriptElementKind.variableElement: + case ScriptElementKind.constantElement: case ScriptElementKind.parameterElement: case ScriptElementKind.localVariableElement: // If it is call or construct signature of lambda's write type name diff --git a/tests/cases/fourslash/completionEntryForConst.ts b/tests/cases/fourslash/completionEntryForConst.ts new file mode 100644 index 0000000000000..f6b7cc42d63d7 --- /dev/null +++ b/tests/cases/fourslash/completionEntryForConst.ts @@ -0,0 +1,7 @@ +/// + +////const c = "s"; +/////**/ + +goTo.marker(); +verify.completionListContains("c", /*text*/ undefined, /*documentation*/ undefined, "constant"); \ No newline at end of file diff --git a/tests/cases/fourslash/navbar_const.ts b/tests/cases/fourslash/navbar_const.ts new file mode 100644 index 0000000000000..ede2a9cd1d8b6 --- /dev/null +++ b/tests/cases/fourslash/navbar_const.ts @@ -0,0 +1,13 @@ +/// + +//// {| "itemName": "c", "kind": "constant", "parentName": "" |}const c = 0; + +test.markers().forEach(marker => { + verify.getScriptLexicalStructureListContains( + marker.data.itemName, + marker.data.kind, + marker.fileName, + marker.data.parentName, + marker.data.isAdditionalRange, + marker.position); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/quickInfoForConstDeclaration.ts b/tests/cases/fourslash/quickInfoForConstDeclaration.ts new file mode 100644 index 0000000000000..dc234b040509f --- /dev/null +++ b/tests/cases/fourslash/quickInfoForConstDeclaration.ts @@ -0,0 +1,6 @@ +/// + +////const /**/c = 0 ; + +goTo.marker(); +verify.quickInfoIs("(constant) c: number"); \ No newline at end of file From fd469d63b1e0e42a435343152e11d972d17adead Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 17 Oct 2014 09:28:42 -0700 Subject: [PATCH 15/25] Fix search for shadowed const declarations by a var declarations to search for any variable instead of only a blockScoped one to ensure we are not picking it up from a wrong scope. --- src/compiler/checker.ts | 4 ++-- ...onstDeclarationShadowedByVarDeclaration2.js | 18 ++++++++++++++++++ ...tDeclarationShadowedByVarDeclaration2.types | 16 ++++++++++++++++ ...onstDeclarationShadowedByVarDeclaration2.ts | 9 +++++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.js create mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.types create mode 100644 tests/cases/compiler/constDeclarationShadowedByVarDeclaration2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5b99e2b2dd905..0065d138e9e11 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6776,8 +6776,8 @@ module ts { // } if (node.initializer && (node.flags & NodeFlags.BlockScoped) === 0) { var symbol = getSymbolOfNode(node); - var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.BlockScoped, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); - if (localDeclarationSymbol && localDeclarationSymbol !== symbol) { + var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); + if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScoped) { if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { error(node, Diagnostics.Cannot_redeclare_constant_0, symbolToString(localDeclarationSymbol)); } diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.js b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.js new file mode 100644 index 0000000000000..67d3e688075ad --- /dev/null +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.js @@ -0,0 +1,18 @@ +//// [constDeclarationShadowedByVarDeclaration2.ts] + +// No errors, const declaration is not shadowed +function outer() { + const x = 0; + function inner() { + var x = "inner"; + } +} + +//// [constDeclarationShadowedByVarDeclaration2.js] +// No errors, const declaration is not shadowed +function outer() { + const x = 0; + function inner() { + var x = "inner"; + } +} diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.types b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.types new file mode 100644 index 0000000000000..4217db455095a --- /dev/null +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration2.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/constDeclarationShadowedByVarDeclaration2.ts === + +// No errors, const declaration is not shadowed +function outer() { +>outer : () => void + + const x = 0; +>x : number + + function inner() { +>inner : () => void + + var x = "inner"; +>x : string + } +} diff --git a/tests/cases/compiler/constDeclarationShadowedByVarDeclaration2.ts b/tests/cases/compiler/constDeclarationShadowedByVarDeclaration2.ts new file mode 100644 index 0000000000000..98930953996bb --- /dev/null +++ b/tests/cases/compiler/constDeclarationShadowedByVarDeclaration2.ts @@ -0,0 +1,9 @@ +// @target: ES6 + +// No errors, const declaration is not shadowed +function outer() { + const x = 0; + function inner() { + var x = "inner"; + } +} \ No newline at end of file From 4ef68b9fb03c21e55d47230ac97b63ebd43bd42e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 17 Oct 2014 10:09:21 -0700 Subject: [PATCH 16/25] Respond to code review comments --- src/compiler/parser.ts | 36 ++++++++++++++++++------------------ src/compiler/types.ts | 9 ++++++--- src/harness/harness.ts | 2 +- src/services/services.ts | 2 +- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 112096615b248..305ef595041cc 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2561,7 +2561,7 @@ module ts { // STATEMENTS function parseStatementAllowingLetDeclaration() { - return parseStatement(/*allowLetDeclarations*/ true); + return parseStatement(/*allowLetAndConstDeclarations*/ true); } function parseBlock(ignoreMissingOpenBrace: boolean, checkForStrictMode: boolean): Block { @@ -2613,8 +2613,8 @@ module ts { parseExpected(SyntaxKind.OpenParenToken); node.expression = parseExpression(); parseExpected(SyntaxKind.CloseParenToken); - node.thenStatement = parseStatement(/*allowLetDeclarations*/ false); - node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement(/*allowLetDeclarations*/ false) : undefined; + node.thenStatement = parseStatement(/*allowLetAndConstDeclarations*/ false); + node.elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement(/*allowLetAndConstDeclarations*/ false) : undefined; return finishNode(node); } @@ -2624,7 +2624,7 @@ module ts { var saveInIterationStatement = inIterationStatement; inIterationStatement = ControlBlockContext.Nested; - node.statement = parseStatement(/*allowLetDeclarations*/ false); + node.statement = parseStatement(/*allowLetAndConstDeclarations*/ false); inIterationStatement = saveInIterationStatement; parseExpected(SyntaxKind.WhileKeyword); @@ -2649,7 +2649,7 @@ module ts { var saveInIterationStatement = inIterationStatement; inIterationStatement = ControlBlockContext.Nested; - node.statement = parseStatement(/*allowLetDeclarations*/ false); + node.statement = parseStatement(/*allowLetAndConstDeclarations*/ false); inIterationStatement = saveInIterationStatement; return finishNode(node); @@ -2722,7 +2722,7 @@ module ts { var saveInIterationStatement = inIterationStatement; inIterationStatement = ControlBlockContext.Nested; - forOrForInStatement.statement = parseStatement(/*allowLetDeclarations*/ false); + forOrForInStatement.statement = parseStatement(/*allowLetAndConstDeclarations*/ false); inIterationStatement = saveInIterationStatement; return finishNode(forOrForInStatement); @@ -2833,7 +2833,7 @@ module ts { parseExpected(SyntaxKind.OpenParenToken); node.expression = parseExpression(); parseExpected(SyntaxKind.CloseParenToken); - node.statement = parseStatement(/*allowLetDeclarations*/ false); + node.statement = parseStatement(/*allowLetAndConstDeclarations*/ false); node = finishNode(node); if (isInStrictMode) { // Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such @@ -2963,9 +2963,9 @@ module ts { return token === SyntaxKind.WhileKeyword || token === SyntaxKind.DoKeyword || token === SyntaxKind.ForKeyword; } - function parseStatementWithLabelSet(allowLetDeclarations: boolean): Statement { + function parseStatementWithLabelSet(allowLetAndConstDeclarations: boolean): Statement { labelledStatementInfo.pushCurrentLabelSet(isIterationStatementStart()); - var statement = parseStatement(allowLetDeclarations); + var statement = parseStatement(allowLetAndConstDeclarations); labelledStatementInfo.pop(); return statement; } @@ -2974,7 +2974,7 @@ module ts { return isIdentifier() && lookAhead(() => nextToken() === SyntaxKind.ColonToken); } - function parseLabelledStatement(allowLetDeclarations: boolean): LabeledStatement { + function parseLabeledStatement(allowLetAndConstDeclarations: boolean): LabeledStatement { var node = createNode(SyntaxKind.LabeledStatement); node.label = parseIdentifier(); parseExpected(SyntaxKind.ColonToken); @@ -2986,7 +2986,7 @@ module ts { // We only want to call parseStatementWithLabelSet when the label set is complete // Therefore, keep parsing labels until we know we're done. - node.statement = isLabel() ? parseLabelledStatement(allowLetDeclarations) : parseStatementWithLabelSet(allowLetDeclarations); + node.statement = isLabel() ? parseLabeledStatement(allowLetAndConstDeclarations) : parseStatementWithLabelSet(allowLetAndConstDeclarations); return finishNode(node); } @@ -3052,14 +3052,14 @@ module ts { } } - function parseStatement(allowLetDeclarations: boolean): Statement { + function parseStatement(allowLetAndConstDeclarations: boolean): Statement { switch (token) { case SyntaxKind.OpenBraceToken: return parseBlock(/* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: - return parseVariableStatement(allowLetDeclarations); + return parseVariableStatement(allowLetAndConstDeclarations); case SyntaxKind.FunctionKeyword: return parseFunctionDeclaration(); case SyntaxKind.SemicolonToken: @@ -3093,7 +3093,7 @@ module ts { return parseDebuggerStatement(); default: if (isLabel()) { - return parseLabelledStatement(allowLetDeclarations); + return parseLabeledStatement(allowLetAndConstDeclarations); } return parseExpressionStatement(); } @@ -3150,7 +3150,7 @@ module ts { () => parseVariableDeclaration(flags, noIn), /*allowTrailingComma*/ false); } - function parseVariableStatement(allowLetDeclarations: boolean, pos?: number, flags?: NodeFlags): VariableStatement { + function parseVariableStatement(allowLetAndConstDeclarations: boolean, pos?: number, flags?: NodeFlags): VariableStatement { var node = createNode(SyntaxKind.VariableStatement, pos); if (flags) node.flags = flags; var errorCountBeforeVarStatement = file.syntacticErrors.length; @@ -3178,7 +3178,7 @@ module ts { grammarErrorOnNode(node, Diagnostics.const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher); } } - else if (!allowLetDeclarations) { + else if (!allowLetAndConstDeclarations) { if (node.flags & NodeFlags.Let) { grammarErrorOnNode(node, Diagnostics.let_must_be_declared_inside_a_block); } @@ -3821,7 +3821,7 @@ module ts { case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: - result = parseVariableStatement(/*allowLetDeclarations*/ true, pos, flags); + result = parseVariableStatement(/*allowLetAndConstDeclarations*/ true, pos, flags); break; case SyntaxKind.FunctionKeyword: result = parseFunctionDeclaration(pos, flags); @@ -3869,7 +3869,7 @@ module ts { var statementStart = scanner.getTokenPos(); var statementFirstTokenLength = scanner.getTextPos() - statementStart; var errorCountBeforeStatement = file.syntacticErrors.length; - var statement = parseStatement(/*allowLetDeclarations*/ false); + var statement = parseStatement(/*allowLetAndConstDeclarations*/ false); if (inAmbientContext && file.syntacticErrors.length === errorCountBeforeStatement) { grammarErrorAtPos(statementStart, statementFirstTokenLength, Diagnostics.Statements_are_not_allowed_in_ambient_contexts); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5eb567e406e91..5a5a5989daba5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -783,7 +783,7 @@ module ts { Transient = 0x04000000, // Transient symbol (created during type check) Prototype = 0x08000000, // Prototype property (no source representation) - BlockScoped = 0x10000000, + BlockScoped = 0x10000000, // A block-scoped declaration Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | UnionProperty, Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter, @@ -793,8 +793,11 @@ module ts { Signature = CallSignature | ConstructSignature | IndexSignature, ParameterExcludes = Value, - VariableExcludes = (Value | BlockScoped) & ~Variable, - BlockScopedExcludes = Value, + VariableExcludes = (Value | BlockScoped) & ~Variable, // Variables can be redeclared, but can not redeclare a block-scoped + // declaration with the same name, or any other value that is not a + // variable, e.g. ValueModule or Class + BlockScopedExcludes = Value, // Block-scoped declarations are not allowed to be re-declared + // they can not merge with anything in the value space PropertyExcludes = Value, EnumMemberExcludes = Value, FunctionExcludes = Value & ~(Function | ValueModule), diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 728c4cc08e0ab..bbabd0462c13e 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -686,7 +686,7 @@ module Harness { } else if (setting.value.toLowerCase() === 'es5') { options.target = ts.ScriptTarget.ES5; } else if (setting.value.toLowerCase() === 'es6') { - options.target = ts.ScriptTarget.ES6; + options.target = ts.ScriptTarget.ES6; } else { throw new Error('Unknown compile target ' + setting.value); } diff --git a/src/services/services.ts b/src/services/services.ts index c52bdb347713b..fb984c9da87b3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2722,7 +2722,7 @@ module ts { if (isFirstDeclarationOfSymbolParameter(symbol)) { return ScriptElementKind.parameterElement; } - else if(forEach(symbol.declarations, d => d.flags & NodeFlags.Const)) { + else if(symbol.valueDeclaration && symbol.valueDeclaration.flags & NodeFlags.Const) { return ScriptElementKind.constantElement; } return isLocalVariableOrFunction(symbol) ? ScriptElementKind.localVariableElement : ScriptElementKind.variableElement; From a5a6c6f2423870d61504d344ef1080795cebda14 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 17 Oct 2014 15:15:22 -0700 Subject: [PATCH 17/25] Allow const and let declarations to be exported in modules. Also ensure that const module elements are not used as references. --- src/compiler/checker.ts | 25 ++++- .../diagnosticInformationMap.generated.ts | 5 +- src/compiler/diagnosticMessages.json | 8 +- src/compiler/parser.ts | 7 +- .../constDeclarations-access2.errors.txt | 7 +- .../reference/constDeclarations-access2.js | 3 + .../constDeclarations-access3.errors.txt | 102 +++++++++++++++++ .../reference/constDeclarations-access3.js | 83 ++++++++++++++ .../constDeclarations-access4.errors.txt | 102 +++++++++++++++++ .../reference/constDeclarations-access4.js | 79 ++++++++++++++ .../constDeclarations-access5.errors.txt | 103 ++++++++++++++++++ .../reference/constDeclarations-access5.js | 89 +++++++++++++++ ...nstDeclarations-invalidContexts.errors.txt | 36 +++--- .../reference/constDeclarations2.errors.txt | 20 ---- .../baselines/reference/constDeclarations2.js | 26 +++++ .../reference/constDeclarations2.types | 18 +++ ...letDeclarations-invalidContexts.errors.txt | 36 +++--- .../reference/letDeclarations2.errors.txt | 11 -- tests/baselines/reference/letDeclarations2.js | 19 ++++ .../reference/letDeclarations2.types | 11 ++ .../compiler/constDeclarations-access2.ts | 2 + .../compiler/constDeclarations-access3.ts | 45 ++++++++ .../compiler/constDeclarations-access4.ts | 45 ++++++++ .../compiler/constDeclarations-access5.ts | 48 ++++++++ 24 files changed, 843 insertions(+), 87 deletions(-) create mode 100644 tests/baselines/reference/constDeclarations-access3.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-access3.js create mode 100644 tests/baselines/reference/constDeclarations-access4.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-access4.js create mode 100644 tests/baselines/reference/constDeclarations-access5.errors.txt create mode 100644 tests/baselines/reference/constDeclarations-access5.js delete mode 100644 tests/baselines/reference/constDeclarations2.errors.txt create mode 100644 tests/baselines/reference/constDeclarations2.js create mode 100644 tests/baselines/reference/constDeclarations2.types delete mode 100644 tests/baselines/reference/letDeclarations2.errors.txt create mode 100644 tests/baselines/reference/letDeclarations2.js create mode 100644 tests/baselines/reference/letDeclarations2.types create mode 100644 tests/cases/compiler/constDeclarations-access3.ts create mode 100644 tests/cases/compiler/constDeclarations-access4.ts create mode 100644 tests/cases/compiler/constDeclarations-access5.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0065d138e9e11..bb96151997a47 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5550,12 +5550,27 @@ module ts { } } - function isConstVariableReference(n: Node) { - if (n.kind === SyntaxKind.Identifier) { - var symbol = findSymbol(n); - return symbol && (symbol.flags & SymbolFlags.Variable) !== 0 && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0; + function isConstVariableReference(n: Node): boolean { + switch (n.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.PropertyAccess: + var symbol = findSymbol(n); + return symbol && (symbol.flags & SymbolFlags.Variable) !== 0 && (getDeclarationFlagsFromSymbol(symbol) & NodeFlags.Const) !== 0; + case SyntaxKind.IndexedAccess: + var index = (n).index; + var symbol = findSymbol((n).object); + if (symbol && index.kind === SyntaxKind.StringLiteral) { + var name = (index).text; + var apparentType = getApparentType(getTypeOfSymbol(symbol)); + var prop = getPropertyOfApparentType(apparentType, name); + return prop && (prop.flags & SymbolFlags.Variable) !== 0 && (getDeclarationFlagsFromSymbol(prop) & NodeFlags.Const) !== 0; + } + return false; + case SyntaxKind.ParenExpression: + return isConstVariableReference((n).expression); + default: + return false; } - return false; } if (!isReferenceOrErrorExpression(n)) { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index d96214ae1d9ee..ef0ab4327a14f 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -119,9 +119,8 @@ module ts { let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." }, const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." }, const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "const must be intialized." }, - const_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "const must be declared inside a block." }, - let_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "let must be declared inside a block." }, - Only_var_declarations_can_be_exported: { code: 1158, category: DiagnosticCategory.Error, key: "Only var declarations can be exported." }, + const_declarations_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "'const' declarations must be declared inside a block." }, + let_declarations_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations must be declared inside a block." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ee1a82b9c13ef..34ecabe31aea4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -467,18 +467,14 @@ "category": "Error", "code": 1155 }, - "const must be declared inside a block.": { + "'const' declarations must be declared inside a block.": { "category": "Error", "code": 1156 }, - "let must be declared inside a block.": { + "'let' declarations must be declared inside a block.": { "category": "Error", "code": 1157 }, - "Only var declarations can be exported.": { - "category": "Error", - "code": 1158 - }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 305ef595041cc..2ee564c730211 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3180,15 +3180,12 @@ module ts { } else if (!allowLetAndConstDeclarations) { if (node.flags & NodeFlags.Let) { - grammarErrorOnNode(node, Diagnostics.let_must_be_declared_inside_a_block); + grammarErrorOnNode(node, Diagnostics.let_declarations_must_be_declared_inside_a_block); } else if (node.flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.const_must_be_declared_inside_a_block); + grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_declared_inside_a_block); } } - else if (node.flags & NodeFlags.Export && node.flags & NodeFlags.BlockScoped) { - grammarErrorOnNode(node, Diagnostics.Only_var_declarations_can_be_exported); - } return node; } diff --git a/tests/baselines/reference/constDeclarations-access2.errors.txt b/tests/baselines/reference/constDeclarations-access2.errors.txt index f3bf7d1d750ce..6a360e11014e8 100644 --- a/tests/baselines/reference/constDeclarations-access2.errors.txt +++ b/tests/baselines/reference/constDeclarations-access2.errors.txt @@ -14,9 +14,10 @@ tests/cases/compiler/constDeclarations-access2.ts(18,1): error TS2449: The opera tests/cases/compiler/constDeclarations-access2.ts(19,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. tests/cases/compiler/constDeclarations-access2.ts(20,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. tests/cases/compiler/constDeclarations-access2.ts(21,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access2.ts(23,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. -==== tests/cases/compiler/constDeclarations-access2.ts (16 errors) ==== +==== tests/cases/compiler/constDeclarations-access2.ts (17 errors) ==== const x = 0 @@ -71,6 +72,10 @@ tests/cases/compiler/constDeclarations-access2.ts(21,3): error TS2449: The opera ~ !!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + ++((x)); + ~~~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + // OK var a = x + 1; diff --git a/tests/baselines/reference/constDeclarations-access2.js b/tests/baselines/reference/constDeclarations-access2.js index e2a1bcd9fa573..fd51c9326368b 100644 --- a/tests/baselines/reference/constDeclarations-access2.js +++ b/tests/baselines/reference/constDeclarations-access2.js @@ -21,6 +21,8 @@ x--; ++x; --x; +++((x)); + // OK var a = x + 1; @@ -57,6 +59,7 @@ x++; x--; ++x; --x; +++((x)); // OK var a = x + 1; function f(v) { diff --git a/tests/baselines/reference/constDeclarations-access3.errors.txt b/tests/baselines/reference/constDeclarations-access3.errors.txt new file mode 100644 index 0000000000000..577b087dff09a --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access3.errors.txt @@ -0,0 +1,102 @@ +tests/cases/compiler/constDeclarations-access3.ts(8,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(9,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(10,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(11,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(12,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(13,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(14,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(15,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(16,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(17,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(18,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(19,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(21,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(22,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(23,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(24,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(26,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access3.ts(28,1): error TS2450: Left-hand side of assignment expression cannot be a constant. + + +==== tests/cases/compiler/constDeclarations-access3.ts (18 errors) ==== + + + module M { + export const x = 0; + } + + // Errors + M.x = 1; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x += 2; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x -= 3; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x *= 4; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x /= 5; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x %= 6; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x <<= 7; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x >>= 8; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x >>>= 9; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x &= 10; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x |= 11; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x ^= 12; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + + M.x++; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + M.x--; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + ++M.x; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + --M.x; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + ++((M.x)); + ~~~~~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + M["x"] = 0; + ~~~~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + + // OK + var a = M.x + 1; + + function f(v: number) { } + f(M.x); + + if (M.x) { } + + M.x; + (M.x); + + -M.x; + +M.x; + + M.x.toString(); + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-access3.js b/tests/baselines/reference/constDeclarations-access3.js new file mode 100644 index 0000000000000..9ac4880bdd13a --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access3.js @@ -0,0 +1,83 @@ +//// [constDeclarations-access3.ts] + + +module M { + export const x = 0; +} + +// Errors +M.x = 1; +M.x += 2; +M.x -= 3; +M.x *= 4; +M.x /= 5; +M.x %= 6; +M.x <<= 7; +M.x >>= 8; +M.x >>>= 9; +M.x &= 10; +M.x |= 11; +M.x ^= 12; + +M.x++; +M.x--; +++M.x; +--M.x; + +++((M.x)); + +M["x"] = 0; + +// OK +var a = M.x + 1; + +function f(v: number) { } +f(M.x); + +if (M.x) { } + +M.x; +(M.x); + +-M.x; ++M.x; + +M.x.toString(); + + +//// [constDeclarations-access3.js] +var M; +(function (M) { + M.x = 0; +})(M || (M = {})); +// Errors +M.x = 1; +M.x += 2; +M.x -= 3; +M.x *= 4; +M.x /= 5; +M.x %= 6; +M.x <<= 7; +M.x >>= 8; +M.x >>>= 9; +M.x &= 10; +M.x |= 11; +M.x ^= 12; +M.x++; +M.x--; +++M.x; +--M.x; +++((M.x)); +M["x"] = 0; +// OK +var a = M.x + 1; +function f(v) { +} +f(M.x); +if (M.x) { +} +M.x; +(M.x); +-M.x; ++M.x; +M.x.toString(); diff --git a/tests/baselines/reference/constDeclarations-access4.errors.txt b/tests/baselines/reference/constDeclarations-access4.errors.txt new file mode 100644 index 0000000000000..9745c0d262497 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access4.errors.txt @@ -0,0 +1,102 @@ +tests/cases/compiler/constDeclarations-access4.ts(8,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(9,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(10,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(11,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(12,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(13,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(14,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(15,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(16,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(17,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(18,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(19,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(21,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(22,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(23,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(24,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(26,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations-access4.ts(28,1): error TS2450: Left-hand side of assignment expression cannot be a constant. + + +==== tests/cases/compiler/constDeclarations-access4.ts (18 errors) ==== + + + declare module M { + const x: number; + } + + // Errors + M.x = 1; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x += 2; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x -= 3; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x *= 4; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x /= 5; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x %= 6; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x <<= 7; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x >>= 8; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x >>>= 9; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x &= 10; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x |= 11; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + M.x ^= 12; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + + M.x++; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + M.x--; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + ++M.x; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + --M.x; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + ++((M.x)); + ~~~~~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + M["x"] = 0; + ~~~~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + + // OK + var a = M.x + 1; + + function f(v: number) { } + f(M.x); + + if (M.x) { } + + M.x; + (M.x); + + -M.x; + +M.x; + + M.x.toString(); + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-access4.js b/tests/baselines/reference/constDeclarations-access4.js new file mode 100644 index 0000000000000..b226e746bbafe --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access4.js @@ -0,0 +1,79 @@ +//// [constDeclarations-access4.ts] + + +declare module M { + const x: number; +} + +// Errors +M.x = 1; +M.x += 2; +M.x -= 3; +M.x *= 4; +M.x /= 5; +M.x %= 6; +M.x <<= 7; +M.x >>= 8; +M.x >>>= 9; +M.x &= 10; +M.x |= 11; +M.x ^= 12; + +M.x++; +M.x--; +++M.x; +--M.x; + +++((M.x)); + +M["x"] = 0; + +// OK +var a = M.x + 1; + +function f(v: number) { } +f(M.x); + +if (M.x) { } + +M.x; +(M.x); + +-M.x; ++M.x; + +M.x.toString(); + + +//// [constDeclarations-access4.js] +// Errors +M.x = 1; +M.x += 2; +M.x -= 3; +M.x *= 4; +M.x /= 5; +M.x %= 6; +M.x <<= 7; +M.x >>= 8; +M.x >>>= 9; +M.x &= 10; +M.x |= 11; +M.x ^= 12; +M.x++; +M.x--; +++M.x; +--M.x; +++((M.x)); +M["x"] = 0; +// OK +var a = M.x + 1; +function f(v) { +} +f(M.x); +if (M.x) { +} +M.x; +(M.x); +-M.x; ++M.x; +M.x.toString(); diff --git a/tests/baselines/reference/constDeclarations-access5.errors.txt b/tests/baselines/reference/constDeclarations-access5.errors.txt new file mode 100644 index 0000000000000..23200e50ee42b --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access5.errors.txt @@ -0,0 +1,103 @@ +tests/cases/compiler/constDeclarations_access_2.ts(4,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(5,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(6,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(7,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(8,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(9,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(10,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(11,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(12,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(13,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(14,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(15,1): error TS2450: Left-hand side of assignment expression cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(17,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(18,1): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(19,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(20,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(22,3): error TS2449: The operand of an increment or decrement operator cannot be a constant. +tests/cases/compiler/constDeclarations_access_2.ts(24,1): error TS2450: Left-hand side of assignment expression cannot be a constant. + + +==== tests/cases/compiler/constDeclarations_access_2.ts (18 errors) ==== + /// + import m = require('constDeclarations_access_1'); + // Errors + m.x = 1; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x += 2; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x -= 3; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x *= 4; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x /= 5; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x %= 6; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x <<= 7; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x >>= 8; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x >>>= 9; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x &= 10; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x |= 11; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m.x ^= 12; + ~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + m + m.x++; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + m.x--; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + ++m.x; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + --m.x; + ~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + ++((m.x)); + ~~~~~~~ +!!! error TS2449: The operand of an increment or decrement operator cannot be a constant. + + m["x"] = 0; + ~~~~~~ +!!! error TS2450: Left-hand side of assignment expression cannot be a constant. + + // OK + var a = m.x + 1; + + function f(v: number) { } + f(m.x); + + if (m.x) { } + + m.x; + (m.x); + + -m.x; + +m.x; + + m.x.toString(); + +==== tests/cases/compiler/constDeclarations_access_1.ts (0 errors) ==== + + + export const x = 0; + \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-access5.js b/tests/baselines/reference/constDeclarations-access5.js new file mode 100644 index 0000000000000..7acc95ad05501 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-access5.js @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/constDeclarations-access5.ts] //// + +//// [constDeclarations_access_1.ts] + + +export const x = 0; + +//// [constDeclarations_access_2.ts] +/// +import m = require('constDeclarations_access_1'); +// Errors +m.x = 1; +m.x += 2; +m.x -= 3; +m.x *= 4; +m.x /= 5; +m.x %= 6; +m.x <<= 7; +m.x >>= 8; +m.x >>>= 9; +m.x &= 10; +m.x |= 11; +m.x ^= 12; +m +m.x++; +m.x--; +++m.x; +--m.x; + +++((m.x)); + +m["x"] = 0; + +// OK +var a = m.x + 1; + +function f(v: number) { } +f(m.x); + +if (m.x) { } + +m.x; +(m.x); + +-m.x; ++m.x; + +m.x.toString(); + + +//// [constDeclarations_access_1.js] +define(["require", "exports"], function (require, exports) { + exports.x = 0; +}); +//// [constDeclarations_access_2.js] +define(["require", "exports", 'constDeclarations_access_1'], function (require, exports, m) { + // Errors + m.x = 1; + m.x += 2; + m.x -= 3; + m.x *= 4; + m.x /= 5; + m.x %= 6; + m.x <<= 7; + m.x >>= 8; + m.x >>>= 9; + m.x &= 10; + m.x |= 11; + m.x ^= 12; + m; + m.x++; + m.x--; + ++m.x; + --m.x; + ++((m.x)); + m["x"] = 0; + // OK + var a = m.x + 1; + function f(v) { + } + f(m.x); + if (m.x) { + } + m.x; + (m.x); + -m.x; + +m.x; + m.x.toString(); +}); diff --git a/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt b/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt index b7aef3dabbef6..bc229185e8304 100644 --- a/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt +++ b/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/constDeclarations-invalidContexts.ts(4,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(6,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(9,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(12,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(17,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(20,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(23,5): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(26,12): error TS1156: const must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(29,29): error TS1156: const must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(4,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(6,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(9,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(12,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(17,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(20,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(23,5): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(26,12): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(29,29): error TS1156: 'const' declarations must be declared inside a block. tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. @@ -16,21 +16,21 @@ tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: A if (true) const c1 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. else const c2 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. while (true) const c3 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. do const c4 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. while (true); var obj; @@ -39,27 +39,27 @@ tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: A !!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. const c5 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. for (var i = 0; i < 10; i++) const c6 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. for (var i2 in {}) const c7 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. if (true) label: const c8 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. while (false) label2: label3: label4: const c9 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: const must be declared inside a block. +!!! error TS1156: 'const' declarations must be declared inside a block. diff --git a/tests/baselines/reference/constDeclarations2.errors.txt b/tests/baselines/reference/constDeclarations2.errors.txt deleted file mode 100644 index 39317b599f9ba..0000000000000 --- a/tests/baselines/reference/constDeclarations2.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/compiler/constDeclarations2.ts(4,5): error TS1158: Only var declarations can be exported. -tests/cases/compiler/constDeclarations2.ts(5,5): error TS1158: Only var declarations can be exported. -tests/cases/compiler/constDeclarations2.ts(6,5): error TS1158: Only var declarations can be exported. - - -==== tests/cases/compiler/constDeclarations2.ts (3 errors) ==== - - // No error - module M { - export const c1 = false; - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1158: Only var declarations can be exported. - export const c2: number = 23; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1158: Only var declarations can be exported. - export const c3 = 0, c4 :string = "", c5 = null; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1158: Only var declarations can be exported. - } - \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations2.js b/tests/baselines/reference/constDeclarations2.js new file mode 100644 index 0000000000000..e4ee67ebdcdd0 --- /dev/null +++ b/tests/baselines/reference/constDeclarations2.js @@ -0,0 +1,26 @@ +//// [constDeclarations2.ts] + +// No error +module M { + export const c1 = false; + export const c2: number = 23; + export const c3 = 0, c4 :string = "", c5 = null; +} + + +//// [constDeclarations2.js] +// No error +var M; +(function (M) { + M.c1 = false; + M.c2 = 23; + M.c3 = 0, M.c4 = "", M.c5 = null; +})(M || (M = {})); + + +//// [constDeclarations2.d.ts] +declare module M { + const c1: boolean; + const c2: number; + const c3: number, c4: string, c5: any; +} diff --git a/tests/baselines/reference/constDeclarations2.types b/tests/baselines/reference/constDeclarations2.types new file mode 100644 index 0000000000000..c81eca96b0dd0 --- /dev/null +++ b/tests/baselines/reference/constDeclarations2.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/constDeclarations2.ts === + +// No error +module M { +>M : typeof M + + export const c1 = false; +>c1 : boolean + + export const c2: number = 23; +>c2 : number + + export const c3 = 0, c4 :string = "", c5 = null; +>c3 : number +>c4 : string +>c5 : any +} + diff --git a/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt b/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt index 3877f61641aaa..0e86e84e78481 100644 --- a/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt +++ b/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/letDeclarations-invalidContexts.ts(4,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(6,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(9,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(12,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(17,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(20,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(23,5): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(26,12): error TS1157: let must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(29,29): error TS1157: let must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(4,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(6,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(9,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(12,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(17,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(20,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(23,5): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(26,12): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(29,29): error TS1157: 'let' declarations must be declared inside a block. tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. @@ -16,21 +16,21 @@ tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All if (true) let l1 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. else let l2 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. while (true) let l3 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. do let l4 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. while (true); var obj; @@ -39,27 +39,27 @@ tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All !!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. let l5 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. for (var i = 0; i < 10; i++) let l6 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. for (var i2 in {}) let l7 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. if (true) label: let l8 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. while (false) label2: label3: label4: let l9 = 0; ~~~~~~~~~~~ -!!! error TS1157: let must be declared inside a block. +!!! error TS1157: 'let' declarations must be declared inside a block. diff --git a/tests/baselines/reference/letDeclarations2.errors.txt b/tests/baselines/reference/letDeclarations2.errors.txt deleted file mode 100644 index 384912a2bb439..0000000000000 --- a/tests/baselines/reference/letDeclarations2.errors.txt +++ /dev/null @@ -1,11 +0,0 @@ -tests/cases/compiler/letDeclarations2.ts(4,5): error TS1158: Only var declarations can be exported. - - -==== tests/cases/compiler/letDeclarations2.ts (1 errors) ==== - - module M { - let l1 = "s"; - export let l2 = 0; - ~~~~~~~~~~~~~~~~~~ -!!! error TS1158: Only var declarations can be exported. - } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations2.js b/tests/baselines/reference/letDeclarations2.js new file mode 100644 index 0000000000000..8a6f039f2ca93 --- /dev/null +++ b/tests/baselines/reference/letDeclarations2.js @@ -0,0 +1,19 @@ +//// [letDeclarations2.ts] + +module M { + let l1 = "s"; + export let l2 = 0; +} + +//// [letDeclarations2.js] +var M; +(function (M) { + let l1 = "s"; + M.l2 = 0; +})(M || (M = {})); + + +//// [letDeclarations2.d.ts] +declare module M { + let l2: number; +} diff --git a/tests/baselines/reference/letDeclarations2.types b/tests/baselines/reference/letDeclarations2.types new file mode 100644 index 0000000000000..2fa08b6d9400b --- /dev/null +++ b/tests/baselines/reference/letDeclarations2.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/letDeclarations2.ts === + +module M { +>M : typeof M + + let l1 = "s"; +>l1 : string + + export let l2 = 0; +>l2 : number +} diff --git a/tests/cases/compiler/constDeclarations-access2.ts b/tests/cases/compiler/constDeclarations-access2.ts index e46889c11261c..e3f83940d1de0 100644 --- a/tests/cases/compiler/constDeclarations-access2.ts +++ b/tests/cases/compiler/constDeclarations-access2.ts @@ -21,6 +21,8 @@ x--; ++x; --x; +++((x)); + // OK var a = x + 1; diff --git a/tests/cases/compiler/constDeclarations-access3.ts b/tests/cases/compiler/constDeclarations-access3.ts new file mode 100644 index 0000000000000..370288dab9734 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-access3.ts @@ -0,0 +1,45 @@ +// @target: ES6 + + +module M { + export const x = 0; +} + +// Errors +M.x = 1; +M.x += 2; +M.x -= 3; +M.x *= 4; +M.x /= 5; +M.x %= 6; +M.x <<= 7; +M.x >>= 8; +M.x >>>= 9; +M.x &= 10; +M.x |= 11; +M.x ^= 12; + +M.x++; +M.x--; +++M.x; +--M.x; + +++((M.x)); + +M["x"] = 0; + +// OK +var a = M.x + 1; + +function f(v: number) { } +f(M.x); + +if (M.x) { } + +M.x; +(M.x); + +-M.x; ++M.x; + +M.x.toString(); diff --git a/tests/cases/compiler/constDeclarations-access4.ts b/tests/cases/compiler/constDeclarations-access4.ts new file mode 100644 index 0000000000000..492f6a31d6df7 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-access4.ts @@ -0,0 +1,45 @@ +// @target: ES6 + + +declare module M { + const x: number; +} + +// Errors +M.x = 1; +M.x += 2; +M.x -= 3; +M.x *= 4; +M.x /= 5; +M.x %= 6; +M.x <<= 7; +M.x >>= 8; +M.x >>>= 9; +M.x &= 10; +M.x |= 11; +M.x ^= 12; + +M.x++; +M.x--; +++M.x; +--M.x; + +++((M.x)); + +M["x"] = 0; + +// OK +var a = M.x + 1; + +function f(v: number) { } +f(M.x); + +if (M.x) { } + +M.x; +(M.x); + +-M.x; ++M.x; + +M.x.toString(); diff --git a/tests/cases/compiler/constDeclarations-access5.ts b/tests/cases/compiler/constDeclarations-access5.ts new file mode 100644 index 0000000000000..1590d9289ef71 --- /dev/null +++ b/tests/cases/compiler/constDeclarations-access5.ts @@ -0,0 +1,48 @@ +// @target: ES6 +// @module: amd + + +// @Filename: constDeclarations_access_1.ts +export const x = 0; + +// @Filename: constDeclarations_access_2.ts +/// +import m = require('constDeclarations_access_1'); +// Errors +m.x = 1; +m.x += 2; +m.x -= 3; +m.x *= 4; +m.x /= 5; +m.x %= 6; +m.x <<= 7; +m.x >>= 8; +m.x >>>= 9; +m.x &= 10; +m.x |= 11; +m.x ^= 12; +m +m.x++; +m.x--; +++m.x; +--m.x; + +++((m.x)); + +m["x"] = 0; + +// OK +var a = m.x + 1; + +function f(v: number) { } +f(m.x); + +if (m.x) { } + +m.x; +(m.x); + +-m.x; ++m.x; + +m.x.toString(); From 0a59cdd5a0dc58853c2b89df23ba73965b1a7f2e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 17 Oct 2014 16:18:18 -0700 Subject: [PATCH 18/25] Treat blockScoped variable declarations as a separate category when it comes to symbol flags, instead of compining BlockScoped and Variable --- src/compiler/binder.ts | 17 +++--- src/compiler/checker.ts | 10 ++-- src/compiler/types.ts | 120 +++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 72 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0760f33ce6795..4441d017802df 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -262,8 +262,8 @@ module ts { } function bindCatchVariableDeclaration(node: CatchBlock) { - var symbol = createSymbol(SymbolFlags.Variable, node.variable.text || "__missing"); - addDeclarationToSymbol(symbol, node, SymbolFlags.Variable); + var symbol = createSymbol(SymbolFlags.FunctionScopedVariable, node.variable.text || "__missing"); + addDeclarationToSymbol(symbol, node, SymbolFlags.FunctionScopedVariable); var saveParent = parent; var savedBlockScopeContainer = blockScopeContainer; parent = blockScopeContainer = node; @@ -273,24 +273,23 @@ module ts { } function bindBlockScopedVariableDeclaration(node: Declaration) { - var symbolKind = SymbolFlags.Variable | SymbolFlags.BlockScoped; switch (blockScopeContainer.kind) { case SyntaxKind.ModuleDeclaration: - declareModuleMember(node, symbolKind, SymbolFlags.BlockScopedExcludes); + declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); break; case SyntaxKind.SourceFile: if (isExternalModule(container)) { - declareModuleMember(node, symbolKind, SymbolFlags.BlockScopedExcludes); + declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); break; } default: if (!blockScopeContainer.locals) { blockScopeContainer.locals = {}; } - declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, SymbolFlags.BlockScopedExcludes); + declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); } - bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false); + bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false); } function bind(node: Node) { @@ -301,14 +300,14 @@ module ts { bindDeclaration(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.Parameter: - bindDeclaration(node, SymbolFlags.Variable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); + bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes, /*isBlockScopeContainer*/ false); break; case SyntaxKind.VariableDeclaration: if (node.flags & NodeFlags.BlockScoped) { bindBlockScopedVariableDeclaration(node); } else { - bindDeclaration(node, SymbolFlags.Variable, SymbolFlags.VariableExcludes, /*isBlockScopeContainer*/ false); + bindDeclaration(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes, /*isBlockScopeContainer*/ false); } break; case SyntaxKind.Property: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bb96151997a47..5caf4acd02e17 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -181,8 +181,8 @@ module ts { function getExcludedSymbolFlags(flags: SymbolFlags): SymbolFlags { var result: SymbolFlags = 0; - if (flags & SymbolFlags.BlockScoped) result |= SymbolFlags.BlockScopedExcludes; - if (flags & SymbolFlags.Variable) result |= SymbolFlags.VariableExcludes; + if (flags & SymbolFlags.BlockScopedVariable) result |= SymbolFlags.BlockScopedVariableExcludes; + if (flags & SymbolFlags.FunctionScopedVariable) result |= SymbolFlags.FunctionScopedVariableExcludes; if (flags & SymbolFlags.Property) result |= SymbolFlags.PropertyExcludes; if (flags & SymbolFlags.EnumMember) result |= SymbolFlags.EnumMemberExcludes; if (flags & SymbolFlags.Function) result |= SymbolFlags.FunctionExcludes; @@ -328,8 +328,8 @@ module ts { error(errorLocation, nameNotFoundMessage, nameArg); } - if (s && s.flags & SymbolFlags.BlockScoped) { - // Block-scoped variables can not be used before thier definition + if (s && s.flags & SymbolFlags.BlockScopedVariable) { + // Block-scoped variables can not be used before their definition var declaration = forEach(s.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined); Debug.assert(declaration, "Bock-scoped variable declaration is undefined"); var declarationSourceFile = getSourceFileOfNode(declaration); @@ -6792,7 +6792,7 @@ module ts { if (node.initializer && (node.flags & NodeFlags.BlockScoped) === 0) { var symbol = getSymbolOfNode(node); var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); - if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScoped) { + if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { error(node, Diagnostics.Cannot_redeclare_constant_0, symbolToString(localDeclarationSymbol)); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5a5a5989daba5..32675c554cdc5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -751,68 +751,72 @@ module ts { } export enum SymbolFlags { - Variable = 0x00000001, // Variable or parameter - Property = 0x00000002, // Property or enum member - EnumMember = 0x00000004, // Enum member - Function = 0x00000008, // Function - Class = 0x00000010, // Class - Interface = 0x00000020, // Interface - Enum = 0x00000040, // Enum - ValueModule = 0x00000080, // Instantiated module - NamespaceModule = 0x00000100, // Uninstantiated module - TypeLiteral = 0x00000200, // Type Literal - ObjectLiteral = 0x00000400, // Object Literal - Method = 0x00000800, // Method - Constructor = 0x00001000, // Constructor - GetAccessor = 0x00002000, // Get accessor - SetAccessor = 0x00004000, // Set accessor - CallSignature = 0x00008000, // Call signature - ConstructSignature = 0x00010000, // Construct signature - IndexSignature = 0x00020000, // Index signature - TypeParameter = 0x00040000, // Type parameter - UnionProperty = 0x00080000, // Property in union type + FunctionScopedVariable = 0x00000001, // Variable (var) or parameter + Property = 0x00000002, // Property or enum member + EnumMember = 0x00000004, // Enum member + Function = 0x00000008, // Function + Class = 0x00000010, // Class + Interface = 0x00000020, // Interface + Enum = 0x00000040, // Enum + ValueModule = 0x00000080, // Instantiated module + NamespaceModule = 0x00000100, // Uninstantiated module + TypeLiteral = 0x00000200, // Type Literal + ObjectLiteral = 0x00000400, // Object Literal + Method = 0x00000800, // Method + Constructor = 0x00001000, // Constructor + GetAccessor = 0x00002000, // Get accessor + SetAccessor = 0x00004000, // Set accessor + CallSignature = 0x00008000, // Call signature + ConstructSignature = 0x00010000, // Construct signature + IndexSignature = 0x00020000, // Index signature + TypeParameter = 0x00040000, // Type parameter + UnionProperty = 0x00080000, // Property in union type // Export markers (see comment in declareModuleMember in binder) - ExportValue = 0x00100000, // Exported value marker - ExportType = 0x00200000, // Exported type marker - ExportNamespace = 0x00400000, // Exported namespace marker - - Import = 0x00800000, // Import - Instantiated = 0x01000000, // Instantiated symbol - Merged = 0x02000000, // Merged symbol (created during program binding) - Transient = 0x04000000, // Transient symbol (created during type check) - Prototype = 0x08000000, // Prototype property (no source representation) - - BlockScoped = 0x10000000, // A block-scoped declaration - - Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | UnionProperty, - Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter, - Namespace = ValueModule | NamespaceModule, - Module = ValueModule | NamespaceModule, - Accessor = GetAccessor | SetAccessor, - Signature = CallSignature | ConstructSignature | IndexSignature, - - ParameterExcludes = Value, - VariableExcludes = (Value | BlockScoped) & ~Variable, // Variables can be redeclared, but can not redeclare a block-scoped - // declaration with the same name, or any other value that is not a - // variable, e.g. ValueModule or Class - BlockScopedExcludes = Value, // Block-scoped declarations are not allowed to be re-declared - // they can not merge with anything in the value space - PropertyExcludes = Value, - EnumMemberExcludes = Value, - FunctionExcludes = Value & ~(Function | ValueModule), - ClassExcludes = (Value | Type) & ~ValueModule, - InterfaceExcludes = Type & ~Interface, - EnumExcludes = (Value | Type) & ~(Enum | ValueModule), - ValueModuleExcludes = Value & ~(Function | Class | Enum | ValueModule), - NamespaceModuleExcludes = 0, - MethodExcludes = Value & ~Method, - GetAccessorExcludes = Value & ~SetAccessor, - SetAccessorExcludes = Value & ~GetAccessor, - TypeParameterExcludes = Type & ~TypeParameter, + ExportValue = 0x00100000, // Exported value marker + ExportType = 0x00200000, // Exported type marker + ExportNamespace = 0x00400000, // Exported namespace marker + + Import = 0x00800000, // Import + Instantiated = 0x01000000, // Instantiated symbol + Merged = 0x02000000, // Merged symbol (created during program binding) + Transient = 0x04000000, // Transient symbol (created during type check) + Prototype = 0x08000000, // Prototype property (no source representation) + + BlockScopedVariable = 0x10000000, // A block-scoped variable (let ot const) + + Variable = FunctionScopedVariable | BlockScopedVariable, + Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | UnionProperty, + Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter, + Namespace = ValueModule | NamespaceModule, + Module = ValueModule | NamespaceModule, + Accessor = GetAccessor | SetAccessor, + Signature = CallSignature | ConstructSignature | IndexSignature, + + ParameterExcludes = Value, + + // Variables can be redeclared, but can not redeclare a block-scoped declaration with the + // same name, or any other value that is not a variable, e.g. ValueModule or Class + FunctionScopedVariableExcludes = Value & ~FunctionScopedVariable, + + // Block-scoped declarations are not allowed to be re-declared + // they can not merge with anything in the value space + BlockScopedVariableExcludes = Value, + PropertyExcludes = Value, + EnumMemberExcludes = Value, + FunctionExcludes = Value & ~(Function | ValueModule), + ClassExcludes = (Value | Type) & ~ValueModule, + InterfaceExcludes = Type & ~Interface, + EnumExcludes = (Value | Type) & ~(Enum | ValueModule), + ValueModuleExcludes = Value & ~(Function | Class | Enum | ValueModule), + NamespaceModuleExcludes = 0, + MethodExcludes = Value & ~Method, + GetAccessorExcludes = Value & ~SetAccessor, + SetAccessorExcludes = Value & ~GetAccessor, + TypeParameterExcludes = Type & ~TypeParameter, // Imports collide with all other imports with the same name. - ImportExcludes = Import, + ImportExcludes = Import, ModuleMember = Variable | Function | Class | Interface | Enum | Module | Import, From dd5c89d5cfb89e682e48c257c0fbae9d4bd010a4 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 20 Oct 2014 13:48:22 -0700 Subject: [PATCH 19/25] Update error messages --- .../diagnosticInformationMap.generated.ts | 6 ++-- src/compiler/diagnosticMessages.json | 6 ++-- src/compiler/parser.ts | 12 +++---- .../constDeclarations-errors.errors.txt | 36 +++++++++---------- ...nstDeclarations-invalidContexts.errors.txt | 36 +++++++++---------- ...letDeclarations-invalidContexts.errors.txt | 36 +++++++++---------- 6 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index ef0ab4327a14f..467797747bea5 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -118,9 +118,9 @@ module ts { var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." }, let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." }, const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." }, - const_must_be_intialized: { code: 1155, category: DiagnosticCategory.Error, key: "const must be intialized." }, - const_declarations_must_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "'const' declarations must be declared inside a block." }, - let_declarations_must_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations must be declared inside a block." }, + const_declarations_must_be_initialized: { code: 1155, category: DiagnosticCategory.Error, key: "'const' declarations must be initialized" }, + const_declarations_can_only_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "'const' declarations can only be declared inside a block." }, + let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 34ecabe31aea4..0f7788eae6e6f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -463,15 +463,15 @@ "category": "Error", "code": 1154 }, - "const must be intialized.": { + "'const' declarations must be initialized": { "category": "Error", "code": 1155 }, - "'const' declarations must be declared inside a block.": { + "'const' declarations can only be declared inside a block.": { "category": "Error", "code": 1156 }, - "'let' declarations must be declared inside a block.": { + "'let' declarations can only be declared inside a block.": { "category": "Error", "code": 1157 }, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1cc667c5cb9b9..a0e992098f7e6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2726,13 +2726,13 @@ module ts { parseExpected(SyntaxKind.OpenParenToken); if (token !== SyntaxKind.SemicolonToken) { if (parseOptional(SyntaxKind.VarKeyword)) { - var declarations = parseVariableDeclarationList(0, true); + var declarations = parseVariableDeclarationList(0, /*noIn*/ true); if (!declarations.length) { error(Diagnostics.Variable_declaration_list_cannot_be_empty); } } else if (parseOptional(SyntaxKind.LetKeyword)) { - var declarations = parseVariableDeclarationList(NodeFlags.Let, true); + var declarations = parseVariableDeclarationList(NodeFlags.Let, /*noIn*/ true); if (!declarations.length) { error(Diagnostics.Variable_declaration_list_cannot_be_empty); } @@ -2741,7 +2741,7 @@ module ts { } } else if (parseOptional(SyntaxKind.ConstKeyword)) { - var declarations = parseVariableDeclarationList(NodeFlags.Const, true); + var declarations = parseVariableDeclarationList(NodeFlags.Const, /*noIn*/ true); if (!declarations.length) { error(Diagnostics.Variable_declaration_list_cannot_be_empty); } @@ -3200,7 +3200,7 @@ module ts { grammarErrorAtPos(initializerStart, initializerFirstTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } if (!inAmbientContext && !node.initializer && flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.const_must_be_intialized); + grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_initialized); } if (isInStrictMode && isEvalOrArgumentsIdentifier(node.name)) { // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code @@ -3245,10 +3245,10 @@ module ts { } else if (!allowLetAndConstDeclarations) { if (node.flags & NodeFlags.Let) { - grammarErrorOnNode(node, Diagnostics.let_declarations_must_be_declared_inside_a_block); + grammarErrorOnNode(node, Diagnostics.let_declarations_can_only_be_declared_inside_a_block); } else if (node.flags & NodeFlags.Const) { - grammarErrorOnNode(node, Diagnostics.const_declarations_must_be_declared_inside_a_block); + grammarErrorOnNode(node, Diagnostics.const_declarations_can_only_be_declared_inside_a_block); } } return node; diff --git a/tests/baselines/reference/constDeclarations-errors.errors.txt b/tests/baselines/reference/constDeclarations-errors.errors.txt index 1766fb4937412..d87007474a1a4 100644 --- a/tests/baselines/reference/constDeclarations-errors.errors.txt +++ b/tests/baselines/reference/constDeclarations-errors.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/constDeclarations-errors.ts(3,7): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(4,7): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(5,7): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(5,11): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(5,15): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(5,27): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(8,11): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(14,11): error TS1155: const must be intialized. -tests/cases/compiler/constDeclarations-errors.ts(17,20): error TS1155: const must be intialized. +tests/cases/compiler/constDeclarations-errors.ts(3,7): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(4,7): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(5,7): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(5,11): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(5,15): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(5,27): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(8,11): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(14,11): error TS1155: 'const' declarations must be initialized +tests/cases/compiler/constDeclarations-errors.ts(17,20): error TS1155: 'const' declarations must be initialized tests/cases/compiler/constDeclarations-errors.ts(11,27): error TS2449: The operand of an increment or decrement operator cannot be a constant. @@ -15,24 +15,24 @@ tests/cases/compiler/constDeclarations-errors.ts(11,27): error TS2449: The opera // error, missing intialicer const c1; ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized const c2: number; ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized const c3, c4, c5 :string, c6; // error, missing initialicer ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized // error, can not be unintalized for(const c in {}) { } ~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized // error, assigning to a const for(const c8 = 0; c8 < 1; c8++) { } @@ -42,9 +42,9 @@ tests/cases/compiler/constDeclarations-errors.ts(11,27): error TS2449: The opera // error, can not be unintalized for(const c9; c9 < 1;) { } ~~ -!!! error TS1155: const must be intialized. +!!! error TS1155: 'const' declarations must be initialized // error, can not be unintalized for(const c10 = 0, c11; c10 < 1;) { } ~~~ -!!! error TS1155: const must be intialized. \ No newline at end of file +!!! error TS1155: 'const' declarations must be initialized \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt b/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt index bc229185e8304..745ef305ac6ba 100644 --- a/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt +++ b/tests/baselines/reference/constDeclarations-invalidContexts.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/constDeclarations-invalidContexts.ts(4,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(6,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(9,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(12,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(17,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(20,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(23,5): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(26,12): error TS1156: 'const' declarations must be declared inside a block. -tests/cases/compiler/constDeclarations-invalidContexts.ts(29,29): error TS1156: 'const' declarations must be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(4,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(6,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(9,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(12,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(17,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(20,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(23,5): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(26,12): error TS1156: 'const' declarations can only be declared inside a block. +tests/cases/compiler/constDeclarations-invalidContexts.ts(29,29): error TS1156: 'const' declarations can only be declared inside a block. tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. @@ -16,21 +16,21 @@ tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: A if (true) const c1 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. else const c2 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. while (true) const c3 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. do const c4 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. while (true); var obj; @@ -39,27 +39,27 @@ tests/cases/compiler/constDeclarations-invalidContexts.ts(16,7): error TS2410: A !!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. const c5 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. for (var i = 0; i < 10; i++) const c6 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. for (var i2 in {}) const c7 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. if (true) label: const c8 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. while (false) label2: label3: label4: const c9 = 0; ~~~~~~~~~~~~~ -!!! error TS1156: 'const' declarations must be declared inside a block. +!!! error TS1156: 'const' declarations can only be declared inside a block. diff --git a/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt b/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt index 0e86e84e78481..ad0c0f741b5ce 100644 --- a/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt +++ b/tests/baselines/reference/letDeclarations-invalidContexts.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/letDeclarations-invalidContexts.ts(4,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(6,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(9,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(12,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(17,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(20,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(23,5): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(26,12): error TS1157: 'let' declarations must be declared inside a block. -tests/cases/compiler/letDeclarations-invalidContexts.ts(29,29): error TS1157: 'let' declarations must be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(4,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(6,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(9,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(12,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(17,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(20,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(23,5): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(26,12): error TS1157: 'let' declarations can only be declared inside a block. +tests/cases/compiler/letDeclarations-invalidContexts.ts(29,29): error TS1157: 'let' declarations can only be declared inside a block. tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All symbols within a 'with' block will be resolved to 'any'. @@ -16,21 +16,21 @@ tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All if (true) let l1 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. else let l2 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. while (true) let l3 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. do let l4 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. while (true); var obj; @@ -39,27 +39,27 @@ tests/cases/compiler/letDeclarations-invalidContexts.ts(16,7): error TS2410: All !!! error TS2410: All symbols within a 'with' block will be resolved to 'any'. let l5 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. for (var i = 0; i < 10; i++) let l6 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. for (var i2 in {}) let l7 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. if (true) label: let l8 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. while (false) label2: label3: label4: let l9 = 0; ~~~~~~~~~~~ -!!! error TS1157: 'let' declarations must be declared inside a block. +!!! error TS1157: 'let' declarations can only be declared inside a block. From 91f40988f113e46f8a1dd9193c3f78715f6e4527 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 20 Oct 2014 15:30:06 -0700 Subject: [PATCH 20/25] Simplify the binder logic for managing blockScopeContainer --- src/compiler/binder.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 4441d017802df..993c8c391439c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -293,7 +293,6 @@ module ts { } function bind(node: Node) { - var isBlockScopeContainer: boolean; node.parent = parent; switch (node.kind) { case SyntaxKind.TypeParameter: @@ -382,16 +381,14 @@ module ts { case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.SwitchStatement: - isBlockScopeContainer = true; + bindChildren(node, 0 , true); + break; default: var saveParent = parent; - var savedBlockScopeContainer = blockScopeContainer; parent = node; - if (isBlockScopeContainer) blockScopeContainer = node; forEachChild(node, bind); parent = saveParent; - blockScopeContainer = savedBlockScopeContainer; } } } From d5fe43b53ed4a48e3e13ce277032cefe95c4e11d Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 20 Oct 2014 15:31:33 -0700 Subject: [PATCH 21/25] allow let and const declarations in module bodies under labels --- src/compiler/parser.ts | 8 ++++---- .../reference/letDeclarations-scopes.errors.txt | 14 ++++++++------ .../baselines/reference/letDeclarations-scopes.js | 15 +++++++++------ tests/cases/compiler/letDeclarations-scopes.ts | 14 ++++++++------ 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a0e992098f7e6..caa62b7ae9eeb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3916,14 +3916,14 @@ module ts { } function parseSourceElement() { - return parseSourceElementOrModuleElement(ModifierContext.SourceElements); + return parseSourceElementOrModuleElement(ModifierContext.SourceElements, /*allowLetAndConstDeclarations*/ false); } function parseModuleElement() { - return parseSourceElementOrModuleElement(ModifierContext.ModuleElements); + return parseSourceElementOrModuleElement(ModifierContext.ModuleElements, /*allowLetAndConstDeclarations*/ true); } - function parseSourceElementOrModuleElement(modifierContext: ModifierContext): Statement { + function parseSourceElementOrModuleElement(modifierContext: ModifierContext, allowLetAndConstDeclarations: boolean): Statement { if (isDeclaration()) { return parseDeclaration(modifierContext); } @@ -3931,7 +3931,7 @@ module ts { var statementStart = scanner.getTokenPos(); var statementFirstTokenLength = scanner.getTextPos() - statementStart; var errorCountBeforeStatement = file.syntacticErrors.length; - var statement = parseStatement(/*allowLetAndConstDeclarations*/ false); + var statement = parseStatement(allowLetAndConstDeclarations); if (inAmbientContext && file.syntacticErrors.length === errorCountBeforeStatement) { grammarErrorAtPos(statementStart, statementFirstTokenLength, Diagnostics.Statements_are_not_allowed_in_ambient_contexts); diff --git a/tests/baselines/reference/letDeclarations-scopes.errors.txt b/tests/baselines/reference/letDeclarations-scopes.errors.txt index df54e0fc3c474..5c89ea98049a6 100644 --- a/tests/baselines/reference/letDeclarations-scopes.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes.errors.txt @@ -105,12 +105,12 @@ tests/cases/compiler/letDeclarations-scopes.ts(28,7): error TS2410: All symbols var F2 = () => { let l = 0; - n = l; + n = l; }; var F3 = function () { let l = 0; - n = l; + n = l; }; // modules @@ -120,8 +120,10 @@ tests/cases/compiler/letDeclarations-scopes.ts(28,7): error TS2410: All symbols { let l = false; - var b2: boolean = l; + var b2: boolean = l; } + + lable: let l2 = 0; } // methods @@ -152,10 +154,10 @@ tests/cases/compiler/letDeclarations-scopes.ts(28,7): error TS2410: All symbols var o = { f() { let l = 0; - n = l; + n = l; }, - f2: () => { + f2: () => { let l = 0; - n = l; + n = l; } } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes.js b/tests/baselines/reference/letDeclarations-scopes.js index 59d42368b6c0c..fb16a03f569f8 100644 --- a/tests/baselines/reference/letDeclarations-scopes.js +++ b/tests/baselines/reference/letDeclarations-scopes.js @@ -100,12 +100,12 @@ function F() { var F2 = () => { let l = 0; -n = l; + n = l; }; var F3 = function () { let l = 0; -n = l; + n = l; }; // modules @@ -115,8 +115,10 @@ module m { { let l = false; - var b2: boolean = l; + var b2: boolean = l; } + + lable: let l2 = 0; } // methods @@ -147,11 +149,11 @@ class C { var o = { f() { let l = 0; -n = l; + n = l; }, -f2: () => { + f2: () => { let l = 0; - n = l; + n = l; } } @@ -251,6 +253,7 @@ var m; let l = false; var b2 = l; } + lable: let l2 = 0; })(m || (m = {})); // methods var C = (function () { diff --git a/tests/cases/compiler/letDeclarations-scopes.ts b/tests/cases/compiler/letDeclarations-scopes.ts index 0393f0f295b60..93f4ce5b4ed0f 100644 --- a/tests/cases/compiler/letDeclarations-scopes.ts +++ b/tests/cases/compiler/letDeclarations-scopes.ts @@ -100,12 +100,12 @@ function F() { var F2 = () => { let l = 0; -n = l; + n = l; }; var F3 = function () { let l = 0; -n = l; + n = l; }; // modules @@ -115,8 +115,10 @@ module m { { let l = false; - var b2: boolean = l; + var b2: boolean = l; } + + lable: let l2 = 0; } // methods @@ -147,10 +149,10 @@ class C { var o = { f() { let l = 0; -n = l; + n = l; }, -f2: () => { + f2: () => { let l = 0; - n = l; + n = l; } } \ No newline at end of file From dd7ca69866a17ff86dd477578c1178f6407e94a4 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 20 Oct 2014 17:38:50 -0700 Subject: [PATCH 22/25] Create a new flag for diagnostics 'isEarly' and disable emit if this flag is set. Set the flag by default on all let and const errors to ensure we are not emitting invalid JS code. --- scripts/processDiagnosticMessages.ts | 6 +- src/compiler/binder.ts | 5 +- src/compiler/checker.ts | 18 ++- src/compiler/core.ts | 6 +- .../diagnosticInformationMap.generated.ts | 10 +- src/compiler/diagnosticMessages.json | 22 +-- src/compiler/emitter.ts | 13 +- src/compiler/tsc.ts | 19 ++- src/compiler/types.ts | 4 + src/harness/harness.ts | 4 +- ...arationShadowedByVarDeclaration.errors.txt | 12 +- ...onstDeclarationShadowedByVarDeclaration.js | 43 ------ .../reference/constDeclarations-access.js | 13 -- .../reference/constDeclarations-access2.js | 74 --------- .../reference/constDeclarations-access3.js | 83 ----------- .../reference/constDeclarations-access4.js | 79 ---------- .../reference/constDeclarations-access5.js | 89 ----------- .../constDeclarations-useBeforeDefinition.js | 24 --- .../constDeclarations-useBeforeDefinition2.js | 12 -- .../enumIdentifierLiterals.errors.txt | 16 +- ...tDeclarations-scopes-duplicates.errors.txt | 88 +++++------ .../letDeclarations-scopes-duplicates.js | 140 ------------------ ...Declarations-scopes-duplicates2.errors.txt | 8 +- .../letDeclarations-scopes-duplicates2.js | 13 -- ...Declarations-scopes-duplicates3.errors.txt | 8 +- .../letDeclarations-scopes-duplicates3.js | 13 -- ...Declarations-scopes-duplicates4.errors.txt | 8 +- .../letDeclarations-scopes-duplicates4.js | 13 -- ...Declarations-scopes-duplicates5.errors.txt | 8 +- .../letDeclarations-scopes-duplicates5.js | 13 -- ...Declarations-scopes-duplicates6.errors.txt | 8 +- .../letDeclarations-scopes-duplicates6.js | 13 -- ...Declarations-scopes-duplicates7.errors.txt | 8 +- .../letDeclarations-scopes-duplicates7.js | 13 -- .../letDeclarations-useBeforeDefinition.js | 24 --- .../letDeclarations-useBeforeDefinition2.js | 12 -- .../reference/parserEnum5.errors.txt | 12 +- .../reference/parserEnum7.errors.txt | 12 +- 38 files changed, 164 insertions(+), 802 deletions(-) delete mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js delete mode 100644 tests/baselines/reference/constDeclarations-access.js delete mode 100644 tests/baselines/reference/constDeclarations-access2.js delete mode 100644 tests/baselines/reference/constDeclarations-access3.js delete mode 100644 tests/baselines/reference/constDeclarations-access4.js delete mode 100644 tests/baselines/reference/constDeclarations-access5.js delete mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition.js delete mode 100644 tests/baselines/reference/constDeclarations-useBeforeDefinition2.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates2.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates3.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates4.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates5.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates6.js delete mode 100644 tests/baselines/reference/letDeclarations-scopes-duplicates7.js delete mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition.js delete mode 100644 tests/baselines/reference/letDeclarations-useBeforeDefinition2.js diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index 6a4aaad9f93ee..eccfb821bb220 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -3,6 +3,7 @@ interface DiagnosticDetails { category: string; code: number; + isEarly?: boolean; } interface InputDiagnosticMessageTable { @@ -63,8 +64,9 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: ' ' + convertPropertyName(nameMap[name]) + ': { code: ' + diagnosticDetails.code + ', category: DiagnosticCategory.' + diagnosticDetails.category + - ', key: "' + name.replace('"', '\\"') + - '" },\r\n'; + ', key: "' + name.replace('"', '\\"') + '"' + + (diagnosticDetails.isEarly ? ', isEarly: true' : '') + + ' },\r\n'; } result += ' };\r\n}'; diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 993c8c391439c..accb46504dc5f 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -87,10 +87,11 @@ module ts { } // Report errors every position with duplicate declaration // Report errors on previous encountered declarations + var message = symbol.flags & SymbolFlags.BlockScopedVariable ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; forEach(symbol.declarations, (declaration) => { - file.semanticErrors.push(createDiagnosticForNode(declaration.name, Diagnostics.Duplicate_identifier_0, getDisplayName(declaration))); + file.semanticErrors.push(createDiagnosticForNode(declaration.name, message, getDisplayName(declaration))); }); - file.semanticErrors.push(createDiagnosticForNode(node.name, Diagnostics.Duplicate_identifier_0, getDisplayName(node))); + file.semanticErrors.push(createDiagnosticForNode(node.name, message, getDisplayName(node))); symbol = createSymbol(0, name); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d9225269145ef..ca250fb7e538e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -109,7 +109,8 @@ module ts { isImplementationOfOverload: isImplementationOfOverload, getAliasedSymbol: resolveImport, isUndefinedSymbol: symbol => symbol === undefinedSymbol, - isArgumentsSymbol: symbol => symbol === argumentsSymbol + isArgumentsSymbol: symbol => symbol === argumentsSymbol, + hasEarlyErrors: hasEarlyErrors }; var undefinedSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient, "undefined"); @@ -228,11 +229,13 @@ module ts { recordMergedSymbol(target, source); } else { + var message = target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable + ? Diagnostics.Cannot_redeclare_block_scoped_variable_0 : Diagnostics.Duplicate_identifier_0; forEach(source.declarations, node => { - error(node.name ? node.name : node, Diagnostics.Duplicate_identifier_0, symbolToString(source)); + error(node.name ? node.name : node, message, symbolToString(source)); }); forEach(target.declarations, node => { - error(node.name ? node.name : node, Diagnostics.Duplicate_identifier_0, symbolToString(source)); + error(node.name ? node.name : node, message, symbolToString(source)); }); } } @@ -327,7 +330,7 @@ module ts { if (s && s.flags & SymbolFlags.BlockScopedVariable) { // Block-scoped variables can not be used before their definition var declaration = forEach(s.declarations, d => d.flags & NodeFlags.BlockScoped ? d : undefined); - Debug.assert(declaration, "Bock-scoped variable declaration is undefined"); + Debug.assert(declaration, "Block-scoped variable declaration is undefined"); var declarationSourceFile = getSourceFileOfNode(declaration); var referenceSourceFile = getSourceFileOfNode(errorLocation); if (declarationSourceFile === referenceSourceFile && declaration.pos > errorLocation.pos) { @@ -6864,7 +6867,7 @@ module ts { var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { - error(node, Diagnostics.Cannot_redeclare_constant_0, symbolToString(localDeclarationSymbol)); + error(node, Diagnostics.Cannot_redeclare_block_scoped_variable_0, symbolToString(localDeclarationSymbol)); } } } @@ -8363,6 +8366,10 @@ module ts { return getDiagnostics().length > 0 || getGlobalDiagnostics().length > 0; } + function hasEarlyErrors(sourceFile?: SourceFile): boolean { + return forEach(getDiagnostics(sourceFile), d => d.isEarly); + } + function isReferencedImportDeclaration(node: ImportDeclaration): boolean { var symbol = getSymbolOfNode(node); if (getSymbolLinks(symbol).referenced) { @@ -8446,6 +8453,7 @@ module ts { getEnumMemberValue: getEnumMemberValue, isTopLevelValueImportedViaEntityName: isTopLevelValueImportedViaEntityName, hasSemanticErrors: hasSemanticErrors, + hasEarlyErrors: hasEarlyErrors, isDeclarationVisible: isDeclarationVisible, isImplementationOfOverload: isImplementationOfOverload, writeTypeAtLocation: writeTypeAtLocation, diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ee7f4701d19d9..ae2cf05312376 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -232,7 +232,8 @@ module ts { messageText: text, category: message.category, - code: message.code + code: message.code, + isEarly: message.isEarly }; } @@ -251,7 +252,8 @@ module ts { messageText: text, category: message.category, - code: message.code + code: message.code, + isEarly: message.isEarly }; } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 467797747bea5..a5dda0b1f4b71 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -114,7 +114,6 @@ module ts { Cannot_compile_external_modules_unless_the_module_flag_is_provided: { code: 1148, category: DiagnosticCategory.Error, key: "Cannot compile external modules unless the '--module' flag is provided." }, Filename_0_differs_from_already_included_filename_1_only_in_casing: { code: 1149, category: DiagnosticCategory.Error, key: "Filename '{0}' differs from already included filename '{1}' only in casing" }, new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: { code: 1150, category: DiagnosticCategory.Error, key: "'new T[]' cannot be used to create an array. Use 'new Array()' instead." }, - An_enum_member_cannot_have_a_numeric_name: { code: 1151, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." }, var_let_or_const_expected: { code: 1152, category: DiagnosticCategory.Error, key: "'var', 'let' or 'const' expected." }, let_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1153, category: DiagnosticCategory.Error, key: "'let' declarations are only available when targeting ECMAScript 6 and higher." }, const_declarations_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1154, category: DiagnosticCategory.Error, key: "'const' declarations are only available when targeting ECMAScript 6 and higher." }, @@ -267,10 +266,11 @@ module ts { Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." }, Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." }, The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." }, - Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration." }, - The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: { code: 2449, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator cannot be a constant." }, - Left_hand_side_of_assignment_expression_cannot_be_a_constant: { code: 2450, category: DiagnosticCategory.Error, key: "Left-hand side of assignment expression cannot be a constant." }, - Cannot_redeclare_constant_0: { code: 2451, category: DiagnosticCategory.Error, key: "Cannot redeclare constant '{0}'." }, + Block_scoped_variable_0_used_before_its_declaration: { code: 2448, category: DiagnosticCategory.Error, key: "Block-scoped variable '{0}' used before its declaration.", isEarly: true }, + The_operand_of_an_increment_or_decrement_operator_cannot_be_a_constant: { code: 2449, category: DiagnosticCategory.Error, key: "The operand of an increment or decrement operator cannot be a constant.", isEarly: true }, + Left_hand_side_of_assignment_expression_cannot_be_a_constant: { code: 2450, category: DiagnosticCategory.Error, key: "Left-hand side of assignment expression cannot be a constant.", isEarly: true }, + Cannot_redeclare_block_scoped_variable_0: { code: 2451, category: DiagnosticCategory.Error, key: "Cannot redeclare block-scoped variable '{0}'.", isEarly: true }, + An_enum_member_cannot_have_a_numeric_name: { code: 2452, category: DiagnosticCategory.Error, key: "An enum member cannot have a numeric name." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0f7788eae6e6f..1336af21aaf80 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -447,10 +447,6 @@ "category": "Error", "code": 1150 }, - "An enum member cannot have a numeric name.": { - "category": "Error", - "code": 1151 - }, "'var', 'let' or 'const' expected.": { "category": "Error", "code": 1152 @@ -1062,19 +1058,27 @@ }, "Block-scoped variable '{0}' used before its declaration.": { "category": "Error", - "code": 2448 + "code": 2448, + "isEarly": true }, "The operand of an increment or decrement operator cannot be a constant.": { "category": "Error", - "code": 2449 + "code": 2449, + "isEarly": true }, "Left-hand side of assignment expression cannot be a constant.": { "category": "Error", - "code": 2450 + "code": 2450, + "isEarly": true }, - "Cannot redeclare constant '{0}'.": { + "Cannot redeclare block-scoped variable '{0}'.": { + "category": "Error", + "code": 2451, + "isEarly": true + }, + "An enum member cannot have a numeric name.": { "category": "Error", - "code": 2451 + "code": 2452 }, "Import declaration '{0}' is using private name '{1}'.": { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5c85bfc1e6ab6..1517584e4c85f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3271,11 +3271,14 @@ module ts { } var hasSemanticErrors = resolver.hasSemanticErrors(); + var hasEarlyErrors = resolver.hasEarlyErrors(targetSourceFile); function emitFile(jsFilePath: string, sourceFile?: SourceFile) { - emitJavaScript(jsFilePath, sourceFile); - if (!hasSemanticErrors && compilerOptions.declaration) { - emitDeclarations(jsFilePath, sourceFile); + if (!hasEarlyErrors) { + emitJavaScript(jsFilePath, sourceFile); + if (!hasSemanticErrors && compilerOptions.declaration) { + emitDeclarations(jsFilePath, sourceFile); + } } } @@ -3315,7 +3318,9 @@ module ts { // Check and update returnCode for syntactic and semantic var returnCode: EmitReturnStatus; - if (hasEmitterError) { + if (hasEarlyErrors) { + returnCode = EmitReturnStatus.AllOutputGenerationSkipped; + } else if (hasEmitterError) { returnCode = EmitReturnStatus.EmitErrorsEncountered; } else if (hasSemanticErrors && compilerOptions.declaration) { returnCode = EmitReturnStatus.DeclarationGenerationSkipped; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index c8cccd2da1ce5..1fab013a8a69f 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -356,13 +356,18 @@ module ts { else { var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true); var checkStart = new Date().getTime(); - var semanticErrors = checker.getDiagnostics(); - var emitStart = new Date().getTime(); - var emitOutput = checker.emitFiles(); - var emitErrors = emitOutput.errors; - exitStatus = emitOutput.emitResultStatus; - var reportStart = new Date().getTime(); - errors = concatenate(semanticErrors, emitErrors); + errors = checker.getDiagnostics(); + if (!checker.hasEarlyErrors()) { + var emitStart = new Date().getTime(); + var emitOutput = checker.emitFiles(); + var emitErrors = emitOutput.errors; + exitStatus = emitOutput.emitResultStatus; + var reportStart = new Date().getTime(); + errors = concatenate(errors, emitErrors); + } + else { + exitStatus = EmitReturnStatus.AllOutputGenerationSkipped; + } } reportDiagnostics(errors); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 10c9500671ecf..4ba895cfe1e25 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -667,6 +667,7 @@ module ts { isImplementationOfOverload(node: FunctionDeclaration): boolean; isUndefinedSymbol(symbol: Symbol): boolean; isArgumentsSymbol(symbol: Symbol): boolean; + hasEarlyErrors(sourceFile?: SourceFile): boolean; // Returns the constant value of this enum member, or 'undefined' if the enum member has a // computed value. @@ -762,6 +763,7 @@ module ts { // Returns the constant value this property access resolves to, or 'undefined' if it does // resolve to a constant. getConstantValue(node: PropertyAccess): number; + hasEarlyErrors(sourceFile?: SourceFile): boolean; } export enum SymbolFlags { @@ -1041,6 +1043,7 @@ module ts { key: string; category: DiagnosticCategory; code: number; + isEarly?: boolean; } // A linked list of formatted diagnostic messages to be used as part of a multiline message. @@ -1061,6 +1064,7 @@ module ts { messageText: string; category: DiagnosticCategory; code: number; + isEarly?: boolean; } export enum DiagnosticCategory { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 54a9a5184fe97..60c5da5a1a68a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -801,9 +801,11 @@ module Harness { var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true); checker.checkProgram(); + var hasEarlyErrors = checker.hasEarlyErrors(); + // only emit if there weren't parse errors var emitResult: ts.EmitResult; - if (!hadParseErrors) { + if (!hadParseErrors && !hasEarlyErrors) { emitResult = checker.emitFiles(); } diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt index 662628e0692c1..629cf7f75af7e 100644 --- a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(7,9): error TS2451: Cannot redeclare constant 'x'. -tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(15,13): error TS2451: Cannot redeclare constant 'y'. -tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS2451: Cannot redeclare constant 'z'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(7,9): error TS2451: Cannot redeclare block-scoped variable 'x'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(15,13): error TS2451: Cannot redeclare block-scoped variable 'y'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS2451: Cannot redeclare block-scoped variable 'z'. ==== tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts (3 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS var x = 0; ~ -!!! error TS2451: Cannot redeclare constant 'x'. +!!! error TS2451: Cannot redeclare block-scoped variable 'x'. } @@ -22,7 +22,7 @@ tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS { var y = 0; ~ -!!! error TS2451: Cannot redeclare constant 'y'. +!!! error TS2451: Cannot redeclare block-scoped variable 'y'. } } @@ -31,5 +31,5 @@ tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS const z = 0; var z = 0 ~ -!!! error TS2451: Cannot redeclare constant 'z'. +!!! error TS2451: Cannot redeclare block-scoped variable 'z'. } \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js deleted file mode 100644 index 9fcc9f8f568f2..0000000000000 --- a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.js +++ /dev/null @@ -1,43 +0,0 @@ -//// [constDeclarationShadowedByVarDeclaration.ts] - -// Error as declaration of var would cause a write to the const value -var x = 0; -{ - const x = 0; - - var x = 0; -} - - -var y = 0; -{ - const y = 0; - { - var y = 0; - } -} - - -{ - const z = 0; - var z = 0 -} - -//// [constDeclarationShadowedByVarDeclaration.js] -// Error as declaration of var would cause a write to the const value -var x = 0; -{ - const x = 0; - var x = 0; -} -var y = 0; -{ - const y = 0; - { - var y = 0; - } -} -{ - const z = 0; - var z = 0; -} diff --git a/tests/baselines/reference/constDeclarations-access.js b/tests/baselines/reference/constDeclarations-access.js deleted file mode 100644 index ba913f2d5fce9..0000000000000 --- a/tests/baselines/reference/constDeclarations-access.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/constDeclarations-access.ts] //// - -//// [file1.ts] - -const x = 0 - -//// [file2.ts] -x++; - -//// [file1.js] -const x = 0; -//// [file2.js] -x++; diff --git a/tests/baselines/reference/constDeclarations-access2.js b/tests/baselines/reference/constDeclarations-access2.js deleted file mode 100644 index fd51c9326368b..0000000000000 --- a/tests/baselines/reference/constDeclarations-access2.js +++ /dev/null @@ -1,74 +0,0 @@ -//// [constDeclarations-access2.ts] - -const x = 0 - -// Errors -x = 1; -x += 2; -x -= 3; -x *= 4; -x /= 5; -x %= 6; -x <<= 7; -x >>= 8; -x >>>= 9; -x &= 10; -x |= 11; -x ^= 12; - -x++; -x--; -++x; ---x; - -++((x)); - -// OK -var a = x + 1; - -function f(v: number) { } -f(x); - -if (x) { } - -x; -(x); - --x; -+x; - -x.toString(); - - -//// [constDeclarations-access2.js] -const x = 0; -// Errors -x = 1; -x += 2; -x -= 3; -x *= 4; -x /= 5; -x %= 6; -x <<= 7; -x >>= 8; -x >>>= 9; -x &= 10; -x |= 11; -x ^= 12; -x++; -x--; -++x; ---x; -++((x)); -// OK -var a = x + 1; -function f(v) { -} -f(x); -if (x) { -} -x; -(x); --x; -+x; -x.toString(); diff --git a/tests/baselines/reference/constDeclarations-access3.js b/tests/baselines/reference/constDeclarations-access3.js deleted file mode 100644 index 9ac4880bdd13a..0000000000000 --- a/tests/baselines/reference/constDeclarations-access3.js +++ /dev/null @@ -1,83 +0,0 @@ -//// [constDeclarations-access3.ts] - - -module M { - export const x = 0; -} - -// Errors -M.x = 1; -M.x += 2; -M.x -= 3; -M.x *= 4; -M.x /= 5; -M.x %= 6; -M.x <<= 7; -M.x >>= 8; -M.x >>>= 9; -M.x &= 10; -M.x |= 11; -M.x ^= 12; - -M.x++; -M.x--; -++M.x; ---M.x; - -++((M.x)); - -M["x"] = 0; - -// OK -var a = M.x + 1; - -function f(v: number) { } -f(M.x); - -if (M.x) { } - -M.x; -(M.x); - --M.x; -+M.x; - -M.x.toString(); - - -//// [constDeclarations-access3.js] -var M; -(function (M) { - M.x = 0; -})(M || (M = {})); -// Errors -M.x = 1; -M.x += 2; -M.x -= 3; -M.x *= 4; -M.x /= 5; -M.x %= 6; -M.x <<= 7; -M.x >>= 8; -M.x >>>= 9; -M.x &= 10; -M.x |= 11; -M.x ^= 12; -M.x++; -M.x--; -++M.x; ---M.x; -++((M.x)); -M["x"] = 0; -// OK -var a = M.x + 1; -function f(v) { -} -f(M.x); -if (M.x) { -} -M.x; -(M.x); --M.x; -+M.x; -M.x.toString(); diff --git a/tests/baselines/reference/constDeclarations-access4.js b/tests/baselines/reference/constDeclarations-access4.js deleted file mode 100644 index b226e746bbafe..0000000000000 --- a/tests/baselines/reference/constDeclarations-access4.js +++ /dev/null @@ -1,79 +0,0 @@ -//// [constDeclarations-access4.ts] - - -declare module M { - const x: number; -} - -// Errors -M.x = 1; -M.x += 2; -M.x -= 3; -M.x *= 4; -M.x /= 5; -M.x %= 6; -M.x <<= 7; -M.x >>= 8; -M.x >>>= 9; -M.x &= 10; -M.x |= 11; -M.x ^= 12; - -M.x++; -M.x--; -++M.x; ---M.x; - -++((M.x)); - -M["x"] = 0; - -// OK -var a = M.x + 1; - -function f(v: number) { } -f(M.x); - -if (M.x) { } - -M.x; -(M.x); - --M.x; -+M.x; - -M.x.toString(); - - -//// [constDeclarations-access4.js] -// Errors -M.x = 1; -M.x += 2; -M.x -= 3; -M.x *= 4; -M.x /= 5; -M.x %= 6; -M.x <<= 7; -M.x >>= 8; -M.x >>>= 9; -M.x &= 10; -M.x |= 11; -M.x ^= 12; -M.x++; -M.x--; -++M.x; ---M.x; -++((M.x)); -M["x"] = 0; -// OK -var a = M.x + 1; -function f(v) { -} -f(M.x); -if (M.x) { -} -M.x; -(M.x); --M.x; -+M.x; -M.x.toString(); diff --git a/tests/baselines/reference/constDeclarations-access5.js b/tests/baselines/reference/constDeclarations-access5.js deleted file mode 100644 index 7acc95ad05501..0000000000000 --- a/tests/baselines/reference/constDeclarations-access5.js +++ /dev/null @@ -1,89 +0,0 @@ -//// [tests/cases/compiler/constDeclarations-access5.ts] //// - -//// [constDeclarations_access_1.ts] - - -export const x = 0; - -//// [constDeclarations_access_2.ts] -/// -import m = require('constDeclarations_access_1'); -// Errors -m.x = 1; -m.x += 2; -m.x -= 3; -m.x *= 4; -m.x /= 5; -m.x %= 6; -m.x <<= 7; -m.x >>= 8; -m.x >>>= 9; -m.x &= 10; -m.x |= 11; -m.x ^= 12; -m -m.x++; -m.x--; -++m.x; ---m.x; - -++((m.x)); - -m["x"] = 0; - -// OK -var a = m.x + 1; - -function f(v: number) { } -f(m.x); - -if (m.x) { } - -m.x; -(m.x); - --m.x; -+m.x; - -m.x.toString(); - - -//// [constDeclarations_access_1.js] -define(["require", "exports"], function (require, exports) { - exports.x = 0; -}); -//// [constDeclarations_access_2.js] -define(["require", "exports", 'constDeclarations_access_1'], function (require, exports, m) { - // Errors - m.x = 1; - m.x += 2; - m.x -= 3; - m.x *= 4; - m.x /= 5; - m.x %= 6; - m.x <<= 7; - m.x >>= 8; - m.x >>>= 9; - m.x &= 10; - m.x |= 11; - m.x ^= 12; - m; - m.x++; - m.x--; - ++m.x; - --m.x; - ++((m.x)); - m["x"] = 0; - // OK - var a = m.x + 1; - function f(v) { - } - f(m.x); - if (m.x) { - } - m.x; - (m.x); - -m.x; - +m.x; - m.x.toString(); -}); diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition.js b/tests/baselines/reference/constDeclarations-useBeforeDefinition.js deleted file mode 100644 index 4fe0e64f27542..0000000000000 --- a/tests/baselines/reference/constDeclarations-useBeforeDefinition.js +++ /dev/null @@ -1,24 +0,0 @@ -//// [constDeclarations-useBeforeDefinition.ts] - -{ - c1; - const c1 = 0; -} - -var v1; -{ - v1; - const v1 = 0; -} - - -//// [constDeclarations-useBeforeDefinition.js] -{ - c1; - const c1 = 0; -} -var v1; -{ - v1; - const v1 = 0; -} diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.js b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.js deleted file mode 100644 index 7d1f4cf572584..0000000000000 --- a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.js +++ /dev/null @@ -1,12 +0,0 @@ -//// [tests/cases/compiler/constDeclarations-useBeforeDefinition2.ts] //// - -//// [file1.ts] - -c; - -//// [file2.ts] -const c = 0; - -//// [out.js] -c; -const c = 0; diff --git a/tests/baselines/reference/enumIdentifierLiterals.errors.txt b/tests/baselines/reference/enumIdentifierLiterals.errors.txt index 60d8ed81f84e4..dbf8734ea73bd 100644 --- a/tests/baselines/reference/enumIdentifierLiterals.errors.txt +++ b/tests/baselines/reference/enumIdentifierLiterals.errors.txt @@ -1,22 +1,22 @@ -tests/cases/compiler/enumIdentifierLiterals.ts(2,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(3,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(4,5): error TS1151: An enum member cannot have a numeric name. -tests/cases/compiler/enumIdentifierLiterals.ts(6,5): error TS1151: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(2,5): error TS2452: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(3,5): error TS2452: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(4,5): error TS2452: An enum member cannot have a numeric name. +tests/cases/compiler/enumIdentifierLiterals.ts(6,5): error TS2452: An enum member cannot have a numeric name. ==== tests/cases/compiler/enumIdentifierLiterals.ts (4 errors) ==== enum Nums { 1.0, ~~~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. 11e-1, ~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. 0.12e1, ~~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. "13e-1", 0xF00D ~~~~~~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt index 41d2813f7c440..b3b620a4c9ee8 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates.errors.txt @@ -1,27 +1,27 @@ -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(3,5): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(4,5): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(6,5): error TS2300: Duplicate identifier 'var2'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(7,7): error TS2300: Duplicate identifier 'var2'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(9,7): error TS2300: Duplicate identifier 'var3'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(10,5): error TS2300: Duplicate identifier 'var3'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(12,7): error TS2300: Duplicate identifier 'var4'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(13,7): error TS2300: Duplicate identifier 'var4'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(3,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(4,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(6,5): error TS2451: Cannot redeclare block-scoped variable 'var2'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(7,7): error TS2451: Cannot redeclare block-scoped variable 'var2'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(9,7): error TS2451: Cannot redeclare block-scoped variable 'var3'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(10,5): error TS2451: Cannot redeclare block-scoped variable 'var3'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(12,7): error TS2451: Cannot redeclare block-scoped variable 'var4'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(13,7): error TS2451: Cannot redeclare block-scoped variable 'var4'. tests/cases/compiler/letDeclarations-scopes-duplicates.ts(15,5): error TS2300: Duplicate identifier 'var5'. tests/cases/compiler/letDeclarations-scopes-duplicates.ts(16,5): error TS2300: Duplicate identifier 'var5'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(18,5): error TS2300: Duplicate identifier 'var6'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(19,5): error TS2300: Duplicate identifier 'var6'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(22,9): error TS2300: Duplicate identifier 'var7'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(23,9): error TS2300: Duplicate identifier 'var7'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(25,13): error TS2300: Duplicate identifier 'var8'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(26,15): error TS2300: Duplicate identifier 'var8'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(32,13): error TS2300: Duplicate identifier 'var9'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(33,13): error TS2300: Duplicate identifier 'var9'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(37,11): error TS2300: Duplicate identifier 'var10'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(38,11): error TS2300: Duplicate identifier 'var10'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(41,9): error TS2300: Duplicate identifier 'var11'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(42,9): error TS2300: Duplicate identifier 'var11'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(46,9): error TS2300: Duplicate identifier 'var12'. -tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2300: Duplicate identifier 'var12'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(18,5): error TS2451: Cannot redeclare block-scoped variable 'var6'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(19,5): error TS2451: Cannot redeclare block-scoped variable 'var6'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(22,9): error TS2451: Cannot redeclare block-scoped variable 'var7'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(23,9): error TS2451: Cannot redeclare block-scoped variable 'var7'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(25,13): error TS2451: Cannot redeclare block-scoped variable 'var8'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(26,15): error TS2451: Cannot redeclare block-scoped variable 'var8'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(32,13): error TS2451: Cannot redeclare block-scoped variable 'var9'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(33,13): error TS2451: Cannot redeclare block-scoped variable 'var9'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(37,11): error TS2451: Cannot redeclare block-scoped variable 'var10'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(38,11): error TS2451: Cannot redeclare block-scoped variable 'var10'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(41,9): error TS2451: Cannot redeclare block-scoped variable 'var11'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(42,9): error TS2451: Cannot redeclare block-scoped variable 'var11'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(46,9): error TS2451: Cannot redeclare block-scoped variable 'var12'. +tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2451: Cannot redeclare block-scoped variable 'var12'. ==== tests/cases/compiler/letDeclarations-scopes-duplicates.ts (24 errors) ==== @@ -29,31 +29,31 @@ tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2300: D // Errors: redeclaration let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. let var1 = 0; // error ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. let var2 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var2'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var2'. const var2 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var2'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var2'. const var3 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var3'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var3'. let var3 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var3'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var3'. const var4 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var4'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var4'. const var4 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var4'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var4'. var var5 = 0; ~~~~ @@ -64,25 +64,25 @@ tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2300: D let var6 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var6'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var6'. var var6 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var6'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var6'. { let var7 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var7'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var7'. let var7 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var7'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var7'. { let var8 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var8'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var8'. const var8 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var8'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var8'. } } @@ -90,36 +90,36 @@ tests/cases/compiler/letDeclarations-scopes-duplicates.ts(47,9): error TS2300: D default: let var9 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var9'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var9'. let var9 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var9'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var9'. } try { const var10 = 0; ~~~~~ -!!! error TS2300: Duplicate identifier 'var10'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var10'. const var10 = 0; ~~~~~ -!!! error TS2300: Duplicate identifier 'var10'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var10'. } catch (e) { let var11 = 0; ~~~~~ -!!! error TS2300: Duplicate identifier 'var11'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var11'. let var11 = 0; ~~~~~ -!!! error TS2300: Duplicate identifier 'var11'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var11'. } function F1() { let var12; ~~~~~ -!!! error TS2300: Duplicate identifier 'var12'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var12'. let var12; ~~~~~ -!!! error TS2300: Duplicate identifier 'var12'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var12'. } // OK diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates.js b/tests/baselines/reference/letDeclarations-scopes-duplicates.js deleted file mode 100644 index c7d2ef9863a04..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates.js +++ /dev/null @@ -1,140 +0,0 @@ -//// [letDeclarations-scopes-duplicates.ts] - -// Errors: redeclaration -let var1 = 0; -let var1 = 0; // error - -let var2 = 0; -const var2 = 0; - -const var3 = 0; -let var3 = 0; - -const var4 = 0; -const var4 = 0; - -var var5 = 0; -let var5 = 0; - -let var6 = 0; -var var6 = 0; - -{ - let var7 = 0; - let var7 = 0; - { - let var8 = 0; - const var8 = 0; - } -} - -switch (0) { - default: - let var9 = 0; - let var9 = 0; -} - -try { - const var10 = 0; - const var10 = 0; -} -catch (e) { - let var11 = 0; - let var11 = 0; -} - -function F1() { - let var12; - let var12; -} - -// OK -var var20 = 0; - -var var20 = 0 -{ - let var20 = 0; - { - let var20 = 0; - } -} - -switch (0) { - default: - let var20 = 0; -} - -try { - let var20 = 0; -} -catch (e) { - let var20 = 0; -} - -function F() { - let var20; -} - - - -//// [letDeclarations-scopes-duplicates.js] -// Errors: redeclaration -let var1 = 0; -let var1 = 0; // error -let var2 = 0; -const var2 = 0; -const var3 = 0; -let var3 = 0; -const var4 = 0; -const var4 = 0; -var var5 = 0; -let var5 = 0; -let var6 = 0; -var var6 = 0; -{ - let var7 = 0; - let var7 = 0; - { - let var8 = 0; - const var8 = 0; - } -} -switch (0) { - default: - let var9 = 0; - let var9 = 0; -} -try { - const var10 = 0; - const var10 = 0; -} -catch (e) { - let var11 = 0; - let var11 = 0; -} -function F1() { - let var12; - let var12; -} -// OK -var var20 = 0; -var var20 = 0; -{ - let var20 = 0; - { - let var20 = 0; - } -} -switch (0) { - default: - let var20 = 0; -} -try { - let var20 = 0; -} -catch (e) { - let var20 = 0; -} -function F() { - let var20; -} diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt index b948b1b7a1440..72b8b5609b695 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates2.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/file1.ts(2,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/file2.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file1.ts (1 errors) ==== let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates2.js b/tests/baselines/reference/letDeclarations-scopes-duplicates2.js deleted file mode 100644 index 9b35bd81c76fa..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates2.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-scopes-duplicates2.ts] //// - -//// [file1.ts] - -let var1 = 0; - -//// [file2.ts] -let var1 = 0; - -//// [file1.js] -let var1 = 0; -//// [file2.js] -let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt index 7222fb9bf22fa..6ed2fb66195ba 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates3.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/file2.ts(1,7): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/file1.ts(2,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/file2.ts(1,7): error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file1.ts (1 errors) ==== let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== const var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates3.js b/tests/baselines/reference/letDeclarations-scopes-duplicates3.js deleted file mode 100644 index e74caf37219a1..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates3.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-scopes-duplicates3.ts] //// - -//// [file1.ts] - -let var1 = 0; - -//// [file2.ts] -const var1 = 0; - -//// [file1.js] -let var1 = 0; -//// [file2.js] -const var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt index e626af7e52a56..ec87809b0cda5 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates4.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/file1.ts(2,7): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/file1.ts(2,7): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/file2.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file1.ts (1 errors) ==== const var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates4.js b/tests/baselines/reference/letDeclarations-scopes-duplicates4.js deleted file mode 100644 index ac338e31c7291..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates4.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-scopes-duplicates4.ts] //// - -//// [file1.ts] - -const var1 = 0; - -//// [file2.ts] -let var1 = 0; - -//// [file1.js] -const var1 = 0; -//// [file2.js] -let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt index ac5f79dd5a8d4..ce3a9da598a4a 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates5.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/file1.ts(2,7): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/file2.ts(1,7): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/file1.ts(2,7): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/file2.ts(1,7): error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file1.ts (1 errors) ==== const var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== const var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates5.js b/tests/baselines/reference/letDeclarations-scopes-duplicates5.js deleted file mode 100644 index 2424c91ab90dd..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates5.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-scopes-duplicates5.ts] //// - -//// [file1.ts] - -const var1 = 0; - -//// [file2.ts] -const var1 = 0; - -//// [file1.js] -const var1 = 0; -//// [file2.js] -const var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt index 0d3a4726bd3f4..d09eda28075d8 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates6.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/file1.ts(2,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/file2.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file1.ts (1 errors) ==== var var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates6.js b/tests/baselines/reference/letDeclarations-scopes-duplicates6.js deleted file mode 100644 index 24edc0b7bde49..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates6.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-scopes-duplicates6.ts] //// - -//// [file1.ts] - -var var1 = 0; - -//// [file2.ts] -let var1 = 0; - -//// [file1.js] -var var1 = 0; -//// [file2.js] -let var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt b/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt index dafbae9708030..dad85f9f81946 100644 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt +++ b/tests/baselines/reference/letDeclarations-scopes-duplicates7.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/file1.ts(2,5): error TS2300: Duplicate identifier 'var1'. -tests/cases/compiler/file2.ts(1,5): error TS2300: Duplicate identifier 'var1'. +tests/cases/compiler/file1.ts(2,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. +tests/cases/compiler/file2.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file1.ts (1 errors) ==== let var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. ==== tests/cases/compiler/file2.ts (1 errors) ==== var var1 = 0; ~~~~ -!!! error TS2300: Duplicate identifier 'var1'. \ No newline at end of file +!!! error TS2451: Cannot redeclare block-scoped variable 'var1'. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-scopes-duplicates7.js b/tests/baselines/reference/letDeclarations-scopes-duplicates7.js deleted file mode 100644 index 4cbc359e2c255..0000000000000 --- a/tests/baselines/reference/letDeclarations-scopes-duplicates7.js +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-scopes-duplicates7.ts] //// - -//// [file1.ts] - -let var1 = 0; - -//// [file2.ts] -var var1 = 0; - -//// [file1.js] -let var1 = 0; -//// [file2.js] -var var1 = 0; diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition.js b/tests/baselines/reference/letDeclarations-useBeforeDefinition.js deleted file mode 100644 index be1f9a127f49a..0000000000000 --- a/tests/baselines/reference/letDeclarations-useBeforeDefinition.js +++ /dev/null @@ -1,24 +0,0 @@ -//// [letDeclarations-useBeforeDefinition.ts] - -{ - l1; - let l1; -} - -var v1; -{ - v1; - let v1 = 0; -} - - -//// [letDeclarations-useBeforeDefinition.js] -{ - l1; - let l1; -} -var v1; -{ - v1; - let v1 = 0; -} diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.js b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.js deleted file mode 100644 index 35560edd1c887..0000000000000 --- a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.js +++ /dev/null @@ -1,12 +0,0 @@ -//// [tests/cases/compiler/letDeclarations-useBeforeDefinition2.ts] //// - -//// [file1.ts] - -l; - -//// [file2.ts] -const l = 0; - -//// [out.js] -l; -const l = 0; diff --git a/tests/baselines/reference/parserEnum5.errors.txt b/tests/baselines/reference/parserEnum5.errors.txt index 40c2c933955a6..b98fdfbfba503 100644 --- a/tests/baselines/reference/parserEnum5.errors.txt +++ b/tests/baselines/reference/parserEnum5.errors.txt @@ -1,9 +1,9 @@ tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(2,12): error TS1005: ',' expected. tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,15): error TS1005: ',' expected. tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,24): error TS1005: ',' expected. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(2,14): error TS1151: An enum member cannot have a numeric name. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,17): error TS1151: An enum member cannot have a numeric name. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,26): error TS1151: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(2,14): error TS2452: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,17): error TS2452: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,26): error TS2452: An enum member cannot have a numeric name. ==== tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts (6 errors) ==== @@ -12,13 +12,13 @@ tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum5.ts(3,26) ~ !!! error TS1005: ',' expected. ~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. enum E1 { a, b: 1, c, d: 2 = 3 } ~ !!! error TS1005: ',' expected. ~ !!! error TS1005: ',' expected. ~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. ~ -!!! error TS1151: An enum member cannot have a numeric name. \ No newline at end of file +!!! error TS2452: An enum member cannot have a numeric name. \ No newline at end of file diff --git a/tests/baselines/reference/parserEnum7.errors.txt b/tests/baselines/reference/parserEnum7.errors.txt index a4a2326546a05..1a7f26df8db9c 100644 --- a/tests/baselines/reference/parserEnum7.errors.txt +++ b/tests/baselines/reference/parserEnum7.errors.txt @@ -1,15 +1,15 @@ -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,3): error TS1151: An enum member cannot have a numeric name. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,6): error TS1151: An enum member cannot have a numeric name. -tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,9): error TS1151: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,3): error TS2452: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,6): error TS2452: An enum member cannot have a numeric name. +tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts(2,9): error TS2452: An enum member cannot have a numeric name. ==== tests/cases/conformance/parser/ecmascript5/EnumDeclarations/parserEnum7.ts (3 errors) ==== enum E { 1, 2, 3 ~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. ~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. ~ -!!! error TS1151: An enum member cannot have a numeric name. +!!! error TS2452: An enum member cannot have a numeric name. } \ No newline at end of file From 373dc760bf78c78f6e2752e35e7e0f8f679019de Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 20 Oct 2014 17:41:16 -0700 Subject: [PATCH 23/25] respond to code review comments --- src/compiler/checker.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca250fb7e538e..b56d8e6434d0f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -333,8 +333,10 @@ module ts { Debug.assert(declaration, "Block-scoped variable declaration is undefined"); var declarationSourceFile = getSourceFileOfNode(declaration); var referenceSourceFile = getSourceFileOfNode(errorLocation); - if (declarationSourceFile === referenceSourceFile && declaration.pos > errorLocation.pos) { - error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name)); + if (declarationSourceFile === referenceSourceFile) { + if (declaration.pos > errorLocation.pos) { + error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, identifierToString(declaration.name)); + } } else if (compilerOptions.out) { var sourceFiles = program.getSourceFiles(); From e4a20849bba25885218a37f8f403e5f21d00f96b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 24 Oct 2014 10:14:36 -0700 Subject: [PATCH 24/25] Ensure let and const declarations in labels are parsed correctelly --- src/compiler/parser.ts | 8 ++-- .../letDeclarations-validContexts.errors.txt | 20 ++++++++++ .../letDeclarations-validContexts.js | 37 +++++++++++++++++++ .../compiler/letDeclarations-validContexts.ts | 20 ++++++++++ 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index caa62b7ae9eeb..79140cff1652b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3916,14 +3916,14 @@ module ts { } function parseSourceElement() { - return parseSourceElementOrModuleElement(ModifierContext.SourceElements, /*allowLetAndConstDeclarations*/ false); + return parseSourceElementOrModuleElement(ModifierContext.SourceElements); } function parseModuleElement() { - return parseSourceElementOrModuleElement(ModifierContext.ModuleElements, /*allowLetAndConstDeclarations*/ true); + return parseSourceElementOrModuleElement(ModifierContext.ModuleElements); } - function parseSourceElementOrModuleElement(modifierContext: ModifierContext, allowLetAndConstDeclarations: boolean): Statement { + function parseSourceElementOrModuleElement(modifierContext: ModifierContext): Statement { if (isDeclaration()) { return parseDeclaration(modifierContext); } @@ -3931,7 +3931,7 @@ module ts { var statementStart = scanner.getTokenPos(); var statementFirstTokenLength = scanner.getTextPos() - statementStart; var errorCountBeforeStatement = file.syntacticErrors.length; - var statement = parseStatement(allowLetAndConstDeclarations); + var statement = parseStatement(/*allowLetAndConstDeclarations*/ true); if (inAmbientContext && file.syntacticErrors.length === errorCountBeforeStatement) { grammarErrorAtPos(statementStart, statementFirstTokenLength, Diagnostics.Statements_are_not_allowed_in_ambient_contexts); diff --git a/tests/baselines/reference/letDeclarations-validContexts.errors.txt b/tests/baselines/reference/letDeclarations-validContexts.errors.txt index de6cf7beef417..3f3b7a2634f09 100644 --- a/tests/baselines/reference/letDeclarations-validContexts.errors.txt +++ b/tests/baselines/reference/letDeclarations-validContexts.errors.txt @@ -126,4 +126,24 @@ tests/cases/compiler/letDeclarations-validContexts.ts(20,7): error TS2410: All s f2: () => { let l29 = 0; } + } + + // labels + label: let l30 = 0; + { + label2: let l31 = 0; + } + + function f3() { + label: let l32 = 0; + { + label2: let l33 = 0; + } + } + + module m3 { + label: let l34 = 0; + { + label2: let l35 = 0; + } } \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-validContexts.js b/tests/baselines/reference/letDeclarations-validContexts.js index daa25014ab33a..13eaafb07120d 100644 --- a/tests/baselines/reference/letDeclarations-validContexts.js +++ b/tests/baselines/reference/letDeclarations-validContexts.js @@ -121,6 +121,26 @@ var o = { f2: () => { let l29 = 0; } +} + +// labels +label: let l30 = 0; +{ + label2: let l31 = 0; +} + +function f3() { + label: let l32 = 0; + { + label2: let l33 = 0; + } +} + +module m3 { + label: let l34 = 0; + { + label2: let l35 = 0; + } } //// [letDeclarations-validContexts.js] @@ -227,3 +247,20 @@ var o = { let l29 = 0; } }; +label: let l30 = 0; +{ + label2: let l31 = 0; +} +function f3() { + label: let l32 = 0; + { + label2: let l33 = 0; + } +} +var m3; +(function (m3) { + label: let l34 = 0; + { + label2: let l35 = 0; + } +})(m3 || (m3 = {})); diff --git a/tests/cases/compiler/letDeclarations-validContexts.ts b/tests/cases/compiler/letDeclarations-validContexts.ts index 32801f2d00966..baedfa2644cb0 100644 --- a/tests/cases/compiler/letDeclarations-validContexts.ts +++ b/tests/cases/compiler/letDeclarations-validContexts.ts @@ -121,4 +121,24 @@ var o = { f2: () => { let l29 = 0; } +} + +// labels +label: let l30 = 0; +{ + label2: let l31 = 0; +} + +function f3() { + label: let l32 = 0; + { + label2: let l33 = 0; + } +} + +module m3 { + label: let l34 = 0; + { + label2: let l35 = 0; + } } \ No newline at end of file From 67c78a266206f3d217259a576583f239a87f6afb Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Fri, 24 Oct 2014 10:30:40 -0700 Subject: [PATCH 25/25] Only check for collisions with variabels and not properties --- src/compiler/checker.ts | 15 +++++------ ...nstDeclarationShadowedByVarDeclaration3.js | 21 ++++++++++++++++ ...DeclarationShadowedByVarDeclaration3.types | 25 +++++++++++++++++++ ...nstDeclarationShadowedByVarDeclaration3.ts | 9 +++++++ 4 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.js create mode 100644 tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.types create mode 100644 tests/cases/compiler/constDeclarationShadowedByVarDeclaration3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6ff0d5f268be6..b1e256f130070 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6885,7 +6885,7 @@ module ts { } } - function checkCollisionsWithConstDeclarations(node: VariableDeclaration) { + function checkCollisionWithConstDeclarations(node: VariableDeclaration) { // Variable declarations are hoisted to the top of their function scope. They can shadow // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition // by the binder as the declaration scope is different. @@ -6906,10 +6906,12 @@ module ts { // } if (node.initializer && (node.flags & NodeFlags.BlockScoped) === 0) { var symbol = getSymbolOfNode(node); - var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); - if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { - if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { - error(node, Diagnostics.Cannot_redeclare_block_scoped_variable_0, symbolToString(localDeclarationSymbol)); + if (symbol.flags & SymbolFlags.FunctionScopedVariable) { + var localDeclarationSymbol = resolveName(node, node.name.text, SymbolFlags.Variable, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined); + if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { + if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.Const) { + error(node, Diagnostics.Cannot_redeclare_block_scoped_variable_0, symbolToString(localDeclarationSymbol)); + } } } } @@ -6938,8 +6940,7 @@ module ts { // Use default messages checkTypeAssignableTo(checkAndMarkExpression(node.initializer), type, node, /*chainedMessage*/ undefined, /*terminalMessage*/ undefined); } - - checkCollisionsWithConstDeclarations(node); + checkCollisionWithConstDeclarations(node); } checkCollisionWithCapturedSuperVariable(node, node.name); diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.js b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.js new file mode 100644 index 0000000000000..6f5b898c5ff56 --- /dev/null +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.js @@ -0,0 +1,21 @@ +//// [constDeclarationShadowedByVarDeclaration3.ts] +// Ensure only checking for const declarations shadowed by vars +class Rule { + public regex: RegExp = new RegExp(''); + public name: string = ''; + + constructor(name: string) { + this.name = name; + } +} + +//// [constDeclarationShadowedByVarDeclaration3.js] +// Ensure only checking for const declarations shadowed by vars +var Rule = (function () { + function Rule(name) { + this.regex = new RegExp(''); + this.name = ''; + this.name = name; + } + return Rule; +})(); diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.types b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.types new file mode 100644 index 0000000000000..89490567f1449 --- /dev/null +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration3.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/constDeclarationShadowedByVarDeclaration3.ts === +// Ensure only checking for const declarations shadowed by vars +class Rule { +>Rule : Rule + + public regex: RegExp = new RegExp(''); +>regex : RegExp +>RegExp : RegExp +>new RegExp('') : RegExp +>RegExp : { (pattern: string, flags?: string): RegExp; new (pattern: string, flags?: string): RegExp; $1: string; $2: string; $3: string; $4: string; $5: string; $6: string; $7: string; $8: string; $9: string; lastMatch: string; } + + public name: string = ''; +>name : string + + constructor(name: string) { +>name : string + + this.name = name; +>this.name = name : string +>this.name : string +>this : Rule +>name : string +>name : string + } +} diff --git a/tests/cases/compiler/constDeclarationShadowedByVarDeclaration3.ts b/tests/cases/compiler/constDeclarationShadowedByVarDeclaration3.ts new file mode 100644 index 0000000000000..5b4229a8e5469 --- /dev/null +++ b/tests/cases/compiler/constDeclarationShadowedByVarDeclaration3.ts @@ -0,0 +1,9 @@ +// Ensure only checking for const declarations shadowed by vars +class Rule { + public regex: RegExp = new RegExp(''); + public name: string = ''; + + constructor(name: string) { + this.name = name; + } +} \ No newline at end of file