Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Unified Diff: pkg/analyzer/lib/src/generated/parser.dart

Issue 736813002: Fix incremental parsing of function literals in initializer lists. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/parser.dart
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 60c522b87bed8440cd01cf81f2f261c84d127c71..16d1ff2ff95de5f4111d0f602b0dee593e2d9a70 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -1913,6 +1913,9 @@ class IncrementalParser {
try {
IncrementalParseDispatcher dispatcher =
new IncrementalParseDispatcher(parser, oldNode);
+ IncrementalParseStateBuilder contextBuilder =
+ new IncrementalParseStateBuilder(parser);
+ contextBuilder.buildState(oldNode);
newNode = parent.accept(dispatcher);
//
// Validate that the new node can replace the old node.
@@ -1983,6 +1986,100 @@ class IncrementalParser {
}
/**
+ * Visitor capable of inferring the correct parser state for incremental
+ * parsing. This visitor visits each parent/child relationship in the chain of
+ * ancestors of the node to be replaced (starting with the root of the parse
+ * tree), updating the parser to the correct state for parsing the child of the
+ * given parent. Once it has visited all of these relationships, the parser
+ * will be in the correct state for reparsing the node to be replaced.
+ *
+ * TODO(paulberry): add support for other pieces of parser state (_inAsync,
+ * _inGenerator, _inLoop, and _inSwitch). Note that _inLoop and _inSwitch only
+ * affect error message generation.
+ */
+class IncrementalParseStateBuilder extends SimpleAstVisitor {
+ /**
+ * The parser whose state should be built.
+ */
+ final Parser _parser;
+
+ /**
+ * The child node in the parent/child relationship currently being visited.
+ * (The corresponding parent is the node passed to the visit...() function.)
+ */
+ AstNode _childNode;
+
+ /**
+ * Create an IncrementalParseStateBuilder which will build the correct state
+ * for [_parser].
+ */
+ IncrementalParseStateBuilder(this._parser);
+
+ /**
+ * Build the correct parser state for parsing a replacement for [node].
+ */
+ void buildState(AstNode node) {
+ List<AstNode> ancestors = <AstNode>[];
+ while (node != null) {
+ ancestors.add(node);
+ node = node.parent;
+ }
+ _parser._inInitializer = false;
+ for (int i = ancestors.length - 2; i >= 0; i--) {
+ _childNode = ancestors[i];
+ ancestors[i + 1].accept(this);
+ }
+ }
+
+ @override
+ void visitArgumentList(ArgumentList node) {
+ _parser._inInitializer = false;
+ }
+
+ @override
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ if (identical(_childNode, node.expression)) {
+ _parser._inInitializer = true;
+ }
+ }
+
+ @override
+ void visitIndexExpression(IndexExpression node) {
+ if (identical(_childNode, node.index)) {
+ _parser._inInitializer = false;
+ }
+ }
+
+ @override
+ void visitInterpolationExpression(InterpolationExpression node) {
+ if (identical(_childNode, node.expression)) {
+ _parser._inInitializer = false;
+ }
+ }
+
+ @override
+ void visitListLiteral(ListLiteral node) {
+ if (node.elements.contains(_childNode)) {
+ _parser._inInitializer = false;
+ }
+ }
+
+ @override
+ void visitMapLiteral(MapLiteral node) {
+ if (node.entries.contains(_childNode)) {
+ _parser._inInitializer = false;
+ }
+ }
+
+ @override
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
+ if (identical(_childNode, node.expression)) {
+ _parser._inInitializer = false;
+ }
+ }
+}
+
+/**
* Instances of the class `InsufficientContextException` represent a situation in which an AST
* node cannot be re-parsed because there is not enough context to know how to re-parse the node.
* Clients can attempt to re-parse the parent of the node.
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698