From 2f833d5f97d348f225b903d2969554e24021f948 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 12 Dec 2014 02:21:45 -0800 Subject: [PATCH] Provide a way for tests to try out incremental parsing. --- src/compiler/parser.ts | 13 +++++++------ src/harness/harnessLanguageService.ts | 2 +- src/services/services.ts | 14 ++++++++------ tests/cases/unittests/incrementalParser.ts | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ac014fea9e8..a3d9fb51fca 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -641,9 +641,9 @@ module ts { var sourceFile: SourceFile; - return parseSourceFile(sourceText, /*textChangeRange:*/ undefined, setParentNodes); + return parseSourceFile(sourceText, setParentNodes); - function parseSourceFile(text: string, textChangeRange: TextChangeRange, setParentNodes: boolean): SourceFile { + function parseSourceFile(text: string, setParentNodes: boolean): SourceFile { // Set our initial state before parsing. sourceText = text; parsingContext = 0; @@ -703,7 +703,7 @@ module ts { if (sourceFile.statements.length === 0) { // If we don't have any statements in the current source file, hten there's no real // way to incrementally parse. So just do a full parse instead. - return parseSourceFile(newText, /*textChangeRange:*/ undefined, /*setNodeParents*/ true); + return parseSourceFile(newText, /*setNodeParents*/ true); } syntaxCursor = createSyntaxCursor(sourceFile); @@ -739,8 +739,9 @@ module ts { updateTokenPositionsAndMarkElements(sourceFile, changeRange.span().start(), changeRange.span().end(), changeRange.newSpan().end(), delta); - // Don't pass along the text change range for now. We'll pass it along once incremental - // parsing is enabled. + // Now that we've set up our internal incremental state just proceed and parse the + // source file in the normal fashion. When possible the parser will retrieve and + // reuse nodes from the old tree. // // Note: passing in 'true' for setNodeParents is very important. When incrementally // parsing, we will be reusing nodes from the old tree, and placing it into new @@ -748,7 +749,7 @@ module 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. - var result = parseSourceFile(newText, /*textChangeRange:*/ undefined, /*setNodeParents*/ true); + var result = parseSourceFile(newText, /*setNodeParents*/ true); // Clear out the syntax cursor so it doesn't keep anything alive longer than it should. syntaxCursor = undefined; diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 430dcc24477..e850fb57c01 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -126,7 +126,7 @@ module Harness.LanguageService { isOpen: boolean, textChangeRange: ts.TextChangeRange ): ts.SourceFile { - return ts.updateLanguageServiceSourceFile(document, scriptSnapshot, version, isOpen, textChangeRange); + return ts.updateLanguageServiceSourceFile(document, scriptSnapshot, version, isOpen, textChangeRange, /*useIncremental:*/ false); } public releaseDocument(fileName: string, compilationSettings: ts.CompilerOptions): void { diff --git a/src/services/services.ts b/src/services/services.ts index 6d1a7c357ef..0c3abf090ae 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1519,7 +1519,7 @@ module ts { var editRange = this.hostCache.getChangeRange(filename, this.currentFileVersion, this.currentSourceFile.scriptSnapshot); var start = new Date().getTime(); - sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, /*isOpen*/ true, editRange); + sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, /*isOpen*/ true, editRange, /*useIncremental:*/ false); this.host.log("SyntaxTreeCache.Initialize: updateSourceFile: " + (new Date().getTime() - start)); } @@ -1553,7 +1553,7 @@ module ts { return sourceFile; } - export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TextChangeRange): SourceFile { + export function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, isOpen: boolean, textChangeRange: TextChangeRange, useIncremental: boolean): SourceFile { if (textChangeRange && Debug.shouldAssert(AssertionLevel.Normal)) { var oldText = sourceFile.scriptSnapshot; var newText = scriptSnapshot; @@ -1576,9 +1576,11 @@ module ts { if (textChangeRange) { if (version !== sourceFile.version || isOpen != sourceFile.isOpen) { // Once incremental parsing is ready, then just call into this function. - // var newSourceFile = sourceFile.update(scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange); - // setSourceFileFields(newSourceFile, scriptSnapshot, version, isOpen); - // return newSourceFile; + if (useIncremental) { + var newSourceFile = sourceFile.update(scriptSnapshot.getText(0, scriptSnapshot.getLength()), textChangeRange); + setSourceFileFields(newSourceFile, scriptSnapshot, version, isOpen); + return newSourceFile; + } } } @@ -1661,7 +1663,7 @@ module ts { var entry = lookUp(bucket, filename); Debug.assert(entry !== undefined); - entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, isOpen, textChangeRange); + entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, isOpen, textChangeRange, /*useIncremental:*/ false); return entry.sourceFile; } diff --git a/tests/cases/unittests/incrementalParser.ts b/tests/cases/unittests/incrementalParser.ts index a1ab175e114..ddbd8acfc02 100644 --- a/tests/cases/unittests/incrementalParser.ts +++ b/tests/cases/unittests/incrementalParser.ts @@ -55,7 +55,7 @@ module ts { Utils.assertInvariants(newTree, /*parent:*/ undefined); // Create a tree for the new text, in an incremental fashion. - var incrementalNewTree = updateLanguageServiceSourceFile(oldTree, newText, oldTree.version + ".", /*isOpen:*/ true, textChangeRange); + var incrementalNewTree = updateLanguageServiceSourceFile(oldTree, newText, oldTree.version + ".", /*isOpen:*/ true, textChangeRange, /*useIncremental:*/ false); Utils.assertInvariants(incrementalNewTree, /*parent:*/ undefined); // We should get the same tree when doign a full or incremental parse.