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

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

Issue 184893003: New analyzer snapshot. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
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 // This code was auto-generated, is not intended to be edited, and is subject to 5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information. 6 // significant change. Please see the README file for more information.
7 7
8 library engine.resolver; 8 library engine.resolver;
9 9
10 import 'dart:collection'; 10 import 'dart:collection';
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 57
58 static String _NG_ONE_WAY_ONE_TIME = "NgOneWayOneTime"; 58 static String _NG_ONE_WAY_ONE_TIME = "NgOneWayOneTime";
59 59
60 static String _NG_TWO_WAY = "NgTwoWay"; 60 static String _NG_TWO_WAY = "NgTwoWay";
61 61
62 static Element getElement(ASTNode node, int offset) { 62 static Element getElement(ASTNode node, int offset) {
63 // maybe node is not SimpleStringLiteral 63 // maybe node is not SimpleStringLiteral
64 if (node is! SimpleStringLiteral) { 64 if (node is! SimpleStringLiteral) {
65 return null; 65 return null;
66 } 66 }
67 SimpleStringLiteral literal = node as SimpleStringLiteral;
68 // maybe has AngularElement
69 {
70 Element element = literal.toolkitElement;
71 if (element is AngularElement) {
72 return element;
73 }
74 }
67 // prepare enclosing ClassDeclaration 75 // prepare enclosing ClassDeclaration
68 ClassDeclaration classDeclaration = node.getAncestor(ClassDeclaration); 76 ClassDeclaration classDeclaration = node.getAncestor(ClassDeclaration);
69 if (classDeclaration == null) { 77 if (classDeclaration == null) {
70 return null; 78 return null;
71 } 79 }
72 // prepare ClassElement 80 // prepare ClassElement
73 ClassElement classElement = classDeclaration.element; 81 ClassElement classElement = classDeclaration.element;
74 if (classElement == null) { 82 if (classElement == null) {
75 return null; 83 return null;
76 } 84 }
77 // check toolkit objects 85 // check toolkit objects
78 for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) { 86 for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) {
79 List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARR AY; 87 List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARR AY;
80 // maybe name 88 // maybe name
81 if (toolkitObject is AngularElement) { 89 if (toolkitObject is AngularElement) {
82 if (isNameCoveredByLiteral(toolkitObject, node)) { 90 if (isNameCoveredByLiteral(toolkitObject, node)) {
83 return toolkitObject; 91 return toolkitObject;
84 } 92 }
85 } 93 }
94 // try selector
95 if (toolkitObject is AngularHasSelectorElement) {
96 AngularHasSelectorElement hasSelector = toolkitObject;
97 AngularSelectorElement selector = hasSelector.selector;
98 if (isNameCoveredByLiteral(selector, node)) {
99 return selector;
100 }
101 }
86 // try properties of AngularComponentElement 102 // try properties of AngularComponentElement
87 if (toolkitObject is AngularComponentElement) { 103 if (toolkitObject is AngularComponentElement) {
88 AngularComponentElement component = toolkitObject; 104 AngularComponentElement component = toolkitObject;
89 // try selector
90 {
91 AngularSelectorElement selector = component.selector;
92 if (isNameCoveredByLiteral(selector, node)) {
93 return selector;
94 }
95 }
96 // try properties
97 properties = component.properties; 105 properties = component.properties;
98 } 106 }
99 // try properties of AngularDirectiveElement 107 // try properties of AngularDirectiveElement
100 if (toolkitObject is AngularDirectiveElement) { 108 if (toolkitObject is AngularDirectiveElement) {
101 AngularDirectiveElement directive = toolkitObject; 109 AngularDirectiveElement directive = toolkitObject;
102 properties = directive.properties; 110 properties = directive.properties;
103 } 111 }
104 // check properties 112 // check properties
105 for (AngularPropertyElement property in properties) { 113 for (AngularPropertyElement property in properties) {
106 // property name (use complete node range) 114 // property name (use complete node range)
(...skipping 15 matching lines...) Expand all
122 return null; 130 return null;
123 } 131 }
124 132
125 /** 133 /**
126 * Parses given selector text and returns [AngularSelectorElement]. May be `nu ll` if 134 * Parses given selector text and returns [AngularSelectorElement]. May be `nu ll` if
127 * cannot parse. 135 * cannot parse.
128 */ 136 */
129 static AngularSelectorElement parseSelector(int offset, String text) { 137 static AngularSelectorElement parseSelector(int offset, String text) {
130 // [attribute] 138 // [attribute]
131 if (StringUtilities.startsWithChar(text, 0x5B) && StringUtilities.endsWithCh ar(text, 0x5D)) { 139 if (StringUtilities.startsWithChar(text, 0x5B) && StringUtilities.endsWithCh ar(text, 0x5D)) {
132 int nameOffset = offset + "[".length; 140 int nameOffset = offset + 1;
133 String attributeName = text.substring(1, text.length - 1); 141 String attributeName = text.substring(1, text.length - 1);
134 // TODO(scheglov) report warning if there are spaces between [ and identif ier 142 // TODO(scheglov) report warning if there are spaces between [ and identif ier
135 return new HasAttributeSelectorElementImpl(attributeName, nameOffset); 143 return new HasAttributeSelectorElementImpl(attributeName, nameOffset);
136 } 144 }
145 // .class
146 if (StringUtilities.startsWithChar(text, 0x2E)) {
147 int nameOffset = offset + 1;
148 String className = text.substring(1, text.length);
149 return new AngularHasClassSelectorElementImpl(className, nameOffset);
150 }
137 // tag[attribute] 151 // tag[attribute]
138 if (StringUtilities.endsWithChar(text, 0x5D)) { 152 if (StringUtilities.endsWithChar(text, 0x5D)) {
139 int index = StringUtilities.indexOf1(text, 0, 0x5B); 153 int index = StringUtilities.indexOf1(text, 0, 0x5B);
140 if (index != -1) { 154 if (index != -1) {
141 String tagName = text.substring(0, index); 155 String tagName = text.substring(0, index);
142 String attributeName = text.substring(index + 1, text.length - 1); 156 String attributeName = text.substring(index + 1, text.length - 1);
143 if (StringUtilities.isTagName(tagName)) { 157 if (StringUtilities.isTagName(tagName)) {
144 return new IsTagHasAttributeSelectorElementImpl(tagName, attributeName ); 158 return new IsTagHasAttributeSelectorElementImpl(tagName, attributeName );
145 } 159 }
146 } 160 }
147 } 161 }
148 // tag 162 // tag
149 if (StringUtilities.isTagName(text)) { 163 if (StringUtilities.isTagName(text)) {
150 return new IsTagSelectorElementImpl(text, offset); 164 return new AngularTagSelectorElementImpl(text, offset);
151 } 165 }
152 return null; 166 return null;
153 } 167 }
154 168
155 /** 169 /**
156 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio n]. 170 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio n].
157 */ 171 */
158 static FieldElement getOnlyFieldElement(FieldDeclaration fieldDeclaration) { 172 static FieldElement getOnlyFieldElement(FieldDeclaration fieldDeclaration) {
159 NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables; 173 NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables;
160 return fields[0].element as FieldElement; 174 return fields[0].element as FieldElement;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 * The listener to which errors will be reported. 222 * The listener to which errors will be reported.
209 */ 223 */
210 AnalysisErrorListener _errorListener; 224 AnalysisErrorListener _errorListener;
211 225
212 /** 226 /**
213 * The source containing the unit that will be analyzed. 227 * The source containing the unit that will be analyzed.
214 */ 228 */
215 Source _source; 229 Source _source;
216 230
217 /** 231 /**
232 * The compilation unit with built Dart element models.
233 */
234 CompilationUnit _unit;
235
236 /**
218 * The [ClassDeclaration] that is currently being analyzed. 237 * The [ClassDeclaration] that is currently being analyzed.
219 */ 238 */
220 ClassDeclaration _classDeclaration; 239 ClassDeclaration _classDeclaration;
221 240
222 /** 241 /**
223 * The [ClassElementImpl] that is currently being analyzed. 242 * The [ClassElementImpl] that is currently being analyzed.
224 */ 243 */
225 ClassElementImpl _classElement; 244 ClassElementImpl _classElement;
226 245
227 /** 246 /**
228 * The [ToolkitObjectElement]s to set for [classElement]. 247 * The [ToolkitObjectElement]s to set for [classElement].
229 */ 248 */
230 List<ToolkitObjectElement> _classToolkitObjects = []; 249 List<ToolkitObjectElement> _classToolkitObjects = [];
231 250
232 /** 251 /**
233 * The [Annotation] that is currently being analyzed. 252 * The [Annotation] that is currently being analyzed.
234 */ 253 */
235 Annotation _annotation; 254 Annotation _annotation;
236 255
237 /** 256 /**
238 * Initialize a newly created compilation unit element builder. 257 * Initialize a newly created compilation unit element builder.
239 * 258 *
240 * @param errorListener the listener to which errors will be reported. 259 * @param errorListener the listener to which errors will be reported.
241 * @param source the source containing the unit that will be analyzed 260 * @param source the source containing the unit that will be analyzed
261 * @param unit the compilation unit with built Dart element models
242 */ 262 */
243 AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source sour ce) { 263 AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source sour ce, CompilationUnit unit) {
244 this._errorListener = errorListener; 264 this._errorListener = errorListener;
245 this._source = source; 265 this._source = source;
266 this._unit = unit;
246 } 267 }
247 268
248 /** 269 /**
249 * Builds Angular specific element models and adds them to the existing Dart e lements. 270 * Builds Angular specific element models and adds them to the existing Dart e lements.
250 *
251 * @param unit the compilation unit with built Dart element models
252 */ 271 */
253 void build(CompilationUnit unit) { 272 void build() {
273 parseViews();
254 // process classes 274 // process classes
255 for (CompilationUnitMember unitMember in unit.declarations) { 275 for (CompilationUnitMember unitMember in _unit.declarations) {
256 if (unitMember is ClassDeclaration) { 276 if (unitMember is ClassDeclaration) {
257 this._classDeclaration = unitMember; 277 this._classDeclaration = unitMember;
258 this._classElement = _classDeclaration.element as ClassElementImpl; 278 this._classElement = _classDeclaration.element as ClassElementImpl;
259 this._classToolkitObjects.clear(); 279 this._classToolkitObjects.clear();
260 // process annotations 280 // process annotations
261 NodeList<Annotation> annotations = _classDeclaration.metadata; 281 NodeList<Annotation> annotations = _classDeclaration.metadata;
262 for (Annotation annotation in annotations) { 282 for (Annotation annotation in annotations) {
263 // verify annotation 283 // verify annotation
264 if (annotation.arguments == null) { 284 if (annotation.arguments == null) {
265 continue; 285 continue;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 styleUriOffset = getStringArgumentOffset(_CSS_URL); 416 styleUriOffset = getStringArgumentOffset(_CSS_URL);
397 } 417 }
398 // create 418 // create
399 if (isValid) { 419 if (isValid) {
400 AngularComponentElementImpl element = new AngularComponentElementImpl(name , nameOffset, _annotation.offset); 420 AngularComponentElementImpl element = new AngularComponentElementImpl(name , nameOffset, _annotation.offset);
401 element.selector = selector; 421 element.selector = selector;
402 element.templateUri = templateUri; 422 element.templateUri = templateUri;
403 element.templateUriOffset = templateUriOffset; 423 element.templateUriOffset = templateUriOffset;
404 element.styleUri = styleUri; 424 element.styleUri = styleUri;
405 element.styleUriOffset = styleUriOffset; 425 element.styleUriOffset = styleUriOffset;
406 element.properties = parseNgComponentProperties(true); 426 element.properties = parseNgComponentProperties();
427 element.scopeProperties = parseScopeProperties();
407 _classToolkitObjects.add(element); 428 _classToolkitObjects.add(element);
408 } 429 }
409 } 430 }
410 431
411 /** 432 /**
412 * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration]. 433 * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration].
413 */ 434 */
414 List<AngularPropertyElement> parseNgComponentProperties(bool fromFields) { 435 List<AngularPropertyElement> parseNgComponentProperties() {
415 List<AngularPropertyElement> properties = []; 436 List<AngularPropertyElement> properties = [];
416 parseNgComponentProperties_fromMap(properties); 437 parseNgComponentProperties_fromMap(properties);
417 if (fromFields) { 438 parseNgComponentProperties_fromFields(properties);
418 parseNgComponentProperties_fromFields(properties);
419 }
420 return new List.from(properties); 439 return new List.from(properties);
421 } 440 }
422 441
423 /** 442 /**
424 * Parses [AngularPropertyElement]s from [annotation]. 443 * Parses [AngularPropertyElement]s from [annotation].
425 */ 444 */
426 void parseNgComponentProperties_fromFields(List<AngularPropertyElement> proper ties) { 445 void parseNgComponentProperties_fromFields(List<AngularPropertyElement> proper ties) {
427 NodeList<ClassMember> members = _classDeclaration.members; 446 NodeList<ClassMember> members = _classDeclaration.members;
428 for (ClassMember member in members) { 447 for (ClassMember member in members) {
429 if (member is FieldDeclaration) { 448 if (member is FieldDeclaration) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 if (selector == null) { 594 if (selector == null) {
576 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se lectorLiteral]); 595 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se lectorLiteral]);
577 isValid = false; 596 isValid = false;
578 } 597 }
579 } 598 }
580 // create 599 // create
581 if (isValid) { 600 if (isValid) {
582 int offset = _annotation.offset; 601 int offset = _annotation.offset;
583 AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offs et); 602 AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offs et);
584 element.selector = selector; 603 element.selector = selector;
585 element.properties = parseNgComponentProperties(false); 604 element.properties = parseNgComponentProperties();
586 _classToolkitObjects.add(element); 605 _classToolkitObjects.add(element);
587 } 606 }
588 } 607 }
589 608
590 void parseNgFilter() { 609 void parseNgFilter() {
591 bool isValid = true; 610 bool isValid = true;
592 // name 611 // name
593 if (!hasStringArgument(_NAME)) { 612 if (!hasStringArgument(_NAME)) {
594 reportErrorForAnnotation(AngularCode.MISSING_NAME, []); 613 reportErrorForAnnotation(AngularCode.MISSING_NAME, []);
595 isValid = false; 614 isValid = false;
596 } 615 }
597 // create 616 // create
598 if (isValid) { 617 if (isValid) {
599 String name = getStringArgument(_NAME); 618 String name = getStringArgument(_NAME);
600 int nameOffset = getStringArgumentOffset(_NAME); 619 int nameOffset = getStringArgumentOffset(_NAME);
601 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset)); 620 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset));
602 } 621 }
603 } 622 }
604 623
624 List<AngularScopePropertyElement> parseScopeProperties() {
625 List<AngularScopePropertyElement> properties = [];
626 _classDeclaration.accept(new RecursiveASTVisitor_AngularCompilationUnitBuild er_parseScopeProperties(properties));
627 return new List.from(properties);
628 }
629
630 /**
631 * Create [AngularViewElement] for each valid <code>view('template.html')</cod e> invocation,
632 * where <code>view</code> is <code>ViewFactory</code>.
633 */
634 void parseViews() {
635 List<AngularViewElement> views = [];
636 _unit.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseView s(views));
637 if (!views.isEmpty) {
638 List<AngularViewElement> viewArray = new List.from(views);
639 (_unit.element as CompilationUnitElementImpl).angularViews = viewArray;
640 }
641 }
642
605 void reportError(ASTNode node, ErrorCode errorCode, List<Object> arguments) { 643 void reportError(ASTNode node, ErrorCode errorCode, List<Object> arguments) {
606 int offset = node.offset; 644 int offset = node.offset;
607 int length = node.length; 645 int length = node.length;
608 reportError2(offset, length, errorCode, arguments); 646 reportError2(offset, length, errorCode, arguments);
609 } 647 }
610 648
611 void reportError2(int offset, int length, ErrorCode errorCode, List<Object> ar guments) { 649 void reportError2(int offset, int length, ErrorCode errorCode, List<Object> ar guments) {
612 _errorListener.onError(new AnalysisError.con2(_source, offset, length, error Code, arguments)); 650 _errorListener.onError(new AnalysisError.con2(_source, offset, length, error Code, arguments));
613 } 651 }
614 652
615 void reportErrorForAnnotation(ErrorCode errorCode, List<Object> arguments) { 653 void reportErrorForAnnotation(ErrorCode errorCode, List<Object> arguments) {
616 reportError(_annotation, errorCode, arguments); 654 reportError(_annotation, errorCode, arguments);
617 } 655 }
618 656
619 void reportErrorForArgument(String argumentName, ErrorCode errorCode, List<Obj ect> arguments) { 657 void reportErrorForArgument(String argumentName, ErrorCode errorCode, List<Obj ect> arguments) {
620 Expression argument = getArgument(argumentName); 658 Expression argument = getArgument(argumentName);
621 reportError(argument, errorCode, arguments); 659 reportError(argument, errorCode, arguments);
622 } 660 }
623 } 661 }
624 662
663 class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseScopeProperties ext ends RecursiveASTVisitor<Object> {
664 List<AngularScopePropertyElement> properties;
665
666 RecursiveASTVisitor_AngularCompilationUnitBuilder_parseScopeProperties(this.pr operties) : super();
667
668 Object visitAssignmentExpression(AssignmentExpression node) {
669 addProperty(node);
670 return super.visitAssignmentExpression(node);
671 }
672
673 void addProperty(AssignmentExpression node) {
674 // try to find "name" in scope[name]
675 SimpleStringLiteral nameNode = getNameNode(node.leftHandSide);
676 if (nameNode == null) {
677 return;
678 }
679 // prepare unique
680 String name = nameNode.stringValue;
681 if (hasPropertyWithName(name)) {
682 return;
683 }
684 // do add property
685 int nameOffset = nameNode.valueOffset;
686 AngularScopePropertyElement property = new AngularScopePropertyElementImpl(n ame, nameOffset, node.rightHandSide.bestType);
687 nameNode.toolkitElement = property;
688 properties.add(property);
689 }
690
691 SimpleStringLiteral getNameNode(Expression node) {
692 if (node is IndexExpression) {
693 IndexExpression indexExpression = node;
694 Expression target = indexExpression.target;
695 Expression index = indexExpression.index;
696 if (index is SimpleStringLiteral && isContext(target)) {
697 return index;
698 }
699 }
700 return null;
701 }
702
703 bool hasPropertyWithName(String name) {
704 for (AngularScopePropertyElement property in properties) {
705 if (property.name == name) {
706 return true;
707 }
708 }
709 return false;
710 }
711
712 bool isContext(Expression target) {
713 if (target is PrefixedIdentifier) {
714 PrefixedIdentifier prefixed = target;
715 SimpleIdentifier prefix = prefixed.prefix;
716 SimpleIdentifier identifier = prefixed.identifier;
717 return (identifier.name == "context") && isScope(prefix);
718 }
719 return false;
720 }
721
722 bool isScope(Expression target) {
723 if (target != null) {
724 Type2 type = target.bestType;
725 if (type is InterfaceType) {
726 InterfaceType interfaceType = type;
727 return interfaceType.name == "Scope";
728 }
729 }
730 return false;
731 }
732 }
733
734 class RecursiveASTVisitor_AngularCompilationUnitBuilder_parseViews extends Recur siveASTVisitor<Object> {
735 List<AngularViewElement> views;
736
737 RecursiveASTVisitor_AngularCompilationUnitBuilder_parseViews(this.views) : sup er();
738
739 Object visitMethodInvocation(MethodInvocation node) {
740 addView(node);
741 return super.visitMethodInvocation(node);
742 }
743
744 void addView(MethodInvocation node) {
745 // only one argument
746 List<Expression> arguments = node.argumentList.arguments;
747 if (arguments.length != 1) {
748 return;
749 }
750 // String literal
751 Expression argument = arguments[0];
752 if (argument is! SimpleStringLiteral) {
753 return;
754 }
755 SimpleStringLiteral literal = argument as SimpleStringLiteral;
756 // just view('template')
757 if (node.realTarget != null) {
758 return;
759 }
760 // should be ViewFactory
761 if (!isViewFactory(node.methodName)) {
762 return;
763 }
764 // add AngularViewElement
765 String templateUri = literal.stringValue;
766 int templateUriOffset = literal.valueOffset;
767 views.add(new AngularViewElementImpl(templateUri, templateUriOffset));
768 }
769
770 bool isViewFactory(Expression target) {
771 if (target is SimpleIdentifier) {
772 SimpleIdentifier identifier = target;
773 Element element = identifier.staticElement;
774 if (element is VariableElement) {
775 VariableElement variable = element;
776 Type2 type = variable.type;
777 if (type is InterfaceType) {
778 InterfaceType interfaceType = type;
779 return interfaceType.name == "ViewFactory";
780 }
781 }
782 }
783 return false;
784 }
785 }
786
625 /** 787 /**
626 * Instances of the class `CompilationUnitBuilder` build an element model for a single 788 * Instances of the class `CompilationUnitBuilder` build an element model for a single
627 * compilation unit. 789 * compilation unit.
628 * 790 *
629 * @coverage dart.engine.resolver 791 * @coverage dart.engine.resolver
630 */ 792 */
631 class CompilationUnitBuilder { 793 class CompilationUnitBuilder {
632 /** 794 /**
633 * Build the compilation unit element for the given source. 795 * Build the compilation unit element for the given source.
634 * 796 *
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 _isValidMixin = false; 983 _isValidMixin = false;
822 ElementHolder holder = new ElementHolder(); 984 ElementHolder holder = new ElementHolder();
823 bool wasInFunction = _inFunction; 985 bool wasInFunction = _inFunction;
824 _inFunction = true; 986 _inFunction = true;
825 try { 987 try {
826 visitChildren(holder, node); 988 visitChildren(holder, node);
827 } finally { 989 } finally {
828 _inFunction = wasInFunction; 990 _inFunction = wasInFunction;
829 } 991 }
830 SimpleIdentifier constructorName = node.name; 992 SimpleIdentifier constructorName = node.name;
831 ConstructorElementImpl element = new ConstructorElementImpl(constructorName) ; 993 ConstructorElementImpl element = new ConstructorElementImpl.con1(constructor Name);
832 if (node.factoryKeyword != null) { 994 if (node.factoryKeyword != null) {
833 element.factory = true; 995 element.factory = true;
834 } 996 }
835 element.functions = holder.functions; 997 element.functions = holder.functions;
836 element.labels = holder.labels; 998 element.labels = holder.labels;
837 element.localVariables = holder.localVariables; 999 element.localVariables = holder.localVariables;
838 element.parameters = holder.parameters; 1000 element.parameters = holder.parameters;
839 element.const2 = node.constKeyword != null; 1001 element.const2 = node.constKeyword != null;
840 _currentHolder.addConstructor(element); 1002 _currentHolder.addConstructor(element);
841 node.element = element; 1003 node.element = element;
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 } 1482 }
1321 } 1483 }
1322 1484
1323 /** 1485 /**
1324 * Creates the [ConstructorElement]s array with the single default constructor element. 1486 * Creates the [ConstructorElement]s array with the single default constructor element.
1325 * 1487 *
1326 * @param interfaceType the interface type for which to create a default const ructor 1488 * @param interfaceType the interface type for which to create a default const ructor
1327 * @return the [ConstructorElement]s array with the single default constructor element 1489 * @return the [ConstructorElement]s array with the single default constructor element
1328 */ 1490 */
1329 List<ConstructorElement> createDefaultConstructors(InterfaceTypeImpl interface Type) { 1491 List<ConstructorElement> createDefaultConstructors(InterfaceTypeImpl interface Type) {
1330 ConstructorElementImpl constructor = new ConstructorElementImpl(null); 1492 ConstructorElementImpl constructor = new ConstructorElementImpl.con1(null);
1331 constructor.synthetic = true; 1493 constructor.synthetic = true;
1332 constructor.returnType = interfaceType; 1494 constructor.returnType = interfaceType;
1333 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor); 1495 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
1334 _functionTypesToFix.add(type); 1496 _functionTypesToFix.add(type);
1335 constructor.type = type; 1497 constructor.type = type;
1336 return <ConstructorElement> [constructor]; 1498 return <ConstructorElement> [constructor];
1337 } 1499 }
1338 1500
1339 /** 1501 /**
1340 * Create the types associated with the given type parameters, setting the typ e of each type 1502 * Create the types associated with the given type parameters, setting the typ e of each type
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 this._errorListener = new RecordingErrorListener(); 2010 this._errorListener = new RecordingErrorListener();
1849 } 2011 }
1850 2012
1851 /** 2013 /**
1852 * Build the HTML element for the given source. 2014 * Build the HTML element for the given source.
1853 * 2015 *
1854 * @param source the source describing the compilation unit 2016 * @param source the source describing the compilation unit
1855 * @return the HTML element that was built 2017 * @return the HTML element that was built
1856 * @throws AnalysisException if the analysis could not be performed 2018 * @throws AnalysisException if the analysis could not be performed
1857 */ 2019 */
1858 HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, s ource.modificationStamp, _context.parseHtmlUnit(source)); 2020 HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _ context.getModificationStamp(source), _context.parseHtmlUnit(source));
1859 2021
1860 /** 2022 /**
1861 * Build the HTML element for the given source. 2023 * Build the HTML element for the given source.
1862 * 2024 *
1863 * @param source the source describing the compilation unit 2025 * @param source the source describing the compilation unit
1864 * @param modificationStamp the modification time of the source for which an e lement is being 2026 * @param modificationStamp the modification time of the source for which an e lement is being
1865 * built 2027 * built
1866 * @param unit the AST structure representing the HTML 2028 * @param unit the AST structure representing the HTML
1867 * @throws AnalysisException if the analysis could not be performed 2029 * @throws AnalysisException if the analysis could not be performed
1868 */ 2030 */
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 } else { 2079 } else {
1918 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl (node); 2080 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl (node);
1919 if (scriptSourcePath != null) { 2081 if (scriptSourcePath != null) {
1920 try { 2082 try {
1921 scriptSourcePath = Uri.encodeFull(scriptSourcePath); 2083 scriptSourcePath = Uri.encodeFull(scriptSourcePath);
1922 // Force an exception to be thrown if the URI is invalid so that we can report the 2084 // Force an exception to be thrown if the URI is invalid so that we can report the
1923 // problem. 2085 // problem.
1924 parseUriWithException(scriptSourcePath); 2086 parseUriWithException(scriptSourcePath);
1925 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath); 2087 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
1926 script.scriptSource = scriptSource; 2088 script.scriptSource = scriptSource;
1927 if (scriptSource == null || !scriptSource.exists()) { 2089 if (!_context.exists(scriptSource)) {
1928 reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribu te, [scriptSourcePath]); 2090 reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribu te, [scriptSourcePath]);
1929 } 2091 }
1930 } on URISyntaxException catch (exception) { 2092 } on URISyntaxException catch (exception) {
1931 reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scri ptSourcePath]); 2093 reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scri ptSourcePath]);
1932 } 2094 }
1933 } 2095 }
1934 node.scriptElement = script; 2096 node.scriptElement = script;
1935 _scripts.add(script); 2097 _scripts.add(script);
1936 } 2098 }
1937 } finally { 2099 } finally {
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
2856 } 3018 }
2857 } 3019 }
2858 } 3020 }
2859 3021
2860 /** 3022 /**
2861 * Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed 3023 * Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed
2862 * to terminate by executing a `return` statement, `throw` expression, `rethrow` 3024 * to terminate by executing a `return` statement, `throw` expression, `rethrow`
2863 * expression, or simple infinite loop such as `while(true)`. 3025 * expression, or simple infinite loop such as `while(true)`.
2864 */ 3026 */
2865 class ExitDetector extends GeneralizingASTVisitor<bool> { 3027 class ExitDetector extends GeneralizingASTVisitor<bool> {
3028 /**
3029 * Set to `true` when a `break` is encountered, and reset to `false` when a
3030 * `do`, `while`, `for` or `switch` block is entered.
3031 */
3032 bool _enclosingBlockContainsBreak = false;
3033
2866 bool visitArgumentList(ArgumentList node) => visitExpressions(node.arguments); 3034 bool visitArgumentList(ArgumentList node) => visitExpressions(node.arguments);
2867 3035
2868 bool visitAsExpression(AsExpression node) => node.expression.accept(this); 3036 bool visitAsExpression(AsExpression node) => node.expression.accept(this);
2869 3037
2870 bool visitAssertStatement(AssertStatement node) => node.condition.accept(this) ; 3038 bool visitAssertStatement(AssertStatement node) => node.condition.accept(this) ;
2871 3039
2872 bool visitAssignmentExpression(AssignmentExpression node) => node.leftHandSide .accept(this) || node.rightHandSide.accept(this); 3040 bool visitAssignmentExpression(AssignmentExpression node) => node.leftHandSide .accept(this) || node.rightHandSide.accept(this);
2873 3041
2874 bool visitBinaryExpression(BinaryExpression node) { 3042 bool visitBinaryExpression(BinaryExpression node) {
2875 Expression lhsExpression = node.leftOperand; 3043 Expression lhsExpression = node.leftOperand;
(...skipping 20 matching lines...) Expand all
2896 } 3064 }
2897 } 3065 }
2898 } 3066 }
2899 return lhsExpression.accept(this) || node.rightOperand.accept(this); 3067 return lhsExpression.accept(this) || node.rightOperand.accept(this);
2900 } 3068 }
2901 3069
2902 bool visitBlock(Block node) => visitStatements(node.statements); 3070 bool visitBlock(Block node) => visitStatements(node.statements);
2903 3071
2904 bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this) ; 3072 bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this) ;
2905 3073
2906 bool visitBreakStatement(BreakStatement node) => false; 3074 bool visitBreakStatement(BreakStatement node) {
3075 _enclosingBlockContainsBreak = true;
3076 return false;
3077 }
2907 3078
2908 bool visitCascadeExpression(CascadeExpression node) { 3079 bool visitCascadeExpression(CascadeExpression node) {
2909 Expression target = node.target; 3080 Expression target = node.target;
2910 if (target.accept(this)) { 3081 if (target.accept(this)) {
2911 return true; 3082 return true;
2912 } 3083 }
2913 return visitExpressions(node.cascadeSections); 3084 return visitExpressions(node.cascadeSections);
2914 } 3085 }
2915 3086
2916 bool visitConditionalExpression(ConditionalExpression node) { 3087 bool visitConditionalExpression(ConditionalExpression node) {
2917 Expression conditionExpression = node.condition; 3088 Expression conditionExpression = node.condition;
2918 Expression thenStatement = node.thenExpression; 3089 Expression thenStatement = node.thenExpression;
2919 Expression elseStatement = node.elseExpression; 3090 Expression elseStatement = node.elseExpression;
2920 // TODO(jwren) Do we want to take constant expressions into account, evaluat e if(false) {} 3091 // TODO(jwren) Do we want to take constant expressions into account, evaluat e if(false) {}
2921 // differently than if(<condition>), when <condition> evaluates to a constan t false value? 3092 // differently than if(<condition>), when <condition> evaluates to a constan t false value?
2922 if (conditionExpression.accept(this)) { 3093 if (conditionExpression.accept(this)) {
2923 return true; 3094 return true;
2924 } 3095 }
2925 if (thenStatement == null || elseStatement == null) { 3096 if (thenStatement == null || elseStatement == null) {
2926 return false; 3097 return false;
2927 } 3098 }
2928 return thenStatement.accept(this) && elseStatement.accept(this); 3099 return thenStatement.accept(this) && elseStatement.accept(this);
2929 } 3100 }
2930 3101
2931 bool visitContinueStatement(ContinueStatement node) => false; 3102 bool visitContinueStatement(ContinueStatement node) => false;
2932 3103
2933 bool visitDoStatement(DoStatement node) { 3104 bool visitDoStatement(DoStatement node) {
2934 Expression conditionExpression = node.condition; 3105 bool outerBreakValue = _enclosingBlockContainsBreak;
2935 if (conditionExpression.accept(this)) { 3106 _enclosingBlockContainsBreak = false;
2936 return true; 3107 try {
3108 Expression conditionExpression = node.condition;
3109 if (conditionExpression.accept(this)) {
3110 return true;
3111 }
3112 // TODO(jwren) Do we want to take all constant expressions into account?
3113 if (conditionExpression is BooleanLiteral) {
3114 BooleanLiteral booleanLiteral = conditionExpression;
3115 // If do {} while (true), and the body doesn't return or the body doesn' t have a break, then
3116 // return true.
3117 bool blockReturns = node.body.accept(this);
3118 if (booleanLiteral.value && (blockReturns || !_enclosingBlockContainsBre ak)) {
3119 return true;
3120 }
3121 }
3122 return false;
3123 } finally {
3124 _enclosingBlockContainsBreak = outerBreakValue;
2937 } 3125 }
2938 // TODO(jwren) Do we want to take all constant expressions into account?
2939 if (conditionExpression is BooleanLiteral) {
2940 BooleanLiteral booleanLiteral = conditionExpression;
2941 if (booleanLiteral.value) {
2942 return node.body.accept(this);
2943 }
2944 }
2945 return false;
2946 } 3126 }
2947 3127
2948 bool visitEmptyStatement(EmptyStatement node) => false; 3128 bool visitEmptyStatement(EmptyStatement node) => false;
2949 3129
2950 bool visitExpressionStatement(ExpressionStatement node) => node.expression.acc ept(this); 3130 bool visitExpressionStatement(ExpressionStatement node) => node.expression.acc ept(this);
2951 3131
2952 bool visitForEachStatement(ForEachStatement node) => node.iterator.accept(this ); 3132 bool visitForEachStatement(ForEachStatement node) {
3133 bool outerBreakValue = _enclosingBlockContainsBreak;
3134 _enclosingBlockContainsBreak = false;
3135 try {
3136 return node.iterator.accept(this);
3137 } finally {
3138 _enclosingBlockContainsBreak = outerBreakValue;
3139 }
3140 }
2953 3141
2954 bool visitForStatement(ForStatement node) { 3142 bool visitForStatement(ForStatement node) {
2955 if (node.variables != null && visitVariableDeclarations(node.variables.varia bles)) { 3143 bool outerBreakValue = _enclosingBlockContainsBreak;
2956 return true; 3144 _enclosingBlockContainsBreak = false;
3145 try {
3146 if (node.variables != null && visitVariableDeclarations(node.variables.var iables)) {
3147 return true;
3148 }
3149 if (node.initialization != null && node.initialization.accept(this)) {
3150 return true;
3151 }
3152 Expression conditionExpression = node.condition;
3153 if (conditionExpression != null && conditionExpression.accept(this)) {
3154 return true;
3155 }
3156 if (visitExpressions(node.updaters)) {
3157 return true;
3158 }
3159 // TODO(jwren) Do we want to take all constant expressions into account?
3160 // If for(; true; ) (or for(;;)), and the body doesn't return or the body doesn't have a
3161 // break, then return true.
3162 bool implicitOrExplictTrue = conditionExpression == null || (conditionExpr ession is BooleanLiteral && conditionExpression.value);
3163 if (implicitOrExplictTrue) {
3164 bool blockReturns = node.body.accept(this);
3165 if (blockReturns || !_enclosingBlockContainsBreak) {
3166 return true;
3167 }
3168 }
3169 return false;
3170 } finally {
3171 _enclosingBlockContainsBreak = outerBreakValue;
2957 } 3172 }
2958 if (node.initialization != null && node.initialization.accept(this)) {
2959 return true;
2960 }
2961 if (node.condition != null && node.condition.accept(this)) {
2962 return true;
2963 }
2964 return visitExpressions(node.updaters);
2965 } 3173 }
2966 3174
2967 bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => f alse; 3175 bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) => f alse;
2968 3176
2969 bool visitFunctionExpression(FunctionExpression node) => false; 3177 bool visitFunctionExpression(FunctionExpression node) => false;
2970 3178
2971 bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 3179 bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
2972 if (node.function.accept(this)) { 3180 if (node.function.accept(this)) {
2973 return true; 3181 return true;
2974 } 3182 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 3258
3051 bool visitReturnStatement(ReturnStatement node) => true; 3259 bool visitReturnStatement(ReturnStatement node) => true;
3052 3260
3053 bool visitSuperExpression(SuperExpression node) => false; 3261 bool visitSuperExpression(SuperExpression node) => false;
3054 3262
3055 bool visitSwitchCase(SwitchCase node) => visitStatements(node.statements); 3263 bool visitSwitchCase(SwitchCase node) => visitStatements(node.statements);
3056 3264
3057 bool visitSwitchDefault(SwitchDefault node) => visitStatements(node.statements ); 3265 bool visitSwitchDefault(SwitchDefault node) => visitStatements(node.statements );
3058 3266
3059 bool visitSwitchStatement(SwitchStatement node) { 3267 bool visitSwitchStatement(SwitchStatement node) {
3060 bool hasDefault = false; 3268 bool outerBreakValue = _enclosingBlockContainsBreak;
3061 NodeList<SwitchMember> memberList = node.members; 3269 _enclosingBlockContainsBreak = false;
3062 List<SwitchMember> members = new List.from(memberList); 3270 try {
3063 for (int i = 0; i < members.length; i++) { 3271 bool hasDefault = false;
3064 SwitchMember switchMember = members[i]; 3272 NodeList<SwitchMember> memberList = node.members;
3065 if (switchMember is SwitchDefault) { 3273 List<SwitchMember> members = new List.from(memberList);
3066 hasDefault = true; 3274 for (int i = 0; i < members.length; i++) {
3067 // If this is the last member and there are no statements, return false 3275 SwitchMember switchMember = members[i];
3068 if (switchMember.statements.isEmpty && i + 1 == members.length) { 3276 if (switchMember is SwitchDefault) {
3277 hasDefault = true;
3278 // If this is the last member and there are no statements, return fals e
3279 if (switchMember.statements.isEmpty && i + 1 == members.length) {
3280 return false;
3281 }
3282 }
3283 // For switch members with no statements, don't visit the children, othe rwise, return false if
3284 // no return is found in the children statements
3285 if (!switchMember.statements.isEmpty && !switchMember.accept(this)) {
3069 return false; 3286 return false;
3070 } 3287 }
3071 } 3288 }
3072 // For switch members with no statements, don't visit the children, otherw ise, return false if 3289 return hasDefault;
3073 // no return is found in the children statements 3290 } finally {
3074 if (!switchMember.statements.isEmpty && !switchMember.accept(this)) { 3291 _enclosingBlockContainsBreak = outerBreakValue;
3075 return false;
3076 }
3077 } 3292 }
3078 return hasDefault;
3079 } 3293 }
3080 3294
3081 bool visitThisExpression(ThisExpression node) => false; 3295 bool visitThisExpression(ThisExpression node) => false;
3082 3296
3083 bool visitThrowExpression(ThrowExpression node) => true; 3297 bool visitThrowExpression(ThrowExpression node) => true;
3084 3298
3085 bool visitTryStatement(TryStatement node) { 3299 bool visitTryStatement(TryStatement node) {
3086 if (node.body.accept(this)) { 3300 if (node.body.accept(this)) {
3087 return true; 3301 return true;
3088 } 3302 }
(...skipping 20 matching lines...) Expand all
3109 NodeList<VariableDeclaration> variables = node.variables.variables; 3323 NodeList<VariableDeclaration> variables = node.variables.variables;
3110 for (int i = 0; i < variables.length; i++) { 3324 for (int i = 0; i < variables.length; i++) {
3111 if (variables[i].accept(this)) { 3325 if (variables[i].accept(this)) {
3112 return true; 3326 return true;
3113 } 3327 }
3114 } 3328 }
3115 return false; 3329 return false;
3116 } 3330 }
3117 3331
3118 bool visitWhileStatement(WhileStatement node) { 3332 bool visitWhileStatement(WhileStatement node) {
3119 Expression conditionExpression = node.condition; 3333 bool outerBreakValue = _enclosingBlockContainsBreak;
3120 if (conditionExpression.accept(this)) { 3334 _enclosingBlockContainsBreak = false;
3121 return true; 3335 try {
3336 Expression conditionExpression = node.condition;
3337 if (conditionExpression.accept(this)) {
3338 return true;
3339 }
3340 // TODO(jwren) Do we want to take all constant expressions into account?
3341 if (conditionExpression is BooleanLiteral) {
3342 BooleanLiteral booleanLiteral = conditionExpression;
3343 // If while(true), and the body doesn't return or the body doesn't have a break, then return
3344 // true.
3345 bool blockReturns = node.body.accept(this);
3346 if (booleanLiteral.value && (blockReturns || !_enclosingBlockContainsBre ak)) {
3347 return true;
3348 }
3349 }
3350 return false;
3351 } finally {
3352 _enclosingBlockContainsBreak = outerBreakValue;
3122 } 3353 }
3123 // TODO(jwren) Do we want to take all constant expressions into account?
3124 if (conditionExpression is BooleanLiteral) {
3125 BooleanLiteral booleanLiteral = conditionExpression;
3126 if (booleanLiteral.value) {
3127 return node.body.accept(this);
3128 }
3129 }
3130 return false;
3131 } 3354 }
3132 3355
3133 bool visitExpressions(NodeList<Expression> expressions) { 3356 bool visitExpressions(NodeList<Expression> expressions) {
3134 for (int i = expressions.length - 1; i >= 0; i--) { 3357 for (int i = expressions.length - 1; i >= 0; i--) {
3135 if (expressions[i].accept(this)) { 3358 if (expressions[i].accept(this)) {
3136 return true; 3359 return true;
3137 } 3360 }
3138 } 3361 }
3139 return false; 3362 return false;
3140 } 3363 }
(...skipping 28 matching lines...) Expand all
3169 List<CompilationUnit> _compilationUnits; 3392 List<CompilationUnit> _compilationUnits;
3170 3393
3171 AnalysisContext _context; 3394 AnalysisContext _context;
3172 3395
3173 AnalysisErrorListener _errorListener; 3396 AnalysisErrorListener _errorListener;
3174 3397
3175 ImportsVerifier _importsVerifier; 3398 ImportsVerifier _importsVerifier;
3176 3399
3177 bool _enableDart2JSHints = false; 3400 bool _enableDart2JSHints = false;
3178 3401
3402 /**
3403 * The inheritance manager used to find overridden methods.
3404 */
3405 InheritanceManager _manager;
3406
3179 HintGenerator(List<CompilationUnit> compilationUnits, AnalysisContext context, AnalysisErrorListener errorListener) { 3407 HintGenerator(List<CompilationUnit> compilationUnits, AnalysisContext context, AnalysisErrorListener errorListener) {
3180 this._compilationUnits = compilationUnits; 3408 this._compilationUnits = compilationUnits;
3181 this._context = context; 3409 this._context = context;
3182 this._errorListener = errorListener; 3410 this._errorListener = errorListener;
3183 LibraryElement library = compilationUnits[0].element.library; 3411 LibraryElement library = compilationUnits[0].element.library;
3184 _importsVerifier = new ImportsVerifier(library); 3412 _importsVerifier = new ImportsVerifier(library);
3185 _enableDart2JSHints = context.analysisOptions.dart2jsHint; 3413 _enableDart2JSHints = context.analysisOptions.dart2jsHint;
3414 _manager = new InheritanceManager(compilationUnits[0].element.library);
3186 } 3415 }
3187 3416
3188 void generateForLibrary() { 3417 void generateForLibrary() {
3189 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.hints.star t(); 3418 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.hints.star t();
3190 try { 3419 try {
3191 for (int i = 0; i < _compilationUnits.length; i++) { 3420 for (int i = 0; i < _compilationUnits.length; i++) {
3192 CompilationUnitElement element = _compilationUnits[i].element; 3421 CompilationUnitElement element = _compilationUnits[i].element;
3193 if (element != null) { 3422 if (element != null) {
3194 if (i == 0) { 3423 if (i == 0) {
3195 _importsVerifier.inDefiningCompilationUnit = true; 3424 _importsVerifier.inDefiningCompilationUnit = true;
3196 generateForCompilationUnit(_compilationUnits[i], element.source); 3425 generateForCompilationUnit(_compilationUnits[i], element.source);
3197 _importsVerifier.inDefiningCompilationUnit = false; 3426 _importsVerifier.inDefiningCompilationUnit = false;
3198 } else { 3427 } else {
3199 generateForCompilationUnit(_compilationUnits[i], element.source); 3428 generateForCompilationUnit(_compilationUnits[i], element.source);
3200 } 3429 }
3201 } 3430 }
3202 } 3431 }
3203 ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter(_er rorListener, _compilationUnits[0].element.source); 3432 ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter(_er rorListener, _compilationUnits[0].element.source);
3204 _importsVerifier.generateDuplicateImportHints(definingCompilationUnitError Reporter); 3433 _importsVerifier.generateDuplicateImportHints(definingCompilationUnitError Reporter);
3205 _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorRep orter); 3434 _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorRep orter);
3206 } finally { 3435 } finally {
3207 timeCounter.stop(); 3436 timeCounter.stop();
3208 } 3437 }
3209 } 3438 }
3210 3439
3211 void generateForCompilationUnit(CompilationUnit unit, Source source) { 3440 void generateForCompilationUnit(CompilationUnit unit, Source source) {
3212 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); 3441 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
3213 _importsVerifier.visitCompilationUnit(unit); 3442 unit.accept(_importsVerifier);
3214 // dead code analysis 3443 // dead code analysis
3215 new DeadCodeVerifier(errorReporter).visitCompilationUnit(unit); 3444 unit.accept(new DeadCodeVerifier(errorReporter));
3216 // dart2js analysis 3445 // dart2js analysis
3217 if (_enableDart2JSHints) { 3446 if (_enableDart2JSHints) {
3218 new Dart2JSVerifier(errorReporter).visitCompilationUnit(unit); 3447 unit.accept(new Dart2JSVerifier(errorReporter));
3219 } 3448 }
3220 // Dart best practices 3449 // Dart best practices
3221 new BestPracticesVerifier(errorReporter).visitCompilationUnit(unit); 3450 unit.accept(new BestPracticesVerifier(errorReporter));
3451 unit.accept(new OverrideVerifier(_manager, errorReporter));
3222 // Find to-do comments 3452 // Find to-do comments
3223 new ToDoFinder(errorReporter).findIn(unit); 3453 new ToDoFinder(errorReporter).findIn(unit);
3224 } 3454 }
3225 } 3455 }
3226 3456
3227 /** 3457 /**
3228 * Instances of the class `ImportsVerifier` visit all of the referenced librarie s in the 3458 * Instances of the class `ImportsVerifier` visit all of the referenced librarie s in the
3229 * source code verifying that all of the imports are used, otherwise a 3459 * source code verifying that all of the imports are used, otherwise a
3230 * [HintCode#UNUSED_IMPORT] is generated with 3460 * [HintCode#UNUSED_IMPORT] is generated with
3231 * [generateUnusedImportHints]. 3461 * [generateUnusedImportHints].
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
3558 */ 3788 */
3559 void visitMetadata(NodeList<Annotation> annotations) { 3789 void visitMetadata(NodeList<Annotation> annotations) {
3560 for (Annotation annotation in annotations) { 3790 for (Annotation annotation in annotations) {
3561 Identifier name = annotation.name; 3791 Identifier name = annotation.name;
3562 visitIdentifier(name.staticElement, name.name); 3792 visitIdentifier(name.staticElement, name.name);
3563 } 3793 }
3564 } 3794 }
3565 } 3795 }
3566 3796
3567 /** 3797 /**
3798 * Instances of the class `OverrideVerifier` visit all of the declarations in a compilation
3799 * unit to verify that if they have an override annotation it is being used corr ectly.
3800 */
3801 class OverrideVerifier extends RecursiveASTVisitor<Object> {
3802 /**
3803 * The inheritance manager used to find overridden methods.
3804 */
3805 InheritanceManager _manager;
3806
3807 /**
3808 * The error reporter used to report errors.
3809 */
3810 ErrorReporter _errorReporter;
3811
3812 /**
3813 * Initialize a newly created verifier to look for inappropriate uses of the o verride annotation.
3814 *
3815 * @param manager the inheritance manager used to find overridden methods
3816 * @param errorReporter the error reporter used to report errors
3817 */
3818 OverrideVerifier(InheritanceManager manager, ErrorReporter errorReporter) {
3819 this._manager = manager;
3820 this._errorReporter = errorReporter;
3821 }
3822
3823 Object visitMethodDeclaration(MethodDeclaration node) {
3824 ExecutableElement element = node.element;
3825 if (isOverride(element)) {
3826 if (getOverriddenMember(element) == null) {
3827 if (element is MethodElement) {
3828 _errorReporter.reportError3(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD , node.name, []);
3829 } else if (element is PropertyAccessorElement) {
3830 if (element.isGetter) {
3831 _errorReporter.reportError3(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETT ER, node.name, []);
3832 } else {
3833 _errorReporter.reportError3(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETT ER, node.name, []);
3834 }
3835 }
3836 }
3837 }
3838 return super.visitMethodDeclaration(node);
3839 }
3840
3841 /**
3842 * Return the member that overrides the given member.
3843 *
3844 * @param member the member that overrides the returned member
3845 * @return the member that overrides the given member
3846 */
3847 ExecutableElement getOverriddenMember(ExecutableElement member) {
3848 LibraryElement library = member.library;
3849 if (library == null) {
3850 return null;
3851 }
3852 ClassElement classElement = member.getAncestor(ClassElement);
3853 if (classElement == null) {
3854 return null;
3855 }
3856 return _manager.lookupInheritance(classElement, member.name);
3857 }
3858
3859 /**
3860 * Return `true` if the given element has an override annotation associated wi th it.
3861 *
3862 * @param element the element being tested
3863 * @return `true` if the element has an override annotation associated with it
3864 */
3865 bool isOverride(Element element) => element != null && element.isOverride;
3866 }
3867
3868 /**
3568 * Instances of the class `PubVerifier` traverse an AST structure looking for de viations from 3869 * Instances of the class `PubVerifier` traverse an AST structure looking for de viations from
3569 * pub best practices. 3870 * pub best practices.
3570 */ 3871 */
3571 class PubVerifier extends RecursiveASTVisitor<Object> { 3872 class PubVerifier extends RecursiveASTVisitor<Object> {
3572 static String _PUBSPEC_YAML = "pubspec.yaml"; 3873 static String _PUBSPEC_YAML = "pubspec.yaml";
3573 3874
3574 /** 3875 /**
3575 * The analysis context containing the sources to be analyzed 3876 * The analysis context containing the sources to be analyzed
3576 */ 3877 */
3577 AnalysisContext _context; 3878 AnalysisContext _context;
(...skipping 30 matching lines...) Expand all
3608 int fullNameIndex = fullName.length; 3909 int fullNameIndex = fullName.length;
3609 while (pathIndex < path.length && StringUtilities.startsWith3(path, pathIn dex, 0x2E, 0x2E, 0x2F)) { 3910 while (pathIndex < path.length && StringUtilities.startsWith3(path, pathIn dex, 0x2E, 0x2E, 0x2F)) {
3610 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); 3911 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex);
3611 if (fullNameIndex < 4) { 3912 if (fullNameIndex < 4) {
3612 return false; 3913 return false;
3613 } 3914 }
3614 // Check for "/lib" at a specified place in the fullName 3915 // Check for "/lib" at a specified place in the fullName
3615 if (StringUtilities.startsWith4(fullName, fullNameIndex - 4, 0x2F, 0x6C, 0x69, 0x62)) { 3916 if (StringUtilities.startsWith4(fullName, fullNameIndex - 4, 0x2F, 0x6C, 0x69, 0x62)) {
3616 String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSP EC_YAML; 3917 String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSP EC_YAML;
3617 Source pubspecSource = _context.sourceFactory.resolveUri(source, relat ivePubspecPath); 3918 Source pubspecSource = _context.sourceFactory.resolveUri(source, relat ivePubspecPath);
3618 if (pubspecSource != null && pubspecSource.exists()) { 3919 if (_context.exists(pubspecSource)) {
3619 // Files inside the lib directory hierarchy should not reference fil es outside 3920 // Files inside the lib directory hierarchy should not reference fil es outside
3620 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB _REFERENCES_FILE_OUTSIDE, uriLiteral, []); 3921 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB _REFERENCES_FILE_OUTSIDE, uriLiteral, []);
3621 } 3922 }
3622 return true; 3923 return true;
3623 } 3924 }
3624 pathIndex += 3; 3925 pathIndex += 3;
3625 } 3926 }
3626 } 3927 }
3627 return false; 3928 return false;
3628 } 3929 }
(...skipping 21 matching lines...) Expand all
3650 } 3951 }
3651 pathIndex = StringUtilities.indexOf5(path, pathIndex + 4, 0x2F, 0x6C, 0x69 , 0x62, 0x2F); 3952 pathIndex = StringUtilities.indexOf5(path, pathIndex + 4, 0x2F, 0x6C, 0x69 , 0x62, 0x2F);
3652 } 3953 }
3653 return false; 3954 return false;
3654 } 3955 }
3655 3956
3656 bool checkForFileImportOutsideLibReferencesFileInside2(StringLiteral uriLitera l, String path, int pathIndex) { 3957 bool checkForFileImportOutsideLibReferencesFileInside2(StringLiteral uriLitera l, String path, int pathIndex) {
3657 Source source = getSource(uriLiteral); 3958 Source source = getSource(uriLiteral);
3658 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; 3959 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML;
3659 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub specPath); 3960 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub specPath);
3660 if (pubspecSource == null || !pubspecSource.exists()) { 3961 if (!_context.exists(pubspecSource)) {
3661 return false; 3962 return false;
3662 } 3963 }
3663 String fullName = getSourceFullName(source); 3964 String fullName = getSourceFullName(source);
3664 if (fullName != null) { 3965 if (fullName != null) {
3665 if (StringUtilities.indexOf5(fullName, 0, 0x2F, 0x6C, 0x69, 0x62, 0x2F) < 0) { 3966 if (StringUtilities.indexOf5(fullName, 0, 0x2F, 0x6C, 0x69, 0x62, 0x2F) < 0) {
3666 // Files outside the lib directory hierarchy should not reference files inside 3967 // Files outside the lib directory hierarchy should not reference files inside
3667 // ... use package: url instead 3968 // ... use package: url instead
3668 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_RE FERENCES_FILE_INSIDE, uriLiteral, []); 3969 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_RE FERENCES_FILE_INSIDE, uriLiteral, []);
3669 return true; 3970 return true;
3670 } 3971 }
(...skipping 1293 matching lines...) Expand 10 before | Expand all | Expand 10 after
4964 * names in hide and show combinators that are not defined in the imported libra ry (which is not an 5265 * names in hide and show combinators that are not defined in the imported libra ry (which is not an
4965 * error). 5266 * error).
4966 * 5267 *
4967 * @coverage dart.engine.resolver 5268 * @coverage dart.engine.resolver
4968 */ 5269 */
4969 class ElementResolver extends SimpleASTVisitor<Object> { 5270 class ElementResolver extends SimpleASTVisitor<Object> {
4970 /** 5271 /**
4971 * Checks if the given expression is the reference to the type, if it is then the 5272 * Checks if the given expression is the reference to the type, if it is then the
4972 * [ClassElement] is returned, otherwise `null` is returned. 5273 * [ClassElement] is returned, otherwise `null` is returned.
4973 * 5274 *
4974 * @param expr the expression to evaluate 5275 * @param expression the expression to evaluate
4975 * @return the [ClassElement] if the given expression is the reference to the type, and 5276 * @return the [ClassElement] if the given expression is the reference to the type, and
4976 * `null` otherwise 5277 * `null` otherwise
4977 */ 5278 */
4978 static ClassElementImpl getTypeReference(Expression expr) { 5279 static ClassElementImpl getTypeReference(Expression expression) {
4979 if (expr is Identifier) { 5280 if (expression is Identifier) {
4980 Identifier identifier = expr; 5281 Element staticElement = expression.staticElement;
4981 if (identifier.staticElement is ClassElementImpl) { 5282 if (staticElement is ClassElementImpl) {
4982 return identifier.staticElement as ClassElementImpl; 5283 return staticElement;
4983 } 5284 }
4984 } 5285 }
4985 return null; 5286 return null;
4986 } 5287 }
4987 5288
4988 /** 5289 /**
5290 * Return `true` if the given identifier is the return type of a constructor d eclaration.
5291 *
4989 * @return `true` if the given identifier is the return type of a constructor declaration. 5292 * @return `true` if the given identifier is the return type of a constructor declaration.
4990 */ 5293 */
4991 static bool isConstructorReturnType(SimpleIdentifier node) { 5294 static bool isConstructorReturnType(SimpleIdentifier identifier) {
4992 ASTNode parent = node.parent; 5295 ASTNode parent = identifier.parent;
4993 if (parent is ConstructorDeclaration) { 5296 if (parent is ConstructorDeclaration) {
4994 ConstructorDeclaration constructor = parent; 5297 return identical(parent.returnType, identifier);
4995 return identical(constructor.returnType, node);
4996 } 5298 }
4997 return false; 5299 return false;
4998 } 5300 }
4999 5301
5000 /** 5302 /**
5303 * Return `true` if the given identifier is the return type of a factory const ructor.
5304 *
5001 * @return `true` if the given identifier is the return type of a factory cons tructor 5305 * @return `true` if the given identifier is the return type of a factory cons tructor
5002 * declaration. 5306 * declaration.
5003 */ 5307 */
5004 static bool isFactoryConstructorReturnType(SimpleIdentifier node) { 5308 static bool isFactoryConstructorReturnType(SimpleIdentifier node) {
5005 ASTNode parent = node.parent; 5309 ASTNode parent = node.parent;
5006 if (parent is ConstructorDeclaration) { 5310 if (parent is ConstructorDeclaration) {
5007 ConstructorDeclaration constructor = parent; 5311 ConstructorDeclaration constructor = parent;
5008 return identical(constructor.returnType, node) && constructor.factoryKeywo rd != null; 5312 return identical(constructor.returnType, node) && constructor.factoryKeywo rd != null;
5009 } 5313 }
5010 return false; 5314 return false;
5011 } 5315 }
5012 5316
5013 /** 5317 /**
5014 * Checks if the given 'super' expression is used in the valid context. 5318 * Return `true` if the given 'super' expression is used in a valid context.
5015 * 5319 *
5016 * @param node the 'super' expression to analyze 5320 * @param node the 'super' expression to analyze
5017 * @return `true` if the given 'super' expression is in the valid context 5321 * @return `true` if the 'super' expression is in a valid context
5018 */ 5322 */
5019 static bool isSuperInValidContext(SuperExpression node) { 5323 static bool isSuperInValidContext(SuperExpression node) {
5020 for (ASTNode n = node; n != null; n = n.parent) { 5324 for (ASTNode n = node; n != null; n = n.parent) {
5021 if (n is CompilationUnit) { 5325 if (n is CompilationUnit) {
5022 return false; 5326 return false;
5023 } 5327 }
5024 if (n is ConstructorDeclaration) { 5328 if (n is ConstructorDeclaration) {
5025 ConstructorDeclaration constructor = n as ConstructorDeclaration; 5329 ConstructorDeclaration constructor = n as ConstructorDeclaration;
5026 return constructor.factoryKeyword == null; 5330 return constructor.factoryKeyword == null;
5027 } 5331 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5106 operatorType = operatorFromCompoundAssignment(operatorType); 5410 operatorType = operatorFromCompoundAssignment(operatorType);
5107 Expression leftHandSide = node.leftHandSide; 5411 Expression leftHandSide = node.leftHandSide;
5108 if (leftHandSide != null) { 5412 if (leftHandSide != null) {
5109 String methodName = operatorType.lexeme; 5413 String methodName = operatorType.lexeme;
5110 Type2 staticType = getStaticType(leftHandSide); 5414 Type2 staticType = getStaticType(leftHandSide);
5111 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth odName); 5415 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth odName);
5112 node.staticElement = staticMethod; 5416 node.staticElement = staticMethod;
5113 Type2 propagatedType = getPropagatedType(leftHandSide); 5417 Type2 propagatedType = getPropagatedType(leftHandSide);
5114 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy pe, methodName); 5418 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy pe, methodName);
5115 node.propagatedElement = propagatedMethod; 5419 node.propagatedElement = propagatedMethod;
5116 bool shouldReportMissingMember_static = shouldReportMissingMember(static Type, staticMethod); 5420 if (shouldReportMissingMember(staticType, staticMethod)) {
5117 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_s tatic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMeth od) : false; 5421 _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element , StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.disp layName]);
5118 // 5422 } else if (_enableHints && shouldReportMissingMember(propagatedType, pro pagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, tru e, false)) {
5119 // If we are about to generate the hint (propagated version of this warn ing), then check 5423 _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.ele ment, HintCode.UNDEFINED_METHOD, operator, [methodName, propagatedType.displayNa me]);
5120 // that the member is not in a subtype of the propagated type.
5121 //
5122 if (shouldReportMissingMember_propagated) {
5123 if (memberFoundInSubclass(propagatedType.element, methodName, true, fa lse)) {
5124 shouldReportMissingMember_propagated = false;
5125 }
5126 }
5127 if (shouldReportMissingMember_static || shouldReportMissingMember_propag ated) {
5128 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa rningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode;
5129 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissin gMember_static ? staticType.element : propagatedType.element, errorCode, operato r, [
5130 methodName,
5131 shouldReportMissingMember_static ? staticType.displayName : propag atedType.displayName]);
5132 } 5424 }
5133 } 5425 }
5134 } 5426 }
5135 return null; 5427 return null;
5136 } 5428 }
5137 5429
5138 Object visitBinaryExpression(BinaryExpression node) { 5430 Object visitBinaryExpression(BinaryExpression node) {
5139 sc.Token operator = node.operator; 5431 sc.Token operator = node.operator;
5140 if (operator.isUserDefinableOperator) { 5432 if (operator.isUserDefinableOperator) {
5141 Expression leftOperand = node.leftOperand; 5433 Expression leftOperand = node.leftOperand;
5142 if (leftOperand != null) { 5434 if (leftOperand != null) {
5143 String methodName = operator.lexeme; 5435 String methodName = operator.lexeme;
5144 Type2 staticType = getStaticType(leftOperand); 5436 Type2 staticType = getStaticType(leftOperand);
5145 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho dName); 5437 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho dName);
5146 node.staticElement = staticMethod; 5438 node.staticElement = staticMethod;
5147 Type2 propagatedType = getPropagatedType(leftOperand); 5439 Type2 propagatedType = getPropagatedType(leftOperand);
5148 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp e, methodName); 5440 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp e, methodName);
5149 node.propagatedElement = propagatedMethod; 5441 node.propagatedElement = propagatedMethod;
5150 bool shouldReportMissingMember_static = shouldReportMissingMember(static Type, staticMethod); 5442 if (shouldReportMissingMember(staticType, staticMethod)) {
5151 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_s tatic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMeth od) : false; 5443 _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element , StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.di splayName]);
5152 // 5444 } else if (_enableHints && shouldReportMissingMember(propagatedType, pro pagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, tru e, false)) {
5153 // If we are about to generate the hint (propagated version of this warn ing), then check 5445 _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.ele ment, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.display Name]);
5154 // that the member is not in a subtype of the propagated type.
5155 //
5156 if (shouldReportMissingMember_propagated) {
5157 if (memberFoundInSubclass(propagatedType.element, methodName, true, fa lse)) {
5158 shouldReportMissingMember_propagated = false;
5159 }
5160 }
5161 if (shouldReportMissingMember_static || shouldReportMissingMember_propag ated) {
5162 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa rningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
5163 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissin gMember_static ? staticType.element : propagatedType.element, errorCode, operato r, [
5164 methodName,
5165 shouldReportMissingMember_static ? staticType.displayName : propag atedType.displayName]);
5166 } 5446 }
5167 } 5447 }
5168 } 5448 }
5169 return null; 5449 return null;
5170 } 5450 }
5171 5451
5172 Object visitBreakStatement(BreakStatement node) { 5452 Object visitBreakStatement(BreakStatement node) {
5173 SimpleIdentifier labelNode = node.label; 5453 lookupLabel(node, node.label);
5174 LabelElementImpl labelElement = lookupLabel(node, labelNode);
5175 if (labelElement != null && labelElement.isOnSwitchMember) {
5176 _resolver.reportError9(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, lab elNode, []);
5177 }
5178 return null; 5454 return null;
5179 } 5455 }
5180 5456
5181 Object visitClassDeclaration(ClassDeclaration node) { 5457 Object visitClassDeclaration(ClassDeclaration node) {
5182 setMetadata(node.element, node); 5458 setMetadata(node.element, node);
5183 return null; 5459 return null;
5184 } 5460 }
5185 5461
5186 Object visitClassTypeAlias(ClassTypeAlias node) { 5462 Object visitClassTypeAlias(ClassTypeAlias node) {
5187 setMetadata(node.element, node); 5463 setMetadata(node.element, node);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
5268 } 5544 }
5269 } 5545 }
5270 return null; 5546 return null;
5271 } 5547 }
5272 5548
5273 Object visitConstructorDeclaration(ConstructorDeclaration node) { 5549 Object visitConstructorDeclaration(ConstructorDeclaration node) {
5274 super.visitConstructorDeclaration(node); 5550 super.visitConstructorDeclaration(node);
5275 ConstructorElement element = node.element; 5551 ConstructorElement element = node.element;
5276 if (element is ConstructorElementImpl) { 5552 if (element is ConstructorElementImpl) {
5277 ConstructorElementImpl constructorElement = element; 5553 ConstructorElementImpl constructorElement = element;
5278 // set redirected factory constructor
5279 ConstructorName redirectedNode = node.redirectedConstructor; 5554 ConstructorName redirectedNode = node.redirectedConstructor;
5280 if (redirectedNode != null) { 5555 if (redirectedNode != null) {
5556 // set redirected factory constructor
5281 ConstructorElement redirectedElement = redirectedNode.staticElement; 5557 ConstructorElement redirectedElement = redirectedNode.staticElement;
5282 constructorElement.redirectedConstructor = redirectedElement; 5558 constructorElement.redirectedConstructor = redirectedElement;
5283 } 5559 } else {
5284 // set redirected generate constructor 5560 // set redirected generative constructor
5285 for (ConstructorInitializer initializer in node.initializers) { 5561 for (ConstructorInitializer initializer in node.initializers) {
5286 if (initializer is RedirectingConstructorInvocation) { 5562 if (initializer is RedirectingConstructorInvocation) {
5287 ConstructorElement redirectedElement = initializer.staticElement; 5563 ConstructorElement redirectedElement = initializer.staticElement;
5288 constructorElement.redirectedConstructor = redirectedElement; 5564 constructorElement.redirectedConstructor = redirectedElement;
5565 }
5289 } 5566 }
5290 } 5567 }
5291 setMetadata(constructorElement, node); 5568 setMetadata(constructorElement, node);
5292 } 5569 }
5293 return null; 5570 return null;
5294 } 5571 }
5295 5572
5296 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 5573 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
5297 SimpleIdentifier fieldName = node.fieldName; 5574 SimpleIdentifier fieldName = node.fieldName;
5298 ClassElement enclosingClass = _resolver.enclosingClass; 5575 ClassElement enclosingClass = _resolver.enclosingClass;
5299 FieldElement fieldElement = enclosingClass.getField(fieldName.name); 5576 FieldElement fieldElement = enclosingClass.getField(fieldName.name);
5300 fieldName.staticElement = fieldElement; 5577 fieldName.staticElement = fieldElement;
5301 if (fieldElement == null || fieldElement.isSynthetic) {
5302 _resolver.reportError9(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_F IELD, node, [fieldName]);
5303 } else if (fieldElement.isStatic) {
5304 _resolver.reportError9(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
5305 }
5306 return null; 5578 return null;
5307 } 5579 }
5308 5580
5309 Object visitConstructorName(ConstructorName node) { 5581 Object visitConstructorName(ConstructorName node) {
5310 Type2 type = node.type.type; 5582 Type2 type = node.type.type;
5311 if (type != null && type.isDynamic) { 5583 if (type != null && type.isDynamic) {
5312 return null; 5584 return null;
5313 } else if (type is! InterfaceType) { 5585 } else if (type is! InterfaceType) {
5314 // TODO(brianwilkerson) Report these errors. 5586 // TODO(brianwilkerson) Report these errors.
5315 ASTNode parent = node.parent; 5587 // ASTNode parent = node.getParent();
5316 if (parent is InstanceCreationExpression) { 5588 // if (parent instanceof InstanceCreationExpression) {
5317 if (parent.isConst) { 5589 // if (((InstanceCreationExpression) parent).isConst()) {
5318 } else { 5590 // // CompileTimeErrorCode.CONST_WITH_NON_TYPE
5319 } 5591 // } else {
5320 } else { 5592 // // StaticWarningCode.NEW_WITH_NON_TYPE
5321 } 5593 // }
5594 // } else {
5595 // // This is part of a redirecting factory constructor; not sure w hich error code to use
5596 // }
5322 return null; 5597 return null;
5323 } 5598 }
5324 // look up ConstructorElement 5599 // look up ConstructorElement
5325 ConstructorElement constructor; 5600 ConstructorElement constructor;
5326 SimpleIdentifier name = node.name; 5601 SimpleIdentifier name = node.name;
5327 InterfaceType interfaceType = type as InterfaceType; 5602 InterfaceType interfaceType = type as InterfaceType;
5328 if (name == null) { 5603 if (name == null) {
5329 constructor = interfaceType.lookUpConstructor(null, _definingLibrary); 5604 constructor = interfaceType.lookUpConstructor(null, _definingLibrary);
5330 } else { 5605 } else {
5331 constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary) ; 5606 constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary) ;
5332 name.staticElement = constructor; 5607 name.staticElement = constructor;
5333 } 5608 }
5334 node.staticElement = constructor; 5609 node.staticElement = constructor;
5335 return null; 5610 return null;
5336 } 5611 }
5337 5612
5338 Object visitContinueStatement(ContinueStatement node) { 5613 Object visitContinueStatement(ContinueStatement node) {
5339 SimpleIdentifier labelNode = node.label; 5614 lookupLabel(node, node.label);
5340 LabelElementImpl labelElement = lookupLabel(node, labelNode);
5341 if (labelElement != null && labelElement.isOnSwitchStatement) {
5342 _resolver.reportError9(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNo de, []);
5343 }
5344 return null; 5615 return null;
5345 } 5616 }
5346 5617
5347 Object visitDeclaredIdentifier(DeclaredIdentifier node) { 5618 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
5348 setMetadata(node.element, node); 5619 setMetadata(node.element, node);
5349 return null; 5620 return null;
5350 } 5621 }
5351 5622
5352 Object visitExportDirective(ExportDirective node) { 5623 Object visitExportDirective(ExportDirective node) {
5353 Element element = node.element; 5624 Element element = node.element;
5354 if (element is ExportElement) { 5625 if (element is ExportElement) {
5355 // The element is null when the URI is invalid 5626 // The element is null when the URI is invalid
5356 // TODO(brianwilkerson) Figure out whether the element can ever be somethi ng other than an 5627 // TODO(brianwilkerson) Figure out whether the element can ever be somethi ng other than an
5357 // ExportElement 5628 // ExportElement
5358 resolveCombinators(element.exportedLibrary, node.combinators); 5629 resolveCombinators(element.exportedLibrary, node.combinators);
5359 setMetadata(element, node); 5630 setMetadata(element, node);
5360 } 5631 }
5361 return null; 5632 return null;
5362 } 5633 }
5363 5634
5364 Object visitFieldFormalParameter(FieldFormalParameter node) { 5635 Object visitFieldFormalParameter(FieldFormalParameter node) {
5365 String fieldName = node.identifier.name;
5366 ClassElement classElement = _resolver.enclosingClass;
5367 if (classElement != null) {
5368 FieldElement fieldElement = classElement.getField(fieldName);
5369 if (fieldElement == null || fieldElement.isSynthetic) {
5370 _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_ EXISTANT_FIELD, node, [fieldName]);
5371 } else {
5372 ParameterElement parameterElement = node.element;
5373 if (parameterElement is FieldFormalParameterElementImpl) {
5374 FieldFormalParameterElementImpl fieldFormal = parameterElement;
5375 Type2 declaredType = fieldFormal.type;
5376 Type2 fieldType = fieldElement.type;
5377 if (fieldElement.isSynthetic) {
5378 _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_ NON_EXISTANT_FIELD, node, [fieldName]);
5379 } else if (fieldElement.isStatic) {
5380 _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_ STATIC_FIELD, node, [fieldName]);
5381 } else if (declaredType != null && fieldType != null && !declaredType. isAssignableTo(fieldType)) {
5382 _resolver.reportError9(StaticWarningCode.FIELD_INITIALIZING_FORMAL_N OT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
5383 }
5384 } else {
5385 if (fieldElement.isSynthetic) {
5386 _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_ NON_EXISTANT_FIELD, node, [fieldName]);
5387 } else if (fieldElement.isStatic) {
5388 _resolver.reportError9(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_ STATIC_FIELD, node, [fieldName]);
5389 }
5390 }
5391 }
5392 }
5393 // else {
5394 // // TODO(jwren) Report error, constructor initializer variable is a top level element
5395 // // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCo des)
5396 // }
5397 setMetadata2(node.element, node); 5636 setMetadata2(node.element, node);
5398 return super.visitFieldFormalParameter(node); 5637 return super.visitFieldFormalParameter(node);
5399 } 5638 }
5400 5639
5401 Object visitFunctionDeclaration(FunctionDeclaration node) { 5640 Object visitFunctionDeclaration(FunctionDeclaration node) {
5402 setMetadata(node.element, node); 5641 setMetadata(node.element, node);
5403 return null; 5642 return null;
5404 } 5643 }
5405 5644
5406 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 5645 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
5666 5905
5667 Object visitPostfixExpression(PostfixExpression node) { 5906 Object visitPostfixExpression(PostfixExpression node) {
5668 Expression operand = node.operand; 5907 Expression operand = node.operand;
5669 String methodName = getPostfixOperator(node); 5908 String methodName = getPostfixOperator(node);
5670 Type2 staticType = getStaticType(operand); 5909 Type2 staticType = getStaticType(operand);
5671 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName); 5910 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName);
5672 node.staticElement = staticMethod; 5911 node.staticElement = staticMethod;
5673 Type2 propagatedType = getPropagatedType(operand); 5912 Type2 propagatedType = getPropagatedType(operand);
5674 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho dName); 5913 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho dName);
5675 node.propagatedElement = propagatedMethod; 5914 node.propagatedElement = propagatedMethod;
5676 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType , staticMethod); 5915 if (shouldReportMissingMember(staticType, staticMethod)) {
5677 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; 5916 _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, St aticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.d isplayName]);
5678 // 5917 } else if (_enableHints && shouldReportMissingMember(propagatedType, propaga tedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, f alse)) {
5679 // If we are about to generate the hint (propagated version of this warning) , then check 5918 _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.element , HintCode.UNDEFINED_OPERATOR, node.operator, [methodName, propagatedType.displa yName]);
5680 // that the member is not in a subtype of the propagated type.
5681 //
5682 if (shouldReportMissingMember_propagated) {
5683 if (memberFoundInSubclass(propagatedType.element, methodName, true, false) ) {
5684 shouldReportMissingMember_propagated = false;
5685 }
5686 }
5687 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated ) {
5688 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
5689 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMem ber_static ? staticType.element : propagatedType.element, errorCode, node.operat or, [
5690 methodName,
5691 shouldReportMissingMember_static ? staticType.displayName : propagated Type.displayName]);
5692 } 5919 }
5693 return null; 5920 return null;
5694 } 5921 }
5695 5922
5696 Object visitPrefixedIdentifier(PrefixedIdentifier node) { 5923 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
5697 SimpleIdentifier prefix = node.prefix; 5924 SimpleIdentifier prefix = node.prefix;
5698 SimpleIdentifier identifier = node.identifier; 5925 SimpleIdentifier identifier = node.identifier;
5699 // 5926 //
5700 // First, check to see whether the prefix is really a prefix. 5927 // First, check to see whether the prefix is really a prefix.
5701 // 5928 //
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
5755 sc.TokenType operatorType = operator.type; 5982 sc.TokenType operatorType = operator.type;
5756 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { 5983 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) {
5757 Expression operand = node.operand; 5984 Expression operand = node.operand;
5758 String methodName = getPrefixOperator(node); 5985 String methodName = getPrefixOperator(node);
5759 Type2 staticType = getStaticType(operand); 5986 Type2 staticType = getStaticType(operand);
5760 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName) ; 5987 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName) ;
5761 node.staticElement = staticMethod; 5988 node.staticElement = staticMethod;
5762 Type2 propagatedType = getPropagatedType(operand); 5989 Type2 propagatedType = getPropagatedType(operand);
5763 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met hodName); 5990 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met hodName);
5764 node.propagatedElement = propagatedMethod; 5991 node.propagatedElement = propagatedMethod;
5765 bool shouldReportMissingMember_static = shouldReportMissingMember(staticTy pe, staticMethod); 5992 if (shouldReportMissingMember(staticType, staticMethod)) {
5766 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_sta tic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod ) : false; 5993 _resolver.reportErrorProxyConditionalAnalysisError3(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.disp layName]);
5767 // 5994 } else if (_enableHints && shouldReportMissingMember(propagatedType, propa gatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
5768 // If we are about to generate the hint (propagated version of this warnin g), then check 5995 _resolver.reportErrorProxyConditionalAnalysisError3(propagatedType.eleme nt, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayNa me]);
5769 // that the member is not in a subtype of the propagated type.
5770 //
5771 if (shouldReportMissingMember_propagated) {
5772 if (memberFoundInSubclass(propagatedType.element, methodName, true, fals e)) {
5773 shouldReportMissingMember_propagated = false;
5774 }
5775 }
5776 if (shouldReportMissingMember_static || shouldReportMissingMember_propagat ed) {
5777 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarn ingCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
5778 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingM ember_static ? staticType.element : propagatedType.element, errorCode, operator, [
5779 methodName,
5780 shouldReportMissingMember_static ? staticType.displayName : propagat edType.displayName]);
5781 } 5996 }
5782 } 5997 }
5783 return null; 5998 return null;
5784 } 5999 }
5785 6000
5786 Object visitPropertyAccess(PropertyAccess node) { 6001 Object visitPropertyAccess(PropertyAccess node) {
5787 Expression target = node.realTarget; 6002 Expression target = node.realTarget;
5788 if (target is SuperExpression && !isSuperInValidContext(target)) { 6003 if (target is SuperExpression && !isSuperInValidContext(target)) {
5789 return null; 6004 return null;
5790 } 6005 }
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
6047 * [StaticWarningCode#UNDEFINED_OPERATOR] is generated. 6262 * [StaticWarningCode#UNDEFINED_OPERATOR] is generated.
6048 * 6263 *
6049 * @param node the index expression to resolve 6264 * @param node the index expression to resolve
6050 * @param target the target of the expression 6265 * @param target the target of the expression
6051 * @param methodName the name of the operator associated with the context of u sing of the given 6266 * @param methodName the name of the operator associated with the context of u sing of the given
6052 * index expression 6267 * index expression
6053 * @return `true` if and only if an error code is generated on the passed node 6268 * @return `true` if and only if an error code is generated on the passed node
6054 */ 6269 */
6055 bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, S tring methodName, MethodElement staticMethod, MethodElement propagatedMethod, Ty pe2 staticType, Type2 propagatedType) { 6270 bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, S tring methodName, MethodElement staticMethod, MethodElement propagatedMethod, Ty pe2 staticType, Type2 propagatedType) {
6056 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType , staticMethod); 6271 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType , staticMethod);
6057 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod) : false; 6272 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati c && _enableHints && shouldReportMissingMember(propagatedType, propagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, false);
6058 //
6059 // If we are about to generate the hint (propagated version of this warning) , then check
6060 // that the member is not in a subtype of the propagated type.
6061 //
6062 if (shouldReportMissingMember_propagated) {
6063 if (memberFoundInSubclass(propagatedType.element, methodName, true, false) ) {
6064 shouldReportMissingMember_propagated = false;
6065 }
6066 }
6067 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated ) { 6273 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated ) {
6068 sc.Token leftBracket = node.leftBracket; 6274 sc.Token leftBracket = node.leftBracket;
6069 sc.Token rightBracket = node.rightBracket; 6275 sc.Token rightBracket = node.rightBracket;
6070 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; 6276 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode;
6071 if (leftBracket == null || rightBracket == null) { 6277 if (leftBracket == null || rightBracket == null) {
6072 _resolver.reportErrorProxyConditionalAnalysisError(shouldReportMissingMe mber_static ? staticType.element : propagatedType.element, errorCode, node, [ 6278 _resolver.reportErrorProxyConditionalAnalysisError(shouldReportMissingMe mber_static ? staticType.element : propagatedType.element, errorCode, node, [
6073 methodName, 6279 methodName,
6074 shouldReportMissingMember_static ? staticType.displayName : propagat edType.displayName]); 6280 shouldReportMissingMember_static ? staticType.displayName : propagat edType.displayName]);
6075 } else { 6281 } else {
6076 int offset = leftBracket.offset; 6282 int offset = leftBracket.offset;
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
6701 } else if (operator == sc.TokenType.PERCENT_EQ) { 6907 } else if (operator == sc.TokenType.PERCENT_EQ) {
6702 return sc.TokenType.PERCENT; 6908 return sc.TokenType.PERCENT;
6703 } else if (operator == sc.TokenType.PLUS_EQ) { 6909 } else if (operator == sc.TokenType.PLUS_EQ) {
6704 return sc.TokenType.PLUS; 6910 return sc.TokenType.PLUS;
6705 } else if (operator == sc.TokenType.SLASH_EQ) { 6911 } else if (operator == sc.TokenType.SLASH_EQ) {
6706 return sc.TokenType.SLASH; 6912 return sc.TokenType.SLASH;
6707 } else if (operator == sc.TokenType.STAR_EQ) { 6913 } else if (operator == sc.TokenType.STAR_EQ) {
6708 return sc.TokenType.STAR; 6914 return sc.TokenType.STAR;
6709 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) { 6915 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) {
6710 return sc.TokenType.TILDE_SLASH; 6916 return sc.TokenType.TILDE_SLASH;
6917 } else {
6918 // Internal error: Unmapped assignment operator.
6919 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme } to it's corresponding operator");
6920 return operator;
6711 } 6921 }
6712 break; 6922 break;
6713 } 6923 }
6714 // Internal error: Unmapped assignment operator.
6715 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
6716 return operator;
6717 } 6924 }
6718 6925
6719 void resolveAnnotationConstructorInvocationArguments(Annotation annotation, Co nstructorElement constructor) { 6926 void resolveAnnotationConstructorInvocationArguments(Annotation annotation, Co nstructorElement constructor) {
6720 ArgumentList argumentList = annotation.arguments; 6927 ArgumentList argumentList = annotation.arguments;
6721 // error will be reported in ConstantVerifier 6928 // error will be reported in ConstantVerifier
6722 if (argumentList == null) { 6929 if (argumentList == null) {
6723 return; 6930 return;
6724 } 6931 }
6725 // resolve arguments to parameters 6932 // resolve arguments to parameters
6726 List<ParameterElement> parameters = resolveArgumentsToParameters(true, argum entList, constructor); 6933 List<ParameterElement> parameters = resolveArgumentsToParameters(true, argum entList, constructor);
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
7479 } 7686 }
7480 7687
7481 /** 7688 /**
7482 * Instances of the class `InheritanceManager` manage the knowledge of where cla ss members 7689 * Instances of the class `InheritanceManager` manage the knowledge of where cla ss members
7483 * (methods, getters & setters) are inherited from. 7690 * (methods, getters & setters) are inherited from.
7484 * 7691 *
7485 * @coverage dart.engine.resolver 7692 * @coverage dart.engine.resolver
7486 */ 7693 */
7487 class InheritanceManager { 7694 class InheritanceManager {
7488 /** 7695 /**
7696 * Given some array of [ExecutableElement]s, this method creates a synthetic e lement as
7697 * described in the Superinterfaces section of Inheritance and Overriding.
7698 *
7699 * TODO (jwren) Copy contents from the Spec into this javadoc.
7700 *
7701 * TODO (jwren) Associate a propagated type to the synthetic method element us ing least upper
7702 * bound calls
7703 */
7704 static ExecutableElement computeMergedExecutableElement(List<ExecutableElement > elementArrayToMerge) {
7705 int h = getNumOfPositionalParameters(elementArrayToMerge[0]);
7706 int r = getNumOfRequiredParameters(elementArrayToMerge[0]);
7707 Set<String> namedParametersList = new Set<String>();
7708 for (int i = 1; i < elementArrayToMerge.length; i++) {
7709 ExecutableElement element = elementArrayToMerge[i];
7710 int numOfPositionalParams = getNumOfPositionalParameters(element);
7711 if (h < numOfPositionalParams) {
7712 h = numOfPositionalParams;
7713 }
7714 int numOfRequiredParams = getNumOfRequiredParameters(element);
7715 if (r > numOfRequiredParams) {
7716 r = numOfRequiredParams;
7717 }
7718 namedParametersList.addAll(getNamedParameterNames(element));
7719 }
7720 if (r > h) {
7721 return null;
7722 }
7723 return createSyntheticExecutableElement(elementArrayToMerge, elementArrayToM erge[0].displayName, r, h - r, new List.from(namedParametersList));
7724 }
7725
7726 /**
7727 * Used by [computeMergedExecutableElement] to actually create the
7728 * synthetic element.
7729 *
7730 * @param elementArrayToMerge the array used to create the synthetic element
7731 * @param name the name of the method, getter or setter
7732 * @param numOfRequiredParameters the number of required parameters
7733 * @param numOfPositionalParameters the number of positional parameters
7734 * @param namedParameters the list of [String]s that are the named parameters
7735 * @return the created synthetic element
7736 */
7737 static ExecutableElement createSyntheticExecutableElement(List<ExecutableEleme nt> elementArrayToMerge, String name, int numOfRequiredParameters, int numOfPosi tionalParameters, List<String> namedParameters) {
7738 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
7739 SimpleIdentifier nameIdentifier = new SimpleIdentifier(new sc.StringToken(sc .TokenType.IDENTIFIER, name, 0));
7740 ExecutableElementImpl executable;
7741 if (elementArrayToMerge[0] is MethodElement) {
7742 MultiplyInheritedMethodElementImpl unionedMethod = new MultiplyInheritedMe thodElementImpl(nameIdentifier);
7743 unionedMethod.inheritedElements = elementArrayToMerge;
7744 executable = unionedMethod;
7745 } else {
7746 MultiplyInheritedPropertyAccessorElementImpl unionedPropertyAccessor = new MultiplyInheritedPropertyAccessorElementImpl(nameIdentifier);
7747 unionedPropertyAccessor.getter = (elementArrayToMerge[0] as PropertyAccess orElement).isGetter;
7748 unionedPropertyAccessor.setter = (elementArrayToMerge[0] as PropertyAccess orElement).isSetter;
7749 unionedPropertyAccessor.inheritedElements = elementArrayToMerge;
7750 executable = unionedPropertyAccessor;
7751 }
7752 int numOfParameters = numOfRequiredParameters + numOfPositionalParameters + namedParameters.length;
7753 List<ParameterElement> parameters = new List<ParameterElement>(numOfParamete rs);
7754 int i = 0;
7755 for (int j = 0; j < numOfRequiredParameters; j++, i++) {
7756 ParameterElementImpl parameter = new ParameterElementImpl.con2("", 0);
7757 parameter.type = dynamicType;
7758 parameter.parameterKind = ParameterKind.REQUIRED;
7759 parameters[i] = parameter;
7760 }
7761 for (int k = 0; k < numOfPositionalParameters; k++, i++) {
7762 ParameterElementImpl parameter = new ParameterElementImpl.con2("", 0);
7763 parameter.type = dynamicType;
7764 parameter.parameterKind = ParameterKind.POSITIONAL;
7765 parameters[i] = parameter;
7766 }
7767 for (int m = 0; m < namedParameters.length; m++, i++) {
7768 ParameterElementImpl parameter = new ParameterElementImpl.con2(namedParame ters[m], 0);
7769 parameter.type = dynamicType;
7770 parameter.parameterKind = ParameterKind.NAMED;
7771 parameters[i] = parameter;
7772 }
7773 executable.returnType = dynamicType;
7774 executable.parameters = parameters;
7775 FunctionTypeImpl methodType = new FunctionTypeImpl.con1(executable);
7776 executable.type = methodType;
7777 return executable;
7778 }
7779
7780 /**
7781 * Given some [ExecutableElement], return the list of named parameters.
7782 */
7783 static List<String> getNamedParameterNames(ExecutableElement executableElement ) {
7784 List<String> namedParameterNames = new List<String>();
7785 List<ParameterElement> parameters = executableElement.parameters;
7786 for (int i = 0; i < parameters.length; i++) {
7787 ParameterElement parameterElement = parameters[i];
7788 if (identical(parameterElement.parameterKind, ParameterKind.NAMED)) {
7789 namedParameterNames.add(parameterElement.name);
7790 }
7791 }
7792 return namedParameterNames;
7793 }
7794
7795 /**
7796 * Given some [ExecutableElement] return the number of parameters of the speci fied kind.
7797 */
7798 static int getNumOfParameters(ExecutableElement executableElement, ParameterKi nd parameterKind) {
7799 int parameterCount = 0;
7800 List<ParameterElement> parameters = executableElement.parameters;
7801 for (int i = 0; i < parameters.length; i++) {
7802 ParameterElement parameterElement = parameters[i];
7803 if (identical(parameterElement.parameterKind, parameterKind)) {
7804 parameterCount++;
7805 }
7806 }
7807 return parameterCount;
7808 }
7809
7810 /**
7811 * Given some [ExecutableElement] return the number of positional parameters.
7812 *
7813 * Note: by positional we mean [ParameterKind#REQUIRED] or [ParameterKind#POSI TIONAL].
7814 */
7815 static int getNumOfPositionalParameters(ExecutableElement executableElement) = > getNumOfParameters(executableElement, ParameterKind.REQUIRED) + getNumOfParame ters(executableElement, ParameterKind.POSITIONAL);
7816
7817 /**
7818 * Given some [ExecutableElement] return the number of required parameters.
7819 */
7820 static int getNumOfRequiredParameters(ExecutableElement executableElement) => getNumOfParameters(executableElement, ParameterKind.REQUIRED);
7821
7822 /**
7489 * The [LibraryElement] that is managed by this manager. 7823 * The [LibraryElement] that is managed by this manager.
7490 */ 7824 */
7491 LibraryElement _library; 7825 LibraryElement _library;
7492 7826
7493 /** 7827 /**
7494 * This is a mapping between each [ClassElement] and a map between the [String ] member 7828 * This is a mapping between each [ClassElement] and a map between the [String ] member
7495 * names and the associated [ExecutableElement] in the mixin and superclass ch ain. 7829 * names and the associated [ExecutableElement] in the mixin and superclass ch ain.
7496 */ 7830 */
7497 Map<ClassElement, MemberMap> _classLookup; 7831 Map<ClassElement, MemberMap> _classLookup;
7498 7832
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
7693 // 8027 //
7694 // Include the members from the superclass in the resultMap 8028 // Include the members from the superclass in the resultMap
7695 // 8029 //
7696 recordMapWithClassMembers(resultMap, supertype); 8030 recordMapWithClassMembers(resultMap, supertype);
7697 } 8031 }
7698 // 8032 //
7699 // Include the members from the mixins in the resultMap 8033 // Include the members from the mixins in the resultMap
7700 // 8034 //
7701 List<InterfaceType> mixins = classElt.mixins; 8035 List<InterfaceType> mixins = classElt.mixins;
7702 for (int i = mixins.length - 1; i >= 0; i--) { 8036 for (int i = mixins.length - 1; i >= 0; i--) {
7703 recordMapWithClassMembers(resultMap, mixins[i]); 8037 recordMapWithClassMembersFromMixin(resultMap, mixins[i]);
7704 } 8038 }
7705 _classLookup[classElt] = resultMap; 8039 _classLookup[classElt] = resultMap;
7706 return resultMap; 8040 return resultMap;
7707 } 8041 }
7708 8042
7709 /** 8043 /**
7710 * Compute and return the inheritance path given the context of a type and a m ember that is 8044 * Compute and return the inheritance path given the context of a type and a m ember that is
7711 * overridden in the inheritance path (for which the type is in the path). 8045 * overridden in the inheritance path (for which the type is in the path).
7712 * 8046 *
7713 * @param chain the inheritance path that is built up as this method calls its elf recursively, 8047 * @param chain the inheritance path that is built up as this method calls its elf recursively,
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
7861 return resultMap; 8195 return resultMap;
7862 } 8196 }
7863 } 8197 }
7864 } 8198 }
7865 } 8199 }
7866 if (lookupMaps.length == 0) { 8200 if (lookupMaps.length == 0) {
7867 _interfaceLookup[classElt] = resultMap; 8201 _interfaceLookup[classElt] = resultMap;
7868 return resultMap; 8202 return resultMap;
7869 } 8203 }
7870 // 8204 //
7871 // Union all of the maps together, grouping the ExecutableElements into sets . 8205 // Union all of the lookupMaps together into unionMap, grouping the Executab leElements into a
8206 // list where none of the elements are equal where equality is determined by having equal
8207 // function types. (We also take note too of the kind of the element: ()->in t and () -> int may
8208 // not be equal if one is a getter and the other is a method.)
7872 // 8209 //
7873 Map<String, Set<ExecutableElement>> unionMap = new Map<String, Set<Executabl eElement>>(); 8210 Map<String, List<ExecutableElement>> unionMap = new Map<String, List<Executa bleElement>>();
7874 for (MemberMap lookupMap in lookupMaps) { 8211 for (MemberMap lookupMap in lookupMaps) {
7875 for (int i = 0; i < lookupMap.size; i++) { 8212 int lookupMapSize = lookupMap.size;
8213 for (int i = 0; i < lookupMapSize; i++) {
8214 // Get the string key, if null, break.
7876 String key = lookupMap.getKey(i); 8215 String key = lookupMap.getKey(i);
7877 if (key == null) { 8216 if (key == null) {
7878 break; 8217 break;
7879 } 8218 }
7880 Set<ExecutableElement> set = unionMap[key]; 8219 // Get the list value out of the unionMap
7881 if (set == null) { 8220 List<ExecutableElement> list = unionMap[key];
7882 set = new Set<ExecutableElement>(); 8221 // If we haven't created such a map for this key yet, do create it and p ut the list entry
7883 unionMap[key] = set; 8222 // into the unionMap.
8223 if (list == null) {
8224 list = new List<ExecutableElement>();
8225 unionMap[key] = list;
7884 } 8226 }
7885 set.add(lookupMap.getValue(i)); 8227 // Fetch the entry out of this lookupMap
8228 ExecutableElement newExecutableElementEntry = lookupMap.getValue(i);
8229 if (list.isEmpty) {
8230 // If the list is empty, just the new value
8231 list.add(newExecutableElementEntry);
8232 } else {
8233 // Otherwise, only add the newExecutableElementEntry if it isn't alrea dy in the list, this
8234 // covers situation where a class inherits two methods (or two getters ) that are
8235 // identical.
8236 bool alreadyInList = false;
8237 bool isMethod1 = newExecutableElementEntry is MethodElement;
8238 for (ExecutableElement executableElementInList in list) {
8239 bool isMethod2 = executableElementInList is MethodElement;
8240 if (identical(isMethod1, isMethod2) && executableElementInList.type == newExecutableElementEntry.type) {
8241 alreadyInList = true;
8242 break;
8243 }
8244 }
8245 if (!alreadyInList) {
8246 list.add(newExecutableElementEntry);
8247 }
8248 }
7886 } 8249 }
7887 } 8250 }
7888 // 8251 //
7889 // Loop through the entries in the union map, adding them to the resultMap a ppropriately. 8252 // Loop through the entries in the unionMap, adding them to the resultMap ap propriately.
7890 // 8253 //
7891 for (MapEntry<String, Set<ExecutableElement>> entry in getMapEntrySet(unionM ap)) { 8254 for (MapEntry<String, List<ExecutableElement>> entry in getMapEntrySet(union Map)) {
7892 String key = entry.getKey(); 8255 String key = entry.getKey();
7893 Set<ExecutableElement> set = entry.getValue(); 8256 List<ExecutableElement> list = entry.getValue();
7894 int numOfEltsWithMatchingNames = set.length; 8257 int numOfEltsWithMatchingNames = list.length;
7895 if (numOfEltsWithMatchingNames == 1) { 8258 if (numOfEltsWithMatchingNames == 1) {
7896 resultMap.put(key, new JavaIterator(set).next()); 8259 //
8260 // Example: class A inherits only 1 method named 'm'. Since it is the o nly such method, it
8261 // is inherited.
8262 // Another example: class A inherits 2 methods named 'm' from 2 differen t interfaces, but
8263 // they both have the same signature, so it is the method inherited.
8264 //
8265 resultMap.put(key, list[0]);
7897 } else { 8266 } else {
8267 //
8268 // Then numOfEltsWithMatchingNames > 1, check for the warning cases.
8269 //
7898 bool allMethods = true; 8270 bool allMethods = true;
7899 bool allSetters = true; 8271 bool allSetters = true;
7900 bool allGetters = true; 8272 bool allGetters = true;
7901 for (ExecutableElement executableElement in set) { 8273 for (ExecutableElement executableElement in list) {
7902 if (executableElement is PropertyAccessorElement) { 8274 if (executableElement is PropertyAccessorElement) {
7903 allMethods = false; 8275 allMethods = false;
7904 if (executableElement.isSetter) { 8276 if (executableElement.isSetter) {
7905 allGetters = false; 8277 allGetters = false;
7906 } else { 8278 } else {
7907 allSetters = false; 8279 allSetters = false;
7908 } 8280 }
7909 } else { 8281 } else {
7910 allGetters = false; 8282 allGetters = false;
7911 allSetters = false; 8283 allSetters = false;
7912 } 8284 }
7913 } 8285 }
8286 //
8287 // If there isn't a mixture of methods with getters, then continue, othe rwise create a
8288 // warning.
8289 //
7914 if (allMethods || allGetters || allSetters) { 8290 if (allMethods || allGetters || allSetters) {
8291 //
7915 // Compute the element whose type is the subtype of all of the other t ypes. 8292 // Compute the element whose type is the subtype of all of the other t ypes.
7916 List<ExecutableElement> elements = new List.from(set); 8293 //
8294 List<ExecutableElement> elements = new List.from(list);
7917 List<FunctionType> executableElementTypes = new List<FunctionType>(num OfEltsWithMatchingNames); 8295 List<FunctionType> executableElementTypes = new List<FunctionType>(num OfEltsWithMatchingNames);
7918 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { 8296 for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
7919 executableElementTypes[i] = elements[i].type; 8297 executableElementTypes[i] = elements[i].type;
7920 } 8298 }
7921 bool foundSubtypeOfAllTypes = false; 8299 List<int> subtypesOfAllOtherTypesIndexes = new List<int>();
7922 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { 8300 for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
7923 FunctionType subtype = executableElementTypes[i]; 8301 FunctionType subtype = executableElementTypes[i];
7924 if (subtype == null) { 8302 if (subtype == null) {
7925 continue; 8303 continue;
7926 } 8304 }
7927 bool subtypeOfAllTypes = true; 8305 bool subtypeOfAllTypes = true;
7928 for (int j = 0; j < numOfEltsWithMatchingNames && subtypeOfAllTypes; j++) { 8306 for (int j = 0; j < numOfEltsWithMatchingNames && subtypeOfAllTypes; j++) {
7929 if (i != j) { 8307 if (i != j) {
7930 if (!subtype.isSubtypeOf(executableElementTypes[j])) { 8308 if (!subtype.isSubtypeOf(executableElementTypes[j])) {
7931 subtypeOfAllTypes = false; 8309 subtypeOfAllTypes = false;
7932 break; 8310 break;
7933 } 8311 }
7934 } 8312 }
7935 } 8313 }
7936 if (subtypeOfAllTypes) { 8314 if (subtypeOfAllTypes) {
7937 foundSubtypeOfAllTypes = true; 8315 subtypesOfAllOtherTypesIndexes.add(i);
7938 resultMap.put(key, elements[i]);
7939 break;
7940 } 8316 }
7941 } 8317 }
7942 if (!foundSubtypeOfAllTypes) { 8318 //
7943 reportError(classElt, classElt.nameOffset, classElt.displayName.leng th, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key]); 8319 // The following is split into three cases determined by the number of elements in subtypesOfAllOtherTypes
8320 //
8321 if (subtypesOfAllOtherTypesIndexes.length == 1) {
8322 //
8323 // Example: class A inherited only 2 method named 'm'. One has the f unction type
8324 // '() -> dynamic' and one has the function type '([int]) -> dynamic '. Since the second
8325 // method is a subtype of all the others, it is the inherited method .
8326 // Tests: InheritanceManagerTest.test_getMapOfMembersInheritedFromIn terfaces_union_oneSubtype_*
8327 //
8328 resultMap.put(key, elements[subtypesOfAllOtherTypesIndexes[0]]);
8329 } else {
8330 if (subtypesOfAllOtherTypesIndexes.isEmpty) {
8331 //
8332 // Example: class A inherited only 2 method named 'm'. One has the function type
8333 // '() -> int' and one has the function type '() -> String'. Since neither is a subtype
8334 // of the other, we create a warning, and have this class inherit nothing.
8335 //
8336 String firstTwoFuntionTypesStr = "${executableElementTypes[0].toSt ring()}, ${executableElementTypes[1].toString()}";
8337 reportError(classElt, classElt.nameOffset, classElt.displayName.le ngth, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFunti onTypesStr]);
8338 } else {
8339 //
8340 // Example: class A inherits 2 methods named 'm'. One has the func tion type
8341 // '(int) -> dynamic' and one has the function type '(num) -> dyna mic'. Since they are
8342 // both a subtype of the other, a synthetic function '(dynamic) -> dynamic' is
8343 // inherited.
8344 // Tests: test_getMapOfMembersInheritedFromInterfaces_union_multip leSubtypes_*
8345 //
8346 List<ExecutableElement> elementArrayToMerge = new List<ExecutableE lement>(subtypesOfAllOtherTypesIndexes.length);
8347 for (int i = 0; i < elementArrayToMerge.length; i++) {
8348 elementArrayToMerge[i] = elements[subtypesOfAllOtherTypesIndexes [i]];
8349 }
8350 ExecutableElement mergedExecutableElement = computeMergedExecutabl eElement(elementArrayToMerge);
8351 if (mergedExecutableElement != null) {
8352 resultMap.put(key, mergedExecutableElement);
8353 }
8354 }
7944 } 8355 }
7945 } else { 8356 } else {
7946 if (!allMethods && !allGetters) { 8357 reportError(classElt, classElt.nameOffset, classElt.displayName.length , StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]);
7947 reportError(classElt, classElt.nameOffset, classElt.displayName.leng th, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]);
7948 }
7949 resultMap.remove(entry.getKey());
7950 } 8358 }
7951 } 8359 }
7952 } 8360 }
7953 _interfaceLookup[classElt] = resultMap; 8361 _interfaceLookup[classElt] = resultMap;
7954 return resultMap; 8362 return resultMap;
7955 } 8363 }
7956 8364
7957 /** 8365 /**
7958 * Given some [ClassElement], this method finds and returns the [ExecutableEle ment] of 8366 * Given some [ClassElement], this method finds and returns the [ExecutableEle ment] of
7959 * the passed name in the class element. Static members, members in super type s and members not 8367 * the passed name in the class element. Static members, members in super type s and members not
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
7996 } 8404 }
7997 List<PropertyAccessorElement> accessors = type.accessors; 8405 List<PropertyAccessorElement> accessors = type.accessors;
7998 for (PropertyAccessorElement accessor in accessors) { 8406 for (PropertyAccessorElement accessor in accessors) {
7999 if (accessor.isAccessibleIn(_library) && !accessor.isStatic) { 8407 if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
8000 map.put(accessor.name, accessor); 8408 map.put(accessor.name, accessor);
8001 } 8409 }
8002 } 8410 }
8003 } 8411 }
8004 8412
8005 /** 8413 /**
8414 * Similar to [recordMapWithClassMembers], but only puts values
8415 * into the map if the additional executable doesn't replace a concrete member with an abstract
8416 * member, ex: NonErrorResolverTest.test_nonAbstractClassInheritsAbstractMembe rOne_mixin_*()
8417 *
8418 * @param map some non-`null` map to put the methods and accessors from the pa ssed
8419 * [ClassElement] into
8420 * @param type the type that will be recorded into the passed map
8421 */
8422 void recordMapWithClassMembersFromMixin(MemberMap map, InterfaceType type) {
8423 List<MethodElement> methods = type.methods;
8424 for (MethodElement method in methods) {
8425 if (method.isAccessibleIn(_library) && !method.isStatic) {
8426 String methodName = method.name;
8427 ExecutableElement elementInMap = map.get(methodName);
8428 if (elementInMap == null || (elementInMap != null && !method.isAbstract) ) {
8429 map.put(methodName, method);
8430 }
8431 }
8432 }
8433 List<PropertyAccessorElement> accessors = type.accessors;
8434 for (PropertyAccessorElement accessor in accessors) {
8435 if (accessor.isAccessibleIn(_library) && !accessor.isStatic) {
8436 String accessorName = accessor.name;
8437 ExecutableElement elementInMap = map.get(accessorName);
8438 if (elementInMap == null || (elementInMap != null && !accessor.isAbstrac t)) {
8439 map.put(accessorName, accessor);
8440 }
8441 }
8442 }
8443 }
8444
8445 /**
8006 * This method is used to report errors on when they are found computing inher itance information. 8446 * This method is used to report errors on when they are found computing inher itance information.
8007 * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where thes e generated 8447 * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where thes e generated
8008 * error codes are reported back into the analysis engine. 8448 * error codes are reported back into the analysis engine.
8009 * 8449 *
8010 * @param classElt the location of the source for which the exception occurred 8450 * @param classElt the location of the source for which the exception occurred
8011 * @param offset the offset of the location of the error 8451 * @param offset the offset of the location of the error
8012 * @param length the length of the location of the error 8452 * @param length the length of the location of the error
8013 * @param errorCode the error code to be associated with this error 8453 * @param errorCode the error code to be associated with this error
8014 * @param arguments the arguments used to build the error message 8454 * @param arguments the arguments used to build the error message
8015 */ 8455 */
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
8285 String uriContent = uriLiteral.stringValue.trim(); 8725 String uriContent = uriLiteral.stringValue.trim();
8286 _directiveUris[directive] = uriContent; 8726 _directiveUris[directive] = uriContent;
8287 uriContent = Uri.encodeFull(uriContent); 8727 uriContent = Uri.encodeFull(uriContent);
8288 if (directive is ImportDirective && uriContent.startsWith(_DART_EXT_SCHEME)) { 8728 if (directive is ImportDirective && uriContent.startsWith(_DART_EXT_SCHEME)) {
8289 _libraryElement.hasExtUri2 = true; 8729 _libraryElement.hasExtUri2 = true;
8290 return null; 8730 return null;
8291 } 8731 }
8292 try { 8732 try {
8293 parseUriWithException(uriContent); 8733 parseUriWithException(uriContent);
8294 Source source = _analysisContext.sourceFactory.resolveUri(librarySource, u riContent); 8734 Source source = _analysisContext.sourceFactory.resolveUri(librarySource, u riContent);
8295 if (source == null || !source.exists()) { 8735 if (!_analysisContext.exists(source)) {
8296 _errorListener.onError(new AnalysisError.con2(librarySource, uriLiteral. offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent] )); 8736 _errorListener.onError(new AnalysisError.con2(librarySource, uriLiteral. offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent] ));
8297 } 8737 }
8298 return source; 8738 return source;
8299 } on URISyntaxException catch (exception) { 8739 } on URISyntaxException catch (exception) {
8300 _errorListener.onError(new AnalysisError.con2(librarySource, uriLiteral.of fset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent])); 8740 _errorListener.onError(new AnalysisError.con2(librarySource, uriLiteral.of fset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
8301 } 8741 }
8302 return null; 8742 return null;
8303 } 8743 }
8304 8744
8305 /** 8745 /**
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
8364 InternalAnalysisContext _analysisContext; 8804 InternalAnalysisContext _analysisContext;
8365 8805
8366 /** 8806 /**
8367 * The listener to which errors will be reported. 8807 * The listener to which errors will be reported.
8368 */ 8808 */
8369 AnalysisErrorListener _errorListener; 8809 AnalysisErrorListener _errorListener;
8370 8810
8371 /** 8811 /**
8372 * The name of the function used as an entry point. 8812 * The name of the function used as an entry point.
8373 */ 8813 */
8374 static String _ENTRY_POINT_NAME = "main"; 8814 static String ENTRY_POINT_NAME = "main";
8375 8815
8376 /** 8816 /**
8377 * Initialize a newly created library element builder. 8817 * Initialize a newly created library element builder.
8378 * 8818 *
8379 * @param resolver the resolver for which the element model is being built 8819 * @param resolver the resolver for which the element model is being built
8380 */ 8820 */
8381 LibraryElementBuilder(LibraryResolver resolver) { 8821 LibraryElementBuilder(LibraryResolver resolver) {
8382 this._analysisContext = resolver.analysisContext; 8822 this._analysisContext = resolver.analysisContext;
8383 this._errorListener = resolver.errorListener; 8823 this._errorListener = resolver.errorListener;
8384 } 8824 }
(...skipping 25 matching lines...) Expand all
8410 // 8850 //
8411 if (directive is LibraryDirective) { 8851 if (directive is LibraryDirective) {
8412 if (libraryNameNode == null) { 8852 if (libraryNameNode == null) {
8413 libraryNameNode = directive.name; 8853 libraryNameNode = directive.name;
8414 directivesToResolve.add(directive); 8854 directivesToResolve.add(directive);
8415 } 8855 }
8416 } else if (directive is PartDirective) { 8856 } else if (directive is PartDirective) {
8417 PartDirective partDirective = directive; 8857 PartDirective partDirective = directive;
8418 StringLiteral partUri = partDirective.uri; 8858 StringLiteral partUri = partDirective.uri;
8419 Source partSource = library.getSource(partDirective); 8859 Source partSource = library.getSource(partDirective);
8420 if (partSource != null && partSource.exists()) { 8860 if (_analysisContext.exists(partSource)) {
8421 hasPartDirective = true; 8861 hasPartDirective = true;
8422 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou rce, library.getAST(partSource)); 8862 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou rce, library.getAST(partSource));
8423 part.uri = library.getUri(partDirective); 8863 part.uri = library.getUri(partDirective);
8424 // 8864 //
8425 // Validate that the part contains a part-of directive with the same n ame as the library. 8865 // Validate that the part contains a part-of directive with the same n ame as the library.
8426 // 8866 //
8427 String partLibraryName = getPartLibraryName(library, partSource, direc tivesToResolve); 8867 String partLibraryName = getPartLibraryName(library, partSource, direc tivesToResolve);
8428 if (partLibraryName == null) { 8868 if (partLibraryName == null) {
8429 _errorListener.onError(new AnalysisError.con2(librarySource, partUri .offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSourc e()])); 8869 _errorListener.onError(new AnalysisError.con2(librarySource, partUri .offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSourc e()]));
8430 } else if (libraryNameNode == null) { 8870 } else if (libraryNameNode == null) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
8486 8926
8487 /** 8927 /**
8488 * Search the top-level functions defined in the given compilation unit for th e entry point. 8928 * Search the top-level functions defined in the given compilation unit for th e entry point.
8489 * 8929 *
8490 * @param element the compilation unit to be searched 8930 * @param element the compilation unit to be searched
8491 * @return the entry point that was found, or `null` if the compilation unit d oes not define 8931 * @return the entry point that was found, or `null` if the compilation unit d oes not define
8492 * an entry point 8932 * an entry point
8493 */ 8933 */
8494 FunctionElement findEntryPoint(CompilationUnitElementImpl element) { 8934 FunctionElement findEntryPoint(CompilationUnitElementImpl element) {
8495 for (FunctionElement function in element.functions) { 8935 for (FunctionElement function in element.functions) {
8496 if (function.name == _ENTRY_POINT_NAME) { 8936 if (function.name == ENTRY_POINT_NAME) {
8497 return function; 8937 return function;
8498 } 8938 }
8499 } 8939 }
8500 return null; 8940 return null;
8501 } 8941 }
8502 8942
8503 /** 8943 /**
8504 * Return the name of the library that the given part is declared to be a part of, or `null` 8944 * Return the name of the library that the given part is declared to be a part of, or `null`
8505 * if the part does not contain a part-of directive. 8945 * if the part does not contain a part-of directive.
8506 * 8946 *
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
8948 Source librarySource = library.librarySource; 9388 Source librarySource = library.librarySource;
8949 if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource) { 9389 if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource) {
8950 ImportElementImpl importElement = new ImportElementImpl(-1); 9390 ImportElementImpl importElement = new ImportElementImpl(-1);
8951 importElement.importedLibrary = _coreLibrary.libraryElement; 9391 importElement.importedLibrary = _coreLibrary.libraryElement;
8952 importElement.synthetic = true; 9392 importElement.synthetic = true;
8953 imports.add(importElement); 9393 imports.add(importElement);
8954 } 9394 }
8955 LibraryElementImpl libraryElement = library.libraryElement; 9395 LibraryElementImpl libraryElement = library.libraryElement;
8956 libraryElement.imports = new List.from(imports); 9396 libraryElement.imports = new List.from(imports);
8957 libraryElement.exports = new List.from(exports); 9397 libraryElement.exports = new List.from(exports);
9398 if (libraryElement.entryPoint == null) {
9399 Namespace namespace = new NamespaceBuilder().createExportNamespace2(libr aryElement);
9400 Element element = namespace.get(LibraryElementBuilder.ENTRY_POINT_NAME);
9401 if (element is FunctionElement) {
9402 libraryElement.entryPoint = element;
9403 }
9404 }
8958 } 9405 }
8959 } 9406 }
8960 9407
8961 /** 9408 /**
8962 * Build element models for all of the libraries in the current cycle. 9409 * Build element models for all of the libraries in the current cycle.
8963 * 9410 *
8964 * @throws AnalysisException if any of the element models cannot be built 9411 * @throws AnalysisException if any of the element models cannot be built
8965 */ 9412 */
8966 void buildElementModels() { 9413 void buildElementModels() {
8967 for (Library library in _librariesInCycles) { 9414 for (Library library in _librariesInCycles) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
9119 /** 9566 /**
9120 * Create an object to represent the information about the library defined by the compilation unit 9567 * Create an object to represent the information about the library defined by the compilation unit
9121 * with the given source. 9568 * with the given source.
9122 * 9569 *
9123 * @param librarySource the source of the library's defining compilation unit 9570 * @param librarySource the source of the library's defining compilation unit
9124 * @return the library object that was created 9571 * @return the library object that was created
9125 * @throws AnalysisException if the library source is not valid 9572 * @throws AnalysisException if the library source is not valid
9126 */ 9573 */
9127 Library createLibrary(Source librarySource) { 9574 Library createLibrary(Source librarySource) {
9128 Library library = new Library(analysisContext, _errorListener, librarySource ); 9575 Library library = new Library(analysisContext, _errorListener, librarySource );
9129 library.definingCompilationUnit;
9130 _libraryMap[librarySource] = library; 9576 _libraryMap[librarySource] = library;
9131 return library; 9577 return library;
9132 } 9578 }
9133 9579
9134 /** 9580 /**
9135 * Create an object to represent the information about the library defined by the compilation unit 9581 * Create an object to represent the information about the library defined by the compilation unit
9136 * with the given source. 9582 * with the given source.
9137 * 9583 *
9138 * @param librarySource the source of the library's defining compilation unit 9584 * @param librarySource the source of the library's defining compilation unit
9139 * @param modificationStamp the modification time of the source from which the compilation unit 9585 * @param modificationStamp the modification time of the source from which the compilation unit
(...skipping 11 matching lines...) Expand all
9151 9597
9152 /** 9598 /**
9153 * Create an object to represent the information about the library defined by the compilation unit 9599 * Create an object to represent the information about the library defined by the compilation unit
9154 * with the given source. Return the library object that was created, or `null ` if the 9600 * with the given source. Return the library object that was created, or `null ` if the
9155 * source is not valid. 9601 * source is not valid.
9156 * 9602 *
9157 * @param librarySource the source of the library's defining compilation unit 9603 * @param librarySource the source of the library's defining compilation unit
9158 * @return the library object that was created 9604 * @return the library object that was created
9159 */ 9605 */
9160 Library createLibraryOrNull(Source librarySource) { 9606 Library createLibraryOrNull(Source librarySource) {
9161 if (!librarySource.exists()) { 9607 if (!analysisContext.exists(librarySource)) {
9162 return null; 9608 return null;
9163 } 9609 }
9164 Library library = new Library(analysisContext, _errorListener, librarySource ); 9610 Library library = new Library(analysisContext, _errorListener, librarySource );
9165 _libraryMap[librarySource] = library; 9611 _libraryMap[librarySource] = library;
9166 return library; 9612 return library;
9167 } 9613 }
9168 9614
9169 /** 9615 /**
9170 * Return an array containing the lexical identifiers associated with the node s in the given list. 9616 * Return an array containing the lexical identifiers associated with the node s in the given list.
9171 * 9617 *
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
9240 } 9686 }
9241 } 9687 }
9242 } finally { 9688 } finally {
9243 timeCounter.stop(); 9689 timeCounter.stop();
9244 } 9690 }
9245 // Angular 9691 // Angular
9246 timeCounter = PerformanceStatistics.angular.start(); 9692 timeCounter = PerformanceStatistics.angular.start();
9247 try { 9693 try {
9248 for (Source source in library.compilationUnitSources) { 9694 for (Source source in library.compilationUnitSources) {
9249 CompilationUnit ast = library.getAST(source); 9695 CompilationUnit ast = library.getAST(source);
9250 new AngularCompilationUnitBuilder(_errorListener, source).build(ast); 9696 new AngularCompilationUnitBuilder(_errorListener, source, ast).build();
9251 } 9697 }
9252 } finally { 9698 } finally {
9253 timeCounter.stop(); 9699 timeCounter.stop();
9254 } 9700 }
9255 } 9701 }
9256 9702
9257 /** 9703 /**
9258 * Return the result of resolving the URI of the given URI-based directive aga inst the URI of the 9704 * Return the result of resolving the URI of the given URI-based directive aga inst the URI of the
9259 * given library, or `null` if the URI is not valid. 9705 * given library, or `null` if the URI is not valid.
9260 * 9706 *
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
9443 * This class is a wrapper for an [AnalysisError] which can also be queried afte r resolution 9889 * This class is a wrapper for an [AnalysisError] which can also be queried afte r resolution
9444 * to find out if the error should actually be reported. In this case, these err ors are conditional 9890 * to find out if the error should actually be reported. In this case, these err ors are conditional
9445 * on the non-existence of an `@proxy` annotation. 9891 * on the non-existence of an `@proxy` annotation.
9446 * 9892 *
9447 * If we have other conditional error codes in the future, we should have this c lass implement some 9893 * If we have other conditional error codes in the future, we should have this c lass implement some
9448 * ConditionalErrorCode so that after resolution, a list of ConditionalErrorCode can be visited 9894 * ConditionalErrorCode so that after resolution, a list of ConditionalErrorCode can be visited
9449 * instead of multiple lists of *ConditionalErrorCodes. 9895 * instead of multiple lists of *ConditionalErrorCodes.
9450 */ 9896 */
9451 class ProxyConditionalAnalysisError { 9897 class ProxyConditionalAnalysisError {
9452 /** 9898 /**
9453 * Return `true` if the given element represents a class that has the proxy an notation.
9454 *
9455 * @param element the class being tested
9456 * @return `true` if the given element represents a class that has the proxy a nnotation
9457 */
9458 static bool classHasProxyAnnotation(Element element) => (element is ClassEleme nt) && element.isProxy;
9459
9460 /**
9461 * The enclosing [ClassElement], this is what will determine if the error code should, or 9899 * The enclosing [ClassElement], this is what will determine if the error code should, or
9462 * should not, be generated on the source. 9900 * should not, be generated on the source.
9463 */ 9901 */
9464 Element _enclosingElement; 9902 Element _enclosingElement;
9465 9903
9466 /** 9904 /**
9467 * The conditional analysis error. 9905 * The conditional analysis error.
9468 */ 9906 */
9469 final AnalysisError analysisError; 9907 final AnalysisError analysisError;
9470 9908
9471 /** 9909 /**
9472 * Instantiate a new ProxyConditionalErrorCode with some enclosing element and the conditional 9910 * Instantiate a new [ProxyConditionalAnalysisError] with some enclosing eleme nt and the
9473 * analysis error. 9911 * conditional analysis error.
9474 * 9912 *
9475 * @param enclosingElement the enclosing element 9913 * @param enclosingElement the enclosing element
9476 * @param analysisError the conditional analysis error 9914 * @param analysisError the conditional analysis error
9477 */ 9915 */
9478 ProxyConditionalAnalysisError(Element enclosingElement, this.analysisError) { 9916 ProxyConditionalAnalysisError(Element enclosingElement, this.analysisError) {
9479 this._enclosingElement = enclosingElement; 9917 this._enclosingElement = enclosingElement;
9480 } 9918 }
9481 9919
9482 /** 9920 /**
9483 * Return `true` iff the enclosing class has the proxy annotation. 9921 * Return `true` iff the enclosing class has the proxy annotation.
9484 * 9922 *
9485 * @return `true` iff the enclosing class has the proxy annotation 9923 * @return `true` iff the enclosing class has the proxy annotation
9486 */ 9924 */
9487 bool shouldIncludeErrorCode() => !classHasProxyAnnotation(_enclosingElement); 9925 bool shouldIncludeErrorCode() {
9926 if (_enclosingElement is ClassElement) {
9927 return !(_enclosingElement as ClassElement).isOrInheritsProxy;
9928 }
9929 return true;
9930 }
9488 } 9931 }
9489 9932
9490 /** 9933 /**
9491 * Instances of the class `ResolverVisitor` are used to resolve the nodes within a single 9934 * Instances of the class `ResolverVisitor` are used to resolve the nodes within a single
9492 * compilation unit. 9935 * compilation unit.
9493 * 9936 *
9494 * @coverage dart.engine.resolver 9937 * @coverage dart.engine.resolver
9495 */ 9938 */
9496 class ResolverVisitor extends ScopedVisitor { 9939 class ResolverVisitor extends ScopedVisitor {
9497 /** 9940 /**
(...skipping 4383 matching lines...) Expand 10 before | Expand all | Expand 10 after
13881 Object visitClassTypeAlias(ClassTypeAlias node) { 14324 Object visitClassTypeAlias(ClassTypeAlias node) {
13882 super.visitClassTypeAlias(node); 14325 super.visitClassTypeAlias(node);
13883 ClassElementImpl classElement = getClassElement(node.name); 14326 ClassElementImpl classElement = getClassElement(node.name);
13884 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS; 14327 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS;
13885 InterfaceType superclassType = resolveType(node.superclass, errorCode, error Code); 14328 InterfaceType superclassType = resolveType(node.superclass, errorCode, error Code);
13886 if (superclassType == null) { 14329 if (superclassType == null) {
13887 superclassType = typeProvider.objectType; 14330 superclassType = typeProvider.objectType;
13888 } 14331 }
13889 if (classElement != null && superclassType != null) { 14332 if (classElement != null && superclassType != null) {
13890 classElement.supertype = superclassType; 14333 classElement.supertype = superclassType;
14334 ClassElement superclassElement = superclassType.element;
14335 if (superclassElement != null) {
14336 List<ConstructorElement> constructors = superclassElement.constructors;
14337 int count = constructors.length;
14338 if (count > 0) {
14339 List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(superclass Type.typeParameters);
14340 List<Type2> argumentTypes = getArgumentTypes(node.superclass.typeArgum ents, parameterTypes);
14341 InterfaceType classType = classElement.type;
14342 List<ConstructorElement> implicitConstructors = new List<ConstructorEl ement>();
14343 for (int i = 0; i < count; i++) {
14344 ConstructorElement explicitConstructor = constructors[i];
14345 if (!explicitConstructor.isFactory) {
14346 implicitConstructors.add(createImplicitContructor(classType, expli citConstructor, parameterTypes, argumentTypes));
14347 }
14348 }
14349 classElement.constructors = new List.from(implicitConstructors);
14350 }
14351 }
13891 } 14352 }
13892 resolve(classElement, node.withClause, node.implementsClause); 14353 resolve(classElement, node.withClause, node.implementsClause);
13893 return null; 14354 return null;
13894 } 14355 }
13895 14356
13896 Object visitConstructorDeclaration(ConstructorDeclaration node) { 14357 Object visitConstructorDeclaration(ConstructorDeclaration node) {
13897 super.visitConstructorDeclaration(node); 14358 super.visitConstructorDeclaration(node);
13898 ExecutableElementImpl element = node.element as ExecutableElementImpl; 14359 ExecutableElementImpl element = node.element as ExecutableElementImpl;
13899 ClassElement definingClass = element.enclosingElement as ClassElement; 14360 ClassElement definingClass = element.enclosingElement as ClassElement;
13900 element.returnType = definingClass.type; 14361 element.returnType = definingClass.type;
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
14321 */ 14782 */
14322 Type2 computeReturnType(TypeName returnType) { 14783 Type2 computeReturnType(TypeName returnType) {
14323 if (returnType == null) { 14784 if (returnType == null) {
14324 return _dynamicType; 14785 return _dynamicType;
14325 } else { 14786 } else {
14326 return returnType.type; 14787 return returnType.type;
14327 } 14788 }
14328 } 14789 }
14329 14790
14330 /** 14791 /**
14792 * Create an implicit constructor that is copied from the given constructor, b ut that is in the
14793 * given class.
14794 *
14795 * @param classType the class in which the implicit constructor is defined
14796 * @param explicitConstructor the constructor on which the implicit constructo r is modeled
14797 * @param parameterTypes the types to be replaced when creating parameters
14798 * @param argumentTypes the types with which the parameters are to be replaced
14799 * @return the implicit constructor that was created
14800 */
14801 ConstructorElement createImplicitContructor(InterfaceType classType, Construct orElement explicitConstructor, List<Type2> parameterTypes, List<Type2> argumentT ypes) {
14802 ConstructorElementImpl implicitConstructor = new ConstructorElementImpl.con2 (explicitConstructor.name, -1);
14803 implicitConstructor.synthetic = true;
14804 implicitConstructor.redirectedConstructor = explicitConstructor;
14805 implicitConstructor.const2 = explicitConstructor.isConst;
14806 implicitConstructor.returnType = classType;
14807 List<ParameterElement> explicitParameters = explicitConstructor.parameters;
14808 int count = explicitParameters.length;
14809 if (count > 0) {
14810 List<ParameterElement> implicitParameters = new List<ParameterElement>(cou nt);
14811 for (int i = 0; i < count; i++) {
14812 ParameterElement explicitParameter = explicitParameters[i];
14813 ParameterElementImpl implicitParameter = new ParameterElementImpl.con2(e xplicitParameter.name, -1);
14814 implicitParameter.const3 = explicitParameter.isConst;
14815 implicitParameter.final2 = explicitParameter.isFinal;
14816 implicitParameter.parameterKind = explicitParameter.parameterKind;
14817 implicitParameter.synthetic = true;
14818 implicitParameter.type = explicitParameter.type.substitute2(argumentType s, parameterTypes);
14819 implicitParameters[i] = implicitParameter;
14820 }
14821 implicitConstructor.parameters = implicitParameters;
14822 }
14823 FunctionTypeImpl type = new FunctionTypeImpl.con1(implicitConstructor);
14824 type.typeArguments = classType.typeArguments;
14825 implicitConstructor.type = type;
14826 return implicitConstructor;
14827 }
14828
14829 /**
14830 * Return an array of argument types that corresponds to the array of paramete r types and that are
14831 * derived from the given list of type arguments.
14832 *
14833 * @param typeArguments the type arguments from which the types will be taken
14834 * @param parameterTypes the parameter types that must be matched by the type arguments
14835 * @return the argument types that correspond to the parameter types
14836 */
14837 List<Type2> getArgumentTypes(TypeArgumentList typeArguments, List<Type2> param eterTypes) {
14838 DynamicTypeImpl dynamic = DynamicTypeImpl.instance;
14839 int parameterCount = parameterTypes.length;
14840 List<Type2> types = new List<Type2>(parameterCount);
14841 if (typeArguments == null) {
14842 for (int i = 0; i < parameterCount; i++) {
14843 types[i] = dynamic;
14844 }
14845 } else {
14846 NodeList<TypeName> arguments = typeArguments.arguments;
14847 int argumentCount = Math.min(arguments.length, parameterCount);
14848 for (int i = 0; i < argumentCount; i++) {
14849 types[i] = arguments[i].type;
14850 }
14851 for (int i = argumentCount; i < parameterCount; i++) {
14852 types[i] = dynamic;
14853 }
14854 }
14855 return types;
14856 }
14857
14858 /**
14331 * Return the class element that represents the class whose name was provided. 14859 * Return the class element that represents the class whose name was provided.
14332 * 14860 *
14333 * @param identifier the name from the declaration of a class 14861 * @param identifier the name from the declaration of a class
14334 * @return the class element that represents the class 14862 * @return the class element that represents the class
14335 */ 14863 */
14336 ClassElementImpl getClassElement(SimpleIdentifier identifier) { 14864 ClassElementImpl getClassElement(SimpleIdentifier identifier) {
14337 // TODO(brianwilkerson) Seems like we should be using ClassDeclaration.getEl ement(). 14865 // TODO(brianwilkerson) Seems like we should be using ClassDeclaration.getEl ement().
14338 if (identifier == null) { 14866 if (identifier == null) {
14339 // TODO(brianwilkerson) Report this 14867 // TODO(brianwilkerson) Report this
14340 // Internal error: We should never build a class declaration without a nam e. 14868 // Internal error: We should never build a class declaration without a nam e.
(...skipping 2084 matching lines...) Expand 10 before | Expand all | Expand 10 after
16425 */ 16953 */
16426 ClassElement _enclosingClass; 16954 ClassElement _enclosingClass;
16427 16955
16428 /** 16956 /**
16429 * The method or function that we are currently visiting, or `null` if we are not inside a 16957 * The method or function that we are currently visiting, or `null` if we are not inside a
16430 * method or function. 16958 * method or function.
16431 */ 16959 */
16432 ExecutableElement _enclosingFunction; 16960 ExecutableElement _enclosingFunction;
16433 16961
16434 /** 16962 /**
16435 * The number of return statements found in the method or function that we are currently visiting 16963 * The return statements found in the method or function that we are currently visiting that have
16436 * that have a return value. 16964 * a return value.
16437 */ 16965 */
16438 int _returnWithCount = 0; 16966 List<ReturnStatement> _returnsWith = new List<ReturnStatement>();
16439 16967
16440 /** 16968 /**
16441 * The number of return statements found in the method or function that we are currently visiting 16969 * The return statements found in the method or function that we are currently visiting that do
16442 * that do not have a return value. 16970 * not have a return value.
16443 */ 16971 */
16444 int _returnWithoutCount = 0; 16972 List<ReturnStatement> _returnsWithout = new List<ReturnStatement>();
16445 16973
16446 /** 16974 /**
16447 * This map is initialized when visiting the contents of a class declaration. If the visitor is 16975 * This map is initialized when visiting the contents of a class declaration. If the visitor is
16448 * not in an enclosing class declaration, then the map is set to `null`. 16976 * not in an enclosing class declaration, then the map is set to `null`.
16449 * 16977 *
16450 * When set the map maps the set of [FieldElement]s in the class to an 16978 * When set the map maps the set of [FieldElement]s in the class to an
16451 * [INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*< /code> 16979 * [INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*< /code>
16452 * methods, specifically [checkForAllFinalInitializedErrorCodes], 16980 * methods, specifically [checkForAllFinalInitializedErrorCodes],
16453 * can make a copy of the map to compute error code states. <code>checkFor*</c ode> methods should 16981 * can make a copy of the map to compute error code states. <code>checkFor*</c ode> methods should
16454 * only ever make a copy, or read from this map after it has been set in 16982 * only ever make a copy, or read from this map after it has been set in
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
16537 checkForArgumentTypeNotAssignable2(node.rightHandSide); 17065 checkForArgumentTypeNotAssignable2(node.rightHandSide);
16538 return super.visitAssignmentExpression(node); 17066 return super.visitAssignmentExpression(node);
16539 } 17067 }
16540 17068
16541 Object visitBinaryExpression(BinaryExpression node) { 17069 Object visitBinaryExpression(BinaryExpression node) {
16542 checkForArgumentTypeNotAssignable2(node.rightOperand); 17070 checkForArgumentTypeNotAssignable2(node.rightOperand);
16543 return super.visitBinaryExpression(node); 17071 return super.visitBinaryExpression(node);
16544 } 17072 }
16545 17073
16546 Object visitBlockFunctionBody(BlockFunctionBody node) { 17074 Object visitBlockFunctionBody(BlockFunctionBody node) {
16547 int previousReturnWithCount = _returnWithCount; 17075 List<ReturnStatement> previousReturnsWith = _returnsWith;
16548 int previousReturnWithoutCount = _returnWithoutCount; 17076 List<ReturnStatement> previousReturnsWithout = _returnsWithout;
16549 try { 17077 try {
16550 _returnWithCount = 0; 17078 _returnsWith = new List<ReturnStatement>();
16551 _returnWithoutCount = 0; 17079 _returnsWithout = new List<ReturnStatement>();
16552 super.visitBlockFunctionBody(node); 17080 super.visitBlockFunctionBody(node);
16553 checkForMixedReturns(node); 17081 checkForMixedReturns(node);
16554 } finally { 17082 } finally {
16555 _returnWithCount = previousReturnWithCount; 17083 _returnsWith = previousReturnsWith;
16556 _returnWithoutCount = previousReturnWithoutCount; 17084 _returnsWithout = previousReturnsWithout;
16557 } 17085 }
16558 return null; 17086 return null;
16559 } 17087 }
17088
17089 Object visitBreakStatement(BreakStatement node) {
17090 SimpleIdentifier labelNode = node.label;
17091 if (labelNode != null) {
17092 Element labelElement = labelNode.staticElement;
17093 if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) {
17094 _errorReporter.reportError3(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMB ER, labelNode, []);
17095 }
17096 }
17097 return null;
17098 }
16560 17099
16561 Object visitCatchClause(CatchClause node) { 17100 Object visitCatchClause(CatchClause node) {
16562 bool previousIsInCatchClause = _isInCatchClause; 17101 bool previousIsInCatchClause = _isInCatchClause;
16563 try { 17102 try {
16564 _isInCatchClause = true; 17103 _isInCatchClause = true;
16565 return super.visitCatchClause(node); 17104 return super.visitCatchClause(node);
16566 } finally { 17105 } finally {
16567 _isInCatchClause = previousIsInCatchClause; 17106 _isInCatchClause = previousIsInCatchClause;
16568 } 17107 }
16569 } 17108 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
16662 return super.visitConstructorDeclaration(node); 17201 return super.visitConstructorDeclaration(node);
16663 } finally { 17202 } finally {
16664 _isEnclosingConstructorConst = false; 17203 _isEnclosingConstructorConst = false;
16665 _enclosingFunction = outerFunction; 17204 _enclosingFunction = outerFunction;
16666 } 17205 }
16667 } 17206 }
16668 17207
16669 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 17208 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
16670 _isInConstructorInitializer = true; 17209 _isInConstructorInitializer = true;
16671 try { 17210 try {
17211 checkForInvalidField(node);
16672 checkForFieldInitializerNotAssignable(node); 17212 checkForFieldInitializerNotAssignable(node);
16673 return super.visitConstructorFieldInitializer(node); 17213 return super.visitConstructorFieldInitializer(node);
16674 } finally { 17214 } finally {
16675 _isInConstructorInitializer = false; 17215 _isInConstructorInitializer = false;
16676 } 17216 }
16677 } 17217 }
16678 17218
17219 Object visitContinueStatement(ContinueStatement node) {
17220 SimpleIdentifier labelNode = node.label;
17221 if (labelNode != null) {
17222 Element labelElement = labelNode.staticElement;
17223 if (labelElement is LabelElementImpl && labelElement.isOnSwitchStatement) {
17224 _errorReporter.reportError3(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
17225 }
17226 }
17227 return null;
17228 }
17229
16679 Object visitDefaultFormalParameter(DefaultFormalParameter node) { 17230 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
16680 checkForInvalidAssignment2(node.identifier, node.defaultValue); 17231 checkForInvalidAssignment2(node.identifier, node.defaultValue);
16681 checkForDefaultValueInFunctionTypedParameter(node); 17232 checkForDefaultValueInFunctionTypedParameter(node);
16682 return super.visitDefaultFormalParameter(node); 17233 return super.visitDefaultFormalParameter(node);
16683 } 17234 }
16684 17235
16685 Object visitDoStatement(DoStatement node) { 17236 Object visitDoStatement(DoStatement node) {
16686 checkForNonBoolCondition(node.condition); 17237 checkForNonBoolCondition(node.condition);
16687 return super.visitDoStatement(node); 17238 return super.visitDoStatement(node);
16688 } 17239 }
(...skipping 15 matching lines...) Expand all
16704 Object visitFieldDeclaration(FieldDeclaration node) { 17255 Object visitFieldDeclaration(FieldDeclaration node) {
16705 if (!node.isStatic) { 17256 if (!node.isStatic) {
16706 VariableDeclarationList variables = node.fields; 17257 VariableDeclarationList variables = node.fields;
16707 if (variables.isConst) { 17258 if (variables.isConst) {
16708 _errorReporter.reportError6(CompileTimeErrorCode.CONST_INSTANCE_FIELD, v ariables.keyword, []); 17259 _errorReporter.reportError6(CompileTimeErrorCode.CONST_INSTANCE_FIELD, v ariables.keyword, []);
16709 } 17260 }
16710 } 17261 }
16711 _isInStaticVariableDeclaration = node.isStatic; 17262 _isInStaticVariableDeclaration = node.isStatic;
16712 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; 17263 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
16713 try { 17264 try {
16714 checkForAllInvalidOverrideErrorCodes2(node); 17265 checkForAllInvalidOverrideErrorCodes3(node);
16715 return super.visitFieldDeclaration(node); 17266 return super.visitFieldDeclaration(node);
16716 } finally { 17267 } finally {
16717 _isInStaticVariableDeclaration = false; 17268 _isInStaticVariableDeclaration = false;
16718 _isInInstanceVariableDeclaration = false; 17269 _isInInstanceVariableDeclaration = false;
16719 } 17270 }
16720 } 17271 }
16721 17272
16722 Object visitFieldFormalParameter(FieldFormalParameter node) { 17273 Object visitFieldFormalParameter(FieldFormalParameter node) {
17274 checkForValidField(node);
16723 checkForConstFormalParameter(node); 17275 checkForConstFormalParameter(node);
16724 checkForPrivateOptionalParameter(node); 17276 checkForPrivateOptionalParameter(node);
16725 checkForFieldInitializingFormalRedirectingConstructor(node); 17277 checkForFieldInitializingFormalRedirectingConstructor(node);
16726 return super.visitFieldFormalParameter(node); 17278 return super.visitFieldFormalParameter(node);
16727 } 17279 }
16728 17280
16729 Object visitFunctionDeclaration(FunctionDeclaration node) { 17281 Object visitFunctionDeclaration(FunctionDeclaration node) {
16730 ExecutableElement outerFunction = _enclosingFunction; 17282 ExecutableElement outerFunction = _enclosingFunction;
16731 try { 17283 try {
16732 SimpleIdentifier identifier = node.name; 17284 SimpleIdentifier identifier = node.name;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
16885 checkForNonVoidReturnTypeForSetter(node.returnType); 17437 checkForNonVoidReturnTypeForSetter(node.returnType);
16886 checkForConflictingStaticSetterAndInstanceMember(node); 17438 checkForConflictingStaticSetterAndInstanceMember(node);
16887 } else if (node.isOperator) { 17439 } else if (node.isOperator) {
16888 checkForOptionalParameterInOperator(node); 17440 checkForOptionalParameterInOperator(node);
16889 checkForWrongNumberOfParametersForOperator(node); 17441 checkForWrongNumberOfParametersForOperator(node);
16890 checkForNonVoidReturnTypeForOperator(node); 17442 checkForNonVoidReturnTypeForOperator(node);
16891 } else { 17443 } else {
16892 checkForConflictingInstanceMethodSetter(node); 17444 checkForConflictingInstanceMethodSetter(node);
16893 } 17445 }
16894 checkForConcreteClassWithAbstractMember(node); 17446 checkForConcreteClassWithAbstractMember(node);
16895 checkForAllInvalidOverrideErrorCodes3(node); 17447 checkForAllInvalidOverrideErrorCodes4(node);
16896 return super.visitMethodDeclaration(node); 17448 return super.visitMethodDeclaration(node);
16897 } finally { 17449 } finally {
16898 _enclosingFunction = previousFunction; 17450 _enclosingFunction = previousFunction;
16899 _isInStaticMethod = false; 17451 _isInStaticMethod = false;
16900 } 17452 }
16901 } 17453 }
16902 17454
16903 Object visitMethodInvocation(MethodInvocation node) { 17455 Object visitMethodInvocation(MethodInvocation node) {
16904 Expression target = node.realTarget; 17456 Expression target = node.realTarget;
16905 SimpleIdentifier methodName = node.methodName; 17457 SimpleIdentifier methodName = node.methodName;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
16971 } 17523 }
16972 } 17524 }
16973 17525
16974 Object visitRethrowExpression(RethrowExpression node) { 17526 Object visitRethrowExpression(RethrowExpression node) {
16975 checkForRethrowOutsideCatch(node); 17527 checkForRethrowOutsideCatch(node);
16976 return super.visitRethrowExpression(node); 17528 return super.visitRethrowExpression(node);
16977 } 17529 }
16978 17530
16979 Object visitReturnStatement(ReturnStatement node) { 17531 Object visitReturnStatement(ReturnStatement node) {
16980 if (node.expression == null) { 17532 if (node.expression == null) {
16981 _returnWithoutCount++; 17533 _returnsWithout.add(node);
16982 } else { 17534 } else {
16983 _returnWithCount++; 17535 _returnsWith.add(node);
16984 } 17536 }
16985 checkForAllReturnStatementErrorCodes(node); 17537 checkForAllReturnStatementErrorCodes(node);
16986 return super.visitReturnStatement(node); 17538 return super.visitReturnStatement(node);
16987 } 17539 }
16988 17540
16989 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 17541 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
16990 checkForConstFormalParameter(node); 17542 checkForConstFormalParameter(node);
16991 checkForPrivateOptionalParameter(node); 17543 checkForPrivateOptionalParameter(node);
16992 return super.visitSimpleFormalParameter(node); 17544 return super.visitSimpleFormalParameter(node);
16993 } 17545 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
17188 } 17740 }
17189 } 17741 }
17190 } 17742 }
17191 return foundError; 17743 return foundError;
17192 } 17744 }
17193 17745
17194 /** 17746 /**
17195 * This checks the passed executable element against override-error codes. 17747 * This checks the passed executable element against override-error codes.
17196 * 17748 *
17197 * @param executableElement a non-null [ExecutableElement] to evaluate 17749 * @param executableElement a non-null [ExecutableElement] to evaluate
17750 * @param overriddenExecutable the element that the executableElement is overr iding
17198 * @param parameters the parameters of the executable element 17751 * @param parameters the parameters of the executable element
17199 * @param errorNameTarget the node to report problems on 17752 * @param errorNameTarget the node to report problems on
17200 * @return `true` if and only if an error code is generated on the passed node 17753 * @return `true` if and only if an error code is generated on the passed node
17201 * @see StaticWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC 17754 * @see StaticWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
17202 * @see CompileTimeErrorCode#INVALID_OVERRIDE_REQUIRED 17755 * @see CompileTimeErrorCode#INVALID_OVERRIDE_REQUIRED
17203 * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL 17756 * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL
17204 * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED 17757 * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED
17205 * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE 17758 * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE
17206 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE 17759 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE
17207 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE 17760 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
17208 * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE 17761 * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE
17209 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE 17762 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
17210 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE 17763 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
17211 * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES 17764 * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
17212 */ 17765 */
17213 bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, List<ParameterElement> parameters, List<ASTNode> parameterLocations, SimpleIden tifier errorNameTarget) { 17766 bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, ExecutableElement overriddenExecutable, List<ParameterElement> parameters, List <ASTNode> parameterLocations, SimpleIdentifier errorNameTarget) {
17214 String executableElementName = executableElement.name;
17215 bool executableElementPrivate = Identifier.isPrivateName(executableElementNa me);
17216 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan ce(_enclosingClass, executableElementName);
17217 bool isGetter = false; 17767 bool isGetter = false;
17218 bool isSetter = false; 17768 bool isSetter = false;
17219 if (executableElement is PropertyAccessorElement) { 17769 if (executableElement is PropertyAccessorElement) {
17220 PropertyAccessorElement accessorElement = executableElement; 17770 PropertyAccessorElement accessorElement = executableElement;
17221 isGetter = accessorElement.isGetter; 17771 isGetter = accessorElement.isGetter;
17222 isSetter = accessorElement.isSetter; 17772 isSetter = accessorElement.isSetter;
17223 } 17773 }
17774 String executableElementName = executableElement.name;
17224 // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC 17775 // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
17225 if (overriddenExecutable == null) { 17776 if (overriddenExecutable == null) {
17226 if (!isGetter && !isSetter && !executableElement.isOperator) { 17777 if (!isGetter && !isSetter && !executableElement.isOperator) {
17227 Set<ClassElement> visitedClasses = new Set<ClassElement>(); 17778 Set<ClassElement> visitedClasses = new Set<ClassElement>();
17228 InterfaceType superclassType = _enclosingClass.supertype; 17779 InterfaceType superclassType = _enclosingClass.supertype;
17229 ClassElement superclassElement = superclassType == null ? null : supercl assType.element; 17780 ClassElement superclassElement = superclassType == null ? null : supercl assType.element;
17781 bool executableElementPrivate = Identifier.isPrivateName(executableEleme ntName);
17230 while (superclassElement != null && !visitedClasses.contains(superclassE lement)) { 17782 while (superclassElement != null && !visitedClasses.contains(superclassE lement)) {
17231 visitedClasses.add(superclassElement); 17783 visitedClasses.add(superclassElement);
17232 LibraryElement superclassLibrary = superclassElement.library; 17784 LibraryElement superclassLibrary = superclassElement.library;
17233 // Check fields. 17785 // Check fields.
17234 List<FieldElement> fieldElts = superclassElement.fields; 17786 List<FieldElement> fieldElts = superclassElement.fields;
17235 for (FieldElement fieldElt in fieldElts) { 17787 for (FieldElement fieldElt in fieldElts) {
17236 // We need the same name. 17788 // We need the same name.
17237 if (fieldElt.name != executableElementName) { 17789 if (fieldElt.name != executableElementName) {
17238 continue; 17790 continue;
17239 } 17791 }
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
17460 overriddenExecutable.displayName]); 18012 overriddenExecutable.displayName]);
17461 foundError = true; 18013 foundError = true;
17462 } 18014 }
17463 } 18015 }
17464 } 18016 }
17465 } 18017 }
17466 return foundError; 18018 return foundError;
17467 } 18019 }
17468 18020
17469 /** 18021 /**
18022 * This checks the passed executable element against override-error codes. Thi s method computes
18023 * the passed executableElement is overriding and calls
18024 * [checkForAllInvalidOverrideErrorCodes]
18025 * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement ], this
18026 * method loops through the array in the [MultiplyInheritedExecutableElement].
18027 *
18028 * @param executableElement a non-null [ExecutableElement] to evaluate
18029 * @param parameters the parameters of the executable element
18030 * @param errorNameTarget the node to report problems on
18031 * @return `true` if and only if an error code is generated on the passed node
18032 */
18033 bool checkForAllInvalidOverrideErrorCodes2(ExecutableElement executableElement , List<ParameterElement> parameters, List<ASTNode> parameterLocations, SimpleIde ntifier errorNameTarget) {
18034 //
18035 // Compute the overridden executable from the InheritanceManager
18036 //
18037 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan ce(_enclosingClass, executableElement.name);
18038 //
18039 // If the result is a MultiplyInheritedExecutableElement call
18040 // checkForAllInvalidOverrideErrorCodes on all of the elements, until an err or is found.
18041 //
18042 if (overriddenExecutable is MultiplyInheritedExecutableElement) {
18043 MultiplyInheritedExecutableElement multiplyInheritedElement = overriddenEx ecutable;
18044 List<ExecutableElement> overriddenElement = multiplyInheritedElement.inher itedElements;
18045 for (int i = 0; i < overriddenElement.length; i++) {
18046 if (checkForAllInvalidOverrideErrorCodes(executableElement, overriddenEl ement[i], parameters, parameterLocations, errorNameTarget)) {
18047 return true;
18048 }
18049 }
18050 return false;
18051 }
18052 //
18053 // Otherwise, just call checkForAllInvalidOverrideErrorCodes.
18054 //
18055 return checkForAllInvalidOverrideErrorCodes(executableElement, overriddenExe cutable, parameters, parameterLocations, errorNameTarget);
18056 }
18057
18058 /**
17470 * This checks the passed field declaration against override-error codes. 18059 * This checks the passed field declaration against override-error codes.
17471 * 18060 *
17472 * @param node the [MethodDeclaration] to evaluate 18061 * @param node the [MethodDeclaration] to evaluate
17473 * @return `true` if and only if an error code is generated on the passed node 18062 * @return `true` if and only if an error code is generated on the passed node
17474 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) 18063 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement)
17475 */ 18064 */
17476 bool checkForAllInvalidOverrideErrorCodes2(FieldDeclaration node) { 18065 bool checkForAllInvalidOverrideErrorCodes3(FieldDeclaration node) {
17477 if (_enclosingClass == null || node.isStatic) { 18066 if (_enclosingClass == null || node.isStatic) {
17478 return false; 18067 return false;
17479 } 18068 }
17480 bool hasProblems = false; 18069 bool hasProblems = false;
17481 VariableDeclarationList fields = node.fields; 18070 VariableDeclarationList fields = node.fields;
17482 for (VariableDeclaration field in fields.variables) { 18071 for (VariableDeclaration field in fields.variables) {
17483 FieldElement element = field.element as FieldElement; 18072 FieldElement element = field.element as FieldElement;
17484 if (element == null) { 18073 if (element == null) {
17485 continue; 18074 continue;
17486 } 18075 }
17487 PropertyAccessorElement getter = element.getter; 18076 PropertyAccessorElement getter = element.getter;
17488 PropertyAccessorElement setter = element.setter; 18077 PropertyAccessorElement setter = element.setter;
17489 SimpleIdentifier fieldName = field.name; 18078 SimpleIdentifier fieldName = field.name;
17490 if (getter != null) { 18079 if (getter != null) {
17491 hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideError Codes(getter, ParameterElementImpl.EMPTY_ARRAY, ASTNode.EMPTY_ARRAY, fieldName)) ; 18080 hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideError Codes2(getter, ParameterElementImpl.EMPTY_ARRAY, ASTNode.EMPTY_ARRAY, fieldName) );
17492 } 18081 }
17493 if (setter != null) { 18082 if (setter != null) {
17494 hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideError Codes(setter, setter.parameters, <ASTNode> [fieldName], fieldName)); 18083 hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideError Codes2(setter, setter.parameters, <ASTNode> [fieldName], fieldName));
17495 } 18084 }
17496 } 18085 }
17497 return hasProblems; 18086 return hasProblems;
17498 } 18087 }
17499 18088
17500 /** 18089 /**
17501 * This checks the passed method declaration against override-error codes. 18090 * This checks the passed method declaration against override-error codes.
17502 * 18091 *
17503 * @param node the [MethodDeclaration] to evaluate 18092 * @param node the [MethodDeclaration] to evaluate
17504 * @return `true` if and only if an error code is generated on the passed node 18093 * @return `true` if and only if an error code is generated on the passed node
17505 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) 18094 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement)
17506 */ 18095 */
17507 bool checkForAllInvalidOverrideErrorCodes3(MethodDeclaration node) { 18096 bool checkForAllInvalidOverrideErrorCodes4(MethodDeclaration node) {
17508 if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionB ody) { 18097 if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionB ody) {
17509 return false; 18098 return false;
17510 } 18099 }
17511 ExecutableElement executableElement = node.element; 18100 ExecutableElement executableElement = node.element;
17512 if (executableElement == null) { 18101 if (executableElement == null) {
17513 return false; 18102 return false;
17514 } 18103 }
17515 SimpleIdentifier methodName = node.name; 18104 SimpleIdentifier methodName = node.name;
17516 if (methodName.isSynthetic) { 18105 if (methodName.isSynthetic) {
17517 return false; 18106 return false;
17518 } 18107 }
17519 FormalParameterList formalParameterList = node.parameters; 18108 FormalParameterList formalParameterList = node.parameters;
17520 NodeList<FormalParameter> parameterList = formalParameterList != null ? form alParameterList.parameters : null; 18109 NodeList<FormalParameter> parameterList = formalParameterList != null ? form alParameterList.parameters : null;
17521 List<ASTNode> parameters = parameterList != null ? new List.from(parameterLi st) : null; 18110 List<ASTNode> parameters = parameterList != null ? new List.from(parameterLi st) : null;
17522 return checkForAllInvalidOverrideErrorCodes(executableElement, executableEle ment.parameters, parameters, methodName); 18111 return checkForAllInvalidOverrideErrorCodes2(executableElement, executableEl ement.parameters, parameters, methodName);
17523 } 18112 }
17524 18113
17525 /** 18114 /**
17526 * This verifies that all classes of the passed 'with' clause are valid. 18115 * This verifies that all classes of the passed 'with' clause are valid.
17527 * 18116 *
17528 * @param node the 'with' clause to evaluate 18117 * @param node the 'with' clause to evaluate
17529 * @return `true` if and only if an error code is generated on the passed node 18118 * @return `true` if and only if an error code is generated on the passed node
17530 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR 18119 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
17531 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT 18120 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
17532 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER 18121 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
17824 PropertyAccessorElement accessor = element as PropertyAccessorElement; 18413 PropertyAccessorElement accessor = element as PropertyAccessorElement;
17825 element = accessor.variable; 18414 element = accessor.variable;
17826 } 18415 }
17827 if (element is VariableElement) { 18416 if (element is VariableElement) {
17828 VariableElement variable = element as VariableElement; 18417 VariableElement variable = element as VariableElement;
17829 if (variable.isConst) { 18418 if (variable.isConst) {
17830 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_CONST, expre ssion, []); 18419 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_CONST, expre ssion, []);
17831 return true; 18420 return true;
17832 } 18421 }
17833 if (variable.isFinal) { 18422 if (variable.isFinal) {
17834 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre ssion, []); 18423 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre ssion, [variable.name]);
17835 return true; 18424 return true;
17836 } 18425 }
17837 return false; 18426 return false;
17838 } 18427 }
17839 if (element is MethodElement) { 18428 if (element is MethodElement) {
17840 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_METHOD, expres sion, []); 18429 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_METHOD, expres sion, []);
17841 return true; 18430 return true;
17842 } 18431 }
17843 return false; 18432 return false;
17844 } 18433 }
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after
18800 * This verifies that the passed constructor field initializer has compatible field and 19389 * This verifies that the passed constructor field initializer has compatible field and
18801 * initializer expression types. 19390 * initializer expression types.
18802 * 19391 *
18803 * @param node the constructor field initializer to test 19392 * @param node the constructor field initializer to test
18804 * @return `true` if and only if an error code is generated on the passed node 19393 * @return `true` if and only if an error code is generated on the passed node
18805 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE 19394 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
18806 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE 19395 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE
18807 */ 19396 */
18808 bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) { 19397 bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) {
18809 // prepare field element 19398 // prepare field element
18810 Element fieldNameElement = node.fieldName.staticElement; 19399 Element staticElement = node.fieldName.staticElement;
18811 if (fieldNameElement is! FieldElement) { 19400 if (staticElement is! FieldElement) {
18812 return false; 19401 return false;
18813 } 19402 }
18814 FieldElement fieldElement = fieldNameElement as FieldElement; 19403 FieldElement fieldElement = staticElement as FieldElement;
18815 // prepare field type 19404 // prepare field type
18816 Type2 fieldType = fieldElement.type; 19405 Type2 fieldType = fieldElement.type;
18817 // prepare expression type 19406 // prepare expression type
18818 Expression expression = node.expression; 19407 Expression expression = node.expression;
18819 if (expression == null) { 19408 if (expression == null) {
18820 return false; 19409 return false;
18821 } 19410 }
18822 // test the static type of the expression 19411 // test the static type of the expression
18823 Type2 staticType = getStaticType(expression); 19412 Type2 staticType = getStaticType(expression);
18824 if (staticType == null) { 19413 if (staticType == null) {
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
19207 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty pe; 19796 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty pe;
19208 MethodElement invokedMethod = node.staticElement; 19797 MethodElement invokedMethod = node.staticElement;
19209 if (invokedMethod == null) { 19798 if (invokedMethod == null) {
19210 return false; 19799 return false;
19211 } 19800 }
19212 Type2 rightType = invokedMethod.type.returnType; 19801 Type2 rightType = invokedMethod.type.returnType;
19213 if (leftType == null || rightType == null) { 19802 if (leftType == null || rightType == null) {
19214 return false; 19803 return false;
19215 } 19804 }
19216 if (!rightType.isAssignableTo(leftType)) { 19805 if (!rightType.isAssignableTo(leftType)) {
19217 _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, node .rightHandSide, [rightType.displayName, leftType.displayName]); 19806 String leftName = leftType.displayName;
19807 String rightName = rightType.displayName;
19808 if (leftName == rightName) {
19809 leftName = getExtendedDisplayName(leftType);
19810 rightName = getExtendedDisplayName(rightType);
19811 }
19812 _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, node .rightHandSide, [rightName, leftName]);
19218 return true; 19813 return true;
19219 } 19814 }
19220 return false; 19815 return false;
19221 } 19816 }
19222 19817
19223 /** 19818 /**
19224 * This verifies that the passed left hand side and right hand side represent a valid assignment. 19819 * This verifies that the passed left hand side and right hand side represent a valid assignment.
19225 * 19820 *
19226 * @param lhs the left hand side expression 19821 * @param lhs the left hand side expression
19227 * @param rhs the right hand side expression 19822 * @param rhs the right hand side expression
19228 * @return `true` if and only if an error code is generated on the passed node 19823 * @return `true` if and only if an error code is generated on the passed node
19229 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT 19824 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
19230 */ 19825 */
19231 bool checkForInvalidAssignment2(Expression lhs, Expression rhs) { 19826 bool checkForInvalidAssignment2(Expression lhs, Expression rhs) {
19232 if (lhs == null || rhs == null) { 19827 if (lhs == null || rhs == null) {
19233 return false; 19828 return false;
19234 } 19829 }
19235 VariableElement leftElement = getVariableElement(lhs); 19830 VariableElement leftElement = getVariableElement(lhs);
19236 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty pe; 19831 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty pe;
19237 Type2 staticRightType = getStaticType(rhs); 19832 Type2 staticRightType = getStaticType(rhs);
19238 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); 19833 bool isStaticAssignable = staticRightType.isAssignableTo(leftType);
19239 if (!isStaticAssignable) { 19834 if (!isStaticAssignable) {
19240 _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [staticRightType.displayName, leftType.displayName]); 19835 String leftName = leftType.displayName;
19836 String rightName = staticRightType.displayName;
19837 if (leftName == rightName) {
19838 leftName = getExtendedDisplayName(leftType);
19839 rightName = getExtendedDisplayName(staticRightType);
19840 }
19841 _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
19241 return true; 19842 return true;
19242 } 19843 }
19243 // TODO(brianwilkerson) Define a hint corresponding to the warning and repor t it if appropriate. 19844 // TODO(brianwilkerson) Define a hint corresponding to the warning and repor t it if appropriate.
19244 // Type propagatedRightType = rhs.getPropagatedType(); 19845 // Type propagatedRightType = rhs.getPropagatedType();
19245 // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(le ftType); 19846 // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(le ftType);
19246 // if (!isStaticAssignable && !isPropagatedAssignable) { 19847 // if (!isStaticAssignable && !isPropagatedAssignable) {
19247 // errorReporter.reportError( 19848 // errorReporter.reportError(
19248 // StaticTypeWarningCode.INVALID_ASSIGNMENT, 19849 // StaticTypeWarningCode.INVALID_ASSIGNMENT,
19249 // rhs, 19850 // rhs,
19250 // staticRightType.getDisplayName(), 19851 // staticRightType.getDisplayName(),
19251 // leftType.getDisplayName()); 19852 // leftType.getDisplayName());
19252 // return true; 19853 // return true;
19253 // } 19854 // }
19254 return false; 19855 return false;
19255 } 19856 }
19256 19857
19257 /** 19858 /**
19859 * Check the given initializer to ensure that the field being initialized is a valid field.
19860 *
19861 * @param node the field initializer being checked
19862 */
19863 void checkForInvalidField(ConstructorFieldInitializer node) {
19864 SimpleIdentifier fieldName = node.fieldName;
19865 Element staticElement = fieldName.staticElement;
19866 if (staticElement is FieldElement) {
19867 FieldElement fieldElement = staticElement;
19868 if (fieldElement.isSynthetic) {
19869 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXI STANT_FIELD, node, [fieldName]);
19870 } else if (fieldElement.isStatic) {
19871 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_ FIELD, node, [fieldName]);
19872 }
19873 } else {
19874 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXIST ANT_FIELD, node, [fieldName]);
19875 return;
19876 }
19877 }
19878
19879 /**
19258 * This verifies that the usage of the passed 'this' is valid. 19880 * This verifies that the usage of the passed 'this' is valid.
19259 * 19881 *
19260 * @param node the 'this' expression to evaluate 19882 * @param node the 'this' expression to evaluate
19261 * @return `true` if and only if an error code is generated on the passed node 19883 * @return `true` if and only if an error code is generated on the passed node
19262 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS 19884 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS
19263 */ 19885 */
19264 bool checkForInvalidReferenceToThis(ThisExpression node) { 19886 bool checkForInvalidReferenceToThis(ThisExpression node) {
19265 if (!isThisInValidContext(node)) { 19887 if (!isThisInValidContext(node)) {
19266 _errorReporter.reportError3(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS , node, []); 19888 _errorReporter.reportError3(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS , node, []);
19267 return true; 19889 return true;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
19481 20103
19482 /** 20104 /**
19483 * This verifies that the given function body does not contain return statemen ts that both have 20105 * This verifies that the given function body does not contain return statemen ts that both have
19484 * and do not have return values. 20106 * and do not have return values.
19485 * 20107 *
19486 * @param node the function body being tested 20108 * @param node the function body being tested
19487 * @return `true` if and only if an error code is generated on the passed node 20109 * @return `true` if and only if an error code is generated on the passed node
19488 * @see StaticWarningCode#MIXED_RETURN_TYPES 20110 * @see StaticWarningCode#MIXED_RETURN_TYPES
19489 */ 20111 */
19490 bool checkForMixedReturns(BlockFunctionBody node) { 20112 bool checkForMixedReturns(BlockFunctionBody node) {
19491 if (_returnWithCount > 0 && _returnWithoutCount > 0) { 20113 int withCount = _returnsWith.length;
19492 _errorReporter.reportError3(StaticWarningCode.MIXED_RETURN_TYPES, node, [] ); 20114 int withoutCount = _returnsWithout.length;
20115 if (withCount > 0 && withoutCount > 0) {
20116 for (int i = 0; i < withCount; i++) {
20117 _errorReporter.reportError6(StaticWarningCode.MIXED_RETURN_TYPES, _retur nsWith[i].keyword, []);
20118 }
20119 for (int i = 0; i < withoutCount; i++) {
20120 _errorReporter.reportError6(StaticWarningCode.MIXED_RETURN_TYPES, _retur nsWithout[i].keyword, []);
20121 }
19493 return true; 20122 return true;
19494 } 20123 }
19495 return false; 20124 return false;
19496 } 20125 }
19497 20126
19498 /** 20127 /**
19499 * This verifies that the passed mixin does not have an explicitly declared co nstructor. 20128 * This verifies that the passed mixin does not have an explicitly declared co nstructor.
19500 * 20129 *
19501 * @param mixinName the node to report problem on 20130 * @param mixinName the node to report problem on
19502 * @param mixinElement the mixing to evaluate 20131 * @param mixinElement the mixing to evaluate
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
19695 // Loop through the set of all executable elements declared in the implicit interface. 20324 // Loop through the set of all executable elements declared in the implicit interface.
19696 // 20325 //
19697 MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembe rsInheritedFromInterfaces(_enclosingClass); 20326 MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembe rsInheritedFromInterfaces(_enclosingClass);
19698 MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMem bersInheritedFromClasses(_enclosingClass); 20327 MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMem bersInheritedFromClasses(_enclosingClass);
19699 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) { 20328 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) {
19700 String memberName = membersInheritedFromInterfaces.getKey(i); 20329 String memberName = membersInheritedFromInterfaces.getKey(i);
19701 ExecutableElement executableElt = membersInheritedFromInterfaces.getValue( i); 20330 ExecutableElement executableElt = membersInheritedFromInterfaces.getValue( i);
19702 if (memberName == null) { 20331 if (memberName == null) {
19703 break; 20332 break;
19704 } 20333 }
19705 // If the element is defined in Object, skip it. 20334 // If the element is not synthetic and can be determined to be defined in Object, skip it.
19706 if ((executableElt.enclosingElement as ClassElement).type.isObject) { 20335 if (executableElt.enclosingElement != null && (executableElt.enclosingElem ent as ClassElement).type.isObject) {
19707 continue; 20336 continue;
19708 } 20337 }
19709 // Reference the type of the enclosing class 20338 // Reference the type of the enclosing class
19710 InterfaceType enclosingType = _enclosingClass.type; 20339 InterfaceType enclosingType = _enclosingClass.type;
19711 // Check to see if some element is in local enclosing class that matches t he name of the 20340 // Check to see if some element is in local enclosing class that matches t he name of the
19712 // required member. 20341 // required member.
19713 if (isMemberInClassOrMixin(executableElt, _enclosingClass)) { 20342 if (isMemberInClassOrMixin(executableElt, _enclosingClass)) {
19714 // We do not have to verify that this implementation of the found method matches the 20343 // We do not have to verify that this implementation of the found method matches the
19715 // required function type: the set of StaticWarningCode.INVALID_METHOD_O VERRIDE_* warnings 20344 // required function type: the set of StaticWarningCode.INVALID_METHOD_O VERRIDE_* warnings
19716 // break out the different specific situations. 20345 // break out the different specific situations.
(...skipping 23 matching lines...) Expand all
19740 missingOverrides.add(executableElt); 20369 missingOverrides.add(executableElt);
19741 } 20370 }
19742 // Now that we have the set of missing overrides, generate a warning on this class 20371 // Now that we have the set of missing overrides, generate a warning on this class
19743 int missingOverridesSize = missingOverrides.length; 20372 int missingOverridesSize = missingOverrides.length;
19744 if (missingOverridesSize == 0) { 20373 if (missingOverridesSize == 0) {
19745 return false; 20374 return false;
19746 } 20375 }
19747 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid es); 20376 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid es);
19748 List<String> stringMembersArrayListSet = new List<String>(); 20377 List<String> stringMembersArrayListSet = new List<String>();
19749 for (int i = 0; i < missingOverridesArray.length; i++) { 20378 for (int i = 0; i < missingOverridesArray.length; i++) {
19750 String newStrMember = "${missingOverridesArray[i].enclosingElement.display Name}.${missingOverridesArray[i].displayName}"; 20379 String newStrMember;
20380 if (missingOverridesArray[i].enclosingElement != null) {
20381 newStrMember = "${missingOverridesArray[i].enclosingElement.displayName} .${missingOverridesArray[i].displayName}";
20382 } else {
20383 newStrMember = missingOverridesArray[i].displayName;
20384 }
19751 if (!stringMembersArrayListSet.contains(newStrMember)) { 20385 if (!stringMembersArrayListSet.contains(newStrMember)) {
19752 stringMembersArrayListSet.add(newStrMember); 20386 stringMembersArrayListSet.add(newStrMember);
19753 } 20387 }
19754 } 20388 }
19755 List<String> stringMembersArray = new List.from(stringMembersArrayListSet); 20389 List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
19756 AnalysisErrorWithProperties analysisError; 20390 AnalysisErrorWithProperties analysisError;
19757 if (stringMembersArray.length == 1) { 20391 if (stringMembersArray.length == 1) {
19758 analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NO N_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [stringMembersArray[0] ]); 20392 analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NO N_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [stringMembersArray[0] ]);
19759 } else if (stringMembersArray.length == 2) { 20393 } else if (stringMembersArray.length == 2) {
19760 analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NO N_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [stringMembersArray[0] , stringMembersArray[1]]); 20394 analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NO N_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [stringMembersArray[0] , stringMembersArray[1]]);
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
20526 if ((element is MethodElement && !element.isStatic) || (element is PropertyA ccessorElement && !element.isStatic)) { 21160 if ((element is MethodElement && !element.isStatic) || (element is PropertyA ccessorElement && !element.isStatic)) {
20527 return false; 21161 return false;
20528 } 21162 }
20529 if (identical(enclosingElement, _enclosingClass)) { 21163 if (identical(enclosingElement, _enclosingClass)) {
20530 return false; 21164 return false;
20531 } 21165 }
20532 _errorReporter.reportError3(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_N ON_LOCAL_STATIC_MEMBER, name, [name.name]); 21166 _errorReporter.reportError3(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_N ON_LOCAL_STATIC_MEMBER, name, [name.name]);
20533 return true; 21167 return true;
20534 } 21168 }
20535 21169
21170 void checkForValidField(FieldFormalParameter node) {
21171 ParameterElement element = node.element;
21172 if (element is FieldFormalParameterElement) {
21173 FieldElement fieldElement = element.field;
21174 if (fieldElement == null || fieldElement.isSynthetic) {
21175 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR _NON_EXISTANT_FIELD, node, [node.identifier.name]);
21176 } else {
21177 ParameterElement parameterElement = node.element;
21178 if (parameterElement is FieldFormalParameterElementImpl) {
21179 FieldFormalParameterElementImpl fieldFormal = parameterElement;
21180 Type2 declaredType = fieldFormal.type;
21181 Type2 fieldType = fieldElement.type;
21182 if (fieldElement.isSynthetic) {
21183 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL _FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]);
21184 } else if (fieldElement.isStatic) {
21185 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL _FOR_STATIC_FIELD, node, [node.identifier.name]);
21186 } else if (declaredType != null && fieldType != null && !declaredType. isAssignableTo(fieldType)) {
21187 _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZING_FOR MAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
21188 }
21189 } else {
21190 if (fieldElement.isSynthetic) {
21191 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL _FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]);
21192 } else if (fieldElement.isStatic) {
21193 _errorReporter.reportError3(CompileTimeErrorCode.INITIALIZING_FORMAL _FOR_STATIC_FIELD, node, [node.identifier.name]);
21194 }
21195 }
21196 }
21197 }
21198 }
21199
20536 /** 21200 /**
20537 * This verifies the passed operator-method declaration, has correct number of parameters. 21201 * This verifies the passed operator-method declaration, has correct number of parameters.
20538 * 21202 *
20539 * This method assumes that the method declaration was tested to be an operato r declaration before 21203 * This method assumes that the method declaration was tested to be an operato r declaration before
20540 * being called. 21204 * being called.
20541 * 21205 *
20542 * @param node the method declaration to evaluate 21206 * @param node the method declaration to evaluate
20543 * @return `true` if and only if an error code is generated on the passed node 21207 * @return `true` if and only if an error code is generated on the passed node
20544 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR 21208 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
20545 */ 21209 */
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
20653 if (interfaceNode.type == superType) { 21317 if (interfaceNode.type == superType) {
20654 hasProblem = true; 21318 hasProblem = true;
20655 _errorReporter.reportError3(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, [superType.displayName]); 21319 _errorReporter.reportError3(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, [superType.displayName]);
20656 } 21320 }
20657 } 21321 }
20658 // done 21322 // done
20659 return hasProblem; 21323 return hasProblem;
20660 } 21324 }
20661 21325
20662 /** 21326 /**
21327 * Return a display name for the given type that includes the path to the comp ilation unit in
21328 * which the type is defined.
21329 *
21330 * @param type the type for which an extended display name is to be returned
21331 * @return a display name that can help distiguish between two types with the same name
21332 */
21333 String getExtendedDisplayName(Type2 type) {
21334 Element element = type.element;
21335 if (element != null) {
21336 Source source = element.source;
21337 if (source != null) {
21338 return "${type.displayName} (${source.fullName})";
21339 }
21340 }
21341 return type.displayName;
21342 }
21343
21344 /**
20663 * Returns the Type (return type) for a given getter. 21345 * Returns the Type (return type) for a given getter.
20664 * 21346 *
20665 * @param propertyAccessorElement 21347 * @param propertyAccessorElement
20666 * @return The type of the given getter. 21348 * @return The type of the given getter.
20667 */ 21349 */
20668 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) { 21350 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) {
20669 FunctionType functionType = propertyAccessorElement.type; 21351 FunctionType functionType = propertyAccessorElement.type;
20670 if (functionType != null) { 21352 if (functionType != null) {
20671 return functionType.returnType; 21353 return functionType.returnType;
20672 } else { 21354 } else {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
20925 if (parent is CommentReference) { 21607 if (parent is CommentReference) {
20926 CommentReference commentReference = parent; 21608 CommentReference commentReference = parent;
20927 if (commentReference.newKeyword != null) { 21609 if (commentReference.newKeyword != null) {
20928 return true; 21610 return true;
20929 } 21611 }
20930 } 21612 }
20931 return false; 21613 return false;
20932 } 21614 }
20933 21615
20934 bool isUserDefinedObject(EvaluationResultImpl result) => result == null || (re sult is ValidResult && result.isUserDefinedObject); 21616 bool isUserDefinedObject(EvaluationResultImpl result) => result == null || (re sult is ValidResult && result.isUserDefinedObject);
20935
20936 /**
20937 * Return `true` iff the passed [ClassElement] has a concrete implementation o f the
20938 * passed accessor name in the superclass chain.
20939 */
20940 bool memberHasConcreteAccessorImplementationInSuperclassChain(ClassElement cla ssElement, String accessorName, List<ClassElement> superclassChain) {
20941 if (superclassChain.contains(classElement)) {
20942 return false;
20943 } else {
20944 superclassChain.add(classElement);
20945 }
20946 for (PropertyAccessorElement accessor in classElement.accessors) {
20947 if (accessor.name == accessorName) {
20948 if (!accessor.isAbstract) {
20949 return true;
20950 }
20951 }
20952 }
20953 for (InterfaceType mixinType in classElement.mixins) {
20954 if (mixinType != null) {
20955 ClassElement mixinElement = mixinType.element;
20956 if (mixinElement != null) {
20957 for (PropertyAccessorElement accessor in mixinElement.accessors) {
20958 if (accessor.name == accessorName) {
20959 if (!accessor.isAbstract) {
20960 return true;
20961 }
20962 }
20963 }
20964 }
20965 }
20966 }
20967 InterfaceType superType = classElement.supertype;
20968 if (superType != null) {
20969 ClassElement superClassElt = superType.element;
20970 if (superClassElt != null) {
20971 return memberHasConcreteAccessorImplementationInSuperclassChain(superCla ssElt, accessorName, superclassChain);
20972 }
20973 }
20974 return false;
20975 }
20976
20977 /**
20978 * Return `true` iff the passed [ClassElement] has a concrete implementation o f the
20979 * passed method name in the superclass chain.
20980 */
20981 bool memberHasConcreteMethodImplementationInSuperclassChain(ClassElement class Element, String methodName, List<ClassElement> superclassChain) {
20982 if (superclassChain.contains(classElement)) {
20983 return false;
20984 } else {
20985 superclassChain.add(classElement);
20986 }
20987 for (MethodElement method in classElement.methods) {
20988 if (method.name == methodName) {
20989 if (!method.isAbstract) {
20990 return true;
20991 }
20992 }
20993 }
20994 for (InterfaceType mixinType in classElement.mixins) {
20995 if (mixinType != null) {
20996 ClassElement mixinElement = mixinType.element;
20997 if (mixinElement != null) {
20998 for (MethodElement method in mixinElement.methods) {
20999 if (method.name == methodName) {
21000 if (!method.isAbstract) {
21001 return true;
21002 }
21003 }
21004 }
21005 }
21006 }
21007 }
21008 InterfaceType superType = classElement.supertype;
21009 if (superType != null) {
21010 ClassElement superClassElt = superType.element;
21011 if (superClassElt != null) {
21012 return memberHasConcreteMethodImplementationInSuperclassChain(superClass Elt, methodName, superclassChain);
21013 }
21014 }
21015 return false;
21016 }
21017 } 21617 }
21018 21618
21019 /** 21619 /**
21020 * This enum holds one of four states of a field initialization state through a constructor 21620 * This enum holds one of four states of a field initialization state through a constructor
21021 * signature, not initialized, initialized in the field declaration, initialized in the field 21621 * signature, not initialized, initialized in the field declaration, initialized in the field
21022 * formal, and finally, initialized in the initializers list. 21622 * formal, and finally, initialized in the initializers list.
21023 */ 21623 */
21024 class INIT_STATE extends Enum<INIT_STATE> { 21624 class INIT_STATE extends Enum<INIT_STATE> {
21025 static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0); 21625 static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0);
21026 21626
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
21162 * @param correction the template used to create the correction to be displaye d for the error 21762 * @param correction the template used to create the correction to be displaye d for the error
21163 */ 21763 */
21164 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri ng correction) : super(name, ordinal) { 21764 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri ng correction) : super(name, ordinal) {
21165 this.correction9 = correction; 21765 this.correction9 = correction;
21166 } 21766 }
21167 21767
21168 String get correction => correction9; 21768 String get correction => correction9;
21169 21769
21170 ErrorSeverity get errorSeverity => type.severity; 21770 ErrorSeverity get errorSeverity => type.severity;
21171 } 21771 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698