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

Side by Side Diff: pkg/analyzer/lib/src/task/incremental_element_builder.dart

Issue 1155543005: Prepare CompilationUnitElementDelta in IncrementalCompilationUnitElementBuilder. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Move CompilationUnit.replace() into IncrementalCompilationUnitElementBuilder. Created 5 years, 6 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.task.incremental_element_builder; 5 library analyzer.src.task.incremental_element_builder;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/src/generated/ast.dart'; 9 import 'package:analyzer/src/generated/ast.dart';
10 import 'package:analyzer/src/generated/element.dart'; 10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/resolver.dart'; 11 import 'package:analyzer/src/generated/resolver.dart';
12 import 'package:analyzer/src/generated/scanner.dart'; 12 import 'package:analyzer/src/generated/scanner.dart';
13 import 'package:analyzer/src/generated/source.dart'; 13 import 'package:analyzer/src/generated/source.dart';
14 14
15 /** 15 /**
16 * The change of a single [CompilationUnitElement].
17 */
18 class CompilationUnitElementDelta {
19 /**
20 * One or more directives were added/removed.
21 */
22 bool hasDirectiveChange = false;
23
24 /**
25 * The list of added top-level element.
26 */
27 final List<Element> addedDeclarations = <Element>[];
28
29 /**
30 * The list of removed top-level elements.
31 */
32 final List<Element> removedDeclarations = <Element>[];
33 }
34
35 /**
16 * Incrementally updates the existing [unitElement] and builds elements for 36 * Incrementally updates the existing [unitElement] and builds elements for
17 * the [newUnit]. 37 * the [newUnit].
18 */ 38 */
19 class IncrementalCompilationUnitElementBuilder { 39 class IncrementalCompilationUnitElementBuilder {
20 final Source source; 40 final Source unitSource;
21 final Source librarySource; 41 final Source librarySource;
22 final CompilationUnit oldUnit; 42 final CompilationUnit oldUnit;
23 final CompilationUnitElementImpl unitElement; 43 final CompilationUnitElementImpl unitElement;
24 final CompilationUnit newUnit; 44 final CompilationUnit newUnit;
25 final ElementHolder holder = new ElementHolder(); 45 final ElementHolder holder = new ElementHolder();
26 46
27 IncrementalCompilationUnitElementBuilder( 47 /**
28 CompilationUnit oldUnit, this.newUnit) 48 * The change between element models of [oldUnit] and [newUnit].
29 : oldUnit = oldUnit, 49 */
30 unitElement = oldUnit.element, 50 final CompilationUnitElementDelta unitDelta =
31 source = oldUnit.element.source, 51 new CompilationUnitElementDelta();
32 librarySource = (oldUnit.element as CompilationUnitElementImpl).libraryS ource;
33 52
53 factory IncrementalCompilationUnitElementBuilder(
54 CompilationUnit oldUnit, CompilationUnit newUnit) {
55 CompilationUnitElementImpl unitElement = oldUnit.element;
56 return new IncrementalCompilationUnitElementBuilder._(unitElement.source,
57 unitElement.librarySource, oldUnit, newUnit, unitElement);
58 }
59
60 IncrementalCompilationUnitElementBuilder._(this.unitSource,
61 this.librarySource, this.oldUnit, this.newUnit, this.unitElement);
62
63 /**
64 * Updates [oldUnit] to have the same directives and declarations, in the
65 * same order as in [newUnit]. Existing resolution is kept where possible.
66 *
67 * Updates [unitElement] by adding/removing elements as needed.
68 *
69 * Fills [unitDelta] with added/remove elements.
70 */
34 void build() { 71 void build() {
35 new CompilationUnitBuilder().buildCompilationUnit( 72 new CompilationUnitBuilder().buildCompilationUnit(
36 source, newUnit, librarySource); 73 unitSource, newUnit, librarySource);
37 _processDirectives(); 74 _processDirectives();
38 _processUnitMembers(); 75 _processUnitMembers();
39 newUnit.element = unitElement; 76 newUnit.element = unitElement;
40 } 77 _replaceUnitContents(oldUnit, newUnit);
41
42 void _addElementsToHolder(CompilationUnitMember node) {
43 List<Element> elements = _getElements(node);
44 elements.forEach(_addElementToHolder);
45 } 78 }
46 79
47 void _addElementToHolder(Element element) { 80 void _addElementToHolder(Element element) {
48 if (element is PropertyAccessorElement) { 81 if (element is PropertyAccessorElement) {
49 holder.addAccessor(element); 82 holder.addAccessor(element);
50 } else if (element is ClassElement) { 83 } else if (element is ClassElement) {
51 if (element.isEnum) { 84 if (element.isEnum) {
52 holder.addEnum(element); 85 holder.addEnum(element);
53 } else { 86 } else {
54 holder.addType(element); 87 holder.addType(element);
55 } 88 }
56 } else if (element is FunctionElement) { 89 } else if (element is FunctionElement) {
57 holder.addFunction(element); 90 holder.addFunction(element);
58 } else if (element is FunctionTypeAliasElement) { 91 } else if (element is FunctionTypeAliasElement) {
59 holder.addTypeAlias(element); 92 holder.addTypeAlias(element);
60 } else if (element is TopLevelVariableElement) { 93 } else if (element is TopLevelVariableElement) {
61 holder.addTopLevelVariable(element); 94 holder.addTopLevelVariable(element);
62 } 95 }
63 } 96 }
64 97
65 void _processDirectives() { 98 void _processDirectives() {
66 Map<String, Directive> oldDirectiveMap = new HashMap<String, Directive>(); 99 Map<String, Directive> oldDirectiveMap = new HashMap<String, Directive>();
67 for (Directive oldDirective in oldUnit.directives) { 100 for (Directive oldDirective in oldUnit.directives) {
68 String code = TokenUtils.getFullCode(oldDirective); 101 String code = TokenUtils.getFullCode(oldDirective);
69 oldDirectiveMap[code] = oldDirective; 102 oldDirectiveMap[code] = oldDirective;
70 } 103 }
71 // Replace new nodes with the identical old nodes. 104 // Replace new nodes with the identical old nodes.
105 Set<Directive> removedDirectives = oldUnit.directives.toSet();
72 for (Directive newDirective in newUnit.directives) { 106 for (Directive newDirective in newUnit.directives) {
73 String code = TokenUtils.getFullCode(newDirective); 107 String code = TokenUtils.getFullCode(newDirective);
74 // Prepare an old directive. 108 // Prepare an old directive.
75 Directive oldDirective = oldDirectiveMap[code]; 109 Directive oldDirective = oldDirectiveMap[code];
76 if (oldDirective == null) { 110 if (oldDirective == null) {
111 unitDelta.hasDirectiveChange = true;
77 continue; 112 continue;
78 } 113 }
79 // URI's must be resolved to the same sources. 114 // URI's must be resolved to the same sources.
80 if (newDirective is UriBasedDirective && 115 if (newDirective is UriBasedDirective &&
81 oldDirective is UriBasedDirective) { 116 oldDirective is UriBasedDirective) {
82 if (oldDirective.source != newDirective.source) { 117 if (oldDirective.source != newDirective.source) {
83 continue; 118 continue;
84 } 119 }
85 } 120 }
86 // Do replacement. 121 // Do replacement.
87 _replaceNode(newDirective, oldDirective); 122 _replaceNode(newDirective, oldDirective);
123 removedDirectives.remove(oldDirective);
124 }
125 // If there are any directives left, then these directives were removed.
126 if (removedDirectives.isNotEmpty) {
127 unitDelta.hasDirectiveChange = true;
88 } 128 }
89 } 129 }
90 130
91 void _processUnitMembers() { 131 void _processUnitMembers() {
92 Map<String, CompilationUnitMember> oldNodeMap = 132 Map<String, CompilationUnitMember> oldNodeMap =
93 new HashMap<String, CompilationUnitMember>(); 133 new HashMap<String, CompilationUnitMember>();
94 for (CompilationUnitMember oldNode in oldUnit.declarations) { 134 for (CompilationUnitMember oldNode in oldUnit.declarations) {
95 String code = TokenUtils.getFullCode(oldNode); 135 String code = TokenUtils.getFullCode(oldNode);
96 oldNodeMap[code] = oldNode; 136 oldNodeMap[code] = oldNode;
97 } 137 }
138 // Prepare all old top-level elements.
139 Set<Element> removedElements = new Set<Element>();
140 removedElements.addAll(unitElement.accessors);
141 removedElements.addAll(unitElement.enums);
142 removedElements.addAll(unitElement.functions);
143 removedElements.addAll(unitElement.functionTypeAliases);
144 removedElements.addAll(unitElement.types);
145 removedElements.addAll(unitElement.topLevelVariables);
98 // Replace new nodes with the identical old nodes. 146 // Replace new nodes with the identical old nodes.
99 for (CompilationUnitMember newNode in newUnit.declarations) { 147 for (CompilationUnitMember newNode in newUnit.declarations) {
100 String code = TokenUtils.getFullCode(newNode); 148 String code = TokenUtils.getFullCode(newNode);
101 // Prepare an old node. 149 // Prepare an old node.
102 CompilationUnitMember oldNode = oldNodeMap[code]; 150 CompilationUnitMember oldNode = oldNodeMap[code];
103 if (oldNode == null) { 151 if (oldNode == null) {
104 _addElementsToHolder(newNode); 152 List<Element> elements = _getElements(newNode);
153 elements.forEach(_addElementToHolder);
154 elements.forEach(unitDelta.addedDeclarations.add);
105 continue; 155 continue;
106 } 156 }
107 // Do replacement. 157 // Do replacement.
108 _replaceNode(newNode, oldNode); 158 _replaceNode(newNode, oldNode);
109 _addElementsToHolder(oldNode); 159 List<Element> elements = _getElements(oldNode);
160 elements.forEach(_addElementToHolder);
161 elements.forEach(removedElements.remove);
110 } 162 }
163 unitDelta.removedDeclarations.addAll(removedElements);
111 // Update CompilationUnitElement. 164 // Update CompilationUnitElement.
112 unitElement.accessors = holder.accessors; 165 unitElement.accessors = holder.accessors;
113 unitElement.enums = holder.enums; 166 unitElement.enums = holder.enums;
114 unitElement.functions = holder.functions; 167 unitElement.functions = holder.functions;
115 unitElement.typeAliases = holder.typeAliases; 168 unitElement.typeAliases = holder.typeAliases;
116 unitElement.types = holder.types; 169 unitElement.types = holder.types;
117 unitElement.topLevelVariables = holder.topLevelVariables; 170 unitElement.topLevelVariables = holder.topLevelVariables;
118 holder.validate(); 171 holder.validate();
119 } 172 }
120 173
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 elements.add(node.element); 223 elements.add(node.element);
171 } else if (node is Declaration && node.element != null) { 224 } else if (node is Declaration && node.element != null) {
172 Element element = node.element; 225 Element element = node.element;
173 elements.add(element); 226 elements.add(element);
174 if (element is PropertyAccessorElement) { 227 if (element is PropertyAccessorElement) {
175 elements.add(element.variable); 228 elements.add(element.variable);
176 } 229 }
177 } 230 }
178 return elements; 231 return elements;
179 } 232 }
233
234 /**
235 * Replaces contents of the [to] unit with the contenxts of the [from] unit.
236 */
237 static void _replaceUnitContents(CompilationUnit to, CompilationUnit from) {
238 to.directives.clear();
239 to.declarations.clear();
240 to.beginToken = from.beginToken;
241 to.scriptTag = from.scriptTag;
242 to.directives.addAll(from.directives);
243 to.declarations.addAll(from.declarations);
244 to.element = to.element;
245 to.lineInfo = from.lineInfo;
246 }
180 } 247 }
181 248
182 /** 249 /**
183 * Utilities for [Token] manipulations. 250 * Utilities for [Token] manipulations.
184 */ 251 */
185 class TokenUtils { 252 class TokenUtils {
186 static const String _SEPARATOR = "\uFFFF"; 253 static const String _SEPARATOR = "\uFFFF";
187 254
188 /** 255 /**
189 * Copy offsets from [newToken]s to [oldToken]s. 256 * Copy offsets from [newToken]s to [oldToken]s.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 353 }
287 int oldOffset = element.nameOffset; 354 int oldOffset = element.nameOffset;
288 int newOffset = map[oldOffset]; 355 int newOffset = map[oldOffset];
289 assert(newOffset != null); 356 assert(newOffset != null);
290 (element as ElementImpl).nameOffset = newOffset; 357 (element as ElementImpl).nameOffset = newOffset;
291 if (element is! LibraryElement) { 358 if (element is! LibraryElement) {
292 super.visitElement(element); 359 super.visitElement(element);
293 } 360 }
294 } 361 }
295 } 362 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/ast.dart ('k') | pkg/analyzer/test/src/task/incremental_element_builder_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698