Merge pull request #620 from Microsoft/incrementalParsingBug

Fix incremental parsing bug due to non invalidating cached data in nodes...
This commit is contained in:
CyrusNajmabadi 2014-09-05 18:06:15 -07:00
commit 1eacacdc24
3 changed files with 47 additions and 8 deletions

View file

@ -1084,6 +1084,8 @@ module FourSlash {
// Make the edit // Make the edit
var ch = text.charAt(i); var ch = text.charAt(i);
this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset, ch); this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset, ch);
this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset);
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch);
this.editCheckpoint(this.activeFile.fileName); this.editCheckpoint(this.activeFile.fileName);
offset++; offset++;

View file

@ -544,19 +544,30 @@ module TypeScript.Parser {
} }
} }
function replaceTokenInParent(oldToken: ISyntaxToken, newToken: ISyntaxToken): void { function replaceTokenInParent(node: ISyntaxNode, oldToken: ISyntaxToken, newToken: ISyntaxToken): void {
// oldToken may be parented by a node or a list. // oldToken may be parented by a node or a list.
replaceTokenInParentWorker(oldToken, newToken); replaceTokenInParentWorker(oldToken, newToken);
var parent = oldToken.parent; var parent = oldToken.parent;
newToken.parent = parent; newToken.parent = parent;
// Walk upwards to our outermost node, clearing hte cached 'data' in it. This will
// make sure that the fullWidths and incrementally unusable bits are computed correctly
// when next requested.
while (true) {
// Parent must be a list or a node. All of those have a 'data' element. // Parent must be a list or a node. All of those have a 'data' element.
Debug.assert(isNode(parent) || isList(parent) || isSeparatedList(parent)); Debug.assert(isNode(parent) || isList(parent) || isSeparatedList(parent));
var dataElement = <{ data: number }><any>parent; var dataElement = <{ data: number }><any>parent;
if (dataElement.data) { if (dataElement.data) {
dataElement.data &= SyntaxConstants.NodeParsedInStrictModeMask dataElement.data &= SyntaxConstants.NodeParsedInStrictModeMask
} }
if (parent === node) {
break;
}
parent = parent.parent;
}
} }
function replaceTokenInParentWorker(oldToken: ISyntaxToken, newToken: ISyntaxToken): void { function replaceTokenInParentWorker(oldToken: ISyntaxToken, newToken: ISyntaxToken): void {
@ -602,7 +613,7 @@ module TypeScript.Parser {
var oldToken = lastToken(node); var oldToken = lastToken(node);
var newToken = addSkippedTokenAfterToken(oldToken, skippedToken); var newToken = addSkippedTokenAfterToken(oldToken, skippedToken);
replaceTokenInParent(oldToken, newToken); replaceTokenInParent(node, oldToken, newToken);
return node; return node;
} }
@ -611,7 +622,7 @@ module TypeScript.Parser {
var oldToken = firstToken(node); var oldToken = firstToken(node);
var newToken = addSkippedTokensBeforeToken(oldToken, skippedTokens); var newToken = addSkippedTokensBeforeToken(oldToken, skippedTokens);
replaceTokenInParent(oldToken, newToken); replaceTokenInParent(node, oldToken, newToken);
} }
return node; return node;

View file

@ -0,0 +1,26 @@
/// <reference path="fourslash.ts"/>
//// function foo() {
//// function getOccurrencesAtPosition() {
//// switch (node) {
//// enum /*1*/
//// }
////
//// return undefined;
////
//// function keywordToReferenceEntry() {
//// }
//// }
////
//// return {
//// getEmitOutput: (filename): Bar => null,
//// };
//// }
// Force a syntax tree ot be created.
verify.noMatchingBracePositionInCurrentFile(0);
// make sure we check the tree after every edit.
diagnostics.setTypingFidelity(TypingFidelity.High);
goTo.marker('1');
edit.insert('Fo');