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
var ch = text.charAt(i);
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.editCheckpoint(this.activeFile.fileName);
offset++;

View file

@ -544,18 +544,29 @@ 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.
replaceTokenInParentWorker(oldToken, newToken);
var parent = oldToken.parent;
newToken.parent = parent;
// Parent must be a list or a node. All of those have a 'data' element.
Debug.assert(isNode(parent) || isList(parent) || isSeparatedList(parent));
var dataElement = <{ data: number }><any>parent;
if (dataElement.data) {
dataElement.data &= SyntaxConstants.NodeParsedInStrictModeMask
// 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.
Debug.assert(isNode(parent) || isList(parent) || isSeparatedList(parent));
var dataElement = <{ data: number }><any>parent;
if (dataElement.data) {
dataElement.data &= SyntaxConstants.NodeParsedInStrictModeMask
}
if (parent === node) {
break;
}
parent = parent.parent;
}
}
@ -602,7 +613,7 @@ module TypeScript.Parser {
var oldToken = lastToken(node);
var newToken = addSkippedTokenAfterToken(oldToken, skippedToken);
replaceTokenInParent(oldToken, newToken);
replaceTokenInParent(node, oldToken, newToken);
return node;
}
@ -611,7 +622,7 @@ module TypeScript.Parser {
var oldToken = firstToken(node);
var newToken = addSkippedTokensBeforeToken(oldToken, skippedTokens);
replaceTokenInParent(oldToken, newToken);
replaceTokenInParent(node, oldToken, newToken);
}
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');