diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f11c88b2a0b..5bb5142d570 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -417,8 +417,8 @@ namespace ts { // from this SourceFile that are being held onto may change as a result (including // becoming detached from any SourceFile). It is recommended that this SourceFile not // be used once 'update' is called on it. - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean, scriptKind?: ScriptKind): SourceFile { - return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks, scriptKind); + export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { + return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); } /* @internal */ @@ -536,11 +536,10 @@ namespace ts { export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile { - const isJavaScriptFile = hasJavaScriptFileExtension(fileName) || _sourceText.lastIndexOf("// @language=javascript", 0) === 0 || scriptKind == ScriptKind.JS; - + const isJavaScriptFile = scriptKind === ScriptKind.JS || hasJavaScriptFileExtension(fileName); initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor); - const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes); + const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind); clearState(); @@ -588,8 +587,8 @@ namespace ts { sourceText = undefined; } - function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean): SourceFile { - sourceFile = createSourceFile(fileName, languageVersion); + function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind?: ScriptKind): SourceFile { + sourceFile = createSourceFile(fileName, languageVersion, scriptKind); sourceFile.flags = contextFlags; // Prime the scanner. @@ -656,7 +655,7 @@ namespace ts { } } - function createSourceFile(fileName: string, languageVersion: ScriptTarget): SourceFile { + function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind?: ScriptKind): SourceFile { // code from createNode is inlined here so createNode won't have to deal with special case of creating source files // this is quite rare comparing to other nodes and createNode should be as fast as possible const sourceFile = new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length); @@ -669,6 +668,9 @@ namespace ts { sourceFile.languageVariant = getLanguageVariant(sourceFile.fileName); sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, ".d.ts"); + scriptKind = scriptKind || ScriptKind.Unknown; + sourceFile.scriptKind = scriptKind !== ScriptKind.Unknown ? scriptKind : ScriptKind.TS; + return sourceFile; } @@ -6225,7 +6227,7 @@ namespace ts { } namespace IncrementalParser { - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean, scriptKind?: ScriptKind): SourceFile { + export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile { aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive); checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); @@ -6237,7 +6239,7 @@ namespace ts { if (sourceFile.statements.length === 0) { // If we don't have any statements in the current source file, then there's no real // way to incrementally parse. So just do a full parse instead. - return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, scriptKind); + return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind); } // Make sure we're not trying to incrementally update a source file more than once. Once @@ -6301,7 +6303,7 @@ namespace ts { // inconsistent tree. Setting the parents on the new tree should be very fast. We // will immediately bail out of walking any subtrees when we can see that their parents // are already correct. - const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, scriptKind); + const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind); return result; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8c9d1d1d40a..2b76f8a57fb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1532,6 +1532,7 @@ namespace ts { hasNoDefaultLib: boolean; languageVersion: ScriptTarget; + /* @internal */ scriptKind: ScriptKind; // The first node that causes this file to be an external module /* @internal */ externalModuleIndicator: Node; diff --git a/src/services/services.ts b/src/services/services.ts index 80bb0baf629..cb5168039b9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -806,6 +806,7 @@ namespace ts { public identifierCount: number; public symbolCount: number; public version: string; + public scriptKind: ScriptKind; public languageVersion: ScriptTarget; public languageVariant: LanguageVariant; public identifiers: Map; @@ -819,8 +820,8 @@ namespace ts { super(kind, pos, end); } - public update(newText: string, textChangeRange: TextChangeRange, scriptKind?: ScriptKind): SourceFile { - return updateSourceFile(this, newText, textChangeRange, /*aggressiveChecks*/ undefined, scriptKind); + public update(newText: string, textChangeRange: TextChangeRange): SourceFile { + return updateSourceFile(this, newText, textChangeRange); } public getLineAndCharacterOfPosition(position: number): LineAndCharacter { @@ -1834,7 +1835,7 @@ namespace ts { else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. const editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); - sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange, /*aggressiveChecks*/ undefined, scriptKind); + sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } if (sourceFile) { @@ -1969,7 +1970,7 @@ namespace ts { export let disableIncrementalParsing = false; - export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean, scriptKind?: ScriptKind): SourceFile { + export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { // If we were given a text change range, and our version or open-ness changed, then // incrementally parse this file. if (textChangeRange) { @@ -2003,7 +2004,7 @@ namespace ts { : (changedText + suffix); } - const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks, scriptKind); + const newSourceFile = updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later @@ -2024,7 +2025,7 @@ namespace ts { } // Otherwise, just create a new source file. - return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, scriptKind); + return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind); } export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry { @@ -2104,7 +2105,7 @@ namespace ts { // return it as is. if (entry.sourceFile.version !== version) { entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, - scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot), /*aggressiveChecks*/ undefined, scriptKind); + scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } } diff --git a/src/services/shims.ts b/src/services/shims.ts index 571c75482bb..f8c51feca27 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -348,10 +348,10 @@ namespace ts { } public getScriptKind(fileName: string): ScriptKind { - try { + if ("getScriptKind" in this.shimHost) { return this.shimHost.getScriptKind(fileName); } - catch (e) { + else { return ScriptKind.Unknown; } }