| 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 |