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

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

Issue 779333002: Always build elements, then match and restore if matches. (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 import 'dart:math' as math; 8 import 'dart:math' as math;
9 9
10 import 'ast.dart'; 10 import 'ast.dart';
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 @override 153 @override
154 visitCompilationUnit(CompilationUnit node) { 154 visitCompilationUnit(CompilationUnit node) {
155 _processElement(_enclosingUnit); 155 _processElement(_enclosingUnit);
156 super.visitCompilationUnit(node); 156 super.visitCompilationUnit(node);
157 } 157 }
158 158
159 @override 159 @override
160 visitConstructorDeclaration(ConstructorDeclaration node) { 160 visitConstructorDeclaration(ConstructorDeclaration node) {
161 _hasConstructor = true; 161 _hasConstructor = true;
162 SimpleIdentifier constructorName = node.name; 162 SimpleIdentifier constructorName = node.name;
163 ConstructorElement element = constructorName == null ? 163 ConstructorElementImpl element = constructorName == null ?
164 _enclosingClass.unnamedConstructor : 164 _enclosingClass.unnamedConstructor :
165 _enclosingClass.getNamedConstructor(constructorName.name); 165 _enclosingClass.getNamedConstructor(constructorName.name);
166 _processElement(element); 166 _processElement(element);
167 _assertCompatibleParameters(node.parameters, element.parameters);
168 // matches, update the existing element
169 ExecutableElement newElement = node.element;
167 node.element = element; 170 node.element = element;
168 _assertCompatibleParameters(node.parameters, element.parameters); 171 _setLocalElements(element, newElement);
172 _setParameterElements(node.parameters, element.parameters);
169 } 173 }
170 174
171 @override 175 @override
172 visitEnumConstantDeclaration(EnumConstantDeclaration node) { 176 visitEnumConstantDeclaration(EnumConstantDeclaration node) {
173 String name = node.name.name; 177 String name = node.name.name;
174 FieldElement element = _findElement(_enclosingClass.fields, name); 178 FieldElement element = _findElement(_enclosingClass.fields, name);
175 _processElement(element); 179 _processElement(element);
176 } 180 }
177 181
178 @override 182 @override
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 222
219 @override 223 @override
220 visitFunctionDeclaration(FunctionDeclaration node) { 224 visitFunctionDeclaration(FunctionDeclaration node) {
221 // prepare element name 225 // prepare element name
222 String name = node.name.name; 226 String name = node.name.name;
223 if (node.isSetter) { 227 if (node.isSetter) {
224 name += '='; 228 name += '=';
225 } 229 }
226 // prepare element 230 // prepare element
227 Token property = node.propertyKeyword; 231 Token property = node.propertyKeyword;
228 ExecutableElement element; 232 ExecutableElementImpl element;
229 if (property == null) { 233 if (property == null) {
230 element = _findElement(_enclosingUnit.functions, name); 234 element = _findElement(_enclosingUnit.functions, name);
231 } else { 235 } else {
232 element = _findElement(_enclosingUnit.accessors, name); 236 element = _findElement(_enclosingUnit.accessors, name);
233 } 237 }
234 // process element 238 // process element
235 _processElement(element); 239 _processElement(element);
236 node.name.staticElement = element;
237 node.functionExpression.element = element;
238 _assertFalse(element.isSynthetic); 240 _assertFalse(element.isSynthetic);
239 _assertSameType(node.returnType, element.returnType); 241 _assertSameType(node.returnType, element.returnType);
240 _assertCompatibleParameters( 242 _assertCompatibleParameters(
241 node.functionExpression.parameters, 243 node.functionExpression.parameters,
242 element.parameters); 244 element.parameters);
245 // matches, update the existing element
246 ExecutableElement newElement = node.element;
247 node.name.staticElement = element;
248 node.functionExpression.element = element;
249 _setLocalElements(element, newElement);
250 _setParameterElements(
251 node.functionExpression.parameters,
252 element.parameters);
243 } 253 }
244 254
245 @override 255 @override
246 visitFunctionTypeAlias(FunctionTypeAlias node) { 256 visitFunctionTypeAlias(FunctionTypeAlias node) {
247 String name = node.name.name; 257 String name = node.name.name;
248 FunctionTypeAliasElement element = 258 FunctionTypeAliasElement element =
249 _findElement(_enclosingUnit.functionTypeAliases, name); 259 _findElement(_enclosingUnit.functionTypeAliases, name);
250 _processElement(element); 260 _processElement(element);
251 _assertSameTypeParameters(node.typeParameters, element.typeParameters); 261 _assertSameTypeParameters(node.typeParameters, element.typeParameters);
252 _assertSameType(node.returnType, element.returnType); 262 _assertSameType(node.returnType, element.returnType);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 String name = node.name.name; 297 String name = node.name.name;
288 if (name == TokenType.MINUS.lexeme && 298 if (name == TokenType.MINUS.lexeme &&
289 node.parameters.parameters.length == 0) { 299 node.parameters.parameters.length == 0) {
290 name = "unary-"; 300 name = "unary-";
291 } 301 }
292 if (node.isSetter) { 302 if (node.isSetter) {
293 name += '='; 303 name += '=';
294 } 304 }
295 // prepare element 305 // prepare element
296 Token property = node.propertyKeyword; 306 Token property = node.propertyKeyword;
297 ExecutableElement element; 307 ExecutableElementImpl element;
298 if (property == null) { 308 if (property == null) {
299 element = _findElement(_enclosingClass.methods, name); 309 element = _findElement(_enclosingClass.methods, name);
300 } else { 310 } else {
301 element = _findElement(_enclosingClass.accessors, name); 311 element = _findElement(_enclosingClass.accessors, name);
302 } 312 }
303 // process element 313 // process element
304 _processElement(element); 314 _processElement(element);
305 _assertEquals(node.isStatic, element.isStatic); 315 _assertEquals(node.isStatic, element.isStatic);
306 node.name.staticElement = element;
307 _assertSameType(node.returnType, element.returnType); 316 _assertSameType(node.returnType, element.returnType);
308 _assertCompatibleParameters(node.parameters, element.parameters); 317 _assertCompatibleParameters(node.parameters, element.parameters);
318 // matches, update the existing element
319 ExecutableElement newElement = node.element;
320 node.name.staticElement = element;
321 _setLocalElements(element, newElement);
322 _setParameterElements(node.parameters, element.parameters);
309 } 323 }
310 324
311 @override 325 @override
312 visitPartDirective(PartDirective node) { 326 visitPartDirective(PartDirective node) {
313 String uri = _getStringValue(node.uri); 327 String uri = _getStringValue(node.uri);
314 if (uri != null) { 328 if (uri != null) {
315 CompilationUnitElement element = 329 CompilationUnitElement element =
316 _findUriReferencedElement(_enclosingLibrary.parts, uri); 330 _findUriReferencedElement(_enclosingLibrary.parts, uri);
317 _processElement(element); 331 _processElement(element);
318 } 332 }
(...skipping 24 matching lines...) Expand all
343 _assertNotNull(element); 357 _assertNotNull(element);
344 _processElement(element); 358 _processElement(element);
345 _assertEquals(node.isConst, element.isConst); 359 _assertEquals(node.isConst, element.isConst);
346 _assertEquals(node.isFinal, element.isFinal); 360 _assertEquals(node.isFinal, element.isFinal);
347 if (_enclosingFieldNode != null) { 361 if (_enclosingFieldNode != null) {
348 _assertEquals(_enclosingFieldNode.isStatic, element.isStatic); 362 _assertEquals(_enclosingFieldNode.isStatic, element.isStatic);
349 } 363 }
350 _assertSameType( 364 _assertSameType(
351 (node.parent as VariableDeclarationList).type, 365 (node.parent as VariableDeclarationList).type,
352 element.type); 366 element.type);
367 // matches, restore the existing element
368 node.name.staticElement = element;
353 } 369 }
354 370
355 @override 371 @override
356 visitWithClause(WithClause node) { 372 visitWithClause(WithClause node) {
357 List<TypeName> nodes = node.mixinTypes; 373 List<TypeName> nodes = node.mixinTypes;
358 List<InterfaceType> types = _enclosingClass.mixins; 374 List<InterfaceType> types = _enclosingClass.mixins;
359 _assertSameTypes(nodes, types); 375 _assertSameTypes(nodes, types);
360 } 376 }
361 377
362 void _assertCombinators(List<Combinator> nodeCombinators, 378 void _assertCombinators(List<Combinator> nodeCombinators,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 } 421 }
406 } else if (node is FieldFormalParameter) { 422 } else if (node is FieldFormalParameter) {
407 _assertTrue(element.isInitializingFormal); 423 _assertTrue(element.isInitializingFormal);
408 } else if (node is FunctionTypedFormalParameter) { 424 } else if (node is FunctionTypedFormalParameter) {
409 _assertTrue(element.type is FunctionType); 425 _assertTrue(element.type is FunctionType);
410 FunctionType elementType = element.type; 426 FunctionType elementType = element.type;
411 _assertCompatibleParameters(node.parameters, element.parameters); 427 _assertCompatibleParameters(node.parameters, element.parameters);
412 _assertSameType(node.returnType, elementType.returnType); 428 _assertSameType(node.returnType, elementType.returnType);
413 } else if (node is SimpleFormalParameter) { 429 } else if (node is SimpleFormalParameter) {
414 _assertSameType(node.type, element.type); 430 _assertSameType(node.type, element.type);
415 node.identifier.staticElement = element;
416 (element as ElementImpl).nameOffset = node.identifier.offset;
417 (element as ElementImpl).name = node.identifier.name;
418 } 431 }
419 } 432 }
420 433
421 void _assertCompatibleParameters(FormalParameterList nodes, 434 void _assertCompatibleParameters(FormalParameterList nodes,
422 List<ParameterElement> elements) { 435 List<ParameterElement> elements) {
423 if (nodes == null) { 436 if (nodes == null) {
424 return _assertEquals(elements.length, 0); 437 return _assertEquals(elements.length, 0);
425 } 438 }
426 List<FormalParameter> parameters = nodes.parameters; 439 List<FormalParameter> parameters = nodes.parameters;
427 int length = parameters.length; 440 int length = parameters.length;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 /** 620 /**
608 * Return the value of [literal], or `null` if the string is not a constant 621 * Return the value of [literal], or `null` if the string is not a constant
609 * string without any string interpolation. 622 * string without any string interpolation.
610 */ 623 */
611 static String _getStringValue(StringLiteral literal) { 624 static String _getStringValue(StringLiteral literal) {
612 if (literal is StringInterpolation) { 625 if (literal is StringInterpolation) {
613 return null; 626 return null;
614 } 627 }
615 return literal.stringValue; 628 return literal.stringValue;
616 } 629 }
630
631 static void _setLocalElements(ExecutableElementImpl to,
632 ExecutableElement from) {
633 to.functions = from.functions;
634 to.labels = from.labels;
635 to.localVariables = from.localVariables;
636 }
637
638 static void _setParameterElements(FormalParameterList nodes,
639 List<ParameterElement> elements) {
640 if (nodes != null) {
641 for (int i = 0; i < elements.length; i++) {
642 ParameterElement element = elements[i];
643 FormalParameter node = nodes.parameters[i];
644 ParameterElement newElement = node.element;
645 node.identifier.staticElement = element;
646 (element as ElementImpl).name = newElement.name;
647 (element as ElementImpl).nameOffset = newElement.nameOffset;
648 }
649 }
650 }
617 } 651 }
618 652
619 653
620 /** 654 /**
621 * Instances of the class [IncrementalResolver] resolve the smallest portion of 655 * Instances of the class [IncrementalResolver] resolve the smallest portion of
622 * an AST structure that we currently know how to resolve. 656 * an AST structure that we currently know how to resolve.
623 */ 657 */
624 class IncrementalResolver { 658 class IncrementalResolver {
625 /** 659 /**
626 * The object used to access the types from the core library. 660 * The object used to access the types from the core library.
(...skipping 23 matching lines...) Expand all
650 /** 684 /**
651 * The number of characters in the original contents that were replaced. 685 * The number of characters in the original contents that were replaced.
652 */ 686 */
653 final int _updateOldLength; 687 final int _updateOldLength;
654 688
655 /** 689 /**
656 * The number of characters in the replacement text. 690 * The number of characters in the replacement text.
657 */ 691 */
658 final int _updateNewLength; 692 final int _updateNewLength;
659 693
694 RecordingErrorListener errorListener = new RecordingErrorListener();
660 ResolutionContext _resolutionContext; 695 ResolutionContext _resolutionContext;
661 696
662 List<AnalysisError> _resolveErrors = AnalysisError.NO_ERRORS; 697 List<AnalysisError> _resolveErrors = AnalysisError.NO_ERRORS;
663 List<AnalysisError> _verifyErrors = AnalysisError.NO_ERRORS; 698 List<AnalysisError> _verifyErrors = AnalysisError.NO_ERRORS;
664 List<AnalysisError> _hints = AnalysisError.NO_ERRORS; 699 List<AnalysisError> _hints = AnalysisError.NO_ERRORS;
665 700
666 /** 701 /**
667 * Initialize a newly created incremental resolver to resolve a node in the 702 * Initialize a newly created incremental resolver to resolve a node in the
668 * given source in the given library. 703 * given source in the given library.
669 */ 704 */
670 IncrementalResolver(this._typeProvider, this._definingUnit, 705 IncrementalResolver(this._typeProvider, this._definingUnit,
671 this._updateOffset, this._updateOldLength, this._updateNewLength) { 706 this._updateOffset, this._updateOldLength, this._updateNewLength) {
672 _definingLibrary = _definingUnit.library; 707 _definingLibrary = _definingUnit.library;
673 _source = _definingUnit.source; 708 _source = _definingUnit.source;
674 } 709 }
675 710
676 /** 711 /**
677 * Resolve [node], reporting any errors or warnings to the given listener. 712 * Resolve [node], reporting any errors or warnings to the given listener.
678 * 713 *
679 * [node] - the root of the AST structure to be resolved. 714 * [node] - the root of the AST structure to be resolved.
680 * 715 *
681 * Returns `true` if resolution was successful. 716 * Returns `true` if resolution was successful.
682 */ 717 */
683 bool resolve(AstNode node) { 718 bool resolve(AstNode node) {
684 logger.enter('resolve: $_definingUnit'); 719 logger.enter('resolve: $_definingUnit');
685 try { 720 try {
686 logger.log(() => 'node: $node'); 721 logger.log(() => 'node: $node');
687 AstNode rootNode = _findResolutionRoot(node); 722 AstNode rootNode = _findResolutionRoot(node);
688 logger.log(() => 'rootNode: $rootNode'); 723 logger.log(() => 'rootNode: $rootNode');
724 _prepareResolutionContext(rootNode);
689 // update elements 725 // update elements
690 _updateElementNameOffsets( 726 _updateElementNameOffsets(
691 _definingUnit, 727 _definingUnit,
692 _updateOffset, 728 _updateOffset,
693 _updateNewLength - _updateOldLength); 729 _updateNewLength - _updateOldLength);
730 _buildElements(rootNode);
694 if (_elementModelChanged(rootNode)) { 731 if (_elementModelChanged(rootNode)) {
695 return false; 732 return false;
696 } 733 }
697 _updateElements(rootNode);
698 // resolve 734 // resolve
699 _resolveReferences(rootNode); 735 _resolveReferences(rootNode);
700 // verify 736 // verify
701 _verify(rootNode); 737 _verify(rootNode);
702 _generateHints(rootNode); 738 _generateHints(rootNode);
703 // OK 739 // OK
704 return true; 740 return true;
705 } finally { 741 } finally {
706 logger.exit(); 742 logger.exit();
707 } 743 }
708 } 744 }
709 745
746 void _buildElements(AstNode node) {
747 LoggingTimer timer = logger.startTimer();
748 try {
749 ElementHolder holder = new ElementHolder();
750 ElementBuilder builder = new ElementBuilder(holder);
751 node.accept(builder);
752 } finally {
753 timer.stop('build elements');
754 }
755 }
756
710 /** 757 /**
711 * Return `true` if the given node can be resolved independently of any other 758 * Return `true` if the given node can be resolved independently of any other
712 * nodes. 759 * nodes.
713 * 760 *
714 * *Note*: This method needs to be kept in sync with 761 * *Note*: This method needs to be kept in sync with
715 * [ScopeBuilder.ContextBuilder]. 762 * [ScopeBuilder.ContextBuilder].
716 * 763 *
717 * [node] - the node being tested. 764 * [node] - the node being tested.
718 */ 765 */
719 bool _canBeResolved(AstNode node) => 766 bool _canBeResolved(AstNode node) =>
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 */ 843 */
797 Element _getElement(AstNode node) { 844 Element _getElement(AstNode node) {
798 if (node is Declaration) { 845 if (node is Declaration) {
799 return node.element; 846 return node.element;
800 } else if (node is CompilationUnit) { 847 } else if (node is CompilationUnit) {
801 return node.element; 848 return node.element;
802 } 849 }
803 return null; 850 return null;
804 } 851 }
805 852
853 void _prepareResolutionContext(AstNode node) {
854 if (_resolutionContext == null) {
855 _resolutionContext =
856 ResolutionContextBuilder.contextFor(node, errorListener);
857 }
858 }
859
806 _resolveReferences(AstNode node) { 860 _resolveReferences(AstNode node) {
807 LoggingTimer timer = logger.startTimer(); 861 LoggingTimer timer = logger.startTimer();
808 try { 862 try {
809 RecordingErrorListener errorListener = new RecordingErrorListener(); 863 _prepareResolutionContext(node);
810 // prepare context
811 _resolutionContext =
812 ResolutionContextBuilder.contextFor(node, errorListener);
813 Scope scope = _resolutionContext.scope; 864 Scope scope = _resolutionContext.scope;
814 // resolve types 865 // resolve types
815 { 866 {
816 TypeResolverVisitor visitor = new TypeResolverVisitor.con3( 867 TypeResolverVisitor visitor = new TypeResolverVisitor.con3(
817 _definingLibrary, 868 _definingLibrary,
818 _source, 869 _source,
819 _typeProvider, 870 _typeProvider,
820 scope, 871 scope,
821 errorListener); 872 errorListener);
822 node.accept(visitor); 873 node.accept(visitor);
823 } 874 }
824 // resolve variables 875 // resolve variables
825 { 876 {
826 VariableResolverVisitor visitor = new VariableResolverVisitor.con2( 877 VariableResolverVisitor visitor = new VariableResolverVisitor.con2(
827 _definingLibrary, 878 _definingLibrary,
828 _source, 879 _source,
829 _typeProvider, 880 _typeProvider,
830 scope, 881 scope,
831 errorListener); 882 errorListener);
832 node.accept(visitor); 883 node.accept(visitor);
833 } 884 }
834 // resolve references 885 // resolve references
835 { 886 {
836 ResolverVisitor visitor = new ResolverVisitor.con3( 887 ResolverVisitor visitor = new ResolverVisitor.con3(
837 _definingLibrary, 888 _definingLibrary,
838 _source, 889 _source,
839 _typeProvider, 890 _typeProvider,
840 _resolutionContext.scope, 891 scope,
841 errorListener); 892 errorListener);
842 if (_resolutionContext.enclosingClassDeclaration != null) { 893 if (_resolutionContext.enclosingClassDeclaration != null) {
843 visitor.visitClassDeclarationIncrementally( 894 visitor.visitClassDeclarationIncrementally(
844 _resolutionContext.enclosingClassDeclaration); 895 _resolutionContext.enclosingClassDeclaration);
845 } 896 }
846 if (node is Comment) { 897 if (node is Comment) {
847 visitor.resolveOnlyCommentInFunctionBody = true; 898 visitor.resolveOnlyCommentInFunctionBody = true;
848 node = node.parent; 899 node = node.parent;
849 } 900 }
850 visitor.initForIncrementalResolution(); 901 visitor.initForIncrementalResolution();
851 node.accept(visitor); 902 node.accept(visitor);
852 } 903 }
853 // remember errors 904 // remember errors
854 _resolveErrors = errorListener.getErrorsForSource(_source); 905 _resolveErrors = errorListener.getErrorsForSource(_source);
855 } finally { 906 } finally {
856 timer.stop('resolve references'); 907 timer.stop('resolve references');
857 } 908 }
858 } 909 }
859 910
860 void _updateElements(AstNode node) {
861 LoggingTimer timer = logger.startTimer();
862 try {
863 // build elements in node
864 ElementHolder holder;
865 _ElementsRestorer elementsRestorer = new _ElementsRestorer(node);
866 try {
867 holder = new ElementHolder();
868 ElementBuilder builder = new ElementBuilder(holder);
869 node.accept(builder);
870 } finally {
871 elementsRestorer.restore();
872 }
873 // apply compatible changes to elements
874 if (node is FunctionDeclaration) {
875 ExecutableElementImpl oldElement = node.element;
876 // prepare the new element
877 ExecutableElement newElement;
878 {
879 List<FunctionElement> holderFunctions = holder.functions;
880 List<PropertyAccessorElement> holderAccessors = holder.accessors;
881 if (holderFunctions.isNotEmpty) {
882 newElement = holderFunctions[0];
883 } else if (holderAccessors.isNotEmpty) {
884 newElement = holderAccessors[0];
885 }
886 }
887 // update the old Element
888 oldElement.functions = newElement.functions;
889 oldElement.labels = newElement.labels;
890 oldElement.localVariables = newElement.localVariables;
891 }
892 if (node is MethodDeclaration) {
893 ExecutableElementImpl oldElement = node.element;
894 // prepare the new element
895 ExecutableElement newElement;
896 {
897 List<MethodElement> holderMethods = holder.methods;
898 List<PropertyAccessorElement> holderAccessors = holder.accessors;
899 if (holderMethods.isNotEmpty) {
900 newElement = holderMethods[0];
901 } else if (holderAccessors.isNotEmpty) {
902 newElement = holderAccessors[0];
903 }
904 }
905 // update the old Element
906 oldElement.functions = newElement.functions;
907 oldElement.labels = newElement.labels;
908 oldElement.localVariables = newElement.localVariables;
909 }
910 } finally {
911 timer.stop('update elements');
912 }
913 }
914
915 void _verify(AstNode node) { 911 void _verify(AstNode node) {
916 LoggingTimer timer = logger.startTimer(); 912 LoggingTimer timer = logger.startTimer();
917 try { 913 try {
918 RecordingErrorListener errorListener = new RecordingErrorListener(); 914 RecordingErrorListener errorListener = new RecordingErrorListener();
919 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source); 915 ErrorReporter errorReporter = new ErrorReporter(errorListener, _source);
920 ErrorVerifier errorVerifier = new ErrorVerifier( 916 ErrorVerifier errorVerifier = new ErrorVerifier(
921 errorReporter, 917 errorReporter,
922 _definingLibrary, 918 _definingLibrary,
923 _typeProvider, 919 _typeProvider,
924 new InheritanceManager(_definingLibrary)); 920 new InheritanceManager(_definingLibrary));
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 throw new AnalysisException('Uknown parent token type: $parentType'); 1342 throw new AnalysisException('Uknown parent token type: $parentType');
1347 } 1343 }
1348 } 1344 }
1349 } 1345 }
1350 1346
1351 1347
1352 /** 1348 /**
1353 * The context to resolve an [AstNode] in. 1349 * The context to resolve an [AstNode] in.
1354 */ 1350 */
1355 class ResolutionContext { 1351 class ResolutionContext {
1352 CompilationUnitElement enclosingUnit;
1356 ClassDeclaration enclosingClassDeclaration; 1353 ClassDeclaration enclosingClassDeclaration;
1357 ClassElement enclosingClass; 1354 ClassElement enclosingClass;
1358 Scope scope; 1355 Scope scope;
1359 } 1356 }
1360 1357
1361 1358
1362 /** 1359 /**
1363 * Instances of the class [ResolutionContextBuilder] build the context for a 1360 * Instances of the class [ResolutionContextBuilder] build the context for a
1364 * given node in an AST structure. At the moment, this class only handles 1361 * given node in an AST structure. At the moment, this class only handles
1365 * top-level and class-level declarations. 1362 * top-level and class-level declarations.
1366 */ 1363 */
1367 class ResolutionContextBuilder { 1364 class ResolutionContextBuilder {
1368 /** 1365 /**
1369 * The listener to which analysis errors will be reported. 1366 * The listener to which analysis errors will be reported.
1370 */ 1367 */
1371 final AnalysisErrorListener _errorListener; 1368 final AnalysisErrorListener _errorListener;
1372 1369
1373 /** 1370 /**
1371 * The class containing the enclosing [CompilationUnitElement].
1372 */
1373 CompilationUnitElement _enclosingUnit;
1374
1375 /**
1374 * The class containing the enclosing [ClassDeclaration], or `null` if we are 1376 * The class containing the enclosing [ClassDeclaration], or `null` if we are
1375 * not in the scope of a class. 1377 * not in the scope of a class.
1376 */ 1378 */
1377 ClassDeclaration _enclosingClassDeclaration; 1379 ClassDeclaration _enclosingClassDeclaration;
1378 1380
1379 /** 1381 /**
1380 * The class containing the enclosing [ClassElement], or `null` if we are not 1382 * The class containing the enclosing [ClassElement], or `null` if we are not
1381 * in the scope of a class. 1383 * in the scope of a class.
1382 */ 1384 */
1383 ClassElement _enclosingClass; 1385 ClassElement _enclosingClass;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 "Cannot build a scope for an unresolved method"); 1467 "Cannot build a scope for an unresolved method");
1466 } 1468 }
1467 FunctionScope functionScope = new FunctionScope(scope, element); 1469 FunctionScope functionScope = new FunctionScope(scope, element);
1468 functionScope.defineParameters(); 1470 functionScope.defineParameters();
1469 scope = functionScope; 1471 scope = functionScope;
1470 } 1472 }
1471 return scope; 1473 return scope;
1472 } 1474 }
1473 1475
1474 Scope _scopeForCompilationUnit(CompilationUnit node) { 1476 Scope _scopeForCompilationUnit(CompilationUnit node) {
1475 CompilationUnitElement unitElement = node.element; 1477 _enclosingUnit = node.element;
1476 if (unitElement == null) { 1478 if (_enclosingUnit == null) {
1477 throw new AnalysisException( 1479 throw new AnalysisException(
1478 "Cannot create scope: compilation unit is not resolved"); 1480 "Cannot create scope: compilation unit is not resolved");
1479 } 1481 }
1480 LibraryElement libraryElement = unitElement.library; 1482 LibraryElement libraryElement = _enclosingUnit.library;
1481 if (libraryElement == null) { 1483 if (libraryElement == null) {
1482 throw new AnalysisException( 1484 throw new AnalysisException(
1483 "Cannot create scope: compilation unit is not part of a library"); 1485 "Cannot create scope: compilation unit is not part of a library");
1484 } 1486 }
1485 return new LibraryScope(libraryElement, _errorListener); 1487 return new LibraryScope(libraryElement, _errorListener);
1486 } 1488 }
1487 1489
1488 /** 1490 /**
1489 * Return the context in which the given AST structure should be resolved. 1491 * Return the context in which the given AST structure should be resolved.
1490 * 1492 *
1491 * [node] - the root of the AST structure to be resolved. 1493 * [node] - the root of the AST structure to be resolved.
1492 * [errorListener] - the listener to which analysis errors will be reported. 1494 * [errorListener] - the listener to which analysis errors will be reported.
1493 * 1495 *
1494 * Throws [AnalysisException] if the AST structure has not been resolved or 1496 * Throws [AnalysisException] if the AST structure has not been resolved or
1495 * is not part of a [CompilationUnit] 1497 * is not part of a [CompilationUnit]
1496 */ 1498 */
1497 static ResolutionContext contextFor(AstNode node, 1499 static ResolutionContext contextFor(AstNode node,
1498 AnalysisErrorListener errorListener) { 1500 AnalysisErrorListener errorListener) {
1499 if (node == null) { 1501 if (node == null) {
1500 throw new AnalysisException("Cannot create context: node is null"); 1502 throw new AnalysisException("Cannot create context: node is null");
1501 } 1503 }
1502 // build scope 1504 // build scope
1503 ResolutionContextBuilder builder = 1505 ResolutionContextBuilder builder =
1504 new ResolutionContextBuilder(errorListener); 1506 new ResolutionContextBuilder(errorListener);
1505 Scope scope = builder._scopeFor(node); 1507 Scope scope = builder._scopeFor(node);
1506 // prepare context 1508 // prepare context
1507 ResolutionContext context = new ResolutionContext(); 1509 ResolutionContext context = new ResolutionContext();
1508 context.scope = scope; 1510 context.scope = scope;
1511 context.enclosingUnit = builder._enclosingUnit;
1509 context.enclosingClassDeclaration = builder._enclosingClassDeclaration; 1512 context.enclosingClassDeclaration = builder._enclosingClassDeclaration;
1510 context.enclosingClass = builder._enclosingClass; 1513 context.enclosingClass = builder._enclosingClass;
1511 return context; 1514 return context;
1512 } 1515 }
1513 } 1516 }
1514 1517
1515 1518
1516 /** 1519 /**
1517 * Instances of the class [_DeclarationMismatchException] represent an exception 1520 * Instances of the class [_DeclarationMismatchException] represent an exception
1518 * that is thrown when the element model defined by a given AST structure does 1521 * that is thrown when the element model defined by a given AST structure does
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 void _addElement(Element element) { 1593 void _addElement(Element element) {
1591 if (element != null) { 1594 if (element != null) {
1592 matcher._allElements.add(element); 1595 matcher._allElements.add(element);
1593 matcher._unmatchedElements.add(element); 1596 matcher._unmatchedElements.add(element);
1594 } 1597 }
1595 } 1598 }
1596 } 1599 }
1597 1600
1598 1601
1599 /** 1602 /**
1600 * [ElementBuilder] not just builds elements, it also applies them to nodes.
1601 * But we want to keep externally visible (and referenced) elements instances.
1602 * So, we need to remember them and restore.
1603 */
1604 class _ElementsRestorer extends RecursiveAstVisitor {
1605 final Map<AstNode, Element> _elements = <AstNode, Element>{};
1606
1607 _ElementsRestorer(AstNode root) {
1608 root.accept(this);
1609 }
1610
1611 void restore() {
1612 _elements.forEach((AstNode node, Element element) {
1613 if (node is ConstructorDeclaration) {
1614 node.element = element;
1615 } else if (node is FunctionExpression) {
1616 node.element = element;
1617 } else if (node is SimpleIdentifier) {
1618 node.staticElement = element;
1619 }
1620 });
1621 }
1622
1623 @override
1624 visitBlockFunctionBody(BlockFunctionBody node) {
1625 }
1626
1627 @override
1628 visitConstructorDeclaration(ConstructorDeclaration node) {
1629 _elements[node] = node.element;
1630 super.visitConstructorDeclaration(node);
1631 }
1632
1633 @override
1634 visitExpressionFunctionBody(ExpressionFunctionBody node) {
1635 }
1636
1637 @override
1638 visitFunctionExpression(FunctionExpression node) {
1639 _elements[node] = node.element;
1640 super.visitFunctionExpression(node);
1641 }
1642
1643 @override
1644 visitSimpleIdentifier(SimpleIdentifier node) {
1645 _elements[node] = node.staticElement;
1646 }
1647 }
1648
1649
1650 /**
1651 * Describes how two [Token]s are different. 1603 * Describes how two [Token]s are different.
1652 */ 1604 */
1653 class _TokenDifferenceKind { 1605 class _TokenDifferenceKind {
1654 static const COMMENT = const _TokenDifferenceKind('COMMENT'); 1606 static const COMMENT = const _TokenDifferenceKind('COMMENT');
1655 static const COMMENT_DOC = const _TokenDifferenceKind('COMMENT_DOC'); 1607 static const COMMENT_DOC = const _TokenDifferenceKind('COMMENT_DOC');
1656 static const CONTENT = const _TokenDifferenceKind('CONTENT'); 1608 static const CONTENT = const _TokenDifferenceKind('CONTENT');
1657 static const OFFSET = const _TokenDifferenceKind('OFFSET'); 1609 static const OFFSET = const _TokenDifferenceKind('OFFSET');
1658 1610
1659 final String name; 1611 final String name;
1660 1612
1661 const _TokenDifferenceKind(this.name); 1613 const _TokenDifferenceKind(this.name);
1662 1614
1663 @override 1615 @override
1664 String toString() => name; 1616 String toString() => name;
1665 } 1617 }
1666 1618
1667 1619
1668 class _TokenPair { 1620 class _TokenPair {
1669 final _TokenDifferenceKind kind; 1621 final _TokenDifferenceKind kind;
1670 final Token oldToken; 1622 final Token oldToken;
1671 final Token newToken; 1623 final Token newToken;
1672 _TokenPair(this.kind, this.oldToken, this.newToken); 1624 _TokenPair(this.kind, this.oldToken, this.newToken);
1673 } 1625 }
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