OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |