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

Side by Side Diff: pkg/analyzer/lib/src/generated/incremental_resolver.dart

Issue 750083002: Matching for import/export/part directives. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/incremental_resolver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 engine.incremental_resolver; 5 library engine.incremental_resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'ast.dart'; 9 import 'ast.dart';
10 import 'element.dart'; 10 import 'element.dart';
11 import 'error.dart'; 11 import 'error.dart';
12 import 'java_engine.dart'; 12 import 'java_engine.dart';
13 import 'resolver.dart'; 13 import 'resolver.dart';
14 import 'scanner.dart'; 14 import 'scanner.dart';
15 import 'source.dart'; 15 import 'source.dart';
16 16
17 17
18 /** 18 /**
19 * Instances of the class [DeclarationMatcher] determine whether the element 19 * Instances of the class [DeclarationMatcher] determine whether the element
20 * model defined by a given AST structure matches an existing element model. 20 * model defined by a given AST structure matches an existing element model.
21 */ 21 */
22 class DeclarationMatcher extends RecursiveAstVisitor { 22 class DeclarationMatcher extends RecursiveAstVisitor {
23 /** 23 /**
24 * The libary containing the AST nodes being visited.
25 */
26 LibraryElement _enclosingLibrary;
27
28 /**
24 * The compilation unit containing the AST nodes being visited. 29 * The compilation unit containing the AST nodes being visited.
25 */ 30 */
26 CompilationUnitElement _enclosingUnit; 31 CompilationUnitElement _enclosingUnit;
27 32
28 /** 33 /**
29 * The function type alias containing the AST nodes being visited, or `null` i f we are not 34 * The function type alias containing the AST nodes being visited, or `null` i f we are not
30 * in the scope of a function type alias. 35 * in the scope of a function type alias.
31 */ 36 */
32 FunctionTypeAliasElement _enclosingAlias; 37 FunctionTypeAliasElement _enclosingAlias;
33 38
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 _hasConstructor = true; 144 _hasConstructor = true;
140 SimpleIdentifier constructorName = node.name; 145 SimpleIdentifier constructorName = node.name;
141 ConstructorElement element = constructorName == null ? 146 ConstructorElement element = constructorName == null ?
142 _enclosingClass.unnamedConstructor : 147 _enclosingClass.unnamedConstructor :
143 _enclosingClass.getNamedConstructor(constructorName.name); 148 _enclosingClass.getNamedConstructor(constructorName.name);
144 _processElement(element); 149 _processElement(element);
145 _assertCompatibleParameters(node.parameters, element.parameters); 150 _assertCompatibleParameters(node.parameters, element.parameters);
146 } 151 }
147 152
148 @override 153 @override
154 visitEnumConstantDeclaration(EnumConstantDeclaration node) {
155 String name = node.name.name;
156 FieldElement element = _findElement(_enclosingClass.fields, name);
157 _processElement(element);
158 }
159
160 @override
149 visitEnumDeclaration(EnumDeclaration node) { 161 visitEnumDeclaration(EnumDeclaration node) {
150 String name = node.name.name; 162 String name = node.name.name;
151 ClassElement element = _findElement(_enclosingUnit.enums, name); 163 ClassElement element = _findElement(_enclosingUnit.enums, name);
152 _enclosingClass = element; 164 _enclosingClass = element;
153 _processElement(element); 165 _processElement(element);
154 _assertTrue(element.isEnum); 166 _assertTrue(element.isEnum);
155 super.visitEnumDeclaration(node); 167 super.visitEnumDeclaration(node);
156 } 168 }
157 169
158 @override 170 @override
159 visitEnumConstantDeclaration(EnumConstantDeclaration node) { 171 visitExportDirective(ExportDirective node) {
Brian Wilkerson 2014/11/21 19:50:41 Export directives also have combinators. Do we nee
scheglov 2014/11/21 20:07:17 Done.
160 String name = node.name.name; 172 String uri = _getStringValue(node.uri);
161 FieldElement element = _findElement(_enclosingClass.fields, name); 173 if (uri != null) {
162 _processElement(element); 174 ExportElement element =
175 _findUriReferencedElement(_enclosingLibrary.exports, uri);
176 _processElement(element);
177 }
163 } 178 }
164 179
165 @override 180 @override
166 visitExportDirective(ExportDirective node) {
167 String uri = _getStringValue(node.uri);
168 if (uri != null) {
169 LibraryElement library = _enclosingUnit.library;
170 ExportElement exportElement = _findExport(
171 library.exports,
172 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri));
173 _processElement(exportElement);
174 }
175 super.visitExportDirective(node);
176 }
177
178 @override
179 visitExpressionFunctionBody(ExpressionFunctionBody node) { 181 visitExpressionFunctionBody(ExpressionFunctionBody node) {
180 // ignore bodies 182 // ignore bodies
181 } 183 }
182 184
183 @override 185 @override
184 visitExtendsClause(ExtendsClause node) { 186 visitExtendsClause(ExtendsClause node) {
185 _assertSameType(node.superclass, _enclosingClass.supertype); 187 _assertSameType(node.superclass, _enclosingClass.supertype);
186 } 188 }
187 189
188 @override 190 @override
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 visitImplementsClause(ImplementsClause node) { 240 visitImplementsClause(ImplementsClause node) {
239 List<TypeName> nodes = node.interfaces; 241 List<TypeName> nodes = node.interfaces;
240 List<InterfaceType> types = _enclosingClass.interfaces; 242 List<InterfaceType> types = _enclosingClass.interfaces;
241 _assertSameTypes(nodes, types); 243 _assertSameTypes(nodes, types);
242 } 244 }
243 245
244 @override 246 @override
245 visitImportDirective(ImportDirective node) { 247 visitImportDirective(ImportDirective node) {
246 String uri = _getStringValue(node.uri); 248 String uri = _getStringValue(node.uri);
247 if (uri != null) { 249 if (uri != null) {
248 LibraryElement library = _enclosingUnit.library; 250 ImportElement element =
249 ImportElement importElement = _findImport( 251 _findUriReferencedElement(_enclosingLibrary.imports, uri);
250 library.imports, 252 _processElement(element);
251 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri), 253 // match the prefix
252 node.prefix); 254 SimpleIdentifier prefixNode = node.prefix;
253 _processElement(importElement); 255 PrefixElement prefixElement = element.prefix;
256 if (prefixNode == null) {
257 _assertNull(prefixElement);
258 } else {
259 _assertNotNull(prefixElement);
260 _assertEquals(prefixNode.name, prefixElement.name);
261 }
262 // prepare shown/hidden names in the element
263 Set<String> showNames = new Set<String>();
264 Set<String> hideNames = new Set<String>();
265 for (NamespaceCombinator combinator in element.combinators) {
266 if (combinator is ShowElementCombinator) {
267 showNames.addAll(combinator.shownNames);
268 } else if (combinator is HideElementCombinator) {
269 hideNames.addAll(combinator.hiddenNames);
270 }
271 }
272 // match combinators with the node
273 for (Combinator combinator in node.combinators) {
274 if (combinator is ShowCombinator) {
275 for (SimpleIdentifier nameNode in combinator.shownNames) {
276 String name = nameNode.name;
277 _assertTrue(showNames.remove(name));
278 }
279 _assertTrue(showNames.isEmpty);
280 } else if (combinator is HideCombinator) {
281 for (SimpleIdentifier nameNode in combinator.hiddenNames) {
282 String name = nameNode.name;
283 _assertTrue(hideNames.remove(name));
284 }
285 _assertTrue(hideNames.isEmpty);
286 }
287 }
254 } 288 }
255 super.visitImportDirective(node);
256 } 289 }
257 290
258 @override 291 @override
259 visitMethodDeclaration(MethodDeclaration node) { 292 visitMethodDeclaration(MethodDeclaration node) {
260 // prepare element name 293 // prepare element name
261 String name = node.name.name; 294 String name = node.name.name;
262 if (name == TokenType.MINUS.lexeme && 295 if (name == TokenType.MINUS.lexeme &&
263 node.parameters.parameters.length == 0) { 296 node.parameters.parameters.length == 0) {
264 name = "unary-"; 297 name = "unary-";
265 } 298 }
(...skipping 15 matching lines...) Expand all
281 _processElement(element); 314 _processElement(element);
282 // TODO(scheglov) test returnType 315 // TODO(scheglov) test returnType
283 _assertSameType(node.returnType, element.returnType); 316 _assertSameType(node.returnType, element.returnType);
284 _assertCompatibleParameters(node.parameters, element.parameters); 317 _assertCompatibleParameters(node.parameters, element.parameters);
285 } 318 }
286 319
287 @override 320 @override
288 visitPartDirective(PartDirective node) { 321 visitPartDirective(PartDirective node) {
289 String uri = _getStringValue(node.uri); 322 String uri = _getStringValue(node.uri);
290 if (uri != null) { 323 if (uri != null) {
291 Source partSource =
292 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri);
293 CompilationUnitElement element = 324 CompilationUnitElement element =
294 _findPart(_enclosingUnit.library.parts, partSource); 325 _findUriReferencedElement(_enclosingLibrary.parts, uri);
295 _processElement(element); 326 _processElement(element);
296 } 327 }
297 super.visitPartDirective(node); 328 super.visitPartDirective(node);
298 } 329 }
299 330
300 @override 331 @override
301 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { 332 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
302 _inTopLevelVariableDeclaration = true; 333 _inTopLevelVariableDeclaration = true;
303 try { 334 try {
304 super.visitTopLevelVariableDeclaration(node); 335 super.visitTopLevelVariableDeclaration(node);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 throw new _DeclarationMismatchException(); 413 throw new _DeclarationMismatchException();
383 } 414 }
384 } 415 }
385 416
386 void _assertNotNull(Element element) { 417 void _assertNotNull(Element element) {
387 if (element == null) { 418 if (element == null) {
388 throw new _DeclarationMismatchException(); 419 throw new _DeclarationMismatchException();
389 } 420 }
390 } 421 }
391 422
423 void _assertNull(Element element) {
424 if (element != null) {
425 throw new _DeclarationMismatchException();
426 }
427 }
428
392 void _assertSameType(TypeName node, DartType type) { 429 void _assertSameType(TypeName node, DartType type) {
393 // no return type == dynamic 430 // no return type == dynamic
394 if (node == null) { 431 if (node == null) {
395 return _assertTrue(type == null || type.isDynamic); 432 return _assertTrue(type == null || type.isDynamic);
396 } 433 }
397 // check specific type kinds 434 // check specific type kinds
398 String nodeName = node.name.name; 435 String nodeName = node.name.name;
399 if (type is InterfaceType) { 436 if (type is InterfaceType) {
400 _assertEquals(nodeName, type.name); 437 _assertEquals(nodeName, type.name);
401 // check arguments 438 // check arguments
(...skipping 22 matching lines...) Expand all
424 } 461 }
425 } 462 }
426 463
427 void _assertTrue(bool condition) { 464 void _assertTrue(bool condition) {
428 if (!condition) { 465 if (!condition) {
429 throw new _DeclarationMismatchException(); 466 throw new _DeclarationMismatchException();
430 } 467 }
431 } 468 }
432 469
433 /** 470 /**
434 * Given that the comparison is to begin with the given element, capture the e nclosing elements 471 * Given that the comparison is to begin with the given [element], capture
435 * that might be used while performing the comparison. 472 * the enclosing elements that might be used while performing the comparison.
436 *
437 * @param element the element corresponding to the AST structure to be compare d
438 */ 473 */
439 void _captureEnclosingElements(Element element) { 474 void _captureEnclosingElements(Element element) {
440 Element parent = 475 Element parent =
441 element is CompilationUnitElement ? element : element.enclosingElement; 476 element is CompilationUnitElement ? element : element.enclosingElement;
442 while (parent != null) { 477 while (parent != null) {
443 if (parent is CompilationUnitElement) { 478 if (parent is CompilationUnitElement) {
444 _enclosingUnit = parent as CompilationUnitElement; 479 _enclosingUnit = parent as CompilationUnitElement;
480 _enclosingLibrary = element.library;
445 } else if (parent is ClassElement) { 481 } else if (parent is ClassElement) {
446 if (_enclosingClass == null) { 482 if (_enclosingClass == null) {
447 _enclosingClass = parent as ClassElement; 483 _enclosingClass = parent as ClassElement;
448 } 484 }
449 } else if (parent is FunctionTypeAliasElement) { 485 } else if (parent is FunctionTypeAliasElement) {
450 if (_enclosingAlias == null) { 486 if (_enclosingAlias == null) {
451 _enclosingAlias = parent as FunctionTypeAliasElement; 487 _enclosingAlias = parent as FunctionTypeAliasElement;
452 } 488 }
453 } else if (parent is ParameterElement) { 489 } else if (parent is ParameterElement) {
454 if (_enclosingParameter == null) { 490 if (_enclosingParameter == null) {
(...skipping 10 matching lines...) Expand all
465 Element _findElement(List<Element> elements, String name) { 501 Element _findElement(List<Element> elements, String name) {
466 for (Element element in elements) { 502 for (Element element in elements) {
467 if (element.displayName == name) { 503 if (element.displayName == name) {
468 return element; 504 return element;
469 } 505 }
470 } 506 }
471 return null; 507 return null;
472 } 508 }
473 509
474 /** 510 /**
475 * Return the export element from the given array whose library has the given source, or
476 * `null` if there is no such export.
477 *
478 * @param exports the export elements being searched
479 * @param source the source of the library associated with the export element to being searched
480 * for
481 * @return the export element whose library has the given source
482 */
483 ExportElement _findExport(List<ExportElement> exports, Source source) {
484 for (ExportElement export in exports) {
485 if (export.exportedLibrary.source == source) {
486 return export;
487 }
488 }
489 return null;
490 }
491
492 /**
493 * Return the element in the given array of elements that was created for the declaration with the 511 * Return the element in the given array of elements that was created for the declaration with the
494 * given name. 512 * given name.
495 * 513 *
496 * @param elements the elements of the appropriate kind that exist in the curr ent context 514 * @param elements the elements of the appropriate kind that exist in the curr ent context
497 * @param identifier the name node in the declaration of the element to be ret urned 515 * @param identifier the name node in the declaration of the element to be ret urned
498 * @return the element created for the declaration with the given name 516 * @return the element created for the declaration with the given name
499 */ 517 */
500 Element _findIdentifier(List<Element> elements, 518 Element _findIdentifier(List<Element> elements,
501 SimpleIdentifier identifier) => 519 SimpleIdentifier identifier) =>
502 _findWithNameAndOffset(elements, identifier.name, identifier.offset); 520 _findWithNameAndOffset(elements, identifier.name, identifier.offset);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 int offset) { 580 int offset) {
563 for (Element element in elements) { 581 for (Element element in elements) {
564 if (element.displayName == name && element.nameOffset == offset) { 582 if (element.displayName == name && element.nameOffset == offset) {
565 return element; 583 return element;
566 } 584 }
567 } 585 }
568 return null; 586 return null;
569 } 587 }
570 588
571 void _gatherElements(Element element) { 589 void _gatherElements(Element element) {
572 element.accept(new _ElementsGatherer(this)); 590 _ElementsGatherer gatherer = new _ElementsGatherer(this);
591 element.accept(gatherer);
592 // TODO(scheglov) push into CompilationUnitElement
593 if (identical(_enclosingUnit, _enclosingLibrary.definingCompilationUnit)) {
594 gatherer.addElements(_enclosingLibrary.imports);
595 gatherer.addElements(_enclosingLibrary.exports);
596 gatherer.addElements(_enclosingLibrary.parts);
597 }
573 } 598 }
574 599
575 /** 600 /**
576 * Return the value of the given string literal, or `null` if the string is no t a constant 601 * Return the value of the given string literal, or `null` if the string is no t a constant
577 * string without any string interpolation. 602 * string without any string interpolation.
578 * 603 *
579 * @param literal the string literal whose value is to be returned 604 * @param literal the string literal whose value is to be returned
580 * @return the value of the given string literal 605 * @return the value of the given string literal
581 */ 606 */
582 String _getStringValue(StringLiteral literal) { 607 String _getStringValue(StringLiteral literal) {
583 if (literal is StringInterpolation) { 608 if (literal is StringInterpolation) {
584 return null; 609 return null;
585 } 610 }
586 return literal.stringValue; 611 return literal.stringValue;
587 } 612 }
588 613
589 void _processElement(Element element) { 614 void _processElement(Element element) {
590 _assertNotNull(element); 615 _assertNotNull(element);
591 if (!_allElements.contains(element)) { 616 if (!_allElements.contains(element)) {
592 throw new _DeclarationMismatchException(); 617 throw new _DeclarationMismatchException();
593 } 618 }
594 _unmatchedElements.remove(element); 619 _unmatchedElements.remove(element);
595 } 620 }
621
622 /**
623 * Return the [UriReferencedElement] from [elements] with the given [uri], or
624 * `null` if there is no such element.
625 */
626 static UriReferencedElement
627 _findUriReferencedElement(List<UriReferencedElement> elements, String uri) {
628 for (UriReferencedElement element in elements) {
629 if (element.uri == uri) {
630 return element;
631 }
632 }
633 return null;
634 }
596 } 635 }
597 636
598 637
599 /** 638 /**
600 * Instances of the class [IncrementalResolver] resolve the smallest portion of 639 * Instances of the class [IncrementalResolver] resolve the smallest portion of
601 * an AST structure that we currently know how to resolve. 640 * an AST structure that we currently know how to resolve.
602 */ 641 */
603 class IncrementalResolver { 642 class IncrementalResolver {
604 /** 643 /**
605 * The error listener that will be informed of any errors that are found 644 * The error listener that will be informed of any errors that are found
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 super.visitElement(element); 965 super.visitElement(element);
927 } 966 }
928 } 967 }
929 968
930 969
931 class _ElementsGatherer extends GeneralizingElementVisitor { 970 class _ElementsGatherer extends GeneralizingElementVisitor {
932 final DeclarationMatcher matcher; 971 final DeclarationMatcher matcher;
933 972
934 _ElementsGatherer(this.matcher); 973 _ElementsGatherer(this.matcher);
935 974
975 void addElements(List<Element> elements) {
976 for (Element element in elements) {
977 if (!element.isSynthetic) {
978 _addElement(element);
979 }
980 }
981 }
982
936 @override 983 @override
937 visitElement(Element element) { 984 visitElement(Element element) {
938 _addElement(element); 985 _addElement(element);
939 super.visitElement(element); 986 super.visitElement(element);
940 } 987 }
941 988
942 @override 989 @override
943 visitExecutableElement(ExecutableElement element) { 990 visitExecutableElement(ExecutableElement element) {
944 _addElement(element); 991 _addElement(element);
945 } 992 }
(...skipping 14 matching lines...) Expand all
960 // Don't visit children (such as property accessors). 1007 // Don't visit children (such as property accessors).
961 } 1008 }
962 1009
963 void _addElement(Element element) { 1010 void _addElement(Element element) {
964 if (element != null) { 1011 if (element != null) {
965 matcher._allElements.add(element); 1012 matcher._allElements.add(element);
966 matcher._unmatchedElements.add(element); 1013 matcher._unmatchedElements.add(element);
967 } 1014 }
968 } 1015 }
969 } 1016 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/incremental_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698