diff --git a/src/services/compiler/precompile.ts b/src/services/compiler/precompile.ts index 3ff23d85bea..ea4f6364eff 100644 --- a/src/services/compiler/precompile.ts +++ b/src/services/compiler/precompile.ts @@ -20,7 +20,7 @@ module TypeScript { } // Note: This is being using by the host (VS) and is marshaled back and forth. When changing this make sure the changes - // are reflected in the managed side as well. + // are reflected in the managed side as well export interface IFileReference extends ILineAndCharacter { path: string; isResident: boolean; @@ -28,181 +28,17 @@ module TypeScript { length: number; } - /// - /// Preprocessing - /// export interface IPreProcessedFileInfo { referencedFiles: IFileReference[]; importedFiles: IFileReference[]; - diagnostics: Diagnostic[]; - isLibFile: boolean; + diagnostics: TypeScript.Diagnostic[]; + isLibFile: boolean } interface ITripleSlashDirectiveProperties { noDefaultLib: boolean; - diagnostics: Diagnostic[]; + diagnostics: TypeScript.Diagnostic[]; referencedFiles: IFileReference[]; } - function isNoDefaultLibMatch(comment: string): RegExpExecArray { - var isNoDefaultLibRegex = /^(\/\/\/\s*/gim; - return isNoDefaultLibRegex.exec(comment); - } - - export var tripleSlashReferenceRegExp = /^(\/\/\/\s*/; - - function getFileReferenceFromReferencePath(fileName: string, text: ISimpleText, position: number, comment: string, diagnostics: Diagnostic[]): IFileReference { - // First, just see if they've written: /// = 7 && fullReference[6] === "true"; - return { - line: 0, - character: 0, - position: 0, - length: 0, - path: switchToForwardSlashes(adjustedPath), - isResident: isResident - }; - } - } - } - - return null; - } - - var reportDiagnostic = () => { }; - - function processImports(text: ISimpleText, scanner: Scanner.IScanner, token: ISyntaxToken, importedFiles: IFileReference[]): void { - var lineChar = { line: -1, character: -1 }; - - var lineMap = text.lineMap(); - var start = new Date().getTime(); - // Look for: - // import foo = module("foo") - while (token.kind() !== SyntaxKind.EndOfFileToken) { - if (token.kind() === SyntaxKind.ImportKeyword) { - var importToken = token; - token = scanner.scan(/*allowRegularExpression:*/ false); - - if (SyntaxFacts.isIdentifierNameOrAnyKeyword(token)) { - token = scanner.scan(/*allowRegularExpression:*/ false); - - if (token.kind() === SyntaxKind.EqualsToken) { - token = scanner.scan(/*allowRegularExpression:*/ false); - - if (token.kind() === SyntaxKind.ModuleKeyword || token.kind() === SyntaxKind.RequireKeyword) { - token = scanner.scan(/*allowRegularExpression:*/ false); - - if (token.kind() === SyntaxKind.OpenParenToken) { - token = scanner.scan(/*allowRegularExpression:*/ false); - - lineMap.fillLineAndCharacterFromPosition(TypeScript.start(importToken, text), lineChar); - - if (token.kind() === SyntaxKind.StringLiteral) { - var ref = { - line: lineChar.line, - character: lineChar.character, - position: TypeScript.start(token, text), - length: width(token), - path: stripStartAndEndQuotes(switchToForwardSlashes(token.text())), - isResident: false - }; - importedFiles.push(ref); - } - } - } - } - } - } - - token = scanner.scan(/*allowRegularExpression:*/ false); - } - - var totalTime = new Date().getTime() - start; - //TypeScript.fileResolutionScanImportsTime += totalTime; - } - - function processTripleSlashDirectives(fileName: string, text: ISimpleText, firstToken: ISyntaxToken): ITripleSlashDirectiveProperties { - var leadingTrivia = firstToken.leadingTrivia(text); - - var position = 0; - var lineChar = { line: -1, character: -1 }; - var noDefaultLib = false; - var diagnostics: Diagnostic[] = []; - var referencedFiles: IFileReference[] = []; - var lineMap = text.lineMap(); - - for (var i = 0, n = leadingTrivia.count(); i < n; i++) { - var trivia = leadingTrivia.syntaxTriviaAt(i); - - if (trivia.kind() === SyntaxKind.SingleLineCommentTrivia) { - var triviaText = trivia.fullText(); - var referencedCode = getFileReferenceFromReferencePath(fileName, text, position, triviaText, diagnostics); - - if (referencedCode) { - lineMap.fillLineAndCharacterFromPosition(position, lineChar); - referencedCode.position = position; - referencedCode.length = trivia.fullWidth(); - referencedCode.line = lineChar.line; - referencedCode.character = lineChar.character; - - referencedFiles.push(referencedCode); - } - - // is it a lib file? - var isNoDefaultLib = isNoDefaultLibMatch(triviaText); - if (isNoDefaultLib) { - noDefaultLib = isNoDefaultLib[3] === "true"; - } - } - - position += trivia.fullWidth(); - } - - return { noDefaultLib: noDefaultLib, diagnostics: diagnostics, referencedFiles: referencedFiles }; - } - - export function preProcessFile(fileName: string, sourceText: IScriptSnapshot, readImportFiles = true): IPreProcessedFileInfo { - var text = SimpleText.fromScriptSnapshot(sourceText); - var scanner = Scanner.createScanner(ts.ScriptTarget.ES5, text, reportDiagnostic); - - var firstToken = scanner.scan(/*allowRegularExpression:*/ false); - - // only search out dynamic mods - // if you find a dynamic mod, ignore every other mod inside, until you balance rcurlies - // var position - - var importedFiles: IFileReference[] = []; - if (readImportFiles) { - processImports(text, scanner, firstToken, importedFiles); - } - - var properties = processTripleSlashDirectives(fileName, text, firstToken); - - return { referencedFiles: properties.referencedFiles, importedFiles: importedFiles, isLibFile: properties.noDefaultLib, diagnostics: properties.diagnostics }; - } - - export function getReferencedFiles(fileName: string, sourceText: IScriptSnapshot): IFileReference[] { - return preProcessFile(fileName, sourceText, false).referencedFiles; - } } // Tools \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index 5411cac8d0c..b64a5207b85 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -77,6 +77,15 @@ module ts { update(scriptSnapshot: TypeScript.IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TypeScript.TextChangeRange): SourceFile; } + /// + /// Pre-processing + /// + interface ITripleSlashDirectiveProperties { + noDefaultLib: boolean; + diagnostics: TypeScript.Diagnostic[]; + referencedFiles: TypeScript.IFileReference[]; + } + var scanner: Scanner = createScanner(ScriptTarget.ES5, /*skipTrivia*/ true); var emptyArray: any[] = []; @@ -1895,6 +1904,162 @@ module ts { }; } + export var tripleSlashReferenceRegExp = /^(\/\/\/\s*/; + export function preProcessFile(fileName: string, sourceText: TypeScript.IScriptSnapshot, readImportFiles = true): TypeScript.IPreProcessedFileInfo { + var reportDiagnostic = () => { } + function isNoDefaultLibMatch(comment: string): RegExpExecArray { + var isNoDefaultLibRegex = /^(\/\/\/\s*/gim; + return isNoDefaultLibRegex.exec(comment); + } + + function getFileReferenceFromReferencePath(fileName: string, text: TypeScript.ISimpleText, position: number, comment: string, diagnostics: TypeScript.Diagnostic[]): TypeScript.IFileReference { + // First, just see if they've written: /// = 7 && fullReference[6] === "true"; + return { + line: 0, + character: 0, + position: 0, + length: 0, + path: TypeScript.switchToForwardSlashes(adjustedPath), + isResident: isResident + }; + } + } + } + + return null; + } + + function processImports(text: TypeScript.ISimpleText, scanner: TypeScript.Scanner.IScanner, token: TypeScript.ISyntaxToken, importedFiles: TypeScript.IFileReference[]): void { + var lineChar = { line: -1, character: -1 }; + + var lineMap = text.lineMap(); + var start = new Date().getTime(); + // Look for: + // import foo = module("foo") + while (token.kind() !== TypeScript.SyntaxKind.EndOfFileToken) { + if (token.kind() === TypeScript.SyntaxKind.ImportKeyword) { + var importToken = token; + token = scanner.scan(/*allowRegularExpression:*/ false); + + if (TypeScript.SyntaxFacts.isIdentifierNameOrAnyKeyword(token)) { + token = scanner.scan(/*allowRegularExpression:*/ false); + + if (token.kind() === TypeScript.SyntaxKind.EqualsToken) { + token = scanner.scan(/*allowRegularExpression:*/ false); + + if (token.kind() === TypeScript.SyntaxKind.ModuleKeyword || token.kind() === TypeScript.SyntaxKind.RequireKeyword) { + token = scanner.scan(/*allowRegularExpression:*/ false); + + if (token.kind() === TypeScript.SyntaxKind.OpenParenToken) { + token = scanner.scan(/*allowRegularExpression:*/ false); + + lineMap.fillLineAndCharacterFromPosition(TypeScript.start(importToken, text), lineChar); + + if (token.kind() === TypeScript.SyntaxKind.StringLiteral) { + var ref = { + line: lineChar.line, + character: lineChar.character, + position: TypeScript.start(token, text), + length: TypeScript.width(token), + path: TypeScript.stripStartAndEndQuotes(TypeScript.switchToForwardSlashes(token.text())), + isResident: false + }; + importedFiles.push(ref); + } + } + } + } + } + } + + token = scanner.scan(/*allowRegularExpression:*/ false); + } + + var totalTime = new Date().getTime() - start; + //TypeScript.fileResolutionScanImportsTime += totalTime + } + + function processTripleSlashDirectives(fileName: string, text: TypeScript.ISimpleText, firstToken: TypeScript.ISyntaxToken): ITripleSlashDirectiveProperties { + var leadingTrivia = firstToken.leadingTrivia(text); + + var position = 0; + var lineChar = { line: -1, character: -1 }; + var noDefaultLib = false; + var diagnostics: TypeScript.Diagnostic[] = []; + var referencedFiles: TypeScript.IFileReference[] = []; + var lineMap = text.lineMap(); + + for (var i = 0, n = leadingTrivia.count(); i < n; i++) { + var trivia = leadingTrivia.syntaxTriviaAt(i); + + if (trivia.kind() === TypeScript.SyntaxKind.SingleLineCommentTrivia) { + var triviaText = trivia.fullText(); + var referencedCode = getFileReferenceFromReferencePath(fileName, text, position, triviaText, diagnostics); + + if (referencedCode) { + lineMap.fillLineAndCharacterFromPosition(position, lineChar); + referencedCode.position = position; + referencedCode.length = trivia.fullWidth(); + referencedCode.line = lineChar.line; + referencedCode.character = lineChar.character; + + referencedFiles.push(referencedCode); + } + + // is it a lib file? + var isNoDefaultLib = isNoDefaultLibMatch(triviaText); + if (isNoDefaultLib) { + noDefaultLib = isNoDefaultLib[3] === "true"; + } + } + + position += trivia.fullWidth(); + } + + return { noDefaultLib: noDefaultLib, diagnostics: diagnostics, referencedFiles: referencedFiles }; + } + + var text = TypeScript.SimpleText.fromScriptSnapshot(sourceText); + var scanner = TypeScript.Scanner.createScanner(ts.ScriptTarget.ES5, text, reportDiagnostic); + + var firstToken = scanner.scan(/*allowRegularExpression:*/ false); + + // only search out dynamic mods + // if you find a dynamic mod, ignore every other mod inside, until you balance rcurlies + // var position + + var importedFiles: TypeScript.IFileReference[] = []; + if (readImportFiles) { + processImports(text, scanner, firstToken, importedFiles); + } + + var properties = processTripleSlashDirectives(fileName, text, firstToken); + + return { referencedFiles: properties.referencedFiles, importedFiles: importedFiles, isLibFile: properties.noDefaultLib, diagnostics: properties.diagnostics }; + } + /// Helpers export function getNodeModifiers(node: Node): string { var flags = node.flags; diff --git a/src/services/shims.ts b/src/services/shims.ts index fdea0202323..4a31dc62331 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -847,7 +847,7 @@ module ts { return this.forwardJSONCall( "getPreProcessedFileInfo('" + fileName + "')", () => { - var result = TypeScript.preProcessFile(fileName, sourceText); + var result = ts.preProcessFile(fileName, sourceText); //TypeScript.preProcessFile(fileName, sourceText); return result; }); }