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

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

Issue 738183002: Tests for matching classes. (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 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';
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
46 /** 46 /**
47 * The parameter containing the AST nodes being visited, or `null` if we are n ot in the 47 * The parameter containing the AST nodes being visited, or `null` if we are n ot in the
48 * scope of a parameter. 48 * scope of a parameter.
49 */ 49 */
50 ParameterElement _enclosingParameter; 50 ParameterElement _enclosingParameter;
51 51
52 bool _inTopLevelVariableDeclaration = false; 52 bool _inTopLevelVariableDeclaration = false;
53 53
54 /** 54 /**
55 * Is `true` if the current class declaration has a constructor.
56 */
57 bool _hasConstructor = false;
58
59 /**
55 * A set containing all of the elements in the element model that were defined by the old AST node 60 * A set containing all of the elements in the element model that were defined by the old AST node
56 * corresponding to the AST node being visited. 61 * corresponding to the AST node being visited.
57 */ 62 */
58 HashSet<Element> _allElements = new HashSet<Element>(); 63 HashSet<Element> _allElements = new HashSet<Element>();
59 64
60 /** 65 /**
61 * A set containing all of the elements in the element model that were defined by the old AST node 66 * A set containing all of the elements in the element model that were defined by the old AST node
62 * corresponding to the AST node being visited that have not already been matc hed to nodes in the 67 * corresponding to the AST node being visited that have not already been matc hed to nodes in the
63 * AST structure being visited. 68 * AST structure being visited.
64 */ 69 */
65 HashSet<Element> _unmatchedElements = new HashSet<Element>(); 70 HashSet<Element> _unmatchedElements = new HashSet<Element>();
66 71
67 /** 72 /**
68 * Return `true` if the declarations within the given AST structure define an element model 73 * Return `true` if the declarations within the given AST structure define an element model
69 * that is equivalent to the corresponding elements rooted at the given elemen t. 74 * that is equivalent to the corresponding elements rooted at the given elemen t.
70 * 75 *
71 * @param node the AST structure being compared to the element model 76 * @param node the AST structure being compared to the element model
72 * @param element the root of the element model being compared to the AST stru cture 77 * @param element the root of the element model being compared to the AST stru cture
73 * @return `true` if the AST structure defines the same elements as those in t he given 78 * @return `true` if the AST structure defines the same elements as those in t he given
74 * element model 79 * element model
75 */ 80 */
76 bool matches(AstNode node, Element element) { 81 bool matches(AstNode node, Element element) {
77 _captureEnclosingElements(element); 82 _captureEnclosingElements(element);
78 _gatherElements(element); 83 _gatherElements(element);
79 try { 84 try {
80 node.accept(this); 85 node.accept(this);
81 } on _DeclarationMismatchException catch (exception) { 86 } on _DeclarationMismatchException catch (exception, st) {
Brian Wilkerson 2014/11/19 23:07:22 Not sure why you added a parameter if we're not us
scheglov 2014/11/20 05:27:30 Actually the hint _is_ reported here. So, it is my
82 return false; 87 return false;
83 } 88 }
84 print(_unmatchedElements.join('\n'));
85 return _unmatchedElements.isEmpty; 89 return _unmatchedElements.isEmpty;
86 } 90 }
87 91
88 @override 92 @override
89 Object visitCatchClause(CatchClause node) { 93 Object visitCatchClause(CatchClause node) {
90 SimpleIdentifier exceptionParameter = node.exceptionParameter; 94 SimpleIdentifier exceptionParameter = node.exceptionParameter;
91 if (exceptionParameter != null) { 95 if (exceptionParameter != null) {
92 List<LocalVariableElement> localVariables = 96 List<LocalVariableElement> localVariables =
93 _enclosingExecutable.localVariables; 97 _enclosingExecutable.localVariables;
94 LocalVariableElement exceptionElement = 98 LocalVariableElement exceptionElement =
95 _findIdentifier(localVariables, exceptionParameter); 99 _findIdentifier(localVariables, exceptionParameter);
96 _processElement(exceptionElement); 100 _processElement(exceptionElement);
97 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; 101 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
98 if (stackTraceParameter != null) { 102 if (stackTraceParameter != null) {
99 LocalVariableElement stackTraceElement = 103 LocalVariableElement stackTraceElement =
100 _findIdentifier(localVariables, stackTraceParameter); 104 _findIdentifier(localVariables, stackTraceParameter);
101 _processElement(stackTraceElement); 105 _processElement(stackTraceElement);
102 } 106 }
103 } 107 }
104 return super.visitCatchClause(node); 108 return super.visitCatchClause(node);
105 } 109 }
106 110
107 @override 111 @override
108 Object visitClassDeclaration(ClassDeclaration node) { 112 Object visitClassDeclaration(ClassDeclaration node) {
109 ClassElement outerClass = _enclosingClass; 113 String name = node.name.name;
110 try { 114 ClassElement clazz = _findElement(_enclosingUnit.types, name);
111 SimpleIdentifier className = node.name; 115 _enclosingClass = clazz;
112 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); 116 _processElement(clazz);
113 _processElement(_enclosingClass); 117 // check for missing clauses
114 if (!_hasConstructor(node)) { 118 if (node.extendsClause == null) {
115 ConstructorElement constructor = _enclosingClass.unnamedConstructor; 119 _assertTrue(clazz.supertype.name == 'Object');
116 if (constructor.isSynthetic) { 120 }
117 _processElement(constructor); 121 if (node.implementsClause == null) {
118 } 122 _assertTrue(clazz.interfaces.isEmpty);
123 }
124 if (node.withClause == null) {
125 _assertTrue(clazz.mixins.isEmpty);
126 }
127 // process clauses and members
128 _hasConstructor = false;
129 super.visitClassDeclaration(node);
130 // process default constructor
131 if (!_hasConstructor) {
132 ConstructorElement constructor = clazz.unnamedConstructor;
133 _processElement(constructor);
134 if (!constructor.isSynthetic) {
135 _assertEquals(constructor.parameters.length, 0);
119 } 136 }
120 return super.visitClassDeclaration(node);
121 } finally {
122 _enclosingClass = outerClass;
123 } 137 }
138 return null;
124 } 139 }
125 140
126 @override 141 @override
127 Object visitClassTypeAlias(ClassTypeAlias node) { 142 Object visitClassTypeAlias(ClassTypeAlias node) {
128 ClassElement outerClass = _enclosingClass; 143 ClassElement outerClass = _enclosingClass;
129 try { 144 try {
130 SimpleIdentifier className = node.name; 145 SimpleIdentifier className = node.name;
131 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); 146 _enclosingClass = _findIdentifier(_enclosingUnit.types, className);
132 _processElement(_enclosingClass); 147 _processElement(_enclosingClass);
133 return super.visitClassTypeAlias(node); 148 return super.visitClassTypeAlias(node);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 LibraryElement library = _enclosingUnit.library; 233 LibraryElement library = _enclosingUnit.library;
219 ExportElement exportElement = _findExport( 234 ExportElement exportElement = _findExport(
220 library.exports, 235 library.exports,
221 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri)); 236 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri));
222 _processElement(exportElement); 237 _processElement(exportElement);
223 } 238 }
224 return super.visitExportDirective(node); 239 return super.visitExportDirective(node);
225 } 240 }
226 241
227 @override 242 @override
243 visitExtendsClause(ExtendsClause node) {
244 _assertSameType(node.superclass, _enclosingClass.supertype);
245 }
246
247 @override
228 Object visitFieldFormalParameter(FieldFormalParameter node) { 248 Object visitFieldFormalParameter(FieldFormalParameter node) {
229 if (node.parent is! DefaultFormalParameter) { 249 if (node.parent is! DefaultFormalParameter) {
230 SimpleIdentifier parameterName = node.identifier; 250 SimpleIdentifier parameterName = node.identifier;
231 ParameterElement element = _getElementForParameter(node, parameterName); 251 ParameterElement element = _getElementForParameter(node, parameterName);
232 ParameterElement outerParameter = _enclosingParameter; 252 ParameterElement outerParameter = _enclosingParameter;
233 try { 253 try {
234 _enclosingParameter = element; 254 _enclosingParameter = element;
235 _processElement(_enclosingParameter); 255 _processElement(_enclosingParameter);
236 return super.visitFieldFormalParameter(node); 256 return super.visitFieldFormalParameter(node);
237 } finally { 257 } finally {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 return super.visitFunctionTypedFormalParameter(node); 334 return super.visitFunctionTypedFormalParameter(node);
315 } finally { 335 } finally {
316 _enclosingParameter = outerParameter; 336 _enclosingParameter = outerParameter;
317 } 337 }
318 } else { 338 } else {
319 return super.visitFunctionTypedFormalParameter(node); 339 return super.visitFunctionTypedFormalParameter(node);
320 } 340 }
321 } 341 }
322 342
323 @override 343 @override
344 visitImplementsClause(ImplementsClause node) {
345 List<TypeName> nodes = node.interfaces;
346 List<InterfaceType> types = _enclosingClass.interfaces;
347 _assertSameTypes(nodes, types);
348 }
349
350 @override
324 Object visitImportDirective(ImportDirective node) { 351 Object visitImportDirective(ImportDirective node) {
325 String uri = _getStringValue(node.uri); 352 String uri = _getStringValue(node.uri);
326 if (uri != null) { 353 if (uri != null) {
327 LibraryElement library = _enclosingUnit.library; 354 LibraryElement library = _enclosingUnit.library;
328 ImportElement importElement = _findImport( 355 ImportElement importElement = _findImport(
329 library.imports, 356 library.imports,
330 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri), 357 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source, uri),
331 node.prefix); 358 node.prefix);
332 _processElement(importElement); 359 _processElement(importElement);
333 } 360 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 VariableElement element; 500 VariableElement element;
474 if (_enclosingExecutable != null) { 501 if (_enclosingExecutable != null) {
475 element = _findElement(_enclosingExecutable.localVariables, name); 502 element = _findElement(_enclosingExecutable.localVariables, name);
476 } 503 }
477 if (element == null && _enclosingClass != null) { 504 if (element == null && _enclosingClass != null) {
478 element = _findElement(_enclosingClass.fields, name); 505 element = _findElement(_enclosingClass.fields, name);
479 } 506 }
480 return super.visitVariableDeclaration(node); 507 return super.visitVariableDeclaration(node);
481 } 508 }
482 509
510 @override
511 visitWithClause(WithClause node) {
512 List<TypeName> nodes = node.mixinTypes;
513 List<InterfaceType> types = _enclosingClass.mixins;
514 _assertSameTypes(nodes, types);
515 }
516
517 void _assertEquals(Object a, Object b) {
518 if (a != b) {
519 throw new _DeclarationMismatchException();
520 }
521 }
522
523 void _assertFalse(bool condition) {
524 if (condition) {
525 throw new _DeclarationMismatchException();
526 }
527 }
528
529 void _assertNotNull(Element element) {
530 if (element == null) {
531 throw new _DeclarationMismatchException();
532 }
533 }
534
483 void _assertSameType(TypeName node, DartType type) { 535 void _assertSameType(TypeName node, DartType type) {
484 String nodeName = node.name.name; 536 String nodeName = node.name.name;
485 if (type is InterfaceType) { 537 if (type is InterfaceType) {
486 _assertEquals(nodeName, type.name); 538 _assertEquals(nodeName, type.name);
539 // check arguments
487 TypeArgumentList nodeArgumentList = node.typeArguments; 540 TypeArgumentList nodeArgumentList = node.typeArguments;
488 List<DartType> typeArguments = type.typeArguments; 541 List<DartType> typeArguments = type.typeArguments;
489 if (nodeArgumentList == null) { 542 if (nodeArgumentList == null) {
490 _assertTrue(typeArguments.isEmpty); 543 _assertTrue(typeArguments.isEmpty);
491 } else { 544 } else {
492 List<TypeName> nodeArguments = nodeArgumentList.arguments; 545 List<TypeName> nodeArguments = nodeArgumentList.arguments;
493 int numArguments = nodeArguments.length; 546 _assertSameTypes(nodeArguments, typeArguments);
494 _assertEquals(numArguments, typeArguments.length);
495 for (int i = 0; i < numArguments; i++) {
496 _assertSameType(nodeArguments[i], typeArguments[i]);
497 }
498 } 547 }
499 } else { 548 } else {
500 // TODO(scheglov) support other types 549 // TODO(scheglov) support other types
501 _assertTrue(false); 550 _assertTrue(false);
502 } 551 }
503 } 552 }
504 553
505 void _assertFalse(bool condition) { 554 void _assertSameTypes(List<TypeName> nodes, List<DartType> type) {
506 if (condition) { 555 int length = nodes.length;
507 throw new _DeclarationMismatchException(); 556 _assertEquals(length, type.length);
557 for (int i = 0; i < length; i++) {
558 _assertSameType(nodes[i], type[i]);
508 } 559 }
509 } 560 }
510 561
511 void _assertNotNull(Element element) {
512 if (element == null) {
513 throw new _DeclarationMismatchException();
514 }
515 }
516
517 void _assertEquals(Object a, Object b) {
518 if (a != b) {
519 throw new _DeclarationMismatchException();
520 }
521 }
522
523 void _assertTrue(bool condition) { 562 void _assertTrue(bool condition) {
524 if (!condition) { 563 if (!condition) {
525 throw new _DeclarationMismatchException(); 564 throw new _DeclarationMismatchException();
526 } 565 }
527 } 566 }
528 567
529 /** 568 /**
530 * Given that the comparison is to begin with the given element, capture the e nclosing elements 569 * Given that the comparison is to begin with the given element, capture the e nclosing elements
531 * that might be used while performing the comparison. 570 * that might be used while performing the comparison.
532 * 571 *
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 * @param literal the string literal whose value is to be returned 753 * @param literal the string literal whose value is to be returned
715 * @return the value of the given string literal 754 * @return the value of the given string literal
716 */ 755 */
717 String _getStringValue(StringLiteral literal) { 756 String _getStringValue(StringLiteral literal) {
718 if (literal is StringInterpolation) { 757 if (literal is StringInterpolation) {
719 return null; 758 return null;
720 } 759 }
721 return literal.stringValue; 760 return literal.stringValue;
722 } 761 }
723 762
724 /**
725 * Return `true` if the given class defines at least one constructor.
726 *
727 * @param node the class being tested
728 * @return `true` if the class defines at least one constructor
729 */
730 bool _hasConstructor(ClassDeclaration node) {
731 for (ClassMember member in node.members) {
732 if (member is ConstructorDeclaration) {
733 return true;
734 }
735 }
736 return false;
737 }
738
739 void _processElement(Element element) { 763 void _processElement(Element element) {
740 _assertNotNull(element); 764 _assertNotNull(element);
741 if (!_allElements.contains(element)) { 765 if (!_allElements.contains(element)) {
742 throw new _DeclarationMismatchException(); 766 throw new _DeclarationMismatchException();
743 } 767 }
744 bool did = _unmatchedElements.remove(element); 768 _unmatchedElements.remove(element);
745 print('remove: $element | $did');
746 } 769 }
747 } 770 }
748 771
749 772
750 /** 773 /**
751 * Instances of the class [IncrementalResolver] resolve the smallest portion of 774 * Instances of the class [IncrementalResolver] resolve the smallest portion of
752 * an AST structure that we currently know how to resolve. 775 * an AST structure that we currently know how to resolve.
753 */ 776 */
754 class IncrementalResolver { 777 class IncrementalResolver {
755 /** 778 /**
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 } 1102 }
1080 } 1103 }
1081 1104
1082 void _addElement(Element element) { 1105 void _addElement(Element element) {
1083 if (element != null) { 1106 if (element != null) {
1084 matcher._allElements.add(element); 1107 matcher._allElements.add(element);
1085 matcher._unmatchedElements.add(element); 1108 matcher._unmatchedElements.add(element);
1086 } 1109 }
1087 } 1110 }
1088 } 1111 }
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