parser and services changes due to CR comments

- Adding assert to ensure script kinds are not modified for registered docs
- setting script kind in parseSourceFile and consuming it initialize state and getLanguageVariant
This commit is contained in:
Jason Ramsay
2016-02-18 12:19:34 -08:00
parent 81df1cbc0b
commit 3e124ad35d
2 changed files with 41 additions and 16 deletions

View File

@@ -535,9 +535,14 @@ namespace ts {
let parseErrorBeforeNextFinishedNode = false;
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
// Using scriptKind as a condition handles both:
// - 'scriptKind' is unspecified and thus it is `undefined`
// - 'scriptKind' is set and it is `Unknown` (0)
// If the 'scriptKind' is 'undefined' or 'Unknown' then attempt
// to get the ScriptKind from the file name.
scriptKind = scriptKind ? scriptKind : getScriptKindFromFileName(fileName);
const isJavaScriptFile = scriptKind === ScriptKind.JS || hasJavaScriptFileExtension(fileName);
initializeState(fileName, _sourceText, languageVersion, isJavaScriptFile, _syntaxCursor);
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind);
const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
@@ -546,12 +551,28 @@ namespace ts {
return result;
}
function getLanguageVariant(fileName: string) {
// .tsx and .jsx files are treated as jsx language variant.
return fileExtensionIs(fileName, ".tsx") || fileExtensionIs(fileName, ".jsx") || fileExtensionIs(fileName, ".js") ? LanguageVariant.JSX : LanguageVariant.Standard;
function getScriptKindFromFileName(fileName: string): ScriptKind {
const ext = fileName.split(".").pop();
switch (ext.toLowerCase()) {
case "js":
return ScriptKind.JS;
case "jsx":
return ScriptKind.JSX;
case "ts":
return ScriptKind.TS;
case "tsx":
return ScriptKind.TSX;
default:
return ScriptKind.TS;
}
}
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, isJavaScriptFile: boolean, _syntaxCursor: IncrementalParser.SyntaxCursor) {
function getLanguageVariant(scriptKind: ScriptKind) {
// .tsx and .jsx files are treated as jsx language variant.
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
}
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
NodeConstructor = objectAllocator.getNodeConstructor();
SourceFileConstructor = objectAllocator.getSourceFileConstructor();
@@ -564,14 +585,14 @@ namespace ts {
identifierCount = 0;
nodeCount = 0;
contextFlags = isJavaScriptFile ? NodeFlags.JavaScriptFile : NodeFlags.None;
contextFlags = scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX ? NodeFlags.JavaScriptFile : NodeFlags.None;
parseErrorBeforeNextFinishedNode = false;
// Initialize and prime the scanner before parsing the source elements.
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
scanner.setLanguageVariant(getLanguageVariant(fileName));
scanner.setLanguageVariant(getLanguageVariant(scriptKind));
}
function clearState() {
@@ -587,7 +608,7 @@ namespace ts {
sourceText = undefined;
}
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind?: ScriptKind): SourceFile {
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile {
sourceFile = createSourceFile(fileName, languageVersion, scriptKind);
sourceFile.flags = contextFlags;
@@ -655,7 +676,7 @@ namespace ts {
}
}
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind?: ScriptKind): 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 = <SourceFile>new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length);
@@ -665,11 +686,9 @@ namespace ts {
sourceFile.bindDiagnostics = [];
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = normalizePath(fileName);
sourceFile.languageVariant = getLanguageVariant(sourceFile.fileName);
sourceFile.languageVariant = getLanguageVariant(scriptKind);
sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, ".d.ts");
scriptKind = scriptKind || ScriptKind.Unknown;
sourceFile.scriptKind = scriptKind !== ScriptKind.Unknown ? scriptKind : ScriptKind.TS;
sourceFile.scriptKind = scriptKind;
return sourceFile;
}
@@ -5594,7 +5613,7 @@ namespace ts {
}
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
initializeState("file.js", content, ScriptTarget.Latest, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
scanner.setText(content, start, length);
token = scanner.scan();
const jsDocTypeExpression = parseJSDocTypeExpression();
@@ -5913,7 +5932,7 @@ namespace ts {
}
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
initializeState("file.js", content, ScriptTarget.Latest, /*isJavaScriptFile*/ true, /*_syntaxCursor:*/ undefined);
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content };
const jsDocComment = parseJSDocCommentWorker(start, length);
const diagnostics = parseDiagnostics;

View File

@@ -2857,6 +2857,12 @@ namespace ts {
// it's source file any more, and instead defers to DocumentRegistry to get
// either version 1, version 2 (or some other version) depending on what the
// host says should be used.
// We do not support the scenario where a host can modify a registered
// file's script kind, i.e. in one project some file is treated as ".ts"
// and in another as ".js"
Debug.assert(hostFileInformation.scriptKind === oldSourceFile.scriptKind, "Registered script kind (" + oldSourceFile.scriptKind + ") should match new script kind (" + hostFileInformation.scriptKind +") for file: " + fileName);
return documentRegistry.updateDocument(fileName, newSettings, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind);
}