From 460fc037e69145c52229ff9f1cd7c64e4fc75d05 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 25 Nov 2014 12:12:55 -0800 Subject: [PATCH 01/14] Refactoring emitter for emit ES6 features natively --- src/compiler/checker.ts | 2 +- src/compiler/emitter.ts | 64 ++++++++++++++++++++++++----------------- src/compiler/parser.ts | 6 ++-- src/compiler/types.ts | 2 +- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5ee9fa4ab3e..321195e4fb5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8881,7 +8881,7 @@ module ts { // This is necessary as an identifier in short-hand property assignment can contains two meaning: // property name and property value. if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { - return resolveEntityName(location, (location).name, SymbolFlags.Value); + return resolveEntityName(location, (location).name, SymbolFlags.Value); } return undefined; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5cdf98aa63e..8a045bd1dc2 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2197,33 +2197,28 @@ module ts { emitTrailingComments(node); } - function emitShortHandPropertyAssignment(node: ShortHandPropertyDeclaration) { - function emitAsNormalPropertyAssignment() { - emitLeadingComments(node); - // Emit identifier as an identifier - emit(node.name); - write(": "); - // Even though this is stored as identified because it is in short-hand property assignment, - // treated it as expression - emitExpressionIdentifier(node.name); - emitTrailingComments(node); - } + function emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node: ShorthandPropertyDeclaration) { + emitLeadingComments(node); + // Emit identifier as an identifier + emit(node.name); + write(": "); + // Even though this is stored as identified because it is in short-hand property assignment, + // treated it as expression + emitExpressionIdentifier(node.name); + emitTrailingComments(node); + } - if (compilerOptions.target < ScriptTarget.ES6) { - emitAsNormalPropertyAssignment(); + function emitShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { + // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment + var prefix = resolver.getExpressionNamePrefix(node.name); + if (prefix) { + emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); } - else if (compilerOptions.target >= ScriptTarget.ES6) { - // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment - var prefix = resolver.getExpressionNamePrefix(node.name); - if (prefix) { - emitAsNormalPropertyAssignment(); - } - // If short-hand property has no prefix, emit it as short-hand. - else { - emitLeadingComments(node); - emit(node.name); - emitTrailingComments(node); - } + // If short-hand property has no prefix, emit it as short-hand. + else { + emitLeadingComments(node); + emit(node.name); + emitTrailingComments(node); } } @@ -3413,6 +3408,7 @@ module ts { return emitPinnedOrTripleSlashComments(node); } + // Check if node has SyntaxKind which can be emitted the same in both version of ES5 and ES6 switch (node.kind) { case SyntaxKind.Identifier: return emitIdentifier(node); @@ -3451,8 +3447,6 @@ module ts { return emitObjectLiteral(node); case SyntaxKind.PropertyAssignment: return emitPropertyAssignment(node); - case SyntaxKind.ShorthandPropertyAssignment: - return emitShortHandPropertyAssignment(node); case SyntaxKind.PropertyAccess: return emitPropertyAccess(node); case SyntaxKind.IndexedAccess: @@ -3539,6 +3533,22 @@ module ts { case SyntaxKind.SourceFile: return emitSourceFile(node); } + + // Emit node which needs to be emitted differently between ES5 and ES6 + if (compilerOptions.target < ScriptTarget.ES6) { + // Emit node down-leveling + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); + } + } + else if (compilerOptions.target >= ScriptTarget.ES6) { + // Emit node natively in EcmaScript6 + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return emitShorthandPropertyAssignment(node); + } + } } function hasDetachedComments(pos: number) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8d7bf9e4fe7..86b847d1aeb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2764,7 +2764,7 @@ module ts { // Parse to check if it is short-hand property assignment or normal property assignment if ((token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken) && tokenIsIdentifier) { - node = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); + node = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); node.name = propertyName; } else { @@ -3968,7 +3968,7 @@ module ts { case SyntaxKind.ReturnStatement: return checkReturnStatement(node); case SyntaxKind.SetAccessor: return checkSetAccessor(node); case SyntaxKind.SourceFile: return checkSourceFile(node); - case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); + case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); case SyntaxKind.SwitchStatement: return checkSwitchStatement(node); case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); case SyntaxKind.TupleType: return checkTupleType(node); @@ -4832,7 +4832,7 @@ module ts { return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); } - function checkShorthandPropertyAssignment(node: ShortHandPropertyDeclaration): boolean { + function checkShorthandPropertyAssignment(node: ShorthandPropertyDeclaration): boolean { return checkForInvalidQuestionMark(node, Diagnostics.An_object_member_cannot_be_declared_optional); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 83937c24ed9..3df983f595b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -360,7 +360,7 @@ module ts { initializer?: Expression; } - export interface ShortHandPropertyDeclaration extends Declaration { + export interface ShorthandPropertyDeclaration extends Declaration { name: Identifier; } From b55038314356215857247bb444b3d0b340c07a6a Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 25 Nov 2014 12:12:55 -0800 Subject: [PATCH 02/14] Refactoring emitter for emit ES6 features natively --- src/compiler/checker.ts | 2 +- src/compiler/emitter.ts | 64 ++++++++++++++++++++++++----------------- src/compiler/parser.ts | 6 ++-- src/compiler/types.ts | 2 +- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5ee9fa4ab3e..321195e4fb5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8881,7 +8881,7 @@ module ts { // This is necessary as an identifier in short-hand property assignment can contains two meaning: // property name and property value. if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { - return resolveEntityName(location, (location).name, SymbolFlags.Value); + return resolveEntityName(location, (location).name, SymbolFlags.Value); } return undefined; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5cdf98aa63e..6b5c8d1fe39 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2197,33 +2197,28 @@ module ts { emitTrailingComments(node); } - function emitShortHandPropertyAssignment(node: ShortHandPropertyDeclaration) { - function emitAsNormalPropertyAssignment() { - emitLeadingComments(node); - // Emit identifier as an identifier - emit(node.name); - write(": "); - // Even though this is stored as identified because it is in short-hand property assignment, - // treated it as expression - emitExpressionIdentifier(node.name); - emitTrailingComments(node); - } + function emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node: ShorthandPropertyDeclaration) { + emitLeadingComments(node); + // Emit identifier as an identifier + emit(node.name); + write(": "); + // Even though this is stored as identified because it is in short-hand property assignment, + // treated it as expression + emitExpressionIdentifier(node.name); + emitTrailingComments(node); + } - if (compilerOptions.target < ScriptTarget.ES6) { - emitAsNormalPropertyAssignment(); + function emitShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { + // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment + var prefix = resolver.getExpressionNamePrefix(node.name); + if (prefix) { + emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); } - else if (compilerOptions.target >= ScriptTarget.ES6) { - // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment - var prefix = resolver.getExpressionNamePrefix(node.name); - if (prefix) { - emitAsNormalPropertyAssignment(); - } - // If short-hand property has no prefix, emit it as short-hand. - else { - emitLeadingComments(node); - emit(node.name); - emitTrailingComments(node); - } + // If short-hand property has no prefix, emit it as short-hand. + else { + emitLeadingComments(node); + emit(node.name); + emitTrailingComments(node); } } @@ -3413,6 +3408,7 @@ module ts { return emitPinnedOrTripleSlashComments(node); } + // Check if node has SyntaxKind which can be emitted regardless of the ScriptTarget switch (node.kind) { case SyntaxKind.Identifier: return emitIdentifier(node); @@ -3451,8 +3447,6 @@ module ts { return emitObjectLiteral(node); case SyntaxKind.PropertyAssignment: return emitPropertyAssignment(node); - case SyntaxKind.ShorthandPropertyAssignment: - return emitShortHandPropertyAssignment(node); case SyntaxKind.PropertyAccess: return emitPropertyAccess(node); case SyntaxKind.IndexedAccess: @@ -3539,6 +3533,22 @@ module ts { case SyntaxKind.SourceFile: return emitSourceFile(node); } + + // Emit node which needs to be emitted differently depended on ScriptTarget + if (compilerOptions.target < ScriptTarget.ES6) { + // Emit node down-leveling + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); + } + } + else if (compilerOptions.target >= ScriptTarget.ES6) { + // Emit node natively in EcmaScript6 + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return emitShorthandPropertyAssignment(node); + } + } } function hasDetachedComments(pos: number) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8d7bf9e4fe7..86b847d1aeb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2764,7 +2764,7 @@ module ts { // Parse to check if it is short-hand property assignment or normal property assignment if ((token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken) && tokenIsIdentifier) { - node = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); + node = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); node.name = propertyName; } else { @@ -3968,7 +3968,7 @@ module ts { case SyntaxKind.ReturnStatement: return checkReturnStatement(node); case SyntaxKind.SetAccessor: return checkSetAccessor(node); case SyntaxKind.SourceFile: return checkSourceFile(node); - case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); + case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); case SyntaxKind.SwitchStatement: return checkSwitchStatement(node); case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); case SyntaxKind.TupleType: return checkTupleType(node); @@ -4832,7 +4832,7 @@ module ts { return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); } - function checkShorthandPropertyAssignment(node: ShortHandPropertyDeclaration): boolean { + function checkShorthandPropertyAssignment(node: ShorthandPropertyDeclaration): boolean { return checkForInvalidQuestionMark(node, Diagnostics.An_object_member_cannot_be_declared_optional); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 83937c24ed9..3df983f595b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -360,7 +360,7 @@ module ts { initializer?: Expression; } - export interface ShortHandPropertyDeclaration extends Declaration { + export interface ShorthandPropertyDeclaration extends Declaration { name: Identifier; } From 7ba032be3dd5a0d4ad078ad3d6a068ef4951f171 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2014 15:32:52 -0800 Subject: [PATCH 03/14] Emit services as an external module. --- Jakefile | 37 ++++++++++++++++++++++++++----------- src/services/shims.ts | 6 ++++++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Jakefile b/Jakefile index ba82e9c3f43..9ecc126b06d 100644 --- a/Jakefile +++ b/Jakefile @@ -1,6 +1,7 @@ // This file contains the build logic for the public repo var fs = require("fs"); +var os = require("os"); var path = require("path"); var child_process = require("child_process"); @@ -145,7 +146,7 @@ var compilerFilename = "tsc.js"; * @param useBuiltCompiler: true to use the built compiler, false to use the LKG * @param noOutFile: true to compile without using --out */ -function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations) { +function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations, callback) { file(outFile, prereqs, function() { var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory; var options = "-removeComments --module commonjs -noImplicitAny "; @@ -177,6 +178,11 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu prependFile(prefixes[i], outFile); } } + + if (callback) { + callback(); + } + complete(); }); ex.addListener("error", function() { @@ -221,7 +227,7 @@ compileFile(processDiagnosticMessagesJs, [processDiagnosticMessagesTs], [processDiagnosticMessagesTs], [], - false); + /*useBuiltCompiler*/ false); // The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () { @@ -241,7 +247,6 @@ file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], ex.run(); }, {async: true}) - desc("Generates a diagnostic file in TypeScript based on an input JSON file"); task("generate-diagnostics", [diagnosticInfoMapTs]) @@ -252,13 +257,24 @@ compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(co var servicesFile = path.join(builtLocalDirectory, "typescriptServices.js"); var servicesDefinitionsFile = path.join(builtLocalDirectory, "typescriptServices.d.ts"); -compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].concat(servicesSources), [copyright], /*useBuiltCompiler:*/ true, /*noOutFile:*/ false, /*generateDeclarations:*/ true); + +compileFile(servicesFile, + servicesSources, + [builtLocalDirectory, copyright].concat(servicesSources), + [copyright], + /*useBuiltCompiler*/ true, + /*noOutFile*/ false, + /*generateDeclarations*/ true, + /*callback*/ fixDeclarationFile); + +function fixDeclarationFile() { + fs.appendFileSync(servicesDefinitionsFile, os.EOL + "export = ts;") +} // Local target to build the compiler and services desc("Builds the full compiler and services"); task("local", ["generate-diagnostics", "lib", tscFile, servicesFile]); - // Local target to build the compiler and services desc("Sets release mode flag"); task("release", function() { @@ -275,7 +291,6 @@ task("clean", function() { jake.rmRf(builtDirectory); }); - // Generate Markdown spec var word2mdJs = path.join(scriptsDirectory, "word2md.js"); var word2mdTs = path.join(scriptsDirectory, "word2md.ts"); @@ -289,7 +304,7 @@ compileFile(word2mdJs, [word2mdTs], [word2mdTs], [], - false); + /*useBuiltCompiler*/ false); // The generated spec.md; built for the 'generate-spec' task file(specMd, [word2mdJs, specWord], function () { @@ -438,7 +453,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () { // Browser tests var nodeServerOutFile = 'tests/webTestServer.js' var nodeServerInFile = 'tests/webTestServer.ts' -compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], true, true); +compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, /*noOutFile*/ true); desc("Runs browserify on run.js to produce a file suitable for running tests in the browser"); task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() { @@ -513,7 +528,7 @@ task("baseline-accept-rwc", function() { // Webhost var webhostPath = "tests/webhost/webtsc.ts"; var webhostJsPath = "tests/webhost/webtsc.js"; -compileFile(webhostJsPath, [webhostPath], [tscFile, webhostPath].concat(libraryTargets), [], true); +compileFile(webhostJsPath, [webhostPath], [tscFile, webhostPath].concat(libraryTargets), [], /*useBuiltCompiler*/true); desc("Builds the tsc web host"); task("webhost", [webhostJsPath], function() { @@ -523,7 +538,7 @@ task("webhost", [webhostJsPath], function() { // Perf compiler var perftscPath = "tests/perftsc.ts"; var perftscJsPath = "built/local/perftsc.js"; -compileFile(perftscJsPath, [perftscPath], [tscFile, perftscPath, "tests/perfsys.ts"].concat(libraryTargets), [], true); +compileFile(perftscJsPath, [perftscPath], [tscFile, perftscPath, "tests/perfsys.ts"].concat(libraryTargets), [], /*useBuiltCompiler*/ true); desc("Builds augmented version of the compiler for perf tests"); task("perftsc", [perftscJsPath]); @@ -547,7 +562,7 @@ file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function() { var instrumenterPath = harnessDirectory + 'instrumenter.ts'; var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js'; -compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath], [], true); +compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath], [], /*useBuiltCompiler*/ true); desc("Builds an instrumented tsc.js"); task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function() { diff --git a/src/services/shims.ts b/src/services/shims.ts index 49603fd4a2e..9428e8c534f 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -920,3 +920,9 @@ module TypeScript.Services { export var TypeScriptServicesFactory = ts.TypeScriptServicesFactory; } +module ts { + declare var module: any; + if (typeof module !== "undefined" && module.exports) { + module.exports = ts; + } +} \ No newline at end of file From 55be5300044c709cf6712fc9ef5dc34453cb803d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2014 15:52:34 -0800 Subject: [PATCH 04/14] Get rid of emitted empty module. --- src/services/shims.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/services/shims.ts b/src/services/shims.ts index 9428e8c534f..64759fffc9f 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -912,6 +912,11 @@ module ts { throw new Error("Invalid operation"); } } + + declare var module: any; + if (typeof module !== "undefined" && module.exports) { + module.exports = ts; + } } @@ -919,10 +924,3 @@ module ts { module TypeScript.Services { export var TypeScriptServicesFactory = ts.TypeScriptServicesFactory; } - -module ts { - declare var module: any; - if (typeof module !== "undefined" && module.exports) { - module.exports = ts; - } -} \ No newline at end of file From 08165c0b17f18972b774c3fd6d316de39260ba71 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 1 Dec 2014 23:15:13 -0800 Subject: [PATCH 05/14] Ensure getEmitOutput only check the file requested --- src/compiler/checker.ts | 13 ++--- src/compiler/emitter.ts | 35 +++++++++---- src/compiler/types.ts | 3 +- src/harness/fourslash.ts | 7 ++- src/harness/harness.ts | 1 - src/services/services.ts | 52 ++++--------------- ...mitOutputWithEarlySyntacticErrors.baseline | 2 + ...ithSemanticErrorsForMultipleFiles.baseline | 8 +++ ...thSemanticErrorsForMultipleFiles2.baseline | 8 +++ ...thSyntacticErrorsForMultipleFiles.baseline | 6 +++ ...hSyntacticErrorsForMultipleFiles2.baseline | 2 + .../getEmitOutputWithEarlySemanticErrors.ts | 10 ++++ ...utputWithSemanticErrorsForMultipleFiles.ts | 16 ++++++ ...tputWithSemanticErrorsForMultipleFiles2.ts | 17 ++++++ ...tputWithSyntacticErrorsForMultipleFiles.ts | 15 ++++++ ...putWithSyntacticErrorsForMultipleFiles2.ts | 16 ++++++ 16 files changed, 142 insertions(+), 69 deletions(-) create mode 100644 tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline create mode 100644 tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline create mode 100644 tests/cases/fourslash/getEmitOutputWithEarlySemanticErrors.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles2.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles.ts create mode 100644 tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a663b038844..edf966a2fe1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -85,7 +85,6 @@ module ts { getDiagnostics, getDeclarationDiagnostics, getGlobalDiagnostics, - checkProgram, getParentOfSymbol, getNarrowedTypeOfSymbol, getDeclaredTypeOfSymbol, @@ -8634,10 +8633,6 @@ module ts { } } - function checkProgram() { - forEach(program.getSourceFiles(), checkSourceFile); - } - function getSortedDiagnostics(): Diagnostic[]{ Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode"); @@ -8650,12 +8645,11 @@ module ts { } function getDiagnostics(sourceFile?: SourceFile): Diagnostic[]{ - if (sourceFile) { checkSourceFile(sourceFile); return filter(getSortedDiagnostics(), d => d.file === sourceFile); } - checkProgram(); + forEach(program.getSourceFiles(), checkSourceFile); return getSortedDiagnostics(); } @@ -9173,9 +9167,9 @@ module ts { return isImportResolvedToValue(getSymbolOfNode(node)); } - function hasSemanticErrors() { + function hasSemanticErrors(sourceFile?: SourceFile) { // Return true if there is any semantic error in a file or globally - return getDiagnostics().length > 0 || getGlobalDiagnostics().length > 0; + return getDiagnostics(sourceFile).length > 0 || getGlobalDiagnostics().length > 0; } function isEmitBlocked(sourceFile?: SourceFile): boolean { @@ -9293,7 +9287,6 @@ module ts { function invokeEmitter(targetSourceFile?: SourceFile) { var resolver = createResolver(); - checkProgram(); return emitFiles(resolver, targetSourceFile); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fab0433890a..cdb36cc5ac9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3791,20 +3791,14 @@ module ts { } } - var hasSemanticErrors = resolver.hasSemanticErrors(); - var isEmitBlocked = resolver.isEmitBlocked(targetSourceFile); - - function emitFile(jsFilePath: string, sourceFile?: SourceFile) { - if (!isEmitBlocked) { - emitJavaScript(jsFilePath, sourceFile); - if (!hasSemanticErrors && compilerOptions.declaration) { - writeDeclarationFile(jsFilePath, sourceFile); - } - } - } + var hasSemanticErrors: boolean = false; + var isEmitBlocked: boolean = false; if (targetSourceFile === undefined) { // No targetSourceFile is specified (e.g. calling emitter from batch compiler) + hasSemanticErrors = resolver.hasSemanticErrors(); + isEmitBlocked = resolver.isEmitBlocked(); + forEach(program.getSourceFiles(), sourceFile => { if (shouldEmitToOwnFile(sourceFile, compilerOptions)) { var jsFilePath = getOwnEmitOutputFilePath(sourceFile, program, ".js"); @@ -3820,16 +3814,35 @@ module ts { // targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service) if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) { // If shouldEmitToOwnFile returns true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file + hasSemanticErrors = resolver.hasSemanticErrors(targetSourceFile); + isEmitBlocked = resolver.isEmitBlocked(targetSourceFile); + var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js"); emitFile(jsFilePath, targetSourceFile); } else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) { // Otherwise, if --out is specified and targetSourceFile is not a declaration file, // Emit all, non-external-module file, into one single output file + forEach(program.getSourceFiles(), sourceFile => { + if (!shouldEmitToOwnFile(sourceFile, compilerOptions)) { + hasSemanticErrors = hasSemanticErrors || resolver.hasSemanticErrors(sourceFile); + isEmitBlocked = isEmitBlocked || resolver.isEmitBlocked(sourceFile); + } + }); + emitFile(compilerOptions.out); } } + function emitFile(jsFilePath: string, sourceFile?: SourceFile) { + if (!isEmitBlocked) { + emitJavaScript(jsFilePath, sourceFile); + if (!hasSemanticErrors && compilerOptions.declaration) { + writeDeclarationFile(jsFilePath, sourceFile); + } + } + } + // Sort and make the unique list of diagnostics diagnostics.sort(compareDiagnostics); diagnostics = deduplicateSortedDiagnostics(diagnostics); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 277e2cce5ff..0c3f3d96d98 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -861,7 +861,6 @@ module ts { getIdentifierCount(): number; getSymbolCount(): number; getTypeCount(): number; - checkProgram(): void; emitFiles(targetSourceFile?: SourceFile): EmitResult; getParentOfSymbol(symbol: Symbol): Symbol; getNarrowedTypeOfSymbol(symbol: Symbol, node: Node): Type; @@ -973,7 +972,7 @@ module ts { isTopLevelValueImportWithEntityName(node: ImportDeclaration): boolean; getNodeCheckFlags(node: Node): NodeCheckFlags; getEnumMemberValue(node: EnumMember): number; - hasSemanticErrors(): boolean; + hasSemanticErrors(sourceFile?: SourceFile): boolean; isDeclarationVisible(node: Declaration): boolean; isImplementationOfOverload(node: FunctionLikeDeclaration): boolean; writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableOrParameterDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 05e65f5648f..7e364730ede 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2217,11 +2217,10 @@ module FourSlash { // TODO (drosen): We need to enforce checking on these tests. var program = ts.createProgram([Harness.Compiler.fourslashFilename, fileName], { out: "fourslashTestOutput.js", noResolve: true }, host); var checker = ts.createTypeChecker(program, /*fullTypeCheckMode*/ true); - checker.checkProgram(); - var errs = program.getDiagnostics().concat(checker.getDiagnostics()); - if (errs.length > 0) { - throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n')); + var errors = program.getDiagnostics().concat(checker.getDiagnostics()); + if (errors.length > 0) { + throw new Error('Error compiling ' + fileName + ': ' + errors.map(e => e.messageText).join('\r\n')); } checker.emitFiles(); result = result || ''; // Might have an empty fourslash file diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 640d5f0ae53..c0d3ddedce3 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -801,7 +801,6 @@ module Harness { useCaseSensitiveFileNames)); var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true); - checker.checkProgram(); var isEmitBlocked = checker.isEmitBlocked(); diff --git a/src/services/services.ts b/src/services/services.ts index 8bbc03aad6f..a191e5af83c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4665,18 +4665,14 @@ module ts { function getEmitOutput(filename: string): EmitOutput { synchronizeHostData(); + filename = normalizeSlashes(filename); - var compilerOptions = program.getCompilerOptions(); - var targetSourceFile = program.getSourceFile(filename); // Current selected file to be output - // If --out flag is not specified, shouldEmitToOwnFile is true. Otherwise shouldEmitToOwnFile is false. - var shouldEmitToOwnFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions); - var emitOutput: EmitOutput = { - outputFiles: [], - emitOutputStatus: undefined, - }; + var sourceFile = getSourceFile(filename); + + var outputFiles: OutputFile[] = []; function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) { - emitOutput.outputFiles.push({ + outputFiles.push({ name: filename, writeByteOrderMark: writeByteOrderMark, text: data @@ -4686,41 +4682,15 @@ module ts { // Initialize writer for CompilerHost.writeFile writer = getEmitOutputWriter; - var containSyntacticErrors = false; - - if (shouldEmitToOwnFile) { - // Check only the file we want to emit - containSyntacticErrors = containErrors(program.getDiagnostics(targetSourceFile)); - } else { - // Check the syntactic of only sourceFiles that will get emitted into single output - // Terminate the process immediately if we encounter a syntax error from one of the sourceFiles - containSyntacticErrors = forEach(program.getSourceFiles(), sourceFile => { - if (!isExternalModuleOrDeclarationFile(sourceFile)) { - // If emit to a single file then we will check all files that do not have external module - return containErrors(program.getDiagnostics(sourceFile)); - } - return false; - }); - } - - if (containSyntacticErrors) { - // If there is a syntax error, terminate the process and report outputStatus - emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped; - // Reset writer back to undefined to make sure that we produce an error message - // if CompilerHost.writeFile is called when we are not in getEmitOutput - writer = undefined; - return emitOutput; - } - - // Perform semantic and force a type check before emit to ensure that all symbols are updated - // EmitFiles will report if there is an error from TypeChecker and Emitter - // Depend whether we will have to emit into a single file or not either emit only selected file in the project, emit all files into a single file - var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile); - emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; + var emitOutput = getFullTypeCheckChecker().emitFiles(sourceFile); // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput writer = undefined; - return emitOutput; + + return { + outputFiles, + emitOutputStatus: emitOutput.emitResultStatus + }; } function getMeaningFromDeclaration(node: Node): SemanticMeaning { diff --git a/tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline b/tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline new file mode 100644 index 00000000000..a5d5d2eb9d7 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline @@ -0,0 +1,2 @@ +EmitOutputStatus : AllOutputGenerationSkipped + diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline new file mode 100644 index 00000000000..c6396314824 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline @@ -0,0 +1,8 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile1.js +// File to emit, does not contain semantic errors +// expected to be emitted correctelly regardless of the semantic errors in the other file +var noErrors = true; +Filename : tests/cases/fourslash/inputFile1.d.ts +declare var noErrors: boolean; + diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline new file mode 100644 index 00000000000..41b16b40e65 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline @@ -0,0 +1,8 @@ +EmitOutputStatus : DeclarationGenerationSkipped +Filename : out.js +// File to emit, does not contain semantic errors, but --out is passed +// expected to not generate declarations because of the semantic errors in the other file +var noErrors = true; +// File not emitted, and contains semantic errors +var semanticError = "string"; + diff --git a/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline new file mode 100644 index 00000000000..bf27703890b --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline @@ -0,0 +1,6 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile1.js +// File to emit, does not contain syntactic errors +// expected to be emitted correctelly regardless of the syntactic errors in the other file +var noErrors = true; + diff --git a/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline new file mode 100644 index 00000000000..a5d5d2eb9d7 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline @@ -0,0 +1,2 @@ +EmitOutputStatus : AllOutputGenerationSkipped + diff --git a/tests/cases/fourslash/getEmitOutputWithEarlySemanticErrors.ts b/tests/cases/fourslash/getEmitOutputWithEarlySemanticErrors.ts new file mode 100644 index 00000000000..2946fffb808 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithEarlySemanticErrors.ts @@ -0,0 +1,10 @@ +/// + +// @BaselineFile: getEmitOutputWithEarlySyntacticErrors.baseline + +// @Filename: inputFile1.ts +// @emitThisFile: true +//// // File contains early errors. All outputs should be skipped. +//// const uninitialized_const_error; + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts new file mode 100644 index 00000000000..5cfacc36715 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles.ts @@ -0,0 +1,16 @@ +/// + +// @BaselineFile: getEmitOutputWithSemanticErrorsForMultipleFiles.baseline +// @declaration: true + +// @Filename: inputFile1.ts +// @emitThisFile: true +//// // File to emit, does not contain semantic errors +//// // expected to be emitted correctelly regardless of the semantic errors in the other file +//// var noErrors = true; + +// @Filename: inputFile2.ts +//// // File not emitted, and contains semantic errors +//// var semanticError: boolean = "string"; + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles2.ts b/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles2.ts new file mode 100644 index 00000000000..d5cfd1346ca --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSemanticErrorsForMultipleFiles2.ts @@ -0,0 +1,17 @@ +/// + +// @BaselineFile: getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline +// @declaration: true +// @out: out.js + +// @Filename: inputFile1.ts +// @emitThisFile: true +//// // File to emit, does not contain semantic errors, but --out is passed +//// // expected to not generate declarations because of the semantic errors in the other file +//// var noErrors = true; + +// @Filename: inputFile2.ts +//// // File not emitted, and contains semantic errors +//// var semanticError: boolean = "string"; + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles.ts b/tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles.ts new file mode 100644 index 00000000000..3b3d01eaac8 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles.ts @@ -0,0 +1,15 @@ +/// + +// @BaselineFile: getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline + +// @Filename: inputFile1.ts +// @emitThisFile: true +//// // File to emit, does not contain syntactic errors +//// // expected to be emitted correctelly regardless of the syntactic errors in the other file +//// var noErrors = true; + +// @Filename: inputFile2.ts +//// // File not emitted, and contains syntactic errors +//// var syntactic Error; + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles2.ts b/tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles2.ts new file mode 100644 index 00000000000..ce82f958b91 --- /dev/null +++ b/tests/cases/fourslash/getEmitOutputWithSyntacticErrorsForMultipleFiles2.ts @@ -0,0 +1,16 @@ +/// + +// @BaselineFile: getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline +// @out: out.js + +// @Filename: inputFile1.ts +// @emitThisFile: true +//// // File to emit, does not contain syntactic errors, but --out is passed +//// // expected to not generate outputs because of the syntactic errors in the other file. +//// var noErrors = true; + +// @Filename: inputFile2.ts +//// // File not emitted, and contains syntactic errors +//// var syntactic Error; + +verify.baselineGetEmitOutput(); \ No newline at end of file From a6fe980d19c93b8763b00475a1b3e120cc0f3aca Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Dec 2014 13:54:44 -0800 Subject: [PATCH 06/14] Add explanatory comment. Reduce function allocations in the parser. --- src/compiler/parser.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9397661839d..de2d75286dc 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1395,10 +1395,12 @@ module ts { } function parseContextualModifier(t: SyntaxKind): boolean { - return token === t && tryParse(() => { - nextToken(); - return canFollowModifier(); - }); + return token === t && tryParse(nextTokenCanFollowModifier); + } + + function nextTokenCanFollowModifier() { + nextToken(); + return canFollowModifier(); } function parseAnyContextualModifier(): boolean { @@ -4066,9 +4068,13 @@ module ts { // literals. We check to ensure that it is only a string literal later in the grammar // walker. node.expression = parseExpression(); + + // Ensure the string being required is in our 'identifier' table. This will ensure + // that features like 'find refs' will look inside this file when search for its name. if (node.expression.kind === SyntaxKind.StringLiteral) { internIdentifier((node.expression).text); } + parseExpected(SyntaxKind.CloseParenToken); return finishNode(node); } From a6a7e81de2d27671229d6ed7ce68842f40f974e3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Dec 2014 14:05:35 -0800 Subject: [PATCH 07/14] Add failing test. --- ...oduleReferenceDoubleUnderscore1.errors.txt | 22 +++++++++++++++++++ ...xternalModuleReferenceDoubleUnderscore1.js | 19 ++++++++++++++++ ...xternalModuleReferenceDoubleUnderscore1.ts | 16 ++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt create mode 100644 tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js create mode 100644 tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt new file mode 100644 index 00000000000..80e2725d694 --- /dev/null +++ b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts(2,29): error TS2307: Cannot find external module '__timezonecomplete/basics'. + + +==== tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts (1 errors) ==== + declare module 'timezonecomplete' { + import basics = require("__timezonecomplete/basics"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find external module '__timezonecomplete/basics'. + export import TimeUnit = basics.TimeUnit; + } + + declare module '__timezonecomplete/basics' { + export enum TimeUnit { + Second = 0, + Minute = 1, + Hour = 2, + Day = 3, + Week = 4, + Month = 5, + Year = 6, + } + } \ No newline at end of file diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js new file mode 100644 index 00000000000..f6f9572ba6b --- /dev/null +++ b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js @@ -0,0 +1,19 @@ +//// [externalModuleReferenceDoubleUnderscore1.ts] +declare module 'timezonecomplete' { + import basics = require("__timezonecomplete/basics"); + export import TimeUnit = basics.TimeUnit; +} + +declare module '__timezonecomplete/basics' { + export enum TimeUnit { + Second = 0, + Minute = 1, + Hour = 2, + Day = 3, + Week = 4, + Month = 5, + Year = 6, + } +} + +//// [externalModuleReferenceDoubleUnderscore1.js] diff --git a/tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts b/tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts new file mode 100644 index 00000000000..1ff020b4919 --- /dev/null +++ b/tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts @@ -0,0 +1,16 @@ +declare module 'timezonecomplete' { + import basics = require("__timezonecomplete/basics"); + export import TimeUnit = basics.TimeUnit; +} + +declare module '__timezonecomplete/basics' { + export enum TimeUnit { + Second = 0, + Minute = 1, + Hour = 2, + Day = 3, + Week = 4, + Month = 5, + Year = 6, + } +} \ No newline at end of file From ec17f369a2acd19a18bcd6e63327c36634093eac Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Dec 2014 14:14:57 -0800 Subject: [PATCH 08/14] Find imported external modules that start with double underscores. --- src/compiler/checker.ts | 16 +++++--- ...oduleReferenceDoubleUnderscore1.errors.txt | 22 ----------- ...rnalModuleReferenceDoubleUnderscore1.types | 37 +++++++++++++++++++ 3 files changed, 47 insertions(+), 28 deletions(-) delete mode 100644 tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt create mode 100644 tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4fdab0a44a6..9b6af72eb52 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -545,14 +545,18 @@ module ts { return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } - function resolveExternalModuleName(location: Node, moduleExpression: Expression): Symbol { - if (moduleExpression.kind !== SyntaxKind.StringLiteral) { + function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol { + if (moduleReferenceExpression.kind !== SyntaxKind.StringLiteral) { return; } - var moduleLiteral = moduleExpression; + var moduleReferenceLiteral = moduleReferenceExpression; var searchPath = getDirectoryPath(getSourceFile(location).filename); - var moduleName = moduleLiteral.text; + + // Module names are escaped in our symbol table. However, string literal values aren't. + // Escape the name in the "require(...)" clause to ensure we find the right symbol. + var moduleName = escapeIdentifier(moduleReferenceLiteral.text); + if (!moduleName) return; var isRelative = isExternalModuleNameRelative(moduleName); if (!isRelative) { @@ -573,10 +577,10 @@ module ts { if (sourceFile.symbol) { return getResolvedExportSymbol(sourceFile.symbol); } - error(moduleLiteral, Diagnostics.File_0_is_not_an_external_module, sourceFile.filename); + error(moduleReferenceLiteral, Diagnostics.File_0_is_not_an_external_module, sourceFile.filename); return; } - error(moduleLiteral, Diagnostics.Cannot_find_external_module_0, moduleName); + error(moduleReferenceLiteral, Diagnostics.Cannot_find_external_module_0, moduleName); } function getResolvedExportSymbol(moduleSymbol: Symbol): Symbol { diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt deleted file mode 100644 index 80e2725d694..00000000000 --- a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.errors.txt +++ /dev/null @@ -1,22 +0,0 @@ -tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts(2,29): error TS2307: Cannot find external module '__timezonecomplete/basics'. - - -==== tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts (1 errors) ==== - declare module 'timezonecomplete' { - import basics = require("__timezonecomplete/basics"); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2307: Cannot find external module '__timezonecomplete/basics'. - export import TimeUnit = basics.TimeUnit; - } - - declare module '__timezonecomplete/basics' { - export enum TimeUnit { - Second = 0, - Minute = 1, - Hour = 2, - Day = 3, - Week = 4, - Month = 5, - Year = 6, - } - } \ No newline at end of file diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types new file mode 100644 index 00000000000..e255e64d467 --- /dev/null +++ b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts === +declare module 'timezonecomplete' { + import basics = require("__timezonecomplete/basics"); +>basics : typeof basics + + export import TimeUnit = basics.TimeUnit; +>TimeUnit : typeof basics.TimeUnit +>basics : typeof basics +>TimeUnit : basics.TimeUnit +} + +declare module '__timezonecomplete/basics' { + export enum TimeUnit { +>TimeUnit : TimeUnit + + Second = 0, +>Second : TimeUnit + + Minute = 1, +>Minute : TimeUnit + + Hour = 2, +>Hour : TimeUnit + + Day = 3, +>Day : TimeUnit + + Week = 4, +>Week : TimeUnit + + Month = 5, +>Month : TimeUnit + + Year = 6, +>Year : TimeUnit + } +} From a38e76b882aaf5ce15eabba2b267723a2471a6b1 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 2 Dec 2014 13:29:49 -0800 Subject: [PATCH 09/14] Address codereview --- src/compiler/emitter.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 303ca6264cb..e71e7920476 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2202,14 +2202,21 @@ module ts { // Emit identifier as an identifier emit(node.name); write(": "); - // Even though this is stored as identified because it is in short-hand property assignment, - // treated it as expression + // Even though this is stored as identifier treat it as an expression + // Short-hand, { x }, is equivalent of normal form { x: x } emitExpressionIdentifier(node.name); emitTrailingComments(node); } function emitShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { - // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment + // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example: + // module m { + // export var y; + // } + // module m { + // export var obj = { y }; + // } + // The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version var prefix = resolver.getExpressionNamePrefix(node.name); if (prefix) { emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); @@ -3408,7 +3415,7 @@ module ts { return emitPinnedOrTripleSlashComments(node); } - // Check if node has SyntaxKind which can be emitted regardless of the ScriptTarget + // Check if the node can be emitted regardless of the ScriptTarget switch (node.kind) { case SyntaxKind.Identifier: return emitIdentifier(node); @@ -3542,8 +3549,9 @@ module ts { return emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); } } - else if (compilerOptions.target >= ScriptTarget.ES6) { + else { // Emit node natively + Debug.assert(compilerOptions.target >= ScriptTarget.ES6, "Invalid ScriptTarget. We should emit as ES6 or above"); switch (node.kind) { case SyntaxKind.ShorthandPropertyAssignment: return emitShorthandPropertyAssignment(node); From ff3d64f83cf70fac24c90fc3a867330f3bb1e252 Mon Sep 17 00:00:00 2001 From: Yui T Date: Tue, 2 Dec 2014 13:29:49 -0800 Subject: [PATCH 10/14] Address codereview --- src/compiler/emitter.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 303ca6264cb..0a953877866 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2197,22 +2197,29 @@ module ts { emitTrailingComments(node); } - function emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node: ShorthandPropertyDeclaration) { + function emitDownlevelShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { emitLeadingComments(node); // Emit identifier as an identifier emit(node.name); write(": "); - // Even though this is stored as identified because it is in short-hand property assignment, - // treated it as expression + // Even though this is stored as identifier treat it as an expression + // Short-hand, { x }, is equivalent of normal form { x: x } emitExpressionIdentifier(node.name); emitTrailingComments(node); } function emitShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { - // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment + // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example: + // module m { + // export var y; + // } + // module m { + // export var obj = { y }; + // } + // The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version var prefix = resolver.getExpressionNamePrefix(node.name); if (prefix) { - emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); + emitDownlevelShorthandPropertyAssignment(node); } // If short-hand property has no prefix, emit it as short-hand. else { @@ -3408,7 +3415,7 @@ module ts { return emitPinnedOrTripleSlashComments(node); } - // Check if node has SyntaxKind which can be emitted regardless of the ScriptTarget + // Check if the node can be emitted regardless of the ScriptTarget switch (node.kind) { case SyntaxKind.Identifier: return emitIdentifier(node); @@ -3539,11 +3546,12 @@ module ts { // Emit node down-level switch (node.kind) { case SyntaxKind.ShorthandPropertyAssignment: - return emitShorthandPropertyAssignmentAsNormalPropertyAssignment(node); + return emitDownlevelShorthandPropertyAssignment(node); } } - else if (compilerOptions.target >= ScriptTarget.ES6) { + else { // Emit node natively + Debug.assert(compilerOptions.target >= ScriptTarget.ES6, "Invalid ScriptTarget. We should emit as ES6 or above"); switch (node.kind) { case SyntaxKind.ShorthandPropertyAssignment: return emitShorthandPropertyAssignment(node); From 90bf48f2d4baba138a3bbd6edada95679fdcc59d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Dec 2014 14:49:34 -0800 Subject: [PATCH 11/14] Extract reference comments out into their own diagnostics array. Only actual parse errors are stored in parseDiagnostics. Reference errors are stored in a separate array now. --- src/compiler/parser.ts | 96 +++++++++++++++++++++------------------- src/compiler/types.ts | 17 ++++--- src/services/services.ts | 3 ++ 3 files changed, 65 insertions(+), 51 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index de2d75286dc..5acc393c672 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -943,7 +943,6 @@ module ts { } export function createSourceFile(filename: string, sourceText: string, languageVersion: ScriptTarget, version: string, isOpen: boolean = false): SourceFile { - var file: SourceFile; var scanner: Scanner; var token: SyntaxKind; var parsingContext: ParsingContext; @@ -1101,22 +1100,22 @@ module ts { return getPositionFromLineAndCharacter(getLineStarts(), line, character); } - function error(message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { + function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { var start = scanner.getTokenPos(); var length = scanner.getTextPos() - start; - errorAtPosition(start, length, message, arg0, arg1, arg2); + parseErrorAtPosition(start, length, message, arg0, arg1, arg2); } - function errorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { - var lastErrorPosition = file.parseDiagnostics.length - ? file.parseDiagnostics[file.parseDiagnostics.length - 1].start + function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { + var lastErrorPosition = sourceFile.parseDiagnostics.length + ? sourceFile.parseDiagnostics[sourceFile.parseDiagnostics.length - 1].start : -1; // Don't report another error if it would just be at the same position as the last error. if (start !== lastErrorPosition) { - var diagnostic = createFileDiagnostic(file, start, length, message, arg0, arg1, arg2); - file.parseDiagnostics.push(diagnostic); + var diagnostic = createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2); + sourceFile.parseDiagnostics.push(diagnostic); } if (lookAheadMode === LookAheadMode.NoErrorYet) { @@ -1126,7 +1125,7 @@ module ts { function scanError(message: DiagnosticMessage) { var pos = scanner.getTextPos(); - errorAtPosition(pos, 0, message); + parseErrorAtPosition(pos, 0, message); } function onComment(pos: number, end: number) { @@ -1165,7 +1164,7 @@ module ts { // Keep track of the state we'll need to rollback to if lookahead fails (or if the // caller asked us to always reset our state). var saveToken = token; - var saveSyntacticErrorsLength = file.parseDiagnostics.length; + var saveSyntacticErrorsLength = sourceFile.parseDiagnostics.length; // Keep track of the current look ahead mode (this matters if we have nested // speculative parsing). @@ -1187,7 +1186,7 @@ module ts { lookAheadMode = saveLookAheadMode; if (!result || alwaysResetState) { token = saveToken; - file.parseDiagnostics.length = saveSyntacticErrorsLength; + sourceFile.parseDiagnostics.length = saveSyntacticErrorsLength; } return result; @@ -1236,10 +1235,10 @@ module ts { // Report specific message if provided with one. Otherwise, report generic fallback message. if (diagnosticMessage) { - error(diagnosticMessage, arg0); + parseErrorAtCurrentToken(diagnosticMessage, arg0); } else { - error(Diagnostics._0_expected, tokenToString(kind)); + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); } return false; } @@ -1307,10 +1306,10 @@ module ts { function createMissingNode(kind: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node { if (reportAtCurrentPosition) { - errorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); + parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); } else { - error(diagnosticMessage, arg0); + parseErrorAtCurrentToken(diagnosticMessage, arg0); } return createMissingNodeWithoutError(kind); @@ -1601,7 +1600,7 @@ module ts { // Returns true if we should abort parsing. function abortParsingListOrMoveToNextToken(kind: ParsingContext) { - error(parsingContextErrors(kind)); + parseErrorAtCurrentToken(parsingContextErrors(kind)); if (isInSomeParsingContext()) { return true; } @@ -4206,13 +4205,13 @@ module ts { var referencePathMatchResult = getFileReferenceFromReferencePath(comment, range); if (referencePathMatchResult) { var fileReference = referencePathMatchResult.fileReference; - file.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; + sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; var diagnosticMessage = referencePathMatchResult.diagnosticMessage; if (fileReference) { referencedFiles.push(fileReference); } if (diagnosticMessage) { - file.parseDiagnostics.push(createFileDiagnostic(file, range.pos, range.end - range.pos, diagnosticMessage)); + sourceFile.referenceDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -4220,7 +4219,7 @@ module ts { var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if(amdModuleNameMatchResult) { if(amdModuleName) { - file.parseDiagnostics.push(createFileDiagnostic(file, range.pos, range.end - range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); + sourceFile.referenceDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -4241,7 +4240,7 @@ module ts { } function getExternalModuleIndicator() { - return forEach(file.statements, node => + return forEach(sourceFile.statements, node => node.flags & NodeFlags.Export || node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference || node.kind === SyntaxKind.ExportAssignment @@ -4252,15 +4251,15 @@ module ts { var syntacticDiagnostics: Diagnostic[]; function getSyntacticDiagnostics() { if (syntacticDiagnostics === undefined) { - if (file.parseDiagnostics.length > 0) { + if (sourceFile.parseDiagnostics.length > 0) { // Don't bother doing any grammar checks if there are already parser errors. // Otherwise we may end up with too many cascading errors. - syntacticDiagnostics = file.parseDiagnostics; + syntacticDiagnostics = sourceFile.referenceDiagnostics.concat(sourceFile.parseDiagnostics); } else { // No parser errors were reported. Perform our stricter grammar checks. - syntacticDiagnostics = file.grammarDiagnostics; - checkGrammar(sourceText, languageVersion, file); + checkGrammar(sourceText, languageVersion, sourceFile); + syntacticDiagnostics = sourceFile.referenceDiagnostics.concat(sourceFile.grammarDiagnostics); } } @@ -4273,32 +4272,37 @@ module ts { if (fileExtensionIs(filename, ".d.ts")) { rootNodeFlags = NodeFlags.DeclarationFile; } - file = createRootNode(SyntaxKind.SourceFile, 0, sourceText.length, rootNodeFlags); - file.filename = normalizePath(filename); - file.text = sourceText; - file.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition; - file.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter; - file.getLineStarts = getLineStarts; - file.getSyntacticDiagnostics = getSyntacticDiagnostics; - file.parseDiagnostics = []; - file.grammarDiagnostics = []; - file.semanticDiagnostics = []; + + var sourceFile = createRootNode(SyntaxKind.SourceFile, 0, sourceText.length, rootNodeFlags); + + sourceFile.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition; + sourceFile.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter; + sourceFile.getLineStarts = getLineStarts; + sourceFile.getSyntacticDiagnostics = getSyntacticDiagnostics; + + sourceFile.filename = normalizePath(filename); + sourceFile.text = sourceText; + + sourceFile.referenceDiagnostics = []; + sourceFile.parseDiagnostics = []; + sourceFile.grammarDiagnostics = []; + sourceFile.semanticDiagnostics = []; var referenceComments = processReferenceComments(); - file.referencedFiles = referenceComments.referencedFiles; - file.amdDependencies = referenceComments.amdDependencies; - file.amdModuleName = referenceComments.amdModuleName; + sourceFile.referencedFiles = referenceComments.referencedFiles; + sourceFile.amdDependencies = referenceComments.amdDependencies; + sourceFile.amdModuleName = referenceComments.amdModuleName; - file.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement); - file.externalModuleIndicator = getExternalModuleIndicator(); + sourceFile.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement); + sourceFile.externalModuleIndicator = getExternalModuleIndicator(); - file.nodeCount = nodeCount; - file.identifierCount = identifierCount; - file.version = version; - file.isOpen = isOpen; - file.languageVersion = languageVersion; - file.identifiers = identifiers; - return file; + sourceFile.nodeCount = nodeCount; + sourceFile.identifierCount = identifierCount; + sourceFile.version = version; + sourceFile.isOpen = isOpen; + sourceFile.languageVersion = languageVersion; + sourceFile.identifiers = identifiers; + return sourceFile; } function isLeftHandSideExpression(expr: Expression): boolean { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ac94bfae517..e22ae6d8c32 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -795,17 +795,24 @@ module ts { amdDependencies: string[]; amdModuleName: string; referencedFiles: FileReference[]; - semanticDiagnostics: Diagnostic[]; + + // Diagnostics reported about the "/// Date: Tue, 2 Dec 2014 15:04:44 -0800 Subject: [PATCH 12/14] fix crash in signature help --- src/compiler/types.ts | 2 +- src/services/utilities.ts | 4 ---- tests/cases/fourslash/signatureHelpWithUnknown.ts | 6 ++++++ 3 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/signatureHelpWithUnknown.ts diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ac94bfae517..db691b09455 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -257,7 +257,7 @@ module ts { LastTypeNode = ParenthesizedType, FirstPunctuation = OpenBraceToken, LastPunctuation = CaretEqualsToken, - FirstToken = EndOfFileToken, + FirstToken = Unknown, LastToken = TypeKeyword, FirstTriviaToken = SingleLineCommentTrivia, LastTriviaToken = WhitespaceTrivia, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4a3301312fb..9df0476c105 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -280,10 +280,6 @@ module ts { } function nodeHasTokens(n: Node): boolean { - if (n.kind === SyntaxKind.Unknown) { - return false; - } - // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. return n.getWidth() !== 0; diff --git a/tests/cases/fourslash/signatureHelpWithUnknown.ts b/tests/cases/fourslash/signatureHelpWithUnknown.ts new file mode 100644 index 00000000000..00a031b2673 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpWithUnknown.ts @@ -0,0 +1,6 @@ +/// + +////eval(\/*1*/ + +goTo.marker("1"); +verify.signatureHelpCountIs(1); From 636a466552d6018bb113858ae9ac65e33ed999b7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 2 Dec 2014 15:16:09 -0800 Subject: [PATCH 13/14] Added comment. --- src/services/shims.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/shims.ts b/src/services/shims.ts index 64759fffc9f..86671009be2 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -913,6 +913,8 @@ module ts { } } + // Here we expose the TypeScript services as an external module + // so that it may be consumed easily like a node module. declare var module: any; if (typeof module !== "undefined" && module.exports) { module.exports = ts; From 5a7500ca5e62d7e6c7863cf42d156e8bcdc3017c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Dec 2014 16:09:41 -0800 Subject: [PATCH 14/14] Add a dedicated 'EndOfFile' token to a SourceFile. This is important for incremental parsing, as it is where we can attach parse errors at the end of the file to. Also, it helps with things like emitting comments at the end of the file. --- src/compiler/emitter.ts | 3 + src/compiler/parser.ts | 7 +- src/compiler/types.ts | 1 + src/services/services.ts | 4 +- .../reference/anyAssignableToEveryType.js | 5 + .../reference/augmentedTypesClass3.js | 1 + .../baselines/reference/augmentedTypesEnum.js | 3 + .../reference/augmentedTypesEnum2.js | 2 + .../reference/augmentedTypesFunction.js | 3 + .../reference/augmentedTypesInterface.js | 1 + .../reference/augmentedTypesModules.js | 1 + .../baselines/reference/augmentedTypesVar.js | 3 + .../reference/baseIndexSignatureResolution.js | 34 +++ .../reference/commentEmitAtEndOfFile1.js | 22 ++ .../reference/commentEmitAtEndOfFile1.types | 17 ++ .../reference/commentsAtEndOfFile1.js | 1 + ...peratorWithSubtypeObjectOnCallSignature.js | 1 + ...WithSubtypeObjectOnConstructorSignature.js | 1 + ...ubtypeObjectOnInstantiatedCallSignature.js | 1 + ...bjectOnInstantiatedConstructorSignature.js | 1 + tests/baselines/reference/concatError.js | 45 ++++ .../reference/conformanceFunctionOverloads.js | 10 + .../reference/emitCommentsOnlyFile.js | 26 +++ tests/baselines/reference/emitPostComments.js | 26 +++ tests/baselines/reference/emitPreComments.js | 26 +++ tests/baselines/reference/errorSupression1.js | 1 + .../reference/everyTypeAssignableToAny.js | 5 + .../functionConstraintSatisfaction.js | 4 + ...CallWithObjectTypeArgsAndNumericIndexer.js | 7 + ...cCallWithObjectTypeArgsAndStringIndexer.js | 7 + .../reference/heterogeneousArrayLiterals.js | 25 ++ .../innerTypeParameterShadowingOuterOne.js | 8 + .../innerTypeParameterShadowingOuterOne2.js | 10 + .../baselines/reference/moduleIdentifiers.js | 2 + .../reference/nullAssignableToEveryType.js | 5 + .../reference/parserS7.6.1.1_A1.10.js | 8 + .../reference/parserSyntaxWalker.generated.js | 217 ++++++++++++++++++ ...sivelySpecializedConstructorDeclaration.js | 41 ++++ .../baselines/reference/sourceMap-Comment1.js | 1 + .../reference/sourceMap-Comment1.js.map | 2 +- .../sourceMap-Comment1.sourcemap.txt | 13 ++ .../reference/typeParameterAsTypeArgument.js | 10 + ...ParameterUsedAsTypeParameterConstraint3.js | 12 + .../undefinedAssignableToEveryType.js | 5 + tests/baselines/reference/witness.js | 1 + .../cases/compiler/commentEmitAtEndOfFile1.ts | 10 + 46 files changed, 636 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/commentEmitAtEndOfFile1.js create mode 100644 tests/baselines/reference/commentEmitAtEndOfFile1.types create mode 100644 tests/cases/compiler/commentEmitAtEndOfFile1.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b39f58dde0e..7193523bf96 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3443,6 +3443,7 @@ module ts { // Start new file on new line writeLine(); emitDetachedComments(node); + // emit prologue directives prior to __extends var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false); if (!extendsEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitExtends) { @@ -3474,6 +3475,8 @@ module ts { emitCaptureThisForNodeIfNecessary(node); emitLinesStartingAt(node.statements, startIndex); } + + emitLeadingComments(node.endOfFileToken); } function emitNode(node: Node): void { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index aa2a8d5ec4c..06980e19187 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -313,8 +313,10 @@ module ts { case SyntaxKind.FinallyBlock: case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: - case SyntaxKind.SourceFile: return children((node).statements); + case SyntaxKind.SourceFile: + return children((node).statements) || + child((node).endOfFileToken); case SyntaxKind.VariableStatement: return children(node.modifiers) || children((node).declarations); @@ -4294,6 +4296,9 @@ module ts { sourceFile.amdModuleName = referenceComments.amdModuleName; sourceFile.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement); + Debug.assert(token === SyntaxKind.EndOfFileToken); + sourceFile.endOfFileToken = parseTokenNode(); + sourceFile.externalModuleIndicator = getExternalModuleIndicator(); sourceFile.nodeCount = nodeCount; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 81df5c9c42c..edf052a8876 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -786,6 +786,7 @@ module ts { // Source files are declarations when they are external modules. export interface SourceFile extends Declaration { statements: NodeArray; + endOfFileToken: Node; filename: string; text: string; diff --git a/src/services/services.ts b/src/services/services.ts index 29b7431bb23..44c587974df 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -722,6 +722,9 @@ module ts { public filename: string; public text: string; + public statements: NodeArray; + public endOfFileToken: Node; + // These methods will have their implementation provided by the implementation the // compiler actually exports off of SourceFile. public getLineAndCharacterFromPosition: (position: number) => LineAndCharacter; @@ -743,7 +746,6 @@ module ts { public nodeCount: number; public identifierCount: number; public symbolCount: number; - public statements: NodeArray; public version: string; public isOpen: boolean; public languageVersion: ScriptTarget; diff --git a/tests/baselines/reference/anyAssignableToEveryType.js b/tests/baselines/reference/anyAssignableToEveryType.js index 6c117a5054d..75d847709a5 100644 --- a/tests/baselines/reference/anyAssignableToEveryType.js +++ b/tests/baselines/reference/anyAssignableToEveryType.js @@ -83,3 +83,8 @@ function foo(x, y, z) { y = a; z = a; } +//function foo(x: T, y: U, z: V) { +// x = a; +// y = a; +// z = a; +//} diff --git a/tests/baselines/reference/augmentedTypesClass3.js b/tests/baselines/reference/augmentedTypesClass3.js index dd0da2a1646..b42d9dda356 100644 --- a/tests/baselines/reference/augmentedTypesClass3.js +++ b/tests/baselines/reference/augmentedTypesClass3.js @@ -52,3 +52,4 @@ var c5c = (function () { }; return c5c; })(); +//import c5c = require(''); diff --git a/tests/baselines/reference/augmentedTypesEnum.js b/tests/baselines/reference/augmentedTypesEnum.js index f7a83018cfd..484b0addd58 100644 --- a/tests/baselines/reference/augmentedTypesEnum.js +++ b/tests/baselines/reference/augmentedTypesEnum.js @@ -105,3 +105,6 @@ var e6b; (function (e6b) { e6b.y = 2; })(e6b || (e6b = {})); // should be error +// enum then import, messes with error reporting +//enum e7 { One } +//import e7 = require(''); // should be error diff --git a/tests/baselines/reference/augmentedTypesEnum2.js b/tests/baselines/reference/augmentedTypesEnum2.js index 8ab98a7cb7b..434e508f14c 100644 --- a/tests/baselines/reference/augmentedTypesEnum2.js +++ b/tests/baselines/reference/augmentedTypesEnum2.js @@ -40,3 +40,5 @@ var e2 = (function () { }; return e2; })(); +//enum then enum - covered +//enum then import - covered diff --git a/tests/baselines/reference/augmentedTypesFunction.js b/tests/baselines/reference/augmentedTypesFunction.js index 078854e227c..34567c77e8c 100644 --- a/tests/baselines/reference/augmentedTypesFunction.js +++ b/tests/baselines/reference/augmentedTypesFunction.js @@ -93,3 +93,6 @@ var y5b; })(y5b || (y5b = {})); // should be an error function y5c() { } +// function then import, messes with other errors +//function y6() { } +//import y6 = require(''); diff --git a/tests/baselines/reference/augmentedTypesInterface.js b/tests/baselines/reference/augmentedTypesInterface.js index 709b16d615c..a5039f8b1d0 100644 --- a/tests/baselines/reference/augmentedTypesInterface.js +++ b/tests/baselines/reference/augmentedTypesInterface.js @@ -48,3 +48,4 @@ var i3; i3[i3["One"] = 0] = "One"; })(i3 || (i3 = {})); ; +//import i4 = require(''); // error diff --git a/tests/baselines/reference/augmentedTypesModules.js b/tests/baselines/reference/augmentedTypesModules.js index 0c7967b2227..a9bff3fa74b 100644 --- a/tests/baselines/reference/augmentedTypesModules.js +++ b/tests/baselines/reference/augmentedTypesModules.js @@ -268,3 +268,4 @@ var m6; (function (m6) { m6.y = 2; })(m6 || (m6 = {})); +//import m6 = require(''); diff --git a/tests/baselines/reference/augmentedTypesVar.js b/tests/baselines/reference/augmentedTypesVar.js index 4735d647056..f4404cecb3d 100644 --- a/tests/baselines/reference/augmentedTypesVar.js +++ b/tests/baselines/reference/augmentedTypesVar.js @@ -80,3 +80,6 @@ var x6b; (function (x6b) { x6b.y = 2; })(x6b || (x6b = {})); // error +// var then import, messes with other error reporting +//var x7 = 1; +//import x7 = require(''); diff --git a/tests/baselines/reference/baseIndexSignatureResolution.js b/tests/baselines/reference/baseIndexSignatureResolution.js index 0c1e6c610f3..4c2d63bf2c9 100644 --- a/tests/baselines/reference/baseIndexSignatureResolution.js +++ b/tests/baselines/reference/baseIndexSignatureResolution.js @@ -45,3 +45,37 @@ var Derived = (function (_super) { })(Base); var x = null; var y = x[0]; +/* +// Note - the equivalent for normal interface methods works fine: +interface A { + foo(): Base; +} +interface B extends A { + foo(): TBase; +} +var b: B = null; +var z: Derived = b.foo(); +class Base { private a: string; } +class Derived extends Base { private b: string; } + +// Note - commmenting "extends Foo" prevents the error +interface Foo { + [i: number]: Base; +} +interface FooOf extends Foo { + [i: number]: TBase; +} +var x: FooOf = null; +var y: Derived = x[0]; + +/* +// Note - the equivalent for normal interface methods works fine: +interface A { + foo(): Base; +} +interface B extends A { + foo(): TBase; +} +var b: B = null; +var z: Derived = b.foo(); + diff --git a/tests/baselines/reference/commentEmitAtEndOfFile1.js b/tests/baselines/reference/commentEmitAtEndOfFile1.js new file mode 100644 index 00000000000..1a1f7cb8900 --- /dev/null +++ b/tests/baselines/reference/commentEmitAtEndOfFile1.js @@ -0,0 +1,22 @@ +//// [commentEmitAtEndOfFile1.ts] +// test +var f = '' +// test #2 +module foo { + function bar() { } +} +// test #3 +module empty { +} +// test #4 + +//// [commentEmitAtEndOfFile1.js] +// test +var f = ''; +// test #2 +var foo; +(function (foo) { + function bar() { + } +})(foo || (foo = {})); +// test #4 diff --git a/tests/baselines/reference/commentEmitAtEndOfFile1.types b/tests/baselines/reference/commentEmitAtEndOfFile1.types new file mode 100644 index 00000000000..76b5c868cb6 --- /dev/null +++ b/tests/baselines/reference/commentEmitAtEndOfFile1.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/commentEmitAtEndOfFile1.ts === +// test +var f = '' +>f : string + +// test #2 +module foo { +>foo : typeof foo + + function bar() { } +>bar : () => void +} +// test #3 +module empty { +>empty : unknown +} +// test #4 diff --git a/tests/baselines/reference/commentsAtEndOfFile1.js b/tests/baselines/reference/commentsAtEndOfFile1.js index a0b0fe3731e..2d4dae39e6b 100644 --- a/tests/baselines/reference/commentsAtEndOfFile1.js +++ b/tests/baselines/reference/commentsAtEndOfFile1.js @@ -6,3 +6,4 @@ Input: //// [commentsAtEndOfFile1.js] Input: ; +//Testing two diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js index 890add6bc8a..5a00fd85f3c 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js @@ -501,3 +501,4 @@ var r8b8 = b8 !== a8; var r8b9 = b9 !== a9; var r8b10 = b10 !== a10; var r8b11 = b11 !== a11; +//var r8b12 = b12 !== a12; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js index aefeb6d87ff..cba4f67933b 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js @@ -427,3 +427,4 @@ var r8b6 = b6 !== a6; var r8b7 = b7 !== a7; var r8b8 = b8 !== a8; var r8b9 = b9 !== a9; +//var r8b10 = b10 !== a10; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js index 1a83da3e663..1f2400f9bea 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js @@ -316,3 +316,4 @@ var r8b3 = b3 !== a3; var r8b4 = b4 !== a4; var r8b5 = b5 !== a5; var r8b6 = b6 !== a6; +//var r8b7 = b7 !== a7; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js index 393a2485c47..e80480e1a4e 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js @@ -316,3 +316,4 @@ var r8b3 = b3 !== a3; var r8b4 = b4 !== a4; var r8b5 = b5 !== a5; var r8b6 = b6 !== a6; +//var r8b7 = b7 !== a7; diff --git a/tests/baselines/reference/concatError.js b/tests/baselines/reference/concatError.js index e4ae4afdb65..04c0a16b836 100644 --- a/tests/baselines/reference/concatError.js +++ b/tests/baselines/reference/concatError.js @@ -43,3 +43,48 @@ interface Array { var fa; fa = fa.concat([0]); fa = fa.concat(0); +/* + + + + +declare class C { + public m(p1: C>): C; + //public p: T; +} + +var c: C; +var cc: C>; + +c = c.m(cc); +var n1: number[]; +/* +interface Array { + concat(...items: T[][]): T[]; // Note: This overload needs to be picked for arrays of arrays, even though both are applicable + concat(...items: T[]): T[]; +} +*/ +var fa: number[]; + +fa = fa.concat([0]); +fa = fa.concat(0); + + + + + +/* + + + + +declare class C { + public m(p1: C>): C; + //public p: T; +} + +var c: C; +var cc: C>; + +c = c.m(cc); + diff --git a/tests/baselines/reference/conformanceFunctionOverloads.js b/tests/baselines/reference/conformanceFunctionOverloads.js index 15dec719e40..b245f6a2c91 100644 --- a/tests/baselines/reference/conformanceFunctionOverloads.js +++ b/tests/baselines/reference/conformanceFunctionOverloads.js @@ -25,3 +25,13 @@ //// [conformanceFunctionOverloads.js] // Function overloads do not emit code +// Function overload signature with optional parameter +// Function overload signature with optional parameter +// Function overloads with generic and non-generic overloads +// Function overloads whose only difference is returning different unconstrained generic parameters +// Function overloads whose only difference is returning different constrained generic parameters +// Function overloads that differ only by type parameter constraints +// Function overloads with matching accessibility +// Function overloads with matching export +// Function overloads with more params than implementation signature +// Function overloads where return types are same infinitely recursive type reference diff --git a/tests/baselines/reference/emitCommentsOnlyFile.js b/tests/baselines/reference/emitCommentsOnlyFile.js index 263e9dd2588..d720dc3c191 100644 --- a/tests/baselines/reference/emitCommentsOnlyFile.js +++ b/tests/baselines/reference/emitCommentsOnlyFile.js @@ -29,3 +29,29 @@ //// [emitCommentsOnlyFile.js] +/** +* @name Foo +* @class +*/ +/**#@+ +* @memberOf Foo# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ +/** +* @name Foo2 +* @class +*/ +/**#@+ +* @memberOf Foo2# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ diff --git a/tests/baselines/reference/emitPostComments.js b/tests/baselines/reference/emitPostComments.js index 98d1d59457b..8a5736af00d 100644 --- a/tests/baselines/reference/emitPostComments.js +++ b/tests/baselines/reference/emitPostComments.js @@ -31,3 +31,29 @@ var y = 10; //// [emitPostComments.js] var y = 10; +/** +* @name Foo +* @class +*/ +/**#@+ +* @memberOf Foo# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ +/** +* @name Foo2 +* @class +*/ +/**#@+ +* @memberOf Foo2# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ diff --git a/tests/baselines/reference/emitPreComments.js b/tests/baselines/reference/emitPreComments.js index 5a79a430175..4ca3297fce7 100644 --- a/tests/baselines/reference/emitPreComments.js +++ b/tests/baselines/reference/emitPreComments.js @@ -33,3 +33,29 @@ var y = 10; //// [emitPreComments.js] // This is pre comment var y = 10; +/** +* @name Foo +* @class +*/ +/**#@+ +* @memberOf Foo# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ +/** +* @name Foo2 +* @class +*/ +/**#@+ +* @memberOf Foo2# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 92330a6c074..059530be452 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -20,3 +20,4 @@ var Foo = (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); +// So we don't want an error on 'concat'. diff --git a/tests/baselines/reference/everyTypeAssignableToAny.js b/tests/baselines/reference/everyTypeAssignableToAny.js index 5ff22ce1962..8730167c3ff 100644 --- a/tests/baselines/reference/everyTypeAssignableToAny.js +++ b/tests/baselines/reference/everyTypeAssignableToAny.js @@ -113,3 +113,8 @@ function foo(x, y, z) { a = y; a = z; } +//function foo(x: T, y: U, z: V) { +// a = x; +// a = y; +// a = z; +//} diff --git a/tests/baselines/reference/functionConstraintSatisfaction.js b/tests/baselines/reference/functionConstraintSatisfaction.js index 452080917db..a16f4d1ed36 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction.js +++ b/tests/baselines/reference/functionConstraintSatisfaction.js @@ -113,3 +113,7 @@ function foo2(x, y) { foo(x); foo(y); } +//function foo2(x: T, y: U) { +// foo(x); +// foo(y); +//} diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js index aa2da602e25..f300e3a8093 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js @@ -57,3 +57,10 @@ function other3(arg) { // BUG 821629 //var u: U = r2[1]; // ok } +//function other3(arg: T) { +// var b: { [x: number]: T }; +// var r2 = foo(b); +// var d = r2[1]; +// // BUG 821629 +// //var u: U = r2[1]; // ok +//} diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js index c810ce01fd4..eee87caf3de 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js @@ -58,3 +58,10 @@ function other3(arg) { // BUG 821629 //var u: U = r2['hm']; // ok } +//function other3(arg: T) { +// var b: { [x: string]: T }; +// var r2 = foo(b); +// var d: Date = r2['hm']; // ok +// // BUG 821629 +// //var u: U = r2['hm']; // ok +//} diff --git a/tests/baselines/reference/heterogeneousArrayLiterals.js b/tests/baselines/reference/heterogeneousArrayLiterals.js index 8deb3b4b068..4ac929305c0 100644 --- a/tests/baselines/reference/heterogeneousArrayLiterals.js +++ b/tests/baselines/reference/heterogeneousArrayLiterals.js @@ -241,3 +241,28 @@ function foo4(t, u) { var j = [u, derived]; // Derived[] var k = [t, u]; } +//function foo3(t: T, u: U) { +// var a = [t, t]; // T[] +// var b = [t, null]; // T[] +// var c = [t, u]; // {}[] +// var d = [t, 1]; // {}[] +// var e = [() => t, () => u]; // {}[] +// var f = [() => t, () => u, () => null]; // { (): any }[] +// var g = [t, base]; // Base[] +// var h = [t, derived]; // Derived[] +// var i = [u, base]; // Base[] +// var j = [u, derived]; // Derived[] +//} +//function foo4(t: T, u: U) { +// var a = [t, t]; // T[] +// var b = [t, null]; // T[] +// var c = [t, u]; // BUG 821629 +// var d = [t, 1]; // {}[] +// var e = [() => t, () => u]; // {}[] +// var f = [() => t, () => u, () => null]; // { (): any }[] +// var g = [t, base]; // Base[] +// var h = [t, derived]; // Derived[] +// var i = [u, base]; // Base[] +// var j = [u, derived]; // Derived[] +// var k: Base[] = [t, u]; +//} diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js index 81ed990532c..74354468e32 100644 --- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js +++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js @@ -47,3 +47,11 @@ function f2() { var x; x.getDate(); } +//function f2() { +// function g() { +// var x: U; +// x.toFixed(); +// } +// var x: U; +// x.getDate(); +//} diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js index 8a5a9448f18..36a250d365d 100644 --- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js +++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js @@ -66,3 +66,13 @@ var C2 = (function () { }; return C2; })(); +//class C2 { +// g() { +// var x: U; +// x.toFixed(); +// } +// h() { +// var x: U; +// x.getDate(); +// } +//} diff --git a/tests/baselines/reference/moduleIdentifiers.js b/tests/baselines/reference/moduleIdentifiers.js index e2050d98f5d..04d39019482 100644 --- a/tests/baselines/reference/moduleIdentifiers.js +++ b/tests/baselines/reference/moduleIdentifiers.js @@ -18,3 +18,5 @@ var M; //var p: M.P; //var m: M = M; var x1 = M.a; +//var x2 = m.a; +//var q: m.P; diff --git a/tests/baselines/reference/nullAssignableToEveryType.js b/tests/baselines/reference/nullAssignableToEveryType.js index 4901f4837bb..9917ebeac9e 100644 --- a/tests/baselines/reference/nullAssignableToEveryType.js +++ b/tests/baselines/reference/nullAssignableToEveryType.js @@ -80,3 +80,8 @@ function foo(x, y, z) { y = null; z = null; } +//function foo(x: T, y: U, z: V) { +// x = null; +// y = null; +// z = null; +//} diff --git a/tests/baselines/reference/parserS7.6.1.1_A1.10.js b/tests/baselines/reference/parserS7.6.1.1_A1.10.js index 04e0076b16a..6465281d88d 100644 --- a/tests/baselines/reference/parserS7.6.1.1_A1.10.js +++ b/tests/baselines/reference/parserS7.6.1.1_A1.10.js @@ -17,3 +17,11 @@ //// [parserS7.6.1.1_A1.10.js] // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. +/** + * The "for" token can not be used as identifier + * + * @path ch07/7.6/7.6.1/7.6.1.1/S7.6.1.1_A1.10.js + * @description Checking if execution of "for=1" fails + * @negative + */ +//for = 1; diff --git a/tests/baselines/reference/parserSyntaxWalker.generated.js b/tests/baselines/reference/parserSyntaxWalker.generated.js index 3b78baa0f74..392b5545830 100644 --- a/tests/baselines/reference/parserSyntaxWalker.generated.js +++ b/tests/baselines/reference/parserSyntaxWalker.generated.js @@ -289,3 +289,220 @@ // [index: number]: string; // } //} +//import fs = module("fs"); +//module TypeScriptAllInOne { +// export class Program { +// static Main(...args: string[]) { +// try { +// var bfs = new BasicFeatures(); +// var retValue: number = 0; +// retValue = bfs.VARIABLES(); +// if (retValue != 0) { +// return 1; +// } +// retValue = bfs.STATEMENTS(4); +// if (retValue != 0) { +// return 1; +// } +// retValue = bfs.TYPES(); +// if (retValue != 0) { +// return 1; +// } +// retValue = bfs.OPERATOR(); +// if (retValue != 0) { +// return 1; +// } +// } +// catch (e) { +// console.log(e); +// } +// finally { +// } +// console.log('Done'); +// return 0; +// } +// } +// class BasicFeatures { +// /// +// /// Test various of variables. Including nullable,key world as variable,special format +// /// +// /// +// public VARIABLES(): number { +// var local = Number.MAX_VALUE; +// var min = Number.MIN_VALUE; +// var inf = Number.NEGATIVE_INFINITY; +// var nan = Number.NaN; +// var undef = undefined; +// var п = local; +// var м = local; +// var local5 = null; +// var local6 = local5 instanceof fs.File; +// var hex = 0xBADC0DE, Hex = 0XDEADBEEF; +// var float = 6.02e23, float2 = 6.02E-23 +// var char = 'c', \u0066 = '\u0066', hexchar = '\x42'; +// var quoted = '"', quoted2 = "'"; +// var reg = /\w*/; +// var objLit = { "var": number = 42, equals: function (x) { return x["var"] === 42; }, toString: () => 'objLit{42}' }; +// var weekday = Weekdays.Monday; +// var con = char + f + hexchar + float.toString() + float2.toString() + reg.toString() + objLit + weekday; +// // +// var any = 0; +// var boolean = 0; +// var declare = 0; +// var constructor = 0; +// var get = 0; +// var implements = 0; +// var interface = 0; +// var let = 0; +// var module = 0; +// var number = 0; +// var package = 0; +// var private = 0; +// var protected = 0; +// var public = 0; +// var set = 0; +// var static = 0; +// var string = 0; +// var yield = 0; +// var sum3 = any + boolean + declare + constructor + get + implements + interface + let + module + number + package + private + protected + public + set + static + string + yield; +// return 0; +// } +// /// +// /// Test different statements. Including if-else,swith,foreach,(un)checked,lock,using,try-catch-finally +// /// +// /// +// /// +// STATEMENTS(i: number): number { +// var retVal = 0; +// if (i == 1) +// retVal = 1; +// else +// retVal = 0; +// switch (i) { +// case 2: +// retVal = 1; +// break; +// case 3: +// retVal = 1; +// break; +// default: +// break; +// } +// for (var x in { x: 0, y: 1 }) { +// } +// try { +// throw null; +// } +// catch (Exception) { +// } +// finally { +// try { } +// catch (Exception) { } +// } +// return retVal; +// } +// /// +// /// Test types in ts language. Including class,struct,interface,delegate,anonymous type +// /// +// /// +// public TYPES(): number { +// var retVal = 0; +// var c = new CLASS(); +// var xx: IF = c; +// retVal += c.Property; +// retVal += c.Member(); +// retVal += xx ^= Foo() ? 0 : 1; +// //anonymous type +// var anony = { a: new CLASS() }; +// retVal += anony.a.d(); +// return retVal; +// } +// ///// +// ///// Test different operators +// ///// +// ///// +// public OPERATOR(): number { +// var a: number[] = [1, 2, 3, 4, implements , ];/*[] bug*/ // YES [] +// var i = a[1];/*[]*/ +// i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/ +// var b = true && false || true ^ false;/*& | ^*/ +// b = !b;/*!*/ +// i = ~i;/*~i*/ +// b = i < (i - continue ) && (i + 1) > i;/*< && >*/ +// var f = true ? 1 : 0;/*? :*/ // YES : +// i++;/*++*/ +// i--;/*--*/ +// b = true && false || true;/*&& ||*/ +// i = i << 5;/*<<*/ +// i = i >> 5;/*>>*/ +// var j = i; +// b = i == j && i != j && i <= j && i >= j;/*= == && != <= >=*/ +// i += 5.0;/*+=*/ +// i -= i;/*-=*/ +// i *= i;/**=*/ +// if (i == 0) +// i++; +// i /= i;/*/=*/ +// i %= i;/*%=*/ +// i &= i;/*&=*/ +// i |= i;/*|=*/ +// i ^= i;/*^=*/ +// i <<= i;/*<<=*/ +// i >>= i;/*>>=*/ +// if (i == 0 && !b && f == 1) +// return 0; +// else return 1; +// } +// } +// interface IF { +// Foo