| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 63 |
| 64 static String _NG_CALLBACK = "NgCallback"; | 64 static String _NG_CALLBACK = "NgCallback"; |
| 65 | 65 |
| 66 static String _NG_ONE_WAY = "NgOneWay"; | 66 static String _NG_ONE_WAY = "NgOneWay"; |
| 67 | 67 |
| 68 static String _NG_ONE_WAY_ONE_TIME = "NgOneWayOneTime"; | 68 static String _NG_ONE_WAY_ONE_TIME = "NgOneWayOneTime"; |
| 69 | 69 |
| 70 static String _NG_TWO_WAY = "NgTwoWay"; | 70 static String _NG_TWO_WAY = "NgTwoWay"; |
| 71 | 71 |
| 72 static Element getElement(ASTNode node, int offset) { | 72 static Element getElement(ASTNode node, int offset) { |
| 73 // maybe no node |
| 73 if (node == null) { | 74 if (node == null) { |
| 74 return null; | 75 return null; |
| 75 } | 76 } |
| 77 // prepare enclosing ClassDeclaration |
| 76 ClassDeclaration classDeclaration = node.getAncestor(ClassDeclaration); | 78 ClassDeclaration classDeclaration = node.getAncestor(ClassDeclaration); |
| 77 if (classDeclaration == null) { | 79 if (classDeclaration == null) { |
| 78 return null; | 80 return null; |
| 79 } | 81 } |
| 82 // prepare ClassElement |
| 80 ClassElement classElement = classDeclaration.element; | 83 ClassElement classElement = classDeclaration.element; |
| 81 if (classElement == null) { | 84 if (classElement == null) { |
| 82 return null; | 85 return null; |
| 83 } | 86 } |
| 87 // check toolkit objects |
| 84 for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) { | 88 for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) { |
| 85 List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARR
AY; | 89 List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARR
AY; |
| 90 // try properties of AngularComponentElement |
| 86 if (toolkitObject is AngularComponentElement) { | 91 if (toolkitObject is AngularComponentElement) { |
| 87 AngularComponentElement component = toolkitObject; | 92 AngularComponentElement component = toolkitObject; |
| 88 properties = component.properties; | 93 properties = component.properties; |
| 89 } | 94 } |
| 95 // try properties of AngularDirectiveElement |
| 90 if (toolkitObject is AngularDirectiveElement) { | 96 if (toolkitObject is AngularDirectiveElement) { |
| 91 AngularDirectiveElement directive = toolkitObject; | 97 AngularDirectiveElement directive = toolkitObject; |
| 92 properties = directive.properties; | 98 properties = directive.properties; |
| 93 } | 99 } |
| 100 // check properties |
| 94 for (AngularPropertyElement property in properties) { | 101 for (AngularPropertyElement property in properties) { |
| 102 // property name (use complete node range) |
| 95 int propertyOffset = property.nameOffset; | 103 int propertyOffset = property.nameOffset; |
| 96 int propertyEnd = propertyOffset + property.name.length; | 104 int propertyEnd = propertyOffset + property.name.length; |
| 97 if (node.offset <= propertyOffset && propertyEnd < node.end) { | 105 if (node.offset <= propertyOffset && propertyEnd < node.end) { |
| 98 return property; | 106 return property; |
| 99 } | 107 } |
| 108 // field name (use complete node range, including @, => and <=>) |
| 100 FieldElement field = property.field; | 109 FieldElement field = property.field; |
| 101 if (field != null) { | 110 if (field != null) { |
| 102 int fieldOffset = property.fieldNameOffset; | 111 int fieldOffset = property.fieldNameOffset; |
| 103 int fieldEnd = fieldOffset + field.name.length; | 112 int fieldEnd = fieldOffset + field.name.length; |
| 104 if (node.offset <= fieldOffset && fieldEnd < node.end) { | 113 if (node.offset <= fieldOffset && fieldEnd < node.end) { |
| 105 return field; | 114 return field; |
| 106 } | 115 } |
| 107 } | 116 } |
| 108 } | 117 } |
| 109 } | 118 } |
| 119 // no Element |
| 110 return null; | 120 return null; |
| 111 } | 121 } |
| 112 | 122 |
| 113 /** | 123 /** |
| 114 * Checks if given [Type] is an Angular <code>Module</code> or its subclass. | 124 * Checks if given [Type] is an Angular <code>Module</code> or its subclass. |
| 115 */ | 125 */ |
| 116 static bool isModule(Type2 type) { | 126 static bool isModule(Type2 type) { |
| 117 if (type is! InterfaceType) { | 127 if (type is! InterfaceType) { |
| 118 return false; | 128 return false; |
| 119 } | 129 } |
| 120 InterfaceType interfaceType = type as InterfaceType; | 130 InterfaceType interfaceType = type as InterfaceType; |
| 131 // check hierarchy |
| 121 Set<Type2> seenTypes = new Set(); | 132 Set<Type2> seenTypes = new Set(); |
| 122 while (interfaceType != null) { | 133 while (interfaceType != null) { |
| 134 // check for recursion |
| 123 if (!seenTypes.add(interfaceType)) { | 135 if (!seenTypes.add(interfaceType)) { |
| 124 return false; | 136 return false; |
| 125 } | 137 } |
| 138 // check for "Module" |
| 126 if (interfaceType.element.name == "Module") { | 139 if (interfaceType.element.name == "Module") { |
| 127 return true; | 140 return true; |
| 128 } | 141 } |
| 142 // try supertype |
| 129 interfaceType = interfaceType.superclass; | 143 interfaceType = interfaceType.superclass; |
| 130 } | 144 } |
| 145 // no |
| 131 return false; | 146 return false; |
| 132 } | 147 } |
| 133 | 148 |
| 134 /** | 149 /** |
| 135 * Parses given selector text and returns [AngularSelectorElement]. May be `nu
ll` if | 150 * Parses given selector text and returns [AngularSelectorElement]. May be `nu
ll` if |
| 136 * cannot parse. | 151 * cannot parse. |
| 137 */ | 152 */ |
| 138 static AngularSelectorElement parseSelector(int offset, String text) { | 153 static AngularSelectorElement parseSelector(int offset, String text) { |
| 139 if (text.startsWith("[") && text.endsWith("]")) { | 154 if (text.startsWith("[") && text.endsWith("]")) { |
| 140 int nameOffset = offset + "[".length; | 155 int nameOffset = offset + "[".length; |
| 141 String attributeName = text.substring(1, text.length - 1); | 156 String attributeName = text.substring(1, text.length - 1); |
| 157 // TODO(scheglov) report warning if there are spaces between [ and identif
ier |
| 142 return new HasAttributeSelectorElementImpl(attributeName, nameOffset); | 158 return new HasAttributeSelectorElementImpl(attributeName, nameOffset); |
| 143 } | 159 } |
| 144 if (StringUtilities.isTagName(text)) { | 160 if (StringUtilities.isTagName(text)) { |
| 145 return new IsTagSelectorElementImpl(text, offset); | 161 return new IsTagSelectorElementImpl(text, offset); |
| 146 } | 162 } |
| 147 return null; | 163 return null; |
| 148 } | 164 } |
| 149 | 165 |
| 150 /** | 166 /** |
| 151 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio
n]. | 167 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio
n]. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 this._errorListener = errorListener; | 247 this._errorListener = errorListener; |
| 232 this._source = source; | 248 this._source = source; |
| 233 } | 249 } |
| 234 | 250 |
| 235 /** | 251 /** |
| 236 * Builds Angular specific element models and adds them to the existing Dart e
lements. | 252 * Builds Angular specific element models and adds them to the existing Dart e
lements. |
| 237 * | 253 * |
| 238 * @param unit the compilation unit with built Dart element models | 254 * @param unit the compilation unit with built Dart element models |
| 239 */ | 255 */ |
| 240 void build(CompilationUnit unit) { | 256 void build(CompilationUnit unit) { |
| 257 // process classes |
| 241 for (CompilationUnitMember unitMember in unit.declarations) { | 258 for (CompilationUnitMember unitMember in unit.declarations) { |
| 242 if (unitMember is ClassDeclaration) { | 259 if (unitMember is ClassDeclaration) { |
| 243 this._classDeclaration = unitMember; | 260 this._classDeclaration = unitMember; |
| 244 this._classElement = _classDeclaration.element as ClassElementImpl; | 261 this._classElement = _classDeclaration.element as ClassElementImpl; |
| 245 this._classToolkitObjects.clear(); | 262 this._classToolkitObjects.clear(); |
| 246 parseModuleClass(); | 263 parseModuleClass(); |
| 264 // process annotations |
| 247 NodeList<Annotation> annotations = _classDeclaration.metadata; | 265 NodeList<Annotation> annotations = _classDeclaration.metadata; |
| 248 for (Annotation annotation in annotations) { | 266 for (Annotation annotation in annotations) { |
| 249 this._annotation = annotation; | 267 this._annotation = annotation; |
| 268 // @NgFilter |
| 250 if (isAngularAnnotation2(_NG_FILTER)) { | 269 if (isAngularAnnotation2(_NG_FILTER)) { |
| 251 parseNgFilter(); | 270 parseNgFilter(); |
| 252 continue; | 271 continue; |
| 253 } | 272 } |
| 273 // @NgComponent |
| 254 if (isAngularAnnotation2(_NG_COMPONENT)) { | 274 if (isAngularAnnotation2(_NG_COMPONENT)) { |
| 255 parseNgComponent(); | 275 parseNgComponent(); |
| 256 continue; | 276 continue; |
| 257 } | 277 } |
| 278 // @NgController |
| 258 if (isAngularAnnotation2(_NG_CONTROLLER)) { | 279 if (isAngularAnnotation2(_NG_CONTROLLER)) { |
| 259 parseNgController(); | 280 parseNgController(); |
| 260 continue; | 281 continue; |
| 261 } | 282 } |
| 283 // @NgDirective |
| 262 if (isAngularAnnotation2(_NG_DIRECTIVE)) { | 284 if (isAngularAnnotation2(_NG_DIRECTIVE)) { |
| 263 parseNgDirective(); | 285 parseNgDirective(); |
| 264 continue; | 286 continue; |
| 265 } | 287 } |
| 266 } | 288 } |
| 289 // set toolkit objects |
| 267 if (!_classToolkitObjects.isEmpty) { | 290 if (!_classToolkitObjects.isEmpty) { |
| 268 List<ToolkitObjectElement> objects = _classToolkitObjects; | 291 List<ToolkitObjectElement> objects = _classToolkitObjects; |
| 269 _classElement.toolkitObjects = new List.from(objects); | 292 _classElement.toolkitObjects = new List.from(objects); |
| 270 } | 293 } |
| 271 } | 294 } |
| 272 } | 295 } |
| 296 // process modules in variables |
| 273 parseModuleVariables(unit); | 297 parseModuleVariables(unit); |
| 274 } | 298 } |
| 275 | 299 |
| 276 /** | 300 /** |
| 277 * Creates [AngularModuleElementImpl] for given information. | 301 * Creates [AngularModuleElementImpl] for given information. |
| 278 */ | 302 */ |
| 279 AngularModuleElementImpl createModuleElement(List<AngularModuleElement> childM
odules, List<ClassElement> keyTypes) { | 303 AngularModuleElementImpl createModuleElement(List<AngularModuleElement> childM
odules, List<ClassElement> keyTypes) { |
| 280 AngularModuleElementImpl module = new AngularModuleElementImpl(); | 304 AngularModuleElementImpl module = new AngularModuleElementImpl(); |
| 281 module.childModules = new List.from(childModules); | 305 module.childModules = new List.from(childModules); |
| 282 module.keyTypes = new List.from(keyTypes); | 306 module.keyTypes = new List.from(keyTypes); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 } | 380 } |
| 357 | 381 |
| 358 /** | 382 /** |
| 359 * Analyzes [classDeclaration] and if it is a module, creates [AngularModuleEl
ement] | 383 * Analyzes [classDeclaration] and if it is a module, creates [AngularModuleEl
ement] |
| 360 * model for it. | 384 * model for it. |
| 361 */ | 385 */ |
| 362 void parseModuleClass() { | 386 void parseModuleClass() { |
| 363 if (!isModule4) { | 387 if (!isModule4) { |
| 364 return; | 388 return; |
| 365 } | 389 } |
| 390 // check install(), type() and value() invocations |
| 366 List<AngularModuleElement> childModules = []; | 391 List<AngularModuleElement> childModules = []; |
| 367 List<ClassElement> keyTypes = []; | 392 List<ClassElement> keyTypes = []; |
| 368 _classDeclaration.accept(new RecursiveASTVisitor_AngularCompilationUnitBuild
er_parseModuleClass(this, childModules, keyTypes)); | 393 _classDeclaration.accept(new RecursiveASTVisitor_AngularCompilationUnitBuild
er_parseModuleClass(this, childModules, keyTypes)); |
| 394 // set module element |
| 369 AngularModuleElementImpl module = createModuleElement(childModules, keyTypes
); | 395 AngularModuleElementImpl module = createModuleElement(childModules, keyTypes
); |
| 370 _classToolkitObjects.add(module); | 396 _classToolkitObjects.add(module); |
| 371 } | 397 } |
| 372 | 398 |
| 373 /** | 399 /** |
| 374 * Checks if given [MethodInvocation] is an interesting <code>Module</code> me
thod | 400 * Checks if given [MethodInvocation] is an interesting <code>Module</code> me
thod |
| 375 * invocation and remembers corresponding elements into lists. | 401 * invocation and remembers corresponding elements into lists. |
| 376 */ | 402 */ |
| 377 void parseModuleInvocation(MethodInvocation node, List<AngularModuleElement> c
hildModules, List<ClassElement> keyTypes) { | 403 void parseModuleInvocation(MethodInvocation node, List<AngularModuleElement> c
hildModules, List<ClassElement> keyTypes) { |
| 378 String methodName = node.methodName.name; | 404 String methodName = node.methodName.name; |
| 379 NodeList<Expression> arguments = node.argumentList.arguments; | 405 NodeList<Expression> arguments = node.argumentList.arguments; |
| 406 // install() |
| 380 if (arguments.length == 1 && methodName == "install") { | 407 if (arguments.length == 1 && methodName == "install") { |
| 381 Type2 argType = arguments[0].bestType; | 408 Type2 argType = arguments[0].bestType; |
| 382 if (argType is InterfaceType) { | 409 if (argType is InterfaceType) { |
| 383 ClassElement argElement = argType.element; | 410 ClassElement argElement = argType.element; |
| 384 List<ToolkitObjectElement> toolkitObjects = argElement.toolkitObjects; | 411 List<ToolkitObjectElement> toolkitObjects = argElement.toolkitObjects; |
| 385 for (ToolkitObjectElement toolkitObject in toolkitObjects) { | 412 for (ToolkitObjectElement toolkitObject in toolkitObjects) { |
| 386 if (toolkitObject is AngularModuleElement) { | 413 if (toolkitObject is AngularModuleElement) { |
| 387 childModules.add(toolkitObject); | 414 childModules.add(toolkitObject); |
| 388 } | 415 } |
| 389 } | 416 } |
| 390 } | 417 } |
| 391 return; | 418 return; |
| 392 } | 419 } |
| 420 // type() and value() |
| 393 if (arguments.length >= 1 && (methodName == "type" || methodName == "value")
) { | 421 if (arguments.length >= 1 && (methodName == "type" || methodName == "value")
) { |
| 394 Expression arg = arguments[0]; | 422 Expression arg = arguments[0]; |
| 395 if (arg is Identifier) { | 423 if (arg is Identifier) { |
| 396 Element argElement = arg.staticElement; | 424 Element argElement = arg.staticElement; |
| 397 if (argElement is ClassElement) { | 425 if (argElement is ClassElement) { |
| 398 keyTypes.add(argElement); | 426 keyTypes.add(argElement); |
| 399 } | 427 } |
| 400 } | 428 } |
| 401 return; | 429 return; |
| 402 } | 430 } |
| 403 } | 431 } |
| 404 | 432 |
| 405 /** | 433 /** |
| 406 * Checks every local variable in the given unit to see if it is a <code>Modul
e</code> and creates | 434 * Checks every local variable in the given unit to see if it is a <code>Modul
e</code> and creates |
| 407 * [AngularModuleElement] for it. | 435 * [AngularModuleElement] for it. |
| 408 */ | 436 */ |
| 409 void parseModuleVariables(CompilationUnit unit) { | 437 void parseModuleVariables(CompilationUnit unit) { |
| 410 unit.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModul
eVariables(this)); | 438 unit.accept(new RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModul
eVariables(this)); |
| 411 } | 439 } |
| 412 | 440 |
| 413 void parseNgComponent() { | 441 void parseNgComponent() { |
| 414 bool isValid = true; | 442 bool isValid = true; |
| 443 // publishAs |
| 415 if (!hasStringArgument(_PUBLISH_AS)) { | 444 if (!hasStringArgument(_PUBLISH_AS)) { |
| 416 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); | 445 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); |
| 417 isValid = false; | 446 isValid = false; |
| 418 } | 447 } |
| 448 // selector |
| 419 AngularSelectorElement selector = null; | 449 AngularSelectorElement selector = null; |
| 420 if (!hasStringArgument(_SELECTOR)) { | 450 if (!hasStringArgument(_SELECTOR)) { |
| 421 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); | 451 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 422 isValid = false; | 452 isValid = false; |
| 423 } else { | 453 } else { |
| 424 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); | 454 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); |
| 425 selector = parseSelector2(selectorLiteral); | 455 selector = parseSelector2(selectorLiteral); |
| 426 if (selector == null) { | 456 if (selector == null) { |
| 427 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); | 457 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); |
| 428 isValid = false; | 458 isValid = false; |
| 429 } | 459 } |
| 430 } | 460 } |
| 461 // templateUrl |
| 431 if (!hasStringArgument(_TEMPLATE_URL)) { | 462 if (!hasStringArgument(_TEMPLATE_URL)) { |
| 432 reportErrorForAnnotation(AngularCode.MISSING_TEMPLATE_URL, []); | 463 reportErrorForAnnotation(AngularCode.MISSING_TEMPLATE_URL, []); |
| 433 isValid = false; | 464 isValid = false; |
| 434 } | 465 } |
| 466 // cssUrl |
| 435 if (!hasStringArgument(_CSS_URL)) { | 467 if (!hasStringArgument(_CSS_URL)) { |
| 436 reportErrorForAnnotation(AngularCode.MISSING_CSS_URL, []); | 468 reportErrorForAnnotation(AngularCode.MISSING_CSS_URL, []); |
| 437 isValid = false; | 469 isValid = false; |
| 438 } | 470 } |
| 471 // create |
| 439 if (isValid) { | 472 if (isValid) { |
| 440 String name = getStringArgument(_PUBLISH_AS); | 473 String name = getStringArgument(_PUBLISH_AS); |
| 441 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); | 474 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); |
| 442 String templateUri = getStringArgument(_TEMPLATE_URL); | 475 String templateUri = getStringArgument(_TEMPLATE_URL); |
| 443 int templateUriOffset = getStringArgumentOffset(_TEMPLATE_URL); | 476 int templateUriOffset = getStringArgumentOffset(_TEMPLATE_URL); |
| 444 String styleUri = getStringArgument(_CSS_URL); | 477 String styleUri = getStringArgument(_CSS_URL); |
| 445 int styleUriOffset = getStringArgumentOffset(_CSS_URL); | 478 int styleUriOffset = getStringArgumentOffset(_CSS_URL); |
| 446 AngularComponentElementImpl element = new AngularComponentElementImpl(name
, nameOffset); | 479 AngularComponentElementImpl element = new AngularComponentElementImpl(name
, nameOffset); |
| 447 element.selector = selector; | 480 element.selector = selector; |
| 448 element.templateUri = templateUri; | 481 element.templateUri = templateUri; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 468 | 501 |
| 469 /** | 502 /** |
| 470 * Parses [AngularPropertyElement]s from [annotation]. | 503 * Parses [AngularPropertyElement]s from [annotation]. |
| 471 */ | 504 */ |
| 472 void parseNgComponentProperties_fromFields(List<AngularPropertyElement> proper
ties) { | 505 void parseNgComponentProperties_fromFields(List<AngularPropertyElement> proper
ties) { |
| 473 NodeList<ClassMember> members = _classDeclaration.members; | 506 NodeList<ClassMember> members = _classDeclaration.members; |
| 474 for (ClassMember member in members) { | 507 for (ClassMember member in members) { |
| 475 if (member is FieldDeclaration) { | 508 if (member is FieldDeclaration) { |
| 476 FieldDeclaration fieldDeclaration = member; | 509 FieldDeclaration fieldDeclaration = member; |
| 477 for (Annotation annotation in fieldDeclaration.metadata) { | 510 for (Annotation annotation in fieldDeclaration.metadata) { |
| 511 // prepare property kind (if property annotation at all) |
| 478 AngularPropertyKind kind = null; | 512 AngularPropertyKind kind = null; |
| 479 if (isAngularAnnotation(annotation, _NG_ATTR)) { | 513 if (isAngularAnnotation(annotation, _NG_ATTR)) { |
| 480 kind = AngularPropertyKind.ATTR; | 514 kind = AngularPropertyKind.ATTR; |
| 481 } else if (isAngularAnnotation(annotation, _NG_CALLBACK)) { | 515 } else if (isAngularAnnotation(annotation, _NG_CALLBACK)) { |
| 482 kind = AngularPropertyKind.CALLBACK; | 516 kind = AngularPropertyKind.CALLBACK; |
| 483 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY)) { | 517 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY)) { |
| 484 kind = AngularPropertyKind.ONE_WAY; | 518 kind = AngularPropertyKind.ONE_WAY; |
| 485 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY_ONE_TIME)) { | 519 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY_ONE_TIME)) { |
| 486 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; | 520 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; |
| 487 } else if (isAngularAnnotation(annotation, _NG_TWO_WAY)) { | 521 } else if (isAngularAnnotation(annotation, _NG_TWO_WAY)) { |
| 488 kind = AngularPropertyKind.TWO_WAY; | 522 kind = AngularPropertyKind.TWO_WAY; |
| 489 } | 523 } |
| 524 // add property |
| 490 if (kind != null) { | 525 if (kind != null) { |
| 491 SimpleStringLiteral nameLiteral = getOnlySimpleStringLiteralArgument
(annotation); | 526 SimpleStringLiteral nameLiteral = getOnlySimpleStringLiteralArgument
(annotation); |
| 492 FieldElement field = getOnlyFieldElement(fieldDeclaration); | 527 FieldElement field = getOnlyFieldElement(fieldDeclaration); |
| 493 if (nameLiteral != null && field != null) { | 528 if (nameLiteral != null && field != null) { |
| 494 AngularPropertyElementImpl property = new AngularPropertyElementIm
pl(nameLiteral.value, nameLiteral.valueOffset); | 529 AngularPropertyElementImpl property = new AngularPropertyElementIm
pl(nameLiteral.value, nameLiteral.valueOffset); |
| 495 property.field = field; | 530 property.field = field; |
| 496 property.propertyKind = kind; | 531 property.propertyKind = kind; |
| 497 properties.add(property); | 532 properties.add(property); |
| 498 } | 533 } |
| 499 } | 534 } |
| 500 } | 535 } |
| 501 } | 536 } |
| 502 } | 537 } |
| 503 } | 538 } |
| 504 | 539 |
| 505 /** | 540 /** |
| 506 * Parses [AngularPropertyElement]s from [annotation]. | 541 * Parses [AngularPropertyElement]s from [annotation]. |
| 507 */ | 542 */ |
| 508 void parseNgComponentProperties_fromMap(List<AngularPropertyElement> propertie
s) { | 543 void parseNgComponentProperties_fromMap(List<AngularPropertyElement> propertie
s) { |
| 509 Expression mapExpression = getArgument("map"); | 544 Expression mapExpression = getArgument("map"); |
| 545 // may be not properties |
| 510 if (mapExpression == null) { | 546 if (mapExpression == null) { |
| 511 return; | 547 return; |
| 512 } | 548 } |
| 549 // prepare map literal |
| 513 if (mapExpression is! MapLiteral) { | 550 if (mapExpression is! MapLiteral) { |
| 514 reportError(mapExpression, AngularCode.INVALID_PROPERTY_MAP, []); | 551 reportError(mapExpression, AngularCode.INVALID_PROPERTY_MAP, []); |
| 515 return; | 552 return; |
| 516 } | 553 } |
| 517 MapLiteral mapLiteral = mapExpression as MapLiteral; | 554 MapLiteral mapLiteral = mapExpression as MapLiteral; |
| 555 // analyze map entries |
| 518 for (MapLiteralEntry entry in mapLiteral.entries) { | 556 for (MapLiteralEntry entry in mapLiteral.entries) { |
| 557 // prepare property name |
| 519 Expression nameExpression = entry.key; | 558 Expression nameExpression = entry.key; |
| 520 if (nameExpression is! SimpleStringLiteral) { | 559 if (nameExpression is! SimpleStringLiteral) { |
| 521 reportError(nameExpression, AngularCode.INVALID_PROPERTY_NAME, []); | 560 reportError(nameExpression, AngularCode.INVALID_PROPERTY_NAME, []); |
| 522 continue; | 561 continue; |
| 523 } | 562 } |
| 524 SimpleStringLiteral nameLiteral = nameExpression as SimpleStringLiteral; | 563 SimpleStringLiteral nameLiteral = nameExpression as SimpleStringLiteral; |
| 525 String name = nameLiteral.value; | 564 String name = nameLiteral.value; |
| 526 int nameOffset = nameLiteral.valueOffset; | 565 int nameOffset = nameLiteral.valueOffset; |
| 566 // prepare field specification |
| 527 Expression specExpression = entry.value; | 567 Expression specExpression = entry.value; |
| 528 if (specExpression is! SimpleStringLiteral) { | 568 if (specExpression is! SimpleStringLiteral) { |
| 529 reportError(specExpression, AngularCode.INVALID_PROPERTY_SPEC, []); | 569 reportError(specExpression, AngularCode.INVALID_PROPERTY_SPEC, []); |
| 530 continue; | 570 continue; |
| 531 } | 571 } |
| 532 SimpleStringLiteral specLiteral = specExpression as SimpleStringLiteral; | 572 SimpleStringLiteral specLiteral = specExpression as SimpleStringLiteral; |
| 533 String spec = specLiteral.value; | 573 String spec = specLiteral.value; |
| 574 // parse binding kind and field name |
| 534 AngularPropertyKind kind; | 575 AngularPropertyKind kind; |
| 535 int fieldNameOffset; | 576 int fieldNameOffset; |
| 536 if (spec.startsWith(_PREFIX_ATTR)) { | 577 if (spec.startsWith(_PREFIX_ATTR)) { |
| 537 kind = AngularPropertyKind.ATTR; | 578 kind = AngularPropertyKind.ATTR; |
| 538 fieldNameOffset = 1; | 579 fieldNameOffset = 1; |
| 539 } else if (spec.startsWith(_PREFIX_CALLBACK)) { | 580 } else if (spec.startsWith(_PREFIX_CALLBACK)) { |
| 540 kind = AngularPropertyKind.CALLBACK; | 581 kind = AngularPropertyKind.CALLBACK; |
| 541 fieldNameOffset = 1; | 582 fieldNameOffset = 1; |
| 542 } else if (spec.startsWith(_PREFIX_ONE_WAY_ONE_TIME)) { | 583 } else if (spec.startsWith(_PREFIX_ONE_WAY_ONE_TIME)) { |
| 543 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; | 584 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; |
| 544 fieldNameOffset = 3; | 585 fieldNameOffset = 3; |
| 545 } else if (spec.startsWith(_PREFIX_ONE_WAY)) { | 586 } else if (spec.startsWith(_PREFIX_ONE_WAY)) { |
| 546 kind = AngularPropertyKind.ONE_WAY; | 587 kind = AngularPropertyKind.ONE_WAY; |
| 547 fieldNameOffset = 2; | 588 fieldNameOffset = 2; |
| 548 } else if (spec.startsWith(_PREFIX_TWO_WAY)) { | 589 } else if (spec.startsWith(_PREFIX_TWO_WAY)) { |
| 549 kind = AngularPropertyKind.TWO_WAY; | 590 kind = AngularPropertyKind.TWO_WAY; |
| 550 fieldNameOffset = 3; | 591 fieldNameOffset = 3; |
| 551 } else { | 592 } else { |
| 552 reportError(specLiteral, AngularCode.INVALID_PROPERTY_KIND, [spec]); | 593 reportError(specLiteral, AngularCode.INVALID_PROPERTY_KIND, [spec]); |
| 553 continue; | 594 continue; |
| 554 } | 595 } |
| 555 String fieldName = spec.substring(fieldNameOffset); | 596 String fieldName = spec.substring(fieldNameOffset); |
| 556 fieldNameOffset += specLiteral.valueOffset; | 597 fieldNameOffset += specLiteral.valueOffset; |
| 598 // prepare field |
| 557 FieldElement field = _classElement.getField(fieldName); | 599 FieldElement field = _classElement.getField(fieldName); |
| 558 if (field == null) { | 600 if (field == null) { |
| 559 reportError2(fieldNameOffset, fieldName.length, AngularCode.INVALID_PROP
ERTY_FIELD, [fieldName]); | 601 reportError2(fieldNameOffset, fieldName.length, AngularCode.INVALID_PROP
ERTY_FIELD, [fieldName]); |
| 560 continue; | 602 continue; |
| 561 } | 603 } |
| 604 // add property |
| 562 AngularPropertyElementImpl property = new AngularPropertyElementImpl(name,
nameOffset); | 605 AngularPropertyElementImpl property = new AngularPropertyElementImpl(name,
nameOffset); |
| 563 property.field = field; | 606 property.field = field; |
| 564 property.propertyKind = kind; | 607 property.propertyKind = kind; |
| 565 property.fieldNameOffset = fieldNameOffset; | 608 property.fieldNameOffset = fieldNameOffset; |
| 566 properties.add(property); | 609 properties.add(property); |
| 567 } | 610 } |
| 568 } | 611 } |
| 569 | 612 |
| 570 void parseNgController() { | 613 void parseNgController() { |
| 571 bool isValid = true; | 614 bool isValid = true; |
| 615 // publishAs |
| 572 if (!hasStringArgument(_PUBLISH_AS)) { | 616 if (!hasStringArgument(_PUBLISH_AS)) { |
| 573 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); | 617 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); |
| 574 isValid = false; | 618 isValid = false; |
| 575 } | 619 } |
| 620 // selector |
| 576 AngularSelectorElement selector = null; | 621 AngularSelectorElement selector = null; |
| 577 if (!hasStringArgument(_SELECTOR)) { | 622 if (!hasStringArgument(_SELECTOR)) { |
| 578 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); | 623 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 579 isValid = false; | 624 isValid = false; |
| 580 } else { | 625 } else { |
| 581 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); | 626 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); |
| 582 selector = parseSelector2(selectorLiteral); | 627 selector = parseSelector2(selectorLiteral); |
| 583 if (selector == null) { | 628 if (selector == null) { |
| 584 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); | 629 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); |
| 585 isValid = false; | 630 isValid = false; |
| 586 } | 631 } |
| 587 } | 632 } |
| 633 // create |
| 588 if (isValid) { | 634 if (isValid) { |
| 589 String name = getStringArgument(_PUBLISH_AS); | 635 String name = getStringArgument(_PUBLISH_AS); |
| 590 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); | 636 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); |
| 591 AngularControllerElementImpl element = new AngularControllerElementImpl(na
me, nameOffset); | 637 AngularControllerElementImpl element = new AngularControllerElementImpl(na
me, nameOffset); |
| 592 element.selector = selector; | 638 element.selector = selector; |
| 593 _classToolkitObjects.add(element); | 639 _classToolkitObjects.add(element); |
| 594 } | 640 } |
| 595 } | 641 } |
| 596 | 642 |
| 597 void parseNgDirective() { | 643 void parseNgDirective() { |
| 598 bool isValid = true; | 644 bool isValid = true; |
| 645 // selector |
| 599 AngularSelectorElement selector = null; | 646 AngularSelectorElement selector = null; |
| 600 if (!hasStringArgument(_SELECTOR)) { | 647 if (!hasStringArgument(_SELECTOR)) { |
| 601 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); | 648 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 602 isValid = false; | 649 isValid = false; |
| 603 } else { | 650 } else { |
| 604 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); | 651 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); |
| 605 selector = parseSelector2(selectorLiteral); | 652 selector = parseSelector2(selectorLiteral); |
| 606 if (selector == null) { | 653 if (selector == null) { |
| 607 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); | 654 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); |
| 608 isValid = false; | 655 isValid = false; |
| 609 } | 656 } |
| 610 } | 657 } |
| 658 // create |
| 611 if (isValid) { | 659 if (isValid) { |
| 612 int offset = _annotation.offset; | 660 int offset = _annotation.offset; |
| 613 AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offs
et); | 661 AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offs
et); |
| 614 element.selector = selector; | 662 element.selector = selector; |
| 615 element.properties = parseNgComponentProperties(false); | 663 element.properties = parseNgComponentProperties(false); |
| 616 _classToolkitObjects.add(element); | 664 _classToolkitObjects.add(element); |
| 617 } | 665 } |
| 618 } | 666 } |
| 619 | 667 |
| 620 void parseNgFilter() { | 668 void parseNgFilter() { |
| 621 bool isValid = true; | 669 bool isValid = true; |
| 670 // name |
| 622 if (!hasStringArgument(_NAME)) { | 671 if (!hasStringArgument(_NAME)) { |
| 623 reportErrorForAnnotation(AngularCode.MISSING_NAME, []); | 672 reportErrorForAnnotation(AngularCode.MISSING_NAME, []); |
| 624 isValid = false; | 673 isValid = false; |
| 625 } | 674 } |
| 675 // create |
| 626 if (isValid) { | 676 if (isValid) { |
| 627 String name = getStringArgument(_NAME); | 677 String name = getStringArgument(_NAME); |
| 628 int nameOffset = getStringArgumentOffset(_NAME); | 678 int nameOffset = getStringArgumentOffset(_NAME); |
| 629 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset)); | 679 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset)); |
| 630 } | 680 } |
| 631 } | 681 } |
| 632 | 682 |
| 633 void reportError(ASTNode node, ErrorCode errorCode, List<Object> arguments) { | 683 void reportError(ASTNode node, ErrorCode errorCode, List<Object> arguments) { |
| 634 int offset = node.offset; | 684 int offset = node.offset; |
| 635 int length = node.length; | 685 int length = node.length; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables(this.An
gularCompilationUnitBuilder_this) : super(); | 723 RecursiveASTVisitor_AngularCompilationUnitBuilder_parseModuleVariables(this.An
gularCompilationUnitBuilder_this) : super(); |
| 674 | 724 |
| 675 LocalVariableElementImpl _variable = null; | 725 LocalVariableElementImpl _variable = null; |
| 676 | 726 |
| 677 Expression _variableInit = null; | 727 Expression _variableInit = null; |
| 678 | 728 |
| 679 List<AngularModuleElement> _childModules = []; | 729 List<AngularModuleElement> _childModules = []; |
| 680 | 730 |
| 681 List<ClassElement> _keyTypes = []; | 731 List<ClassElement> _keyTypes = []; |
| 682 | 732 |
| 733 Object visitClassDeclaration(ClassDeclaration node) => null; |
| 734 |
| 683 Object visitFunctionDeclaration(FunctionDeclaration node) { | 735 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 684 _childModules.clear(); | 736 _childModules.clear(); |
| 685 _keyTypes.clear(); | 737 _keyTypes.clear(); |
| 686 super.visitFunctionDeclaration(node); | 738 super.visitFunctionDeclaration(node); |
| 687 if (_variable != null) { | 739 if (_variable != null) { |
| 688 AngularModuleElementImpl module = AngularCompilationUnitBuilder_this.creat
eModuleElement(_childModules, _keyTypes); | 740 AngularModuleElementImpl module = AngularCompilationUnitBuilder_this.creat
eModuleElement(_childModules, _keyTypes); |
| 689 _variable.toolkitObjects = <ToolkitObjectElement> [module]; | 741 _variable.toolkitObjects = <ToolkitObjectElement> [module]; |
| 690 } | 742 } |
| 691 return null; | 743 return null; |
| 692 } | 744 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 704 VariableElement element = node.element; | 756 VariableElement element = node.element; |
| 705 if (element is LocalVariableElementImpl && AngularCompilationUnitBuilder.isM
odule2(node)) { | 757 if (element is LocalVariableElementImpl && AngularCompilationUnitBuilder.isM
odule2(node)) { |
| 706 _variable = element; | 758 _variable = element; |
| 707 _variableInit = node.initializer; | 759 _variableInit = node.initializer; |
| 708 } | 760 } |
| 709 return super.visitVariableDeclaration(node); | 761 return super.visitVariableDeclaration(node); |
| 710 } | 762 } |
| 711 | 763 |
| 712 bool isVariableInvocation(MethodInvocation node) { | 764 bool isVariableInvocation(MethodInvocation node) { |
| 713 Expression target = node.realTarget; | 765 Expression target = node.realTarget; |
| 766 // var module = new Module()..type(t1)..type(t2); |
| 714 if (_variableInit is CascadeExpression && target != null && identical(target
.parent, _variableInit)) { | 767 if (_variableInit is CascadeExpression && target != null && identical(target
.parent, _variableInit)) { |
| 715 return true; | 768 return true; |
| 716 } | 769 } |
| 770 // var module = new Module(); |
| 771 // module.type(t); |
| 717 if (target is Identifier) { | 772 if (target is Identifier) { |
| 718 Element targetElement = target.staticElement; | 773 Element targetElement = target.staticElement; |
| 719 return identical(targetElement, _variable); | 774 return identical(targetElement, _variable); |
| 720 } | 775 } |
| 776 // no |
| 721 return false; | 777 return false; |
| 722 } | 778 } |
| 723 } | 779 } |
| 724 | 780 |
| 725 /** | 781 /** |
| 726 * Instances of the class `CompilationUnitBuilder` build an element model for a
single | 782 * Instances of the class `CompilationUnitBuilder` build an element model for a
single |
| 727 * compilation unit. | 783 * compilation unit. |
| 728 * | 784 * |
| 729 * @coverage dart.engine.resolver | 785 * @coverage dart.engine.resolver |
| 730 */ | 786 */ |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 visitChildren(holder, node); | 894 visitChildren(holder, node); |
| 839 SimpleIdentifier className = node.name; | 895 SimpleIdentifier className = node.name; |
| 840 ClassElementImpl element = new ClassElementImpl(className); | 896 ClassElementImpl element = new ClassElementImpl(className); |
| 841 List<TypeParameterElement> typeParameters = holder.typeParameters; | 897 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 842 List<Type2> typeArguments = createTypeParameterTypes(typeParameters); | 898 List<Type2> typeArguments = createTypeParameterTypes(typeParameters); |
| 843 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); | 899 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); |
| 844 interfaceType.typeArguments = typeArguments; | 900 interfaceType.typeArguments = typeArguments; |
| 845 element.type = interfaceType; | 901 element.type = interfaceType; |
| 846 List<ConstructorElement> constructors = holder.constructors; | 902 List<ConstructorElement> constructors = holder.constructors; |
| 847 if (constructors.length == 0) { | 903 if (constructors.length == 0) { |
| 904 // |
| 905 // Create the default constructor. |
| 906 // |
| 848 constructors = createDefaultConstructors(interfaceType); | 907 constructors = createDefaultConstructors(interfaceType); |
| 849 } | 908 } |
| 850 element.abstract = node.abstractKeyword != null; | 909 element.abstract = node.abstractKeyword != null; |
| 851 element.accessors = holder.accessors; | 910 element.accessors = holder.accessors; |
| 852 element.constructors = constructors; | 911 element.constructors = constructors; |
| 853 element.fields = holder.fields; | 912 element.fields = holder.fields; |
| 854 element.methods = holder.methods; | 913 element.methods = holder.methods; |
| 855 element.typeParameters = typeParameters; | 914 element.typeParameters = typeParameters; |
| 856 element.validMixin = _isValidMixin; | 915 element.validMixin = _isValidMixin; |
| 857 int functionTypeCount = _functionTypesToFix.length; | 916 int functionTypeCount = _functionTypesToFix.length; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 872 SimpleIdentifier className = node.name; | 931 SimpleIdentifier className = node.name; |
| 873 ClassElementImpl element = new ClassElementImpl(className); | 932 ClassElementImpl element = new ClassElementImpl(className); |
| 874 element.abstract = node.abstractKeyword != null; | 933 element.abstract = node.abstractKeyword != null; |
| 875 element.typedef = true; | 934 element.typedef = true; |
| 876 List<TypeParameterElement> typeParameters = holder.typeParameters; | 935 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 877 element.typeParameters = typeParameters; | 936 element.typeParameters = typeParameters; |
| 878 List<Type2> typeArguments = createTypeParameterTypes(typeParameters); | 937 List<Type2> typeArguments = createTypeParameterTypes(typeParameters); |
| 879 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); | 938 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); |
| 880 interfaceType.typeArguments = typeArguments; | 939 interfaceType.typeArguments = typeArguments; |
| 881 element.type = interfaceType; | 940 element.type = interfaceType; |
| 941 // set default constructor |
| 882 element.constructors = createDefaultConstructors(interfaceType); | 942 element.constructors = createDefaultConstructors(interfaceType); |
| 883 for (FunctionTypeImpl functionType in _functionTypesToFix) { | 943 for (FunctionTypeImpl functionType in _functionTypesToFix) { |
| 884 functionType.typeArguments = typeArguments; | 944 functionType.typeArguments = typeArguments; |
| 885 } | 945 } |
| 886 _functionTypesToFix = null; | 946 _functionTypesToFix = null; |
| 887 _currentHolder.addType(element); | 947 _currentHolder.addType(element); |
| 888 className.staticElement = element; | 948 className.staticElement = element; |
| 889 holder.validate(); | 949 holder.validate(); |
| 890 return null; | 950 return null; |
| 891 } | 951 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 SimpleIdentifier parameterName = node.parameter.identifier; | 1004 SimpleIdentifier parameterName = node.parameter.identifier; |
| 945 ParameterElementImpl parameter; | 1005 ParameterElementImpl parameter; |
| 946 if (node.parameter is FieldFormalParameter) { | 1006 if (node.parameter is FieldFormalParameter) { |
| 947 parameter = new DefaultFieldFormalParameterElementImpl(parameterName); | 1007 parameter = new DefaultFieldFormalParameterElementImpl(parameterName); |
| 948 } else { | 1008 } else { |
| 949 parameter = new DefaultParameterElementImpl(parameterName); | 1009 parameter = new DefaultParameterElementImpl(parameterName); |
| 950 } | 1010 } |
| 951 parameter.const3 = node.isConst; | 1011 parameter.const3 = node.isConst; |
| 952 parameter.final2 = node.isFinal; | 1012 parameter.final2 = node.isFinal; |
| 953 parameter.parameterKind = node.kind; | 1013 parameter.parameterKind = node.kind; |
| 1014 // set initializer, default value range |
| 954 Expression defaultValue = node.defaultValue; | 1015 Expression defaultValue = node.defaultValue; |
| 955 if (defaultValue != null) { | 1016 if (defaultValue != null) { |
| 956 visit(holder, defaultValue); | 1017 visit(holder, defaultValue); |
| 957 FunctionElementImpl initializer = new FunctionElementImpl.con2(defaultValu
e.beginToken.offset); | 1018 FunctionElementImpl initializer = new FunctionElementImpl.con2(defaultValu
e.beginToken.offset); |
| 958 initializer.functions = holder.functions; | 1019 initializer.functions = holder.functions; |
| 959 initializer.labels = holder.labels; | 1020 initializer.labels = holder.labels; |
| 960 initializer.localVariables = holder.localVariables; | 1021 initializer.localVariables = holder.localVariables; |
| 961 initializer.parameters = holder.parameters; | 1022 initializer.parameters = holder.parameters; |
| 962 initializer.synthetic = true; | 1023 initializer.synthetic = true; |
| 963 parameter.initializer = initializer; | 1024 parameter.initializer = initializer; |
| 964 parameter.setDefaultValueRange(defaultValue.offset, defaultValue.length); | 1025 parameter.setDefaultValueRange(defaultValue.offset, defaultValue.length); |
| 965 } | 1026 } |
| 1027 // visible range |
| 966 setParameterVisibleRange(node, parameter); | 1028 setParameterVisibleRange(node, parameter); |
| 967 _currentHolder.addParameter(parameter); | 1029 _currentHolder.addParameter(parameter); |
| 968 parameterName.staticElement = parameter; | 1030 parameterName.staticElement = parameter; |
| 969 node.parameter.accept(this); | 1031 node.parameter.accept(this); |
| 970 holder.validate(); | 1032 holder.validate(); |
| 971 return null; | 1033 return null; |
| 972 } | 1034 } |
| 973 | 1035 |
| 974 Object visitFieldDeclaration(FieldDeclaration node) { | 1036 Object visitFieldDeclaration(FieldDeclaration node) { |
| 975 bool wasInField = _inFieldContext; | 1037 bool wasInField = _inFieldContext; |
| 976 _inFieldContext = true; | 1038 _inFieldContext = true; |
| 977 try { | 1039 try { |
| 978 node.visitChildren(this); | 1040 node.visitChildren(this); |
| 979 } finally { | 1041 } finally { |
| 980 _inFieldContext = wasInField; | 1042 _inFieldContext = wasInField; |
| 981 } | 1043 } |
| 982 return null; | 1044 return null; |
| 983 } | 1045 } |
| 984 | 1046 |
| 985 Object visitFieldFormalParameter(FieldFormalParameter node) { | 1047 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 986 if (node.parent is! DefaultFormalParameter) { | 1048 if (node.parent is! DefaultFormalParameter) { |
| 987 SimpleIdentifier parameterName = node.identifier; | 1049 SimpleIdentifier parameterName = node.identifier; |
| 988 FieldFormalParameterElementImpl parameter = new FieldFormalParameterElemen
tImpl(parameterName); | 1050 FieldFormalParameterElementImpl parameter = new FieldFormalParameterElemen
tImpl(parameterName); |
| 989 parameter.const3 = node.isConst; | 1051 parameter.const3 = node.isConst; |
| 990 parameter.final2 = node.isFinal; | 1052 parameter.final2 = node.isFinal; |
| 991 parameter.parameterKind = node.kind; | 1053 parameter.parameterKind = node.kind; |
| 992 _currentHolder.addParameter(parameter); | 1054 _currentHolder.addParameter(parameter); |
| 993 parameterName.staticElement = parameter; | 1055 parameterName.staticElement = parameter; |
| 994 } | 1056 } |
| 1057 // |
| 1058 // The children of this parameter include any parameters defined on the type
of this parameter. |
| 1059 // |
| 995 ElementHolder holder = new ElementHolder(); | 1060 ElementHolder holder = new ElementHolder(); |
| 996 visitChildren(holder, node); | 1061 visitChildren(holder, node); |
| 997 (node.element as ParameterElementImpl).parameters = holder.parameters; | 1062 (node.element as ParameterElementImpl).parameters = holder.parameters; |
| 998 holder.validate(); | 1063 holder.validate(); |
| 999 return null; | 1064 return null; |
| 1000 } | 1065 } |
| 1001 | 1066 |
| 1002 Object visitFunctionDeclaration(FunctionDeclaration node) { | 1067 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 1003 FunctionExpression expression = node.functionExpression; | 1068 FunctionExpression expression = node.functionExpression; |
| 1004 if (expression != null) { | 1069 if (expression != null) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1025 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 1090 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
| 1026 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 1091 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
| 1027 } | 1092 } |
| 1028 } | 1093 } |
| 1029 _currentHolder.addFunction(element); | 1094 _currentHolder.addFunction(element); |
| 1030 expression.element = element; | 1095 expression.element = element; |
| 1031 functionName.staticElement = element; | 1096 functionName.staticElement = element; |
| 1032 } else { | 1097 } else { |
| 1033 SimpleIdentifier propertyNameNode = node.name; | 1098 SimpleIdentifier propertyNameNode = node.name; |
| 1034 if (propertyNameNode == null) { | 1099 if (propertyNameNode == null) { |
| 1100 // TODO(brianwilkerson) Report this internal error. |
| 1035 return null; | 1101 return null; |
| 1036 } | 1102 } |
| 1037 String propertyName = propertyNameNode.name; | 1103 String propertyName = propertyNameNode.name; |
| 1038 TopLevelVariableElementImpl variable = _currentHolder.getTopLevelVariabl
e(propertyName) as TopLevelVariableElementImpl; | 1104 TopLevelVariableElementImpl variable = _currentHolder.getTopLevelVariabl
e(propertyName) as TopLevelVariableElementImpl; |
| 1039 if (variable == null) { | 1105 if (variable == null) { |
| 1040 variable = new TopLevelVariableElementImpl.con2(node.name.name); | 1106 variable = new TopLevelVariableElementImpl.con2(node.name.name); |
| 1041 variable.final2 = true; | 1107 variable.final2 = true; |
| 1042 variable.synthetic = true; | 1108 variable.synthetic = true; |
| 1043 _currentHolder.addTopLevelVariable(variable); | 1109 _currentHolder.addTopLevelVariable(variable); |
| 1044 } | 1110 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 | 1194 |
| 1129 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 1195 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 1130 if (node.parent is! DefaultFormalParameter) { | 1196 if (node.parent is! DefaultFormalParameter) { |
| 1131 SimpleIdentifier parameterName = node.identifier; | 1197 SimpleIdentifier parameterName = node.identifier; |
| 1132 ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterNa
me); | 1198 ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterNa
me); |
| 1133 parameter.parameterKind = node.kind; | 1199 parameter.parameterKind = node.kind; |
| 1134 setParameterVisibleRange(node, parameter); | 1200 setParameterVisibleRange(node, parameter); |
| 1135 _currentHolder.addParameter(parameter); | 1201 _currentHolder.addParameter(parameter); |
| 1136 parameterName.staticElement = parameter; | 1202 parameterName.staticElement = parameter; |
| 1137 } | 1203 } |
| 1204 // |
| 1205 // The children of this parameter include any parameters defined on the type
of this parameter. |
| 1206 // |
| 1138 ElementHolder holder = new ElementHolder(); | 1207 ElementHolder holder = new ElementHolder(); |
| 1139 visitChildren(holder, node); | 1208 visitChildren(holder, node); |
| 1140 (node.element as ParameterElementImpl).parameters = holder.parameters; | 1209 (node.element as ParameterElementImpl).parameters = holder.parameters; |
| 1141 holder.validate(); | 1210 holder.validate(); |
| 1142 return null; | 1211 return null; |
| 1143 } | 1212 } |
| 1144 | 1213 |
| 1145 Object visitLabeledStatement(LabeledStatement node) { | 1214 Object visitLabeledStatement(LabeledStatement node) { |
| 1146 bool onSwitchStatement = node.statement is SwitchStatement; | 1215 bool onSwitchStatement = node.statement is SwitchStatement; |
| 1147 for (Label label in node.labels) { | 1216 for (Label label in node.labels) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 LocalVariableElementImpl variable; | 1362 LocalVariableElementImpl variable; |
| 1294 if (isConst && hasInitializer) { | 1363 if (isConst && hasInitializer) { |
| 1295 variable = new ConstLocalVariableElementImpl(variableName); | 1364 variable = new ConstLocalVariableElementImpl(variableName); |
| 1296 } else { | 1365 } else { |
| 1297 variable = new LocalVariableElementImpl(variableName); | 1366 variable = new LocalVariableElementImpl(variableName); |
| 1298 } | 1367 } |
| 1299 element = variable; | 1368 element = variable; |
| 1300 Block enclosingBlock = node.getAncestor(Block); | 1369 Block enclosingBlock = node.getAncestor(Block); |
| 1301 int functionEnd = node.offset + node.length; | 1370 int functionEnd = node.offset + node.length; |
| 1302 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 1371 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
| 1372 // TODO(brianwilkerson) This isn't right for variables declared in a for l
oop. |
| 1303 variable.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 1373 variable.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
| 1304 _currentHolder.addLocalVariable(variable); | 1374 _currentHolder.addLocalVariable(variable); |
| 1305 variableName.staticElement = element; | 1375 variableName.staticElement = element; |
| 1306 } else { | 1376 } else { |
| 1307 SimpleIdentifier variableName = node.name; | 1377 SimpleIdentifier variableName = node.name; |
| 1308 TopLevelVariableElementImpl variable; | 1378 TopLevelVariableElementImpl variable; |
| 1309 if (isConst && hasInitializer) { | 1379 if (isConst && hasInitializer) { |
| 1310 variable = new ConstTopLevelVariableElementImpl(variableName); | 1380 variable = new ConstTopLevelVariableElementImpl(variableName); |
| 1311 } else { | 1381 } else { |
| 1312 variable = new TopLevelVariableElementImpl.con1(variableName); | 1382 variable = new TopLevelVariableElementImpl.con1(variableName); |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1920 String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute
.text; | 1990 String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute
.text; |
| 1921 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath
== null) { | 1991 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath
== null) { |
| 1922 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl
(node); | 1992 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl
(node); |
| 1923 try { | 1993 try { |
| 1924 LibraryResolver resolver = new LibraryResolver(_context); | 1994 LibraryResolver resolver = new LibraryResolver(_context); |
| 1925 LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSourc
e, _modificationStamp, node.script, true) as LibraryElementImpl; | 1995 LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSourc
e, _modificationStamp, node.script, true) as LibraryElementImpl; |
| 1926 script.scriptLibrary = library; | 1996 script.scriptLibrary = library; |
| 1927 _resolvedLibraries.addAll(resolver.resolvedLibraries); | 1997 _resolvedLibraries.addAll(resolver.resolvedLibraries); |
| 1928 _errorListener.addAll(resolver.errorListener); | 1998 _errorListener.addAll(resolver.errorListener); |
| 1929 } on AnalysisException catch (exception) { | 1999 } on AnalysisException catch (exception) { |
| 2000 //TODO (danrubel): Handle or forward the exception |
| 1930 AnalysisEngine.instance.logger.logError3(exception); | 2001 AnalysisEngine.instance.logger.logError3(exception); |
| 1931 } | 2002 } |
| 1932 node.scriptElement = script; | 2003 node.scriptElement = script; |
| 1933 _scripts.add(script); | 2004 _scripts.add(script); |
| 1934 } else { | 2005 } else { |
| 1935 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl
(node); | 2006 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl
(node); |
| 1936 if (scriptSourcePath != null) { | 2007 if (scriptSourcePath != null) { |
| 1937 try { | 2008 try { |
| 1938 scriptSourcePath = Uri.encodeFull(scriptSourcePath); | 2009 scriptSourcePath = Uri.encodeFull(scriptSourcePath); |
| 2010 // Force an exception to be thrown if the URI is invalid so that we
can report the |
| 2011 // problem. |
| 1939 parseUriWithException(scriptSourcePath); | 2012 parseUriWithException(scriptSourcePath); |
| 1940 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource,
scriptSourcePath); | 2013 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource,
scriptSourcePath); |
| 1941 script.scriptSource = scriptSource; | 2014 script.scriptSource = scriptSource; |
| 1942 if (scriptSource == null || !scriptSource.exists()) { | 2015 if (scriptSource == null || !scriptSource.exists()) { |
| 1943 reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribu
te, [scriptSourcePath]); | 2016 reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribu
te, [scriptSourcePath]); |
| 1944 } | 2017 } |
| 1945 } on URISyntaxException catch (exception) { | 2018 } on URISyntaxException catch (exception) { |
| 1946 reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scri
ptSourcePath]); | 2019 reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scri
ptSourcePath]); |
| 1947 } | 2020 } |
| 1948 } | 2021 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) { | 2073 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) { |
| 2001 for (ht.XmlAttributeNode attribute in node.attributes) { | 2074 for (ht.XmlAttributeNode attribute in node.attributes) { |
| 2002 if (attribute.name == _SRC) { | 2075 if (attribute.name == _SRC) { |
| 2003 return attribute; | 2076 return attribute; |
| 2004 } | 2077 } |
| 2005 } | 2078 } |
| 2006 return null; | 2079 return null; |
| 2007 } | 2080 } |
| 2008 | 2081 |
| 2009 Object reportCircularity(ht.XmlTagNode node) { | 2082 Object reportCircularity(ht.XmlTagNode node) { |
| 2083 // |
| 2084 // This should not be possible, but we have an error report that suggests th
at it happened at |
| 2085 // least once. This code will guard against infinite recursion and might hel
p us identify the |
| 2086 // cause of the issue. |
| 2087 // |
| 2010 JavaStringBuilder builder = new JavaStringBuilder(); | 2088 JavaStringBuilder builder = new JavaStringBuilder(); |
| 2011 builder.append("Found circularity in XML nodes: "); | 2089 builder.append("Found circularity in XML nodes: "); |
| 2012 bool first = true; | 2090 bool first = true; |
| 2013 for (ht.XmlTagNode pathNode in _parentNodes) { | 2091 for (ht.XmlTagNode pathNode in _parentNodes) { |
| 2014 if (first) { | 2092 if (first) { |
| 2015 first = false; | 2093 first = false; |
| 2016 } else { | 2094 } else { |
| 2017 builder.append(", "); | 2095 builder.append(", "); |
| 2018 } | 2096 } |
| 2019 String tagName = pathNode.tag; | 2097 String tagName = pathNode.tag; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2134 Object visitBinaryExpression(BinaryExpression node) { | 2212 Object visitBinaryExpression(BinaryExpression node) { |
| 2135 checkForDivisionOptimizationHint(node); | 2213 checkForDivisionOptimizationHint(node); |
| 2136 checkForDeprecatedMemberUse(node.bestElement, node); | 2214 checkForDeprecatedMemberUse(node.bestElement, node); |
| 2137 return super.visitBinaryExpression(node); | 2215 return super.visitBinaryExpression(node); |
| 2138 } | 2216 } |
| 2139 | 2217 |
| 2140 Object visitClassDeclaration(ClassDeclaration node) { | 2218 Object visitClassDeclaration(ClassDeclaration node) { |
| 2141 ClassElement outerClass = _enclosingClass; | 2219 ClassElement outerClass = _enclosingClass; |
| 2142 try { | 2220 try { |
| 2143 _enclosingClass = node.element; | 2221 _enclosingClass = node.element; |
| 2222 // Commented out until we decide that we want this hint in the analyzer |
| 2223 // checkForOverrideEqualsButNotHashCode(node); |
| 2144 return super.visitClassDeclaration(node); | 2224 return super.visitClassDeclaration(node); |
| 2145 } finally { | 2225 } finally { |
| 2146 _enclosingClass = outerClass; | 2226 _enclosingClass = outerClass; |
| 2147 } | 2227 } |
| 2148 } | 2228 } |
| 2149 | 2229 |
| 2150 Object visitExportDirective(ExportDirective node) { | 2230 Object visitExportDirective(ExportDirective node) { |
| 2151 checkForDeprecatedMemberUse(node.uriElement, node); | 2231 checkForDeprecatedMemberUse(node.uriElement, node); |
| 2152 return super.visitExportDirective(node); | 2232 return super.visitExportDirective(node); |
| 2153 } | 2233 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2171 checkForDeprecatedMemberUse(node.staticElement, node); | 2251 checkForDeprecatedMemberUse(node.staticElement, node); |
| 2172 return super.visitInstanceCreationExpression(node); | 2252 return super.visitInstanceCreationExpression(node); |
| 2173 } | 2253 } |
| 2174 | 2254 |
| 2175 Object visitIsExpression(IsExpression node) { | 2255 Object visitIsExpression(IsExpression node) { |
| 2176 checkAllTypeChecks(node); | 2256 checkAllTypeChecks(node); |
| 2177 return super.visitIsExpression(node); | 2257 return super.visitIsExpression(node); |
| 2178 } | 2258 } |
| 2179 | 2259 |
| 2180 Object visitMethodDeclaration(MethodDeclaration node) { | 2260 Object visitMethodDeclaration(MethodDeclaration node) { |
| 2181 checkForOverridingPrivateMember(node); | 2261 // This was determined to not be a good hint, see: dartbug.com/16029 |
| 2262 //checkForOverridingPrivateMember(node); |
| 2182 checkForMissingReturn(node.returnType, node.body); | 2263 checkForMissingReturn(node.returnType, node.body); |
| 2183 return super.visitMethodDeclaration(node); | 2264 return super.visitMethodDeclaration(node); |
| 2184 } | 2265 } |
| 2185 | 2266 |
| 2186 Object visitPostfixExpression(PostfixExpression node) { | 2267 Object visitPostfixExpression(PostfixExpression node) { |
| 2187 checkForDeprecatedMemberUse(node.bestElement, node); | 2268 checkForDeprecatedMemberUse(node.bestElement, node); |
| 2188 return super.visitPostfixExpression(node); | 2269 return super.visitPostfixExpression(node); |
| 2189 } | 2270 } |
| 2190 | 2271 |
| 2191 Object visitPrefixExpression(PrefixExpression node) { | 2272 Object visitPrefixExpression(PrefixExpression node) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2221 */ | 2302 */ |
| 2222 bool checkAllTypeChecks(IsExpression node) { | 2303 bool checkAllTypeChecks(IsExpression node) { |
| 2223 Expression expression = node.expression; | 2304 Expression expression = node.expression; |
| 2224 TypeName typeName = node.type; | 2305 TypeName typeName = node.type; |
| 2225 Type2 lhsType = expression.staticType; | 2306 Type2 lhsType = expression.staticType; |
| 2226 Type2 rhsType = typeName.type; | 2307 Type2 rhsType = typeName.type; |
| 2227 if (lhsType == null || rhsType == null) { | 2308 if (lhsType == null || rhsType == null) { |
| 2228 return false; | 2309 return false; |
| 2229 } | 2310 } |
| 2230 String rhsNameStr = typeName.name.name; | 2311 String rhsNameStr = typeName.name.name; |
| 2312 // if x is dynamic |
| 2231 if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) { | 2313 if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) { |
| 2232 if (node.notOperator == null) { | 2314 if (node.notOperator == null) { |
| 2315 // the is case |
| 2233 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node,
[]); | 2316 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node,
[]); |
| 2234 } else { | 2317 } else { |
| 2318 // the is not case |
| 2235 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node,
[]); | 2319 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node,
[]); |
| 2236 } | 2320 } |
| 2237 return true; | 2321 return true; |
| 2238 } | 2322 } |
| 2239 Element rhsElement = rhsType.element; | 2323 Element rhsElement = rhsType.element; |
| 2240 LibraryElement libraryElement = rhsElement != null ? rhsElement.library : nu
ll; | 2324 LibraryElement libraryElement = rhsElement != null ? rhsElement.library : nu
ll; |
| 2241 if (libraryElement != null && libraryElement.isDartCore) { | 2325 if (libraryElement != null && libraryElement.isDartCore) { |
| 2326 // if x is Object or null is Null |
| 2242 if (rhsType.isObject || (expression is NullLiteral && rhsNameStr == _NULL_
TYPE_NAME)) { | 2327 if (rhsType.isObject || (expression is NullLiteral && rhsNameStr == _NULL_
TYPE_NAME)) { |
| 2243 if (node.notOperator == null) { | 2328 if (node.notOperator == null) { |
| 2329 // the is case |
| 2244 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node
, []); | 2330 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node
, []); |
| 2245 } else { | 2331 } else { |
| 2332 // the is not case |
| 2246 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, nod
e, []); | 2333 _errorReporter.reportError3(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, nod
e, []); |
| 2247 } | 2334 } |
| 2248 return true; | 2335 return true; |
| 2249 } else if (rhsNameStr == _NULL_TYPE_NAME) { | 2336 } else if (rhsNameStr == _NULL_TYPE_NAME) { |
| 2250 if (node.notOperator == null) { | 2337 if (node.notOperator == null) { |
| 2338 // the is case |
| 2251 _errorReporter.reportError3(HintCode.TYPE_CHECK_IS_NULL, node, []); | 2339 _errorReporter.reportError3(HintCode.TYPE_CHECK_IS_NULL, node, []); |
| 2252 } else { | 2340 } else { |
| 2341 // the is not case |
| 2253 _errorReporter.reportError3(HintCode.TYPE_CHECK_IS_NOT_NULL, node, [])
; | 2342 _errorReporter.reportError3(HintCode.TYPE_CHECK_IS_NOT_NULL, node, [])
; |
| 2254 } | 2343 } |
| 2255 return true; | 2344 return true; |
| 2256 } | 2345 } |
| 2257 } | 2346 } |
| 2258 return false; | 2347 return false; |
| 2259 } | 2348 } |
| 2260 | 2349 |
| 2261 /** | 2350 /** |
| 2262 * Given some [Element], look at the associated metadata and report the use of
the member if | 2351 * Given some [Element], look at the associated metadata and report the use of
the member if |
| 2263 * it is declared as deprecated. | 2352 * it is declared as deprecated. |
| 2264 * | 2353 * |
| 2265 * @param element some element to check for deprecated use of | 2354 * @param element some element to check for deprecated use of |
| 2266 * @param node the node use for the location of the error | 2355 * @param node the node use for the location of the error |
| 2267 * @return `true` if and only if a hint code is generated on the passed node | 2356 * @return `true` if and only if a hint code is generated on the passed node |
| 2268 * @see HintCode#DEPRECATED_MEMBER_USE | 2357 * @see HintCode#DEPRECATED_MEMBER_USE |
| 2269 */ | 2358 */ |
| 2270 bool checkForDeprecatedMemberUse(Element element, ASTNode node) { | 2359 bool checkForDeprecatedMemberUse(Element element, ASTNode node) { |
| 2271 if (element != null && element.isDeprecated) { | 2360 if (element != null && element.isDeprecated) { |
| 2272 String displayName = element.displayName; | 2361 String displayName = element.displayName; |
| 2273 if (element is ConstructorElement) { | 2362 if (element is ConstructorElement) { |
| 2363 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), or
have the logic |
| 2364 // centralized elsewhere, instead of doing this logic here. |
| 2274 ConstructorElement constructorElement = element; | 2365 ConstructorElement constructorElement = element; |
| 2275 displayName = constructorElement.enclosingElement.displayName; | 2366 displayName = constructorElement.enclosingElement.displayName; |
| 2276 if (!constructorElement.displayName.isEmpty) { | 2367 if (!constructorElement.displayName.isEmpty) { |
| 2277 displayName = "${displayName}.${constructorElement.displayName}"; | 2368 displayName = "${displayName}.${constructorElement.displayName}"; |
| 2278 } | 2369 } |
| 2279 } | 2370 } |
| 2280 _errorReporter.reportError3(HintCode.DEPRECATED_MEMBER_USE, node, [display
Name]); | 2371 _errorReporter.reportError3(HintCode.DEPRECATED_MEMBER_USE, node, [display
Name]); |
| 2281 return true; | 2372 return true; |
| 2282 } | 2373 } |
| 2283 return false; | 2374 return false; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2309 } | 2400 } |
| 2310 | 2401 |
| 2311 /** | 2402 /** |
| 2312 * Check for the passed binary expression for the [HintCode#DIVISION_OPTIMIZAT
ION]. | 2403 * Check for the passed binary expression for the [HintCode#DIVISION_OPTIMIZAT
ION]. |
| 2313 * | 2404 * |
| 2314 * @param node the binary expression to check | 2405 * @param node the binary expression to check |
| 2315 * @return `true` if and only if a hint code is generated on the passed node | 2406 * @return `true` if and only if a hint code is generated on the passed node |
| 2316 * @see HintCode#DIVISION_OPTIMIZATION | 2407 * @see HintCode#DIVISION_OPTIMIZATION |
| 2317 */ | 2408 */ |
| 2318 bool checkForDivisionOptimizationHint(BinaryExpression node) { | 2409 bool checkForDivisionOptimizationHint(BinaryExpression node) { |
| 2410 // Return if the operator is not '/' |
| 2319 if (node.operator.type != sc.TokenType.SLASH) { | 2411 if (node.operator.type != sc.TokenType.SLASH) { |
| 2320 return false; | 2412 return false; |
| 2321 } | 2413 } |
| 2414 // Return if the '/' operator is not defined in core, or if we don't know it
s static or propagated type |
| 2322 MethodElement methodElement = node.bestElement; | 2415 MethodElement methodElement = node.bestElement; |
| 2323 if (methodElement == null) { | 2416 if (methodElement == null) { |
| 2324 return false; | 2417 return false; |
| 2325 } | 2418 } |
| 2326 LibraryElement libraryElement = methodElement.library; | 2419 LibraryElement libraryElement = methodElement.library; |
| 2327 if (libraryElement != null && !libraryElement.isDartCore) { | 2420 if (libraryElement != null && !libraryElement.isDartCore) { |
| 2328 return false; | 2421 return false; |
| 2329 } | 2422 } |
| 2423 // Report error if the (x/y) has toInt() invoked on it |
| 2330 if (node.parent is ParenthesizedExpression) { | 2424 if (node.parent is ParenthesizedExpression) { |
| 2331 ParenthesizedExpression parenthesizedExpression = wrapParenthesizedExpress
ion(node.parent as ParenthesizedExpression); | 2425 ParenthesizedExpression parenthesizedExpression = wrapParenthesizedExpress
ion(node.parent as ParenthesizedExpression); |
| 2332 if (parenthesizedExpression.parent is MethodInvocation) { | 2426 if (parenthesizedExpression.parent is MethodInvocation) { |
| 2333 MethodInvocation methodInvocation = parenthesizedExpression.parent as Me
thodInvocation; | 2427 MethodInvocation methodInvocation = parenthesizedExpression.parent as Me
thodInvocation; |
| 2334 if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && methodInv
ocation.argumentList.arguments.isEmpty) { | 2428 if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && methodInv
ocation.argumentList.arguments.isEmpty) { |
| 2335 _errorReporter.reportError3(HintCode.DIVISION_OPTIMIZATION, methodInvo
cation, []); | 2429 _errorReporter.reportError3(HintCode.DIVISION_OPTIMIZATION, methodInvo
cation, []); |
| 2336 return true; | 2430 return true; |
| 2337 } | 2431 } |
| 2338 } | 2432 } |
| 2339 } | 2433 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2378 | 2472 |
| 2379 /** | 2473 /** |
| 2380 * Checks that if the passed method declaration is private, it does not overri
de a private member | 2474 * Checks that if the passed method declaration is private, it does not overri
de a private member |
| 2381 * in a superclass. | 2475 * in a superclass. |
| 2382 * | 2476 * |
| 2383 * @param node the method declaration to check | 2477 * @param node the method declaration to check |
| 2384 * @return `true` if and only if a hint code is generated on the passed node | 2478 * @return `true` if and only if a hint code is generated on the passed node |
| 2385 * @see HintCode#OVERRIDDING_PRIVATE_MEMBER | 2479 * @see HintCode#OVERRIDDING_PRIVATE_MEMBER |
| 2386 */ | 2480 */ |
| 2387 bool checkForOverridingPrivateMember(MethodDeclaration node) { | 2481 bool checkForOverridingPrivateMember(MethodDeclaration node) { |
| 2482 // If not in an enclosing class, return false |
| 2388 if (_enclosingClass == null) { | 2483 if (_enclosingClass == null) { |
| 2389 return false; | 2484 return false; |
| 2390 } | 2485 } |
| 2486 // If the member is not private, return false |
| 2391 if (!Identifier.isPrivateName(node.name.name)) { | 2487 if (!Identifier.isPrivateName(node.name.name)) { |
| 2392 return false; | 2488 return false; |
| 2393 } | 2489 } |
| 2490 // Get the element of the member, if null, return false |
| 2394 ExecutableElement executableElement = node.element; | 2491 ExecutableElement executableElement = node.element; |
| 2395 if (executableElement == null) { | 2492 if (executableElement == null) { |
| 2396 return false; | 2493 return false; |
| 2397 } | 2494 } |
| 2495 // Loop through all of the superclasses looking for a matching method or acc
essor |
| 2496 // TODO(jwren) If the HintGenerator needs or has easy access to the Inherita
nceManager in the |
| 2497 // future then this could be refactored down to be more readable, however, s
ince we are only |
| 2498 // looking through super classes (and not the entire interface graph) there
is no pressing need |
| 2398 String elementName = executableElement.name; | 2499 String elementName = executableElement.name; |
| 2399 bool isGetterOrSetter = executableElement is PropertyAccessorElement; | 2500 bool isGetterOrSetter = executableElement is PropertyAccessorElement; |
| 2400 InterfaceType superType = _enclosingClass.supertype; | 2501 InterfaceType superType = _enclosingClass.supertype; |
| 2401 if (superType == null) { | 2502 if (superType == null) { |
| 2402 return false; | 2503 return false; |
| 2403 } | 2504 } |
| 2404 ClassElement classElement = superType.element; | 2505 ClassElement classElement = superType.element; |
| 2405 while (classElement != null) { | 2506 while (classElement != null) { |
| 2406 if (_enclosingClass.library != classElement.library) { | 2507 if (_enclosingClass.library != classElement.library) { |
| 2407 if (isGetterOrSetter) { | 2508 if (isGetterOrSetter) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2443 * | 2544 * |
| 2444 * @param node the as expression to check | 2545 * @param node the as expression to check |
| 2445 * @return `true` if and only if a hint code is generated on the passed node | 2546 * @return `true` if and only if a hint code is generated on the passed node |
| 2446 * @see HintCode#UNNECESSARY_CAST | 2547 * @see HintCode#UNNECESSARY_CAST |
| 2447 */ | 2548 */ |
| 2448 bool checkForUnnecessaryCast(AsExpression node) { | 2549 bool checkForUnnecessaryCast(AsExpression node) { |
| 2449 Expression expression = node.expression; | 2550 Expression expression = node.expression; |
| 2450 TypeName typeName = node.type; | 2551 TypeName typeName = node.type; |
| 2451 Type2 lhsType = expression.staticType; | 2552 Type2 lhsType = expression.staticType; |
| 2452 Type2 rhsType = typeName.type; | 2553 Type2 rhsType = typeName.type; |
| 2554 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to r
emove the |
| 2555 // !(x instanceof TypeParameterType) checks. |
| 2453 if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isD
ynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsT
ype.isSubtypeOf(rhsType)) { | 2556 if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isD
ynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsT
ype.isSubtypeOf(rhsType)) { |
| 2454 _errorReporter.reportError3(HintCode.UNNECESSARY_CAST, node, []); | 2557 _errorReporter.reportError3(HintCode.UNNECESSARY_CAST, node, []); |
| 2455 return true; | 2558 return true; |
| 2456 } | 2559 } |
| 2457 return false; | 2560 return false; |
| 2458 } | 2561 } |
| 2459 } | 2562 } |
| 2460 | 2563 |
| 2461 /** | 2564 /** |
| 2462 * Instances of the class `Dart2JSVerifier` traverse an AST structure looking fo
r hints for | 2565 * Instances of the class `Dart2JSVerifier` traverse an AST structure looking fo
r hints for |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2500 * @see HintCode#IS_NOT_DOUBLE | 2603 * @see HintCode#IS_NOT_DOUBLE |
| 2501 * @see HintCode#IS_NOT_INT | 2604 * @see HintCode#IS_NOT_INT |
| 2502 */ | 2605 */ |
| 2503 bool checkForIsDoubleHints(IsExpression node) { | 2606 bool checkForIsDoubleHints(IsExpression node) { |
| 2504 TypeName typeName = node.type; | 2607 TypeName typeName = node.type; |
| 2505 Type2 type = typeName.type; | 2608 Type2 type = typeName.type; |
| 2506 if (type != null && type.element != null) { | 2609 if (type != null && type.element != null) { |
| 2507 Element element = type.element; | 2610 Element element = type.element; |
| 2508 String typeNameStr = element.name; | 2611 String typeNameStr = element.name; |
| 2509 LibraryElement libraryElement = element.library; | 2612 LibraryElement libraryElement = element.library; |
| 2613 // if (typeNameStr.equals(INT_TYPE_NAME) && libraryElement != null |
| 2614 // && libraryElement.isDartCore()) { |
| 2615 // if (node.getNotOperator() == null) { |
| 2616 // errorReporter.reportError(HintCode.IS_INT, node); |
| 2617 // } else { |
| 2618 // errorReporter.reportError(HintCode.IS_NOT_INT, node); |
| 2619 // } |
| 2620 // return true; |
| 2621 // } else |
| 2510 if (typeNameStr == _DOUBLE_TYPE_NAME && libraryElement != null && libraryE
lement.isDartCore) { | 2622 if (typeNameStr == _DOUBLE_TYPE_NAME && libraryElement != null && libraryE
lement.isDartCore) { |
| 2511 if (node.notOperator == null) { | 2623 if (node.notOperator == null) { |
| 2512 _errorReporter.reportError3(HintCode.IS_DOUBLE, node, []); | 2624 _errorReporter.reportError3(HintCode.IS_DOUBLE, node, []); |
| 2513 } else { | 2625 } else { |
| 2514 _errorReporter.reportError3(HintCode.IS_NOT_DOUBLE, node, []); | 2626 _errorReporter.reportError3(HintCode.IS_NOT_DOUBLE, node, []); |
| 2515 } | 2627 } |
| 2516 return true; | 2628 return true; |
| 2517 } | 2629 } |
| 2518 } | 2630 } |
| 2519 return false; | 2631 return false; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2544 Object visitBinaryExpression(BinaryExpression node) { | 2656 Object visitBinaryExpression(BinaryExpression node) { |
| 2545 sc.Token operator = node.operator; | 2657 sc.Token operator = node.operator; |
| 2546 bool isAmpAmp = identical(operator.type, sc.TokenType.AMPERSAND_AMPERSAND); | 2658 bool isAmpAmp = identical(operator.type, sc.TokenType.AMPERSAND_AMPERSAND); |
| 2547 bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR); | 2659 bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR); |
| 2548 if (isAmpAmp || isBarBar) { | 2660 if (isAmpAmp || isBarBar) { |
| 2549 Expression lhsCondition = node.leftOperand; | 2661 Expression lhsCondition = node.leftOperand; |
| 2550 if (!isDebugConstant(lhsCondition)) { | 2662 if (!isDebugConstant(lhsCondition)) { |
| 2551 ValidResult lhsResult = getConstantBooleanValue(lhsCondition); | 2663 ValidResult lhsResult = getConstantBooleanValue(lhsCondition); |
| 2552 if (lhsResult != null) { | 2664 if (lhsResult != null) { |
| 2553 if (lhsResult.isTrue && isBarBar) { | 2665 if (lhsResult.isTrue && isBarBar) { |
| 2666 // report error on else block: true || !e! |
| 2554 _errorReporter.reportError3(HintCode.DEAD_CODE, node.rightOperand, [
]); | 2667 _errorReporter.reportError3(HintCode.DEAD_CODE, node.rightOperand, [
]); |
| 2668 // only visit the LHS: |
| 2555 safelyVisit(lhsCondition); | 2669 safelyVisit(lhsCondition); |
| 2556 return null; | 2670 return null; |
| 2557 } else if (lhsResult.isFalse && isAmpAmp) { | 2671 } else if (lhsResult.isFalse && isAmpAmp) { |
| 2672 // report error on if block: false && !e! |
| 2558 _errorReporter.reportError3(HintCode.DEAD_CODE, node.rightOperand, [
]); | 2673 _errorReporter.reportError3(HintCode.DEAD_CODE, node.rightOperand, [
]); |
| 2674 // only visit the LHS: |
| 2559 safelyVisit(lhsCondition); | 2675 safelyVisit(lhsCondition); |
| 2560 return null; | 2676 return null; |
| 2561 } | 2677 } |
| 2562 } | 2678 } |
| 2563 } | 2679 } |
| 2564 } | 2680 } |
| 2565 return super.visitBinaryExpression(node); | 2681 return super.visitBinaryExpression(node); |
| 2566 } | 2682 } |
| 2567 | 2683 |
| 2568 /** | 2684 /** |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2589 return null; | 2705 return null; |
| 2590 } | 2706 } |
| 2591 | 2707 |
| 2592 Object visitConditionalExpression(ConditionalExpression node) { | 2708 Object visitConditionalExpression(ConditionalExpression node) { |
| 2593 Expression conditionExpression = node.condition; | 2709 Expression conditionExpression = node.condition; |
| 2594 safelyVisit(conditionExpression); | 2710 safelyVisit(conditionExpression); |
| 2595 if (!isDebugConstant(conditionExpression)) { | 2711 if (!isDebugConstant(conditionExpression)) { |
| 2596 ValidResult result = getConstantBooleanValue(conditionExpression); | 2712 ValidResult result = getConstantBooleanValue(conditionExpression); |
| 2597 if (result != null) { | 2713 if (result != null) { |
| 2598 if (result.isTrue) { | 2714 if (result.isTrue) { |
| 2715 // report error on else block: true ? 1 : !2! |
| 2599 _errorReporter.reportError3(HintCode.DEAD_CODE, node.elseExpression, [
]); | 2716 _errorReporter.reportError3(HintCode.DEAD_CODE, node.elseExpression, [
]); |
| 2600 safelyVisit(node.thenExpression); | 2717 safelyVisit(node.thenExpression); |
| 2601 return null; | 2718 return null; |
| 2602 } else { | 2719 } else { |
| 2720 // report error on if block: false ? !1! : 2 |
| 2603 _errorReporter.reportError3(HintCode.DEAD_CODE, node.thenExpression, [
]); | 2721 _errorReporter.reportError3(HintCode.DEAD_CODE, node.thenExpression, [
]); |
| 2604 safelyVisit(node.elseExpression); | 2722 safelyVisit(node.elseExpression); |
| 2605 return null; | 2723 return null; |
| 2606 } | 2724 } |
| 2607 } | 2725 } |
| 2608 } | 2726 } |
| 2609 return super.visitConditionalExpression(node); | 2727 return super.visitConditionalExpression(node); |
| 2610 } | 2728 } |
| 2611 | 2729 |
| 2612 Object visitIfStatement(IfStatement node) { | 2730 Object visitIfStatement(IfStatement node) { |
| 2613 Expression conditionExpression = node.condition; | 2731 Expression conditionExpression = node.condition; |
| 2614 safelyVisit(conditionExpression); | 2732 safelyVisit(conditionExpression); |
| 2615 if (!isDebugConstant(conditionExpression)) { | 2733 if (!isDebugConstant(conditionExpression)) { |
| 2616 ValidResult result = getConstantBooleanValue(conditionExpression); | 2734 ValidResult result = getConstantBooleanValue(conditionExpression); |
| 2617 if (result != null) { | 2735 if (result != null) { |
| 2618 if (result.isTrue) { | 2736 if (result.isTrue) { |
| 2737 // report error on else block: if(true) {} else {!} |
| 2619 Statement elseStatement = node.elseStatement; | 2738 Statement elseStatement = node.elseStatement; |
| 2620 if (elseStatement != null) { | 2739 if (elseStatement != null) { |
| 2621 _errorReporter.reportError3(HintCode.DEAD_CODE, elseStatement, []); | 2740 _errorReporter.reportError3(HintCode.DEAD_CODE, elseStatement, []); |
| 2622 safelyVisit(node.thenStatement); | 2741 safelyVisit(node.thenStatement); |
| 2623 return null; | 2742 return null; |
| 2624 } | 2743 } |
| 2625 } else { | 2744 } else { |
| 2745 // report error on if block: if (false) {!} else {} |
| 2626 _errorReporter.reportError3(HintCode.DEAD_CODE, node.thenStatement, []
); | 2746 _errorReporter.reportError3(HintCode.DEAD_CODE, node.thenStatement, []
); |
| 2627 safelyVisit(node.elseStatement); | 2747 safelyVisit(node.elseStatement); |
| 2628 return null; | 2748 return null; |
| 2629 } | 2749 } |
| 2630 } | 2750 } |
| 2631 } | 2751 } |
| 2632 return super.visitIfStatement(node); | 2752 return super.visitIfStatement(node); |
| 2633 } | 2753 } |
| 2634 | 2754 |
| 2635 Object visitTryStatement(TryStatement node) { | 2755 Object visitTryStatement(TryStatement node) { |
| 2636 safelyVisit(node.body); | 2756 safelyVisit(node.body); |
| 2637 safelyVisit(node.finallyBlock); | 2757 safelyVisit(node.finallyBlock); |
| 2638 NodeList<CatchClause> catchClauses = node.catchClauses; | 2758 NodeList<CatchClause> catchClauses = node.catchClauses; |
| 2639 int numOfCatchClauses = catchClauses.length; | 2759 int numOfCatchClauses = catchClauses.length; |
| 2640 List<Type2> visitedTypes = new List<Type2>(); | 2760 List<Type2> visitedTypes = new List<Type2>(); |
| 2641 for (int i = 0; i < numOfCatchClauses; i++) { | 2761 for (int i = 0; i < numOfCatchClauses; i++) { |
| 2642 CatchClause catchClause = catchClauses[i]; | 2762 CatchClause catchClause = catchClauses[i]; |
| 2643 if (catchClause.onKeyword != null) { | 2763 if (catchClause.onKeyword != null) { |
| 2764 // on-catch clause found, verify that the exception type is not a subtyp
e of a previous |
| 2765 // on-catch exception type |
| 2644 TypeName typeName = catchClause.exceptionType; | 2766 TypeName typeName = catchClause.exceptionType; |
| 2645 if (typeName != null && typeName.type != null) { | 2767 if (typeName != null && typeName.type != null) { |
| 2646 Type2 currentType = typeName.type; | 2768 Type2 currentType = typeName.type; |
| 2647 if (currentType.isObject) { | 2769 if (currentType.isObject) { |
| 2770 // Found catch clause clause that has Object as an exception type, t
his is equivalent to |
| 2771 // having a catch clause that doesn't have an exception type, visit
the block, but |
| 2772 // generate an error on any following catch clauses (and don't visit
them). |
| 2648 safelyVisit(catchClause); | 2773 safelyVisit(catchClause); |
| 2649 if (i + 1 != numOfCatchClauses) { | 2774 if (i + 1 != numOfCatchClauses) { |
| 2775 // this catch clause is not the last in the try statement |
| 2650 CatchClause nextCatchClause = catchClauses[i + 1]; | 2776 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 2651 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2777 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2652 int offset = nextCatchClause.offset; | 2778 int offset = nextCatchClause.offset; |
| 2653 int length = lastCatchClause.end - offset; | 2779 int length = lastCatchClause.end - offset; |
| 2654 _errorReporter.reportError5(HintCode.DEAD_CODE_CATCH_FOLLOWING_CAT
CH, offset, length, []); | 2780 _errorReporter.reportError5(HintCode.DEAD_CODE_CATCH_FOLLOWING_CAT
CH, offset, length, []); |
| 2655 return null; | 2781 return null; |
| 2656 } | 2782 } |
| 2657 } | 2783 } |
| 2658 for (Type2 type in visitedTypes) { | 2784 for (Type2 type in visitedTypes) { |
| 2659 if (currentType.isSubtypeOf(type)) { | 2785 if (currentType.isSubtypeOf(type)) { |
| 2660 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2786 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2661 int offset = catchClause.offset; | 2787 int offset = catchClause.offset; |
| 2662 int length = lastCatchClause.end - offset; | 2788 int length = lastCatchClause.end - offset; |
| 2663 _errorReporter.reportError5(HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, o
ffset, length, [currentType.displayName, type.displayName]); | 2789 _errorReporter.reportError5(HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, o
ffset, length, [currentType.displayName, type.displayName]); |
| 2664 return null; | 2790 return null; |
| 2665 } | 2791 } |
| 2666 } | 2792 } |
| 2667 visitedTypes.add(currentType); | 2793 visitedTypes.add(currentType); |
| 2668 } | 2794 } |
| 2669 safelyVisit(catchClause); | 2795 safelyVisit(catchClause); |
| 2670 } else { | 2796 } else { |
| 2797 // Found catch clause clause that doesn't have an exception type, visit
the block, but |
| 2798 // generate an error on any following catch clauses (and don't visit the
m). |
| 2671 safelyVisit(catchClause); | 2799 safelyVisit(catchClause); |
| 2672 if (i + 1 != numOfCatchClauses) { | 2800 if (i + 1 != numOfCatchClauses) { |
| 2801 // this catch clause is not the last in the try statement |
| 2673 CatchClause nextCatchClause = catchClauses[i + 1]; | 2802 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 2674 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2803 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2675 int offset = nextCatchClause.offset; | 2804 int offset = nextCatchClause.offset; |
| 2676 int length = lastCatchClause.end - offset; | 2805 int length = lastCatchClause.end - offset; |
| 2677 _errorReporter.reportError5(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
offset, length, []); | 2806 _errorReporter.reportError5(HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
offset, length, []); |
| 2678 return null; | 2807 return null; |
| 2679 } | 2808 } |
| 2680 } | 2809 } |
| 2681 } | 2810 } |
| 2682 return null; | 2811 return null; |
| 2683 } | 2812 } |
| 2684 | 2813 |
| 2685 Object visitWhileStatement(WhileStatement node) { | 2814 Object visitWhileStatement(WhileStatement node) { |
| 2686 Expression conditionExpression = node.condition; | 2815 Expression conditionExpression = node.condition; |
| 2687 safelyVisit(conditionExpression); | 2816 safelyVisit(conditionExpression); |
| 2688 if (!isDebugConstant(conditionExpression)) { | 2817 if (!isDebugConstant(conditionExpression)) { |
| 2689 ValidResult result = getConstantBooleanValue(conditionExpression); | 2818 ValidResult result = getConstantBooleanValue(conditionExpression); |
| 2690 if (result != null) { | 2819 if (result != null) { |
| 2691 if (result.isFalse) { | 2820 if (result.isFalse) { |
| 2821 // report error on if block: while (false) {!} |
| 2692 _errorReporter.reportError3(HintCode.DEAD_CODE, node.body, []); | 2822 _errorReporter.reportError3(HintCode.DEAD_CODE, node.body, []); |
| 2693 return null; | 2823 return null; |
| 2694 } | 2824 } |
| 2695 } | 2825 } |
| 2696 } | 2826 } |
| 2697 safelyVisit(node.body); | 2827 safelyVisit(node.body); |
| 2698 return null; | 2828 return null; |
| 2699 } | 2829 } |
| 2700 | 2830 |
| 2701 /** | 2831 /** |
| 2702 * Given some [Expression], this method returns [ValidResult#RESULT_TRUE] if i
t is | 2832 * Given some [Expression], this method returns [ValidResult#RESULT_TRUE] if i
t is |
| 2703 * `true`, [ValidResult#RESULT_FALSE] if it is `false`, or `null` if the | 2833 * `true`, [ValidResult#RESULT_FALSE] if it is `false`, or `null` if the |
| 2704 * expression is not a constant boolean value. | 2834 * expression is not a constant boolean value. |
| 2705 * | 2835 * |
| 2706 * @param expression the expression to evaluate | 2836 * @param expression the expression to evaluate |
| 2707 * @return [ValidResult#RESULT_TRUE] if it is `true`, [ValidResult#RESULT_FALS
E] | 2837 * @return [ValidResult#RESULT_TRUE] if it is `true`, [ValidResult#RESULT_FALS
E] |
| 2708 * if it is `false`, or `null` if the expression is not a constant boo
lean | 2838 * if it is `false`, or `null` if the expression is not a constant boo
lean |
| 2709 * value | 2839 * value |
| 2710 */ | 2840 */ |
| 2711 ValidResult getConstantBooleanValue(Expression expression) { | 2841 ValidResult getConstantBooleanValue(Expression expression) { |
| 2712 if (expression is BooleanLiteral) { | 2842 if (expression is BooleanLiteral) { |
| 2713 if (expression.value) { | 2843 if (expression.value) { |
| 2714 return new ValidResult(new DartObjectImpl(null, BoolState.from(true))); | 2844 return new ValidResult(new DartObjectImpl(null, BoolState.from(true))); |
| 2715 } else { | 2845 } else { |
| 2716 return new ValidResult(new DartObjectImpl(null, BoolState.from(false))); | 2846 return new ValidResult(new DartObjectImpl(null, BoolState.from(false))); |
| 2717 } | 2847 } |
| 2718 } | 2848 } |
| 2849 // Don't consider situations where we could evaluate to a constant boolean e
xpression with the |
| 2850 // ConstantVisitor |
| 2851 // else { |
| 2852 // EvaluationResultImpl result = expression.accept(new ConstantVisitor(
)); |
| 2853 // if (result == ValidResult.RESULT_TRUE) { |
| 2854 // return ValidResult.RESULT_TRUE; |
| 2855 // } else if (result == ValidResult.RESULT_FALSE) { |
| 2856 // return ValidResult.RESULT_FALSE; |
| 2857 // } |
| 2858 // return null; |
| 2859 // } |
| 2719 return null; | 2860 return null; |
| 2720 } | 2861 } |
| 2721 | 2862 |
| 2722 /** | 2863 /** |
| 2723 * Return `true` if and only if the passed expression is resolved to a constan
t variable. | 2864 * Return `true` if and only if the passed expression is resolved to a constan
t variable. |
| 2724 * | 2865 * |
| 2725 * @param expression some conditional expression | 2866 * @param expression some conditional expression |
| 2726 * @return `true` if and only if the passed expression is resolved to a consta
nt variable | 2867 * @return `true` if and only if the passed expression is resolved to a consta
nt variable |
| 2727 */ | 2868 */ |
| 2728 bool isDebugConstant(Expression expression) { | 2869 bool isDebugConstant(Expression expression) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2800 _importsVerifier.generateDuplicateImportHints(definingCompilationUnitError
Reporter); | 2941 _importsVerifier.generateDuplicateImportHints(definingCompilationUnitError
Reporter); |
| 2801 _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorRep
orter); | 2942 _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorRep
orter); |
| 2802 } finally { | 2943 } finally { |
| 2803 timeCounter.stop(); | 2944 timeCounter.stop(); |
| 2804 } | 2945 } |
| 2805 } | 2946 } |
| 2806 | 2947 |
| 2807 void generateForCompilationUnit(CompilationUnit unit, Source source) { | 2948 void generateForCompilationUnit(CompilationUnit unit, Source source) { |
| 2808 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); | 2949 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); |
| 2809 _importsVerifier.visitCompilationUnit(unit); | 2950 _importsVerifier.visitCompilationUnit(unit); |
| 2951 // dead code analysis |
| 2810 new DeadCodeVerifier(errorReporter).visitCompilationUnit(unit); | 2952 new DeadCodeVerifier(errorReporter).visitCompilationUnit(unit); |
| 2953 // dart2js analysis |
| 2811 if (_enableDart2JSHints) { | 2954 if (_enableDart2JSHints) { |
| 2812 new Dart2JSVerifier(errorReporter).visitCompilationUnit(unit); | 2955 new Dart2JSVerifier(errorReporter).visitCompilationUnit(unit); |
| 2813 } | 2956 } |
| 2957 // Dart best practices |
| 2814 new BestPracticesVerifier(errorReporter).visitCompilationUnit(unit); | 2958 new BestPracticesVerifier(errorReporter).visitCompilationUnit(unit); |
| 2959 // Find to-do comments |
| 2815 new ToDoFinder(errorReporter).findIn(unit); | 2960 new ToDoFinder(errorReporter).findIn(unit); |
| 2816 } | 2961 } |
| 2817 } | 2962 } |
| 2818 | 2963 |
| 2819 /** | 2964 /** |
| 2820 * Instances of the class `ImportsVerifier` visit all of the referenced librarie
s in the | 2965 * Instances of the class `ImportsVerifier` visit all of the referenced librarie
s in the |
| 2821 * source code verifying that all of the imports are used, otherwise a | 2966 * source code verifying that all of the imports are used, otherwise a |
| 2822 * [HintCode#UNUSED_IMPORT] is generated with | 2967 * [HintCode#UNUSED_IMPORT] is generated with |
| 2823 * [generateUnusedImportHints]. | 2968 * [generateUnusedImportHints]. |
| 2824 * | 2969 * |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2916 /** | 3061 /** |
| 2917 * After all of the compilation units have been visited by this visitor, this
method can be called | 3062 * After all of the compilation units have been visited by this visitor, this
method can be called |
| 2918 * to report an [HintCode#UNUSED_IMPORT] hint for each of the import directive
s in the | 3063 * to report an [HintCode#UNUSED_IMPORT] hint for each of the import directive
s in the |
| 2919 * [unusedImports] list. | 3064 * [unusedImports] list. |
| 2920 * | 3065 * |
| 2921 * @param errorReporter the error reporter to report the set of [HintCode#UNUS
ED_IMPORT] | 3066 * @param errorReporter the error reporter to report the set of [HintCode#UNUS
ED_IMPORT] |
| 2922 * hints to | 3067 * hints to |
| 2923 */ | 3068 */ |
| 2924 void generateUnusedImportHints(ErrorReporter errorReporter) { | 3069 void generateUnusedImportHints(ErrorReporter errorReporter) { |
| 2925 for (ImportDirective unusedImport in _unusedImports) { | 3070 for (ImportDirective unusedImport in _unusedImports) { |
| 3071 // Check that the import isn't dart:core |
| 2926 ImportElement importElement = unusedImport.element; | 3072 ImportElement importElement = unusedImport.element; |
| 2927 if (importElement != null) { | 3073 if (importElement != null) { |
| 2928 LibraryElement libraryElement = importElement.importedLibrary; | 3074 LibraryElement libraryElement = importElement.importedLibrary; |
| 2929 if (libraryElement != null && libraryElement.isDartCore) { | 3075 if (libraryElement != null && libraryElement.isDartCore) { |
| 2930 continue; | 3076 continue; |
| 2931 } | 3077 } |
| 2932 } | 3078 } |
| 2933 errorReporter.reportError3(HintCode.UNUSED_IMPORT, unusedImport.uri, []); | 3079 errorReporter.reportError3(HintCode.UNUSED_IMPORT, unusedImport.uri, []); |
| 2934 } | 3080 } |
| 2935 } | 3081 } |
| 2936 | 3082 |
| 2937 Object visitCompilationUnit(CompilationUnit node) { | 3083 Object visitCompilationUnit(CompilationUnit node) { |
| 2938 if (_inDefiningCompilationUnit) { | 3084 if (_inDefiningCompilationUnit) { |
| 2939 NodeList<Directive> directives = node.directives; | 3085 NodeList<Directive> directives = node.directives; |
| 2940 for (Directive directive in directives) { | 3086 for (Directive directive in directives) { |
| 2941 if (directive is ImportDirective) { | 3087 if (directive is ImportDirective) { |
| 2942 ImportDirective importDirective = directive; | 3088 ImportDirective importDirective = directive; |
| 2943 LibraryElement libraryElement = importDirective.uriElement; | 3089 LibraryElement libraryElement = importDirective.uriElement; |
| 2944 if (libraryElement != null) { | 3090 if (libraryElement != null) { |
| 2945 _unusedImports.add(importDirective); | 3091 _unusedImports.add(importDirective); |
| 3092 // |
| 3093 // Initialize prefixElementMap |
| 3094 // |
| 2946 if (importDirective.asToken != null) { | 3095 if (importDirective.asToken != null) { |
| 2947 SimpleIdentifier prefixIdentifier = importDirective.prefix; | 3096 SimpleIdentifier prefixIdentifier = importDirective.prefix; |
| 2948 if (prefixIdentifier != null) { | 3097 if (prefixIdentifier != null) { |
| 2949 Element element = prefixIdentifier.staticElement; | 3098 Element element = prefixIdentifier.staticElement; |
| 2950 if (element is PrefixElement) { | 3099 if (element is PrefixElement) { |
| 2951 PrefixElement prefixElementKey = element; | 3100 PrefixElement prefixElementKey = element; |
| 2952 _prefixElementMap[prefixElementKey] = importDirective; | 3101 _prefixElementMap[prefixElementKey] = importDirective; |
| 2953 } | 3102 } |
| 2954 } | 3103 } |
| 2955 } | 3104 } |
| 3105 // |
| 3106 // Initialize libraryMap: libraryElement -> importDirective |
| 3107 // |
| 2956 putIntoLibraryMap(libraryElement, importDirective); | 3108 putIntoLibraryMap(libraryElement, importDirective); |
| 3109 // |
| 3110 // For this new addition to the libraryMap, also recursively add any
exports from the |
| 3111 // libraryElement |
| 3112 // |
| 2957 addAdditionalLibrariesForExports(libraryElement, importDirective, ne
w List<LibraryElement>()); | 3113 addAdditionalLibrariesForExports(libraryElement, importDirective, ne
w List<LibraryElement>()); |
| 2958 } | 3114 } |
| 2959 } | 3115 } |
| 2960 } | 3116 } |
| 2961 } | 3117 } |
| 3118 // If there are no imports in this library, don't visit the identifiers in t
he library- there |
| 3119 // can be no unused imports. |
| 2962 if (_unusedImports.isEmpty) { | 3120 if (_unusedImports.isEmpty) { |
| 2963 return null; | 3121 return null; |
| 2964 } | 3122 } |
| 2965 if (_unusedImports.length > 1) { | 3123 if (_unusedImports.length > 1) { |
| 3124 // order the list of unusedImports to find duplicates in faster than O(n^2
) time |
| 2966 List<ImportDirective> importDirectiveArray = new List.from(_unusedImports)
; | 3125 List<ImportDirective> importDirectiveArray = new List.from(_unusedImports)
; |
| 2967 importDirectiveArray.sort(ImportDirective.COMPARATOR); | 3126 importDirectiveArray.sort(ImportDirective.COMPARATOR); |
| 2968 ImportDirective currentDirective = importDirectiveArray[0]; | 3127 ImportDirective currentDirective = importDirectiveArray[0]; |
| 2969 for (int i = 1; i < importDirectiveArray.length; i++) { | 3128 for (int i = 1; i < importDirectiveArray.length; i++) { |
| 2970 ImportDirective nextDirective = importDirectiveArray[i]; | 3129 ImportDirective nextDirective = importDirectiveArray[i]; |
| 2971 if (ImportDirective.COMPARATOR(currentDirective, nextDirective) == 0) { | 3130 if (ImportDirective.COMPARATOR(currentDirective, nextDirective) == 0) { |
| 3131 // Add either the currentDirective or nextDirective depending on which
comes second, this |
| 3132 // guarantees that the first of the duplicates won't be highlighted. |
| 2972 if (currentDirective.offset < nextDirective.offset) { | 3133 if (currentDirective.offset < nextDirective.offset) { |
| 2973 _duplicateImports.add(nextDirective); | 3134 _duplicateImports.add(nextDirective); |
| 2974 } else { | 3135 } else { |
| 2975 _duplicateImports.add(currentDirective); | 3136 _duplicateImports.add(currentDirective); |
| 2976 } | 3137 } |
| 2977 } | 3138 } |
| 2978 currentDirective = nextDirective; | 3139 currentDirective = nextDirective; |
| 2979 } | 3140 } |
| 2980 } | 3141 } |
| 2981 return super.visitCompilationUnit(node); | 3142 return super.visitCompilationUnit(node); |
| 2982 } | 3143 } |
| 2983 | 3144 |
| 2984 Object visitExportDirective(ExportDirective node) { | 3145 Object visitExportDirective(ExportDirective node) { |
| 2985 visitMetadata(node.metadata); | 3146 visitMetadata(node.metadata); |
| 2986 return null; | 3147 return null; |
| 2987 } | 3148 } |
| 2988 | 3149 |
| 2989 Object visitImportDirective(ImportDirective node) { | 3150 Object visitImportDirective(ImportDirective node) { |
| 2990 visitMetadata(node.metadata); | 3151 visitMetadata(node.metadata); |
| 2991 return null; | 3152 return null; |
| 2992 } | 3153 } |
| 2993 | 3154 |
| 2994 Object visitLibraryDirective(LibraryDirective node) { | 3155 Object visitLibraryDirective(LibraryDirective node) { |
| 2995 visitMetadata(node.metadata); | 3156 visitMetadata(node.metadata); |
| 2996 return null; | 3157 return null; |
| 2997 } | 3158 } |
| 2998 | 3159 |
| 2999 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 3160 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 3161 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can |
| 3162 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the |
| 3163 // unusedImports list. |
| 3000 SimpleIdentifier prefixIdentifier = node.prefix; | 3164 SimpleIdentifier prefixIdentifier = node.prefix; |
| 3001 Element element = prefixIdentifier.staticElement; | 3165 Element element = prefixIdentifier.staticElement; |
| 3002 if (element is PrefixElement) { | 3166 if (element is PrefixElement) { |
| 3003 _unusedImports.remove(_prefixElementMap[element]); | 3167 _unusedImports.remove(_prefixElementMap[element]); |
| 3004 return null; | 3168 return null; |
| 3005 } | 3169 } |
| 3170 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. |
| 3006 return visitIdentifier(element, prefixIdentifier.name); | 3171 return visitIdentifier(element, prefixIdentifier.name); |
| 3007 } | 3172 } |
| 3008 | 3173 |
| 3009 Object visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node.st
aticElement, node.name); | 3174 Object visitSimpleIdentifier(SimpleIdentifier node) => visitIdentifier(node.st
aticElement, node.name); |
| 3010 | 3175 |
| 3011 void set inDefiningCompilationUnit(bool inDefiningCompilationUnit) { | 3176 void set inDefiningCompilationUnit(bool inDefiningCompilationUnit) { |
| 3012 this._inDefiningCompilationUnit = inDefiningCompilationUnit; | 3177 this._inDefiningCompilationUnit = inDefiningCompilationUnit; |
| 3013 } | 3178 } |
| 3014 | 3179 |
| 3015 /** | 3180 /** |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3030 * Lookup and return the [Namespace] from the [namespaceMap], if the map does
not | 3195 * Lookup and return the [Namespace] from the [namespaceMap], if the map does
not |
| 3031 * have the computed namespace, compute it and cache it in the map. If the imp
ort directive is not | 3196 * have the computed namespace, compute it and cache it in the map. If the imp
ort directive is not |
| 3032 * resolved or is not resolvable, `null` is returned. | 3197 * resolved or is not resolvable, `null` is returned. |
| 3033 * | 3198 * |
| 3034 * @param importDirective the import directive used to compute the returned na
mespace | 3199 * @param importDirective the import directive used to compute the returned na
mespace |
| 3035 * @return the computed or looked up [Namespace] | 3200 * @return the computed or looked up [Namespace] |
| 3036 */ | 3201 */ |
| 3037 Namespace computeNamespace(ImportDirective importDirective) { | 3202 Namespace computeNamespace(ImportDirective importDirective) { |
| 3038 Namespace namespace = _namespaceMap[importDirective]; | 3203 Namespace namespace = _namespaceMap[importDirective]; |
| 3039 if (namespace == null) { | 3204 if (namespace == null) { |
| 3205 // If the namespace isn't in the namespaceMap, then compute and put it in
the map |
| 3040 ImportElement importElement = importDirective.element; | 3206 ImportElement importElement = importDirective.element; |
| 3041 if (importElement != null) { | 3207 if (importElement != null) { |
| 3042 NamespaceBuilder builder = new NamespaceBuilder(); | 3208 NamespaceBuilder builder = new NamespaceBuilder(); |
| 3043 namespace = builder.createImportNamespace(importElement); | 3209 namespace = builder.createImportNamespace(importElement); |
| 3044 _namespaceMap[importDirective] = namespace; | 3210 _namespaceMap[importDirective] = namespace; |
| 3045 } | 3211 } |
| 3046 } | 3212 } |
| 3047 return namespace; | 3213 return namespace; |
| 3048 } | 3214 } |
| 3049 | 3215 |
| 3050 /** | 3216 /** |
| 3051 * The [libraryMap] is a mapping between a library elements and a list of impo
rt | 3217 * The [libraryMap] is a mapping between a library elements and a list of impo
rt |
| 3052 * directives, but when adding these mappings into the [libraryMap], this meth
od can be | 3218 * directives, but when adding these mappings into the [libraryMap], this meth
od can be |
| 3053 * used to simply add the mapping between the library element an an import dir
ective without | 3219 * used to simply add the mapping between the library element an an import dir
ective without |
| 3054 * needing to check to see if a list needs to be created. | 3220 * needing to check to see if a list needs to be created. |
| 3055 */ | 3221 */ |
| 3056 void putIntoLibraryMap(LibraryElement libraryElement, ImportDirective importDi
rective) { | 3222 void putIntoLibraryMap(LibraryElement libraryElement, ImportDirective importDi
rective) { |
| 3057 List<ImportDirective> importList = _libraryMap[libraryElement]; | 3223 List<ImportDirective> importList = _libraryMap[libraryElement]; |
| 3058 if (importList == null) { | 3224 if (importList == null) { |
| 3059 importList = new List<ImportDirective>(); | 3225 importList = new List<ImportDirective>(); |
| 3060 _libraryMap[libraryElement] = importList; | 3226 _libraryMap[libraryElement] = importList; |
| 3061 } | 3227 } |
| 3062 importList.add(importDirective); | 3228 importList.add(importDirective); |
| 3063 } | 3229 } |
| 3064 | 3230 |
| 3065 Object visitIdentifier(Element element, String name) { | 3231 Object visitIdentifier(Element element, String name) { |
| 3066 if (element == null) { | 3232 if (element == null) { |
| 3067 return null; | 3233 return null; |
| 3068 } | 3234 } |
| 3235 // If the element is multiply defined then call this method recursively for
each of the conflicting elements. |
| 3069 if (element is MultiplyDefinedElement) { | 3236 if (element is MultiplyDefinedElement) { |
| 3070 MultiplyDefinedElement multiplyDefinedElement = element; | 3237 MultiplyDefinedElement multiplyDefinedElement = element; |
| 3071 for (Element elt in multiplyDefinedElement.conflictingElements) { | 3238 for (Element elt in multiplyDefinedElement.conflictingElements) { |
| 3072 visitIdentifier(elt, name); | 3239 visitIdentifier(elt, name); |
| 3073 } | 3240 } |
| 3074 return null; | 3241 return null; |
| 3075 } else if (element is PrefixElement) { | 3242 } else if (element is PrefixElement) { |
| 3076 _unusedImports.remove(_prefixElementMap[element]); | 3243 _unusedImports.remove(_prefixElementMap[element]); |
| 3077 return null; | 3244 return null; |
| 3078 } | 3245 } |
| 3079 LibraryElement containingLibrary = element.library; | 3246 LibraryElement containingLibrary = element.library; |
| 3080 if (containingLibrary == null) { | 3247 if (containingLibrary == null) { |
| 3081 return null; | 3248 return null; |
| 3082 } | 3249 } |
| 3250 // If the element is declared in the current library, return. |
| 3083 if (_currentLibrary == containingLibrary) { | 3251 if (_currentLibrary == containingLibrary) { |
| 3084 return null; | 3252 return null; |
| 3085 } | 3253 } |
| 3086 List<ImportDirective> importsFromSameLibrary = _libraryMap[containingLibrary
]; | 3254 List<ImportDirective> importsFromSameLibrary = _libraryMap[containingLibrary
]; |
| 3087 if (importsFromSameLibrary == null) { | 3255 if (importsFromSameLibrary == null) { |
| 3088 return null; | 3256 return null; |
| 3089 } | 3257 } |
| 3090 if (importsFromSameLibrary.length == 1) { | 3258 if (importsFromSameLibrary.length == 1) { |
| 3259 // If there is only one import directive for this library, then it must be
the directive that |
| 3260 // this element is imported with, remove it from the unusedImports list. |
| 3091 ImportDirective usedImportDirective = importsFromSameLibrary[0]; | 3261 ImportDirective usedImportDirective = importsFromSameLibrary[0]; |
| 3092 _unusedImports.remove(usedImportDirective); | 3262 _unusedImports.remove(usedImportDirective); |
| 3093 } else { | 3263 } else { |
| 3264 // Otherwise, for each of the imported directives, use the namespaceMap to |
| 3094 for (ImportDirective importDirective in importsFromSameLibrary) { | 3265 for (ImportDirective importDirective in importsFromSameLibrary) { |
| 3266 // Get the namespace for this import |
| 3095 Namespace namespace = computeNamespace(importDirective); | 3267 Namespace namespace = computeNamespace(importDirective); |
| 3096 if (namespace != null && namespace.get(name) != null) { | 3268 if (namespace != null && namespace.get(name) != null) { |
| 3097 _unusedImports.remove(importDirective); | 3269 _unusedImports.remove(importDirective); |
| 3098 } | 3270 } |
| 3099 } | 3271 } |
| 3100 } | 3272 } |
| 3101 return null; | 3273 return null; |
| 3102 } | 3274 } |
| 3103 | 3275 |
| 3104 /** | 3276 /** |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3156 Source source = getSource(uriLiteral); | 3328 Source source = getSource(uriLiteral); |
| 3157 String fullName = getSourceFullName(source); | 3329 String fullName = getSourceFullName(source); |
| 3158 if (fullName != null) { | 3330 if (fullName != null) { |
| 3159 int pathIndex = 0; | 3331 int pathIndex = 0; |
| 3160 int fullNameIndex = fullName.length; | 3332 int fullNameIndex = fullName.length; |
| 3161 while (pathIndex < path.length && JavaString.startsWithBefore(path, "../",
pathIndex)) { | 3333 while (pathIndex < path.length && JavaString.startsWithBefore(path, "../",
pathIndex)) { |
| 3162 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); | 3334 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); |
| 3163 if (fullNameIndex < 4) { | 3335 if (fullNameIndex < 4) { |
| 3164 return false; | 3336 return false; |
| 3165 } | 3337 } |
| 3338 // Check for "/lib" at a specified place in the fullName |
| 3166 if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) { | 3339 if (JavaString.startsWithBefore(fullName, "/lib", fullNameIndex - 4)) { |
| 3167 String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSP
EC_YAML; | 3340 String relativePubspecPath = path.substring(0, pathIndex + 3) + _PUBSP
EC_YAML; |
| 3168 Source pubspecSource = _context.sourceFactory.resolveUri(source, relat
ivePubspecPath); | 3341 Source pubspecSource = _context.sourceFactory.resolveUri(source, relat
ivePubspecPath); |
| 3169 if (pubspecSource != null && pubspecSource.exists()) { | 3342 if (pubspecSource != null && pubspecSource.exists()) { |
| 3343 // Files inside the lib directory hierarchy should not reference fil
es outside |
| 3170 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB
_REFERENCES_FILE_OUTSIDE, uriLiteral, []); | 3344 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_INSIDE_LIB
_REFERENCES_FILE_OUTSIDE, uriLiteral, []); |
| 3171 } | 3345 } |
| 3172 return true; | 3346 return true; |
| 3173 } | 3347 } |
| 3174 pathIndex += 3; | 3348 pathIndex += 3; |
| 3175 } | 3349 } |
| 3176 } | 3350 } |
| 3177 return false; | 3351 return false; |
| 3178 } | 3352 } |
| 3179 | 3353 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3206 bool checkForFileImportOutsideLibReferencesFileInside2(StringLiteral uriLitera
l, String path, int pathIndex) { | 3380 bool checkForFileImportOutsideLibReferencesFileInside2(StringLiteral uriLitera
l, String path, int pathIndex) { |
| 3207 Source source = getSource(uriLiteral); | 3381 Source source = getSource(uriLiteral); |
| 3208 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; | 3382 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; |
| 3209 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub
specPath); | 3383 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub
specPath); |
| 3210 if (pubspecSource == null || !pubspecSource.exists()) { | 3384 if (pubspecSource == null || !pubspecSource.exists()) { |
| 3211 return false; | 3385 return false; |
| 3212 } | 3386 } |
| 3213 String fullName = getSourceFullName(source); | 3387 String fullName = getSourceFullName(source); |
| 3214 if (fullName != null) { | 3388 if (fullName != null) { |
| 3215 if (!fullName.contains("/lib/")) { | 3389 if (!fullName.contains("/lib/")) { |
| 3390 // Files outside the lib directory hierarchy should not reference files
inside |
| 3391 // ... use package: url instead |
| 3216 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_RE
FERENCES_FILE_INSIDE, uriLiteral, []); | 3392 _errorReporter.reportError3(PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_RE
FERENCES_FILE_INSIDE, uriLiteral, []); |
| 3217 return true; | 3393 return true; |
| 3218 } | 3394 } |
| 3219 } | 3395 } |
| 3220 return false; | 3396 return false; |
| 3221 } | 3397 } |
| 3222 | 3398 |
| 3223 /** | 3399 /** |
| 3224 * This verifies that the passed package import directive does not contain "..
" | 3400 * This verifies that the passed package import directive does not contain "..
" |
| 3225 * | 3401 * |
| 3226 * @param uriLiteral the import URL (not `null`) | 3402 * @param uriLiteral the import URL (not `null`) |
| 3227 * @param path the path to be validated (not `null`) | 3403 * @param path the path to be validated (not `null`) |
| 3228 * @return `true` if and only if an error code is generated on the passed node | 3404 * @return `true` if and only if an error code is generated on the passed node |
| 3229 * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | 3405 * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT |
| 3230 */ | 3406 */ |
| 3231 bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path
) { | 3407 bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path
) { |
| 3232 if (path.startsWith("../") || path.contains("/../")) { | 3408 if (path.startsWith("../") || path.contains("/../")) { |
| 3409 // Package import should not to contain ".." |
| 3233 _errorReporter.reportError3(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_
DOT, uriLiteral, []); | 3410 _errorReporter.reportError3(PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_
DOT, uriLiteral, []); |
| 3234 return true; | 3411 return true; |
| 3235 } | 3412 } |
| 3236 return false; | 3413 return false; |
| 3237 } | 3414 } |
| 3238 | 3415 |
| 3239 /** | 3416 /** |
| 3240 * Answer the source associated with the compilation unit containing the given
AST node. | 3417 * Answer the source associated with the compilation unit containing the given
AST node. |
| 3241 * | 3418 * |
| 3242 * @param node the node (not `null`) | 3419 * @param node the node (not `null`) |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4704 if (leftHandSide != null) { | 4881 if (leftHandSide != null) { |
| 4705 String methodName = operatorType.lexeme; | 4882 String methodName = operatorType.lexeme; |
| 4706 Type2 staticType = getStaticType(leftHandSide); | 4883 Type2 staticType = getStaticType(leftHandSide); |
| 4707 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth
odName); | 4884 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth
odName); |
| 4708 node.staticElement = staticMethod; | 4885 node.staticElement = staticMethod; |
| 4709 Type2 propagatedType = getPropagatedType(leftHandSide); | 4886 Type2 propagatedType = getPropagatedType(leftHandSide); |
| 4710 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy
pe, methodName); | 4887 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy
pe, methodName); |
| 4711 node.propagatedElement = propagatedMethod; | 4888 node.propagatedElement = propagatedMethod; |
| 4712 bool shouldReportMissingMember_static = shouldReportMissingMember(static
Type, staticMethod); | 4889 bool shouldReportMissingMember_static = shouldReportMissingMember(static
Type, staticMethod); |
| 4713 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_s
tatic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMeth
od) : false; | 4890 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_s
tatic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMeth
od) : false; |
| 4891 // |
| 4892 // If we are about to generate the hint (propagated version of this warn
ing), then check |
| 4893 // that the member is not in a subtype of the propagated type. |
| 4894 // |
| 4714 if (shouldReportMissingMember_propagated) { | 4895 if (shouldReportMissingMember_propagated) { |
| 4715 if (memberFoundInSubclass(propagatedType.element, methodName, true, fa
lse)) { | 4896 if (memberFoundInSubclass(propagatedType.element, methodName, true, fa
lse)) { |
| 4716 shouldReportMissingMember_propagated = false; | 4897 shouldReportMissingMember_propagated = false; |
| 4717 } | 4898 } |
| 4718 } | 4899 } |
| 4719 if (shouldReportMissingMember_static || shouldReportMissingMember_propag
ated) { | 4900 if (shouldReportMissingMember_static || shouldReportMissingMember_propag
ated) { |
| 4720 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode; | 4901 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_METHOD : HintCode.UNDEFINED_METHOD) as ErrorCode; |
| 4721 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissin
gMember_static ? staticType.element : propagatedType.element, errorCode, operato
r, [ | 4902 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissin
gMember_static ? staticType.element : propagatedType.element, errorCode, operato
r, [ |
| 4722 methodName, | 4903 methodName, |
| 4723 shouldReportMissingMember_static ? staticType.displayName : propag
atedType.displayName]); | 4904 shouldReportMissingMember_static ? staticType.displayName : propag
atedType.displayName]); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4734 if (leftOperand != null) { | 4915 if (leftOperand != null) { |
| 4735 String methodName = operator.lexeme; | 4916 String methodName = operator.lexeme; |
| 4736 Type2 staticType = getStaticType(leftOperand); | 4917 Type2 staticType = getStaticType(leftOperand); |
| 4737 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho
dName); | 4918 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho
dName); |
| 4738 node.staticElement = staticMethod; | 4919 node.staticElement = staticMethod; |
| 4739 Type2 propagatedType = getPropagatedType(leftOperand); | 4920 Type2 propagatedType = getPropagatedType(leftOperand); |
| 4740 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp
e, methodName); | 4921 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp
e, methodName); |
| 4741 node.propagatedElement = propagatedMethod; | 4922 node.propagatedElement = propagatedMethod; |
| 4742 bool shouldReportMissingMember_static = shouldReportMissingMember(static
Type, staticMethod); | 4923 bool shouldReportMissingMember_static = shouldReportMissingMember(static
Type, staticMethod); |
| 4743 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_s
tatic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMeth
od) : false; | 4924 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_s
tatic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMeth
od) : false; |
| 4925 // |
| 4926 // If we are about to generate the hint (propagated version of this warn
ing), then check |
| 4927 // that the member is not in a subtype of the propagated type. |
| 4928 // |
| 4744 if (shouldReportMissingMember_propagated) { | 4929 if (shouldReportMissingMember_propagated) { |
| 4745 if (memberFoundInSubclass(propagatedType.element, methodName, true, fa
lse)) { | 4930 if (memberFoundInSubclass(propagatedType.element, methodName, true, fa
lse)) { |
| 4746 shouldReportMissingMember_propagated = false; | 4931 shouldReportMissingMember_propagated = false; |
| 4747 } | 4932 } |
| 4748 } | 4933 } |
| 4749 if (shouldReportMissingMember_static || shouldReportMissingMember_propag
ated) { | 4934 if (shouldReportMissingMember_static || shouldReportMissingMember_propag
ated) { |
| 4750 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; | 4935 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; |
| 4751 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissin
gMember_static ? staticType.element : propagatedType.element, errorCode, operato
r, [ | 4936 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissin
gMember_static ? staticType.element : propagatedType.element, errorCode, operato
r, [ |
| 4752 methodName, | 4937 methodName, |
| 4753 shouldReportMissingMember_static ? staticType.displayName : propag
atedType.displayName]); | 4938 shouldReportMissingMember_static ? staticType.displayName : propag
atedType.displayName]); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4775 setMetadata(node.element, node); | 4960 setMetadata(node.element, node); |
| 4776 return null; | 4961 return null; |
| 4777 } | 4962 } |
| 4778 | 4963 |
| 4779 Object visitCommentReference(CommentReference node) { | 4964 Object visitCommentReference(CommentReference node) { |
| 4780 Identifier identifier = node.identifier; | 4965 Identifier identifier = node.identifier; |
| 4781 if (identifier is SimpleIdentifier) { | 4966 if (identifier is SimpleIdentifier) { |
| 4782 SimpleIdentifier simpleIdentifier = identifier; | 4967 SimpleIdentifier simpleIdentifier = identifier; |
| 4783 Element element = resolveSimpleIdentifier(simpleIdentifier); | 4968 Element element = resolveSimpleIdentifier(simpleIdentifier); |
| 4784 if (element == null) { | 4969 if (element == null) { |
| 4970 // |
| 4971 // This might be a reference to an imported name that is missing the pre
fix. |
| 4972 // |
| 4785 element = findImportWithoutPrefix(simpleIdentifier); | 4973 element = findImportWithoutPrefix(simpleIdentifier); |
| 4786 if (element is MultiplyDefinedElement) { | 4974 if (element is MultiplyDefinedElement) { |
| 4975 // TODO(brianwilkerson) Report this error? |
| 4787 element = null; | 4976 element = null; |
| 4788 } | 4977 } |
| 4789 } | 4978 } |
| 4790 if (element == null) { | 4979 if (element == null) { |
| 4791 } else { | 4980 } else { |
| 4792 if (element.library == null || element.library != _definingLibrary) { | 4981 if (element.library == null || element.library != _definingLibrary) { |
| 4793 } | 4982 } |
| 4794 simpleIdentifier.staticElement = element; | 4983 simpleIdentifier.staticElement = element; |
| 4795 if (node.newKeyword != null) { | 4984 if (node.newKeyword != null) { |
| 4796 if (element is ClassElement) { | 4985 if (element is ClassElement) { |
| 4797 ConstructorElement constructor = (element as ClassElement).unnamedCo
nstructor; | 4986 ConstructorElement constructor = (element as ClassElement).unnamedCo
nstructor; |
| 4798 if (constructor == null) { | 4987 if (constructor == null) { |
| 4799 } else { | 4988 } else { |
| 4800 simpleIdentifier.staticElement = constructor; | 4989 simpleIdentifier.staticElement = constructor; |
| 4801 } | 4990 } |
| 4802 } else { | 4991 } else { |
| 4803 } | 4992 } |
| 4804 } | 4993 } |
| 4805 } | 4994 } |
| 4806 } else if (identifier is PrefixedIdentifier) { | 4995 } else if (identifier is PrefixedIdentifier) { |
| 4807 PrefixedIdentifier prefixedIdentifier = identifier; | 4996 PrefixedIdentifier prefixedIdentifier = identifier; |
| 4808 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 4997 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
| 4809 SimpleIdentifier name = prefixedIdentifier.identifier; | 4998 SimpleIdentifier name = prefixedIdentifier.identifier; |
| 4810 Element element = resolveSimpleIdentifier(prefix); | 4999 Element element = resolveSimpleIdentifier(prefix); |
| 4811 if (element == null) { | 5000 if (element == null) { |
| 4812 } else { | 5001 } else { |
| 4813 if (element is PrefixElement) { | 5002 if (element is PrefixElement) { |
| 4814 prefix.staticElement = element; | 5003 prefix.staticElement = element; |
| 5004 // TODO(brianwilkerson) Report this error? |
| 4815 element = _resolver.nameScope.lookup(identifier, _definingLibrary); | 5005 element = _resolver.nameScope.lookup(identifier, _definingLibrary); |
| 4816 name.staticElement = element; | 5006 name.staticElement = element; |
| 4817 return null; | 5007 return null; |
| 4818 } | 5008 } |
| 4819 LibraryElement library = element.library; | 5009 LibraryElement library = element.library; |
| 4820 if (library == null) { | 5010 if (library == null) { |
| 5011 // TODO(brianwilkerson) We need to understand how the library could ev
er be null. |
| 4821 AnalysisEngine.instance.logger.logError("Found element with null libra
ry: ${element.name}"); | 5012 AnalysisEngine.instance.logger.logError("Found element with null libra
ry: ${element.name}"); |
| 4822 } else if (library != _definingLibrary) { | 5013 } else if (library != _definingLibrary) { |
| 4823 } | 5014 } |
| 4824 name.staticElement = element; | 5015 name.staticElement = element; |
| 4825 if (node.newKeyword == null) { | 5016 if (node.newKeyword == null) { |
| 4826 if (element is ClassElement) { | 5017 if (element is ClassElement) { |
| 4827 Element memberElement = lookupGetterOrMethod((element as ClassElemen
t).type, name.name); | 5018 Element memberElement = lookupGetterOrMethod((element as ClassElemen
t).type, name.name); |
| 4828 if (memberElement == null) { | 5019 if (memberElement == null) { |
| 4829 memberElement = (element as ClassElement).getNamedConstructor(name
.name); | 5020 memberElement = (element as ClassElement).getNamedConstructor(name
.name); |
| 4830 if (memberElement == null) { | 5021 if (memberElement == null) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4850 } | 5041 } |
| 4851 } | 5042 } |
| 4852 return null; | 5043 return null; |
| 4853 } | 5044 } |
| 4854 | 5045 |
| 4855 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 5046 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 4856 super.visitConstructorDeclaration(node); | 5047 super.visitConstructorDeclaration(node); |
| 4857 ConstructorElement element = node.element; | 5048 ConstructorElement element = node.element; |
| 4858 if (element is ConstructorElementImpl) { | 5049 if (element is ConstructorElementImpl) { |
| 4859 ConstructorElementImpl constructorElement = element; | 5050 ConstructorElementImpl constructorElement = element; |
| 5051 // set redirected factory constructor |
| 4860 ConstructorName redirectedNode = node.redirectedConstructor; | 5052 ConstructorName redirectedNode = node.redirectedConstructor; |
| 4861 if (redirectedNode != null) { | 5053 if (redirectedNode != null) { |
| 4862 ConstructorElement redirectedElement = redirectedNode.staticElement; | 5054 ConstructorElement redirectedElement = redirectedNode.staticElement; |
| 4863 constructorElement.redirectedConstructor = redirectedElement; | 5055 constructorElement.redirectedConstructor = redirectedElement; |
| 4864 } | 5056 } |
| 5057 // set redirected generate constructor |
| 4865 for (ConstructorInitializer initializer in node.initializers) { | 5058 for (ConstructorInitializer initializer in node.initializers) { |
| 4866 if (initializer is RedirectingConstructorInvocation) { | 5059 if (initializer is RedirectingConstructorInvocation) { |
| 4867 ConstructorElement redirectedElement = initializer.staticElement; | 5060 ConstructorElement redirectedElement = initializer.staticElement; |
| 4868 constructorElement.redirectedConstructor = redirectedElement; | 5061 constructorElement.redirectedConstructor = redirectedElement; |
| 4869 } | 5062 } |
| 4870 } | 5063 } |
| 4871 setMetadata(constructorElement, node); | 5064 setMetadata(constructorElement, node); |
| 4872 } | 5065 } |
| 4873 return null; | 5066 return null; |
| 4874 } | 5067 } |
| 4875 | 5068 |
| 4876 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 5069 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 4877 SimpleIdentifier fieldName = node.fieldName; | 5070 SimpleIdentifier fieldName = node.fieldName; |
| 4878 ClassElement enclosingClass = _resolver.enclosingClass; | 5071 ClassElement enclosingClass = _resolver.enclosingClass; |
| 4879 FieldElement fieldElement = enclosingClass.getField(fieldName.name); | 5072 FieldElement fieldElement = enclosingClass.getField(fieldName.name); |
| 4880 fieldName.staticElement = fieldElement; | 5073 fieldName.staticElement = fieldElement; |
| 4881 if (fieldElement == null || fieldElement.isSynthetic) { | 5074 if (fieldElement == null || fieldElement.isSynthetic) { |
| 4882 _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_F
IELD, node, [fieldName]); | 5075 _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_F
IELD, node, [fieldName]); |
| 4883 } else if (fieldElement.isStatic) { | 5076 } else if (fieldElement.isStatic) { |
| 4884 _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
node, [fieldName]); | 5077 _resolver.reportError7(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
node, [fieldName]); |
| 4885 } | 5078 } |
| 4886 return null; | 5079 return null; |
| 4887 } | 5080 } |
| 4888 | 5081 |
| 4889 Object visitConstructorName(ConstructorName node) { | 5082 Object visitConstructorName(ConstructorName node) { |
| 4890 Type2 type = node.type.type; | 5083 Type2 type = node.type.type; |
| 4891 if (type != null && type.isDynamic) { | 5084 if (type != null && type.isDynamic) { |
| 4892 return null; | 5085 return null; |
| 4893 } else if (type is! InterfaceType) { | 5086 } else if (type is! InterfaceType) { |
| 5087 // TODO(brianwilkerson) Report these errors. |
| 4894 ASTNode parent = node.parent; | 5088 ASTNode parent = node.parent; |
| 4895 if (parent is InstanceCreationExpression) { | 5089 if (parent is InstanceCreationExpression) { |
| 4896 if (parent.isConst) { | 5090 if (parent.isConst) { |
| 4897 } else { | 5091 } else { |
| 4898 } | 5092 } |
| 4899 } else { | 5093 } else { |
| 4900 } | 5094 } |
| 4901 return null; | 5095 return null; |
| 4902 } | 5096 } |
| 5097 // look up ConstructorElement |
| 4903 ConstructorElement constructor; | 5098 ConstructorElement constructor; |
| 4904 SimpleIdentifier name = node.name; | 5099 SimpleIdentifier name = node.name; |
| 4905 InterfaceType interfaceType = type as InterfaceType; | 5100 InterfaceType interfaceType = type as InterfaceType; |
| 4906 if (name == null) { | 5101 if (name == null) { |
| 4907 constructor = interfaceType.lookUpConstructor(null, _definingLibrary); | 5102 constructor = interfaceType.lookUpConstructor(null, _definingLibrary); |
| 4908 } else { | 5103 } else { |
| 4909 constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary)
; | 5104 constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary)
; |
| 4910 name.staticElement = constructor; | 5105 name.staticElement = constructor; |
| 4911 } | 5106 } |
| 4912 node.staticElement = constructor; | 5107 node.staticElement = constructor; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4923 } | 5118 } |
| 4924 | 5119 |
| 4925 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 5120 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 4926 setMetadata(node.element, node); | 5121 setMetadata(node.element, node); |
| 4927 return null; | 5122 return null; |
| 4928 } | 5123 } |
| 4929 | 5124 |
| 4930 Object visitExportDirective(ExportDirective node) { | 5125 Object visitExportDirective(ExportDirective node) { |
| 4931 Element element = node.element; | 5126 Element element = node.element; |
| 4932 if (element is ExportElement) { | 5127 if (element is ExportElement) { |
| 5128 // The element is null when the URI is invalid |
| 5129 // TODO(brianwilkerson) Figure out whether the element can ever be somethi
ng other than an |
| 5130 // ExportElement |
| 4933 resolveCombinators(element.exportedLibrary, node.combinators); | 5131 resolveCombinators(element.exportedLibrary, node.combinators); |
| 4934 setMetadata(element, node); | 5132 setMetadata(element, node); |
| 4935 } | 5133 } |
| 4936 return null; | 5134 return null; |
| 4937 } | 5135 } |
| 4938 | 5136 |
| 4939 Object visitFieldFormalParameter(FieldFormalParameter node) { | 5137 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 4940 String fieldName = node.identifier.name; | 5138 String fieldName = node.identifier.name; |
| 4941 ClassElement classElement = _resolver.enclosingClass; | 5139 ClassElement classElement = _resolver.enclosingClass; |
| 4942 if (classElement != null) { | 5140 if (classElement != null) { |
| 4943 FieldElement fieldElement = classElement.getField(fieldName); | 5141 FieldElement fieldElement = classElement.getField(fieldName); |
| 4944 if (fieldElement == null) { | 5142 if (fieldElement == null) { |
| 4945 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_
EXISTANT_FIELD, node, [fieldName]); | 5143 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_
EXISTANT_FIELD, node, [fieldName]); |
| 4946 } else { | 5144 } else { |
| 4947 ParameterElement parameterElement = node.element; | 5145 ParameterElement parameterElement = node.element; |
| 4948 if (parameterElement is FieldFormalParameterElementImpl) { | 5146 if (parameterElement is FieldFormalParameterElementImpl) { |
| 4949 FieldFormalParameterElementImpl fieldFormal = parameterElement; | 5147 FieldFormalParameterElementImpl fieldFormal = parameterElement; |
| 4950 fieldFormal.field = fieldElement; | 5148 fieldFormal.field = fieldElement; |
| 4951 Type2 declaredType = fieldFormal.type; | 5149 Type2 declaredType = fieldFormal.type; |
| 4952 Type2 fieldType = fieldElement.type; | 5150 Type2 fieldType = fieldElement.type; |
| 4953 if (node.type == null) { | 5151 if (node.type == null) { |
| 4954 fieldFormal.type = fieldType; | 5152 fieldFormal.type = fieldType; |
| 4955 } | 5153 } |
| 4956 if (fieldElement.isSynthetic) { | 5154 if (fieldElement.isSynthetic) { |
| 4957 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
NON_EXISTANT_FIELD, node, [fieldName]); | 5155 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
NON_EXISTANT_FIELD, node, [fieldName]); |
| 4958 } else if (fieldElement.isStatic) { | 5156 } else if (fieldElement.isStatic) { |
| 4959 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
STATIC_FIELD, node, [fieldName]); | 5157 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
STATIC_FIELD, node, [fieldName]); |
| 4960 } else if (declaredType != null && fieldType != null && !declaredType.
isAssignableTo(fieldType)) { | 5158 } else if (declaredType != null && fieldType != null && !declaredType.
isAssignableTo(fieldType)) { |
| 5159 // TODO(brianwilkerson) We should implement a displayName() method f
or types that will |
| 5160 // work nicely with function types and then use that below. |
| 4961 _resolver.reportError7(StaticWarningCode.FIELD_INITIALIZING_FORMAL_N
OT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]); | 5161 _resolver.reportError7(StaticWarningCode.FIELD_INITIALIZING_FORMAL_N
OT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]); |
| 4962 } | 5162 } |
| 4963 } else { | 5163 } else { |
| 4964 if (fieldElement.isSynthetic) { | 5164 if (fieldElement.isSynthetic) { |
| 4965 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
NON_EXISTANT_FIELD, node, [fieldName]); | 5165 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
NON_EXISTANT_FIELD, node, [fieldName]); |
| 4966 } else if (fieldElement.isStatic) { | 5166 } else if (fieldElement.isStatic) { |
| 4967 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
STATIC_FIELD, node, [fieldName]); | 5167 _resolver.reportError7(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_
STATIC_FIELD, node, [fieldName]); |
| 4968 } | 5168 } |
| 4969 } | 5169 } |
| 4970 } | 5170 } |
| 4971 } | 5171 } |
| 5172 // else { |
| 5173 // // TODO(jwren) Report error, constructor initializer variable is a top
level element |
| 5174 // // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCo
des) |
| 5175 // } |
| 4972 return super.visitFieldFormalParameter(node); | 5176 return super.visitFieldFormalParameter(node); |
| 4973 } | 5177 } |
| 4974 | 5178 |
| 4975 Object visitFunctionDeclaration(FunctionDeclaration node) { | 5179 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 4976 setMetadata(node.element, node); | 5180 setMetadata(node.element, node); |
| 4977 return null; | 5181 return null; |
| 4978 } | 5182 } |
| 4979 | 5183 |
| 4980 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 5184 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 5185 // TODO(brianwilkerson) Can we ever resolve the function being invoked? |
| 4981 Expression expression = node.function; | 5186 Expression expression = node.function; |
| 4982 if (expression is FunctionExpression) { | 5187 if (expression is FunctionExpression) { |
| 4983 FunctionExpression functionExpression = expression; | 5188 FunctionExpression functionExpression = expression; |
| 4984 ExecutableElement functionElement = functionExpression.element; | 5189 ExecutableElement functionElement = functionExpression.element; |
| 4985 ArgumentList argumentList = node.argumentList; | 5190 ArgumentList argumentList = node.argumentList; |
| 4986 List<ParameterElement> parameters = resolveArgumentsToParameters(false, ar
gumentList, functionElement); | 5191 List<ParameterElement> parameters = resolveArgumentsToParameters(false, ar
gumentList, functionElement); |
| 4987 if (parameters != null) { | 5192 if (parameters != null) { |
| 4988 argumentList.correspondingStaticParameters = parameters; | 5193 argumentList.correspondingStaticParameters = parameters; |
| 4989 } | 5194 } |
| 4990 } | 5195 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5002 String prefixName = prefixNode.name; | 5207 String prefixName = prefixNode.name; |
| 5003 for (PrefixElement prefixElement in _definingLibrary.prefixes) { | 5208 for (PrefixElement prefixElement in _definingLibrary.prefixes) { |
| 5004 if (prefixElement.displayName == prefixName) { | 5209 if (prefixElement.displayName == prefixName) { |
| 5005 prefixNode.staticElement = prefixElement; | 5210 prefixNode.staticElement = prefixElement; |
| 5006 break; | 5211 break; |
| 5007 } | 5212 } |
| 5008 } | 5213 } |
| 5009 } | 5214 } |
| 5010 ImportElement importElement = node.element; | 5215 ImportElement importElement = node.element; |
| 5011 if (importElement != null) { | 5216 if (importElement != null) { |
| 5217 // The element is null when the URI is invalid |
| 5012 LibraryElement library = importElement.importedLibrary; | 5218 LibraryElement library = importElement.importedLibrary; |
| 5013 if (library != null) { | 5219 if (library != null) { |
| 5014 resolveCombinators(library, node.combinators); | 5220 resolveCombinators(library, node.combinators); |
| 5015 } | 5221 } |
| 5016 setMetadata(importElement, node); | 5222 setMetadata(importElement, node); |
| 5017 } | 5223 } |
| 5018 return null; | 5224 return null; |
| 5019 } | 5225 } |
| 5020 | 5226 |
| 5021 Object visitIndexExpression(IndexExpression node) { | 5227 Object visitIndexExpression(IndexExpression node) { |
| 5022 Expression target = node.realTarget; | 5228 Expression target = node.realTarget; |
| 5023 Type2 staticType = getStaticType(target); | 5229 Type2 staticType = getStaticType(target); |
| 5024 Type2 propagatedType = getPropagatedType(target); | 5230 Type2 propagatedType = getPropagatedType(target); |
| 5025 String getterMethodName = sc.TokenType.INDEX.lexeme; | 5231 String getterMethodName = sc.TokenType.INDEX.lexeme; |
| 5026 String setterMethodName = sc.TokenType.INDEX_EQ.lexeme; | 5232 String setterMethodName = sc.TokenType.INDEX_EQ.lexeme; |
| 5027 bool isInGetterContext = node.inGetterContext(); | 5233 bool isInGetterContext = node.inGetterContext(); |
| 5028 bool isInSetterContext = node.inSetterContext(); | 5234 bool isInSetterContext = node.inSetterContext(); |
| 5029 if (isInGetterContext && isInSetterContext) { | 5235 if (isInGetterContext && isInSetterContext) { |
| 5236 // lookup setter |
| 5030 MethodElement setterStaticMethod = lookUpMethod(target, staticType, setter
MethodName); | 5237 MethodElement setterStaticMethod = lookUpMethod(target, staticType, setter
MethodName); |
| 5031 MethodElement setterPropagatedMethod = lookUpMethod(target, propagatedType
, setterMethodName); | 5238 MethodElement setterPropagatedMethod = lookUpMethod(target, propagatedType
, setterMethodName); |
| 5239 // set setter element |
| 5032 node.staticElement = setterStaticMethod; | 5240 node.staticElement = setterStaticMethod; |
| 5033 node.propagatedElement = setterPropagatedMethod; | 5241 node.propagatedElement = setterPropagatedMethod; |
| 5242 // generate undefined method warning |
| 5034 checkForUndefinedIndexOperator(node, target, getterMethodName, setterStati
cMethod, setterPropagatedMethod, staticType, propagatedType); | 5243 checkForUndefinedIndexOperator(node, target, getterMethodName, setterStati
cMethod, setterPropagatedMethod, staticType, propagatedType); |
| 5244 // lookup getter method |
| 5035 MethodElement getterStaticMethod = lookUpMethod(target, staticType, getter
MethodName); | 5245 MethodElement getterStaticMethod = lookUpMethod(target, staticType, getter
MethodName); |
| 5036 MethodElement getterPropagatedMethod = lookUpMethod(target, propagatedType
, getterMethodName); | 5246 MethodElement getterPropagatedMethod = lookUpMethod(target, propagatedType
, getterMethodName); |
| 5247 // set getter element |
| 5037 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMe
thod, getterPropagatedMethod); | 5248 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMe
thod, getterPropagatedMethod); |
| 5038 node.auxiliaryElements = auxiliaryElements; | 5249 node.auxiliaryElements = auxiliaryElements; |
| 5250 // generate undefined method warning |
| 5039 checkForUndefinedIndexOperator(node, target, getterMethodName, getterStati
cMethod, getterPropagatedMethod, staticType, propagatedType); | 5251 checkForUndefinedIndexOperator(node, target, getterMethodName, getterStati
cMethod, getterPropagatedMethod, staticType, propagatedType); |
| 5040 } else if (isInGetterContext) { | 5252 } else if (isInGetterContext) { |
| 5253 // lookup getter method |
| 5041 MethodElement staticMethod = lookUpMethod(target, staticType, getterMethod
Name); | 5254 MethodElement staticMethod = lookUpMethod(target, staticType, getterMethod
Name); |
| 5042 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, gett
erMethodName); | 5255 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, gett
erMethodName); |
| 5256 // set getter element |
| 5043 node.staticElement = staticMethod; | 5257 node.staticElement = staticMethod; |
| 5044 node.propagatedElement = propagatedMethod; | 5258 node.propagatedElement = propagatedMethod; |
| 5259 // generate undefined method warning |
| 5045 checkForUndefinedIndexOperator(node, target, getterMethodName, staticMetho
d, propagatedMethod, staticType, propagatedType); | 5260 checkForUndefinedIndexOperator(node, target, getterMethodName, staticMetho
d, propagatedMethod, staticType, propagatedType); |
| 5046 } else if (isInSetterContext) { | 5261 } else if (isInSetterContext) { |
| 5262 // lookup setter method |
| 5047 MethodElement staticMethod = lookUpMethod(target, staticType, setterMethod
Name); | 5263 MethodElement staticMethod = lookUpMethod(target, staticType, setterMethod
Name); |
| 5048 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, sett
erMethodName); | 5264 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, sett
erMethodName); |
| 5265 // set setter element |
| 5049 node.staticElement = staticMethod; | 5266 node.staticElement = staticMethod; |
| 5050 node.propagatedElement = propagatedMethod; | 5267 node.propagatedElement = propagatedMethod; |
| 5268 // generate undefined method warning |
| 5051 checkForUndefinedIndexOperator(node, target, setterMethodName, staticMetho
d, propagatedMethod, staticType, propagatedType); | 5269 checkForUndefinedIndexOperator(node, target, setterMethodName, staticMetho
d, propagatedMethod, staticType, propagatedType); |
| 5052 } | 5270 } |
| 5053 return null; | 5271 return null; |
| 5054 } | 5272 } |
| 5055 | 5273 |
| 5056 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 5274 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 5057 ConstructorElement invokedConstructor = node.constructorName.staticElement; | 5275 ConstructorElement invokedConstructor = node.constructorName.staticElement; |
| 5058 node.staticElement = invokedConstructor; | 5276 node.staticElement = invokedConstructor; |
| 5059 ArgumentList argumentList = node.argumentList; | 5277 ArgumentList argumentList = node.argumentList; |
| 5060 List<ParameterElement> parameters = resolveArgumentsToParameters(node.isCons
t, argumentList, invokedConstructor); | 5278 List<ParameterElement> parameters = resolveArgumentsToParameters(node.isCons
t, argumentList, invokedConstructor); |
| 5061 if (parameters != null) { | 5279 if (parameters != null) { |
| 5062 argumentList.correspondingStaticParameters = parameters; | 5280 argumentList.correspondingStaticParameters = parameters; |
| 5063 } | 5281 } |
| 5064 return null; | 5282 return null; |
| 5065 } | 5283 } |
| 5066 | 5284 |
| 5067 Object visitLibraryDirective(LibraryDirective node) { | 5285 Object visitLibraryDirective(LibraryDirective node) { |
| 5068 setMetadata(node.element, node); | 5286 setMetadata(node.element, node); |
| 5069 return null; | 5287 return null; |
| 5070 } | 5288 } |
| 5071 | 5289 |
| 5072 Object visitMethodDeclaration(MethodDeclaration node) { | 5290 Object visitMethodDeclaration(MethodDeclaration node) { |
| 5073 setMetadata(node.element, node); | 5291 setMetadata(node.element, node); |
| 5074 return null; | 5292 return null; |
| 5075 } | 5293 } |
| 5076 | 5294 |
| 5077 Object visitMethodInvocation(MethodInvocation node) { | 5295 Object visitMethodInvocation(MethodInvocation node) { |
| 5078 SimpleIdentifier methodName = node.methodName; | 5296 SimpleIdentifier methodName = node.methodName; |
| 5297 // |
| 5298 // Synthetic identifiers have been already reported during parsing. |
| 5299 // |
| 5079 if (methodName.isSynthetic) { | 5300 if (methodName.isSynthetic) { |
| 5080 return null; | 5301 return null; |
| 5081 } | 5302 } |
| 5303 // |
| 5304 // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm
(a1, ..., an)'. The |
| 5305 // first step is to figure out which executable is being invoked, using both
the static and the |
| 5306 // propagated type information. |
| 5307 // |
| 5082 Expression target = node.realTarget; | 5308 Expression target = node.realTarget; |
| 5083 if (target is SuperExpression && !isSuperInValidContext(target)) { | 5309 if (target is SuperExpression && !isSuperInValidContext(target)) { |
| 5084 return null; | 5310 return null; |
| 5085 } | 5311 } |
| 5086 Element staticElement; | 5312 Element staticElement; |
| 5087 Element propagatedElement; | 5313 Element propagatedElement; |
| 5088 if (target == null) { | 5314 if (target == null) { |
| 5089 staticElement = resolveInvokedElement2(methodName); | 5315 staticElement = resolveInvokedElement2(methodName); |
| 5090 propagatedElement = null; | 5316 propagatedElement = null; |
| 5091 } else { | 5317 } else { |
| 5092 Type2 staticType = getStaticType(target); | 5318 Type2 staticType = getStaticType(target); |
| 5319 // |
| 5320 // If this method invocation is of the form 'C.m' where 'C' is a class, th
en we don't call |
| 5321 // resolveInvokedElement(..) which walks up the class hierarchy, instead w
e just look for the |
| 5322 // member in the type only. |
| 5323 // |
| 5093 ClassElementImpl typeReference = getTypeReference(target); | 5324 ClassElementImpl typeReference = getTypeReference(target); |
| 5094 if (typeReference != null) { | 5325 if (typeReference != null) { |
| 5095 staticElement = propagatedElement = resolveElement(typeReference, method
Name); | 5326 staticElement = propagatedElement = resolveElement(typeReference, method
Name); |
| 5096 } else { | 5327 } else { |
| 5097 staticElement = resolveInvokedElement(target, staticType, methodName); | 5328 staticElement = resolveInvokedElement(target, staticType, methodName); |
| 5098 propagatedElement = resolveInvokedElement(target, getPropagatedType(targ
et), methodName); | 5329 propagatedElement = resolveInvokedElement(target, getPropagatedType(targ
et), methodName); |
| 5099 } | 5330 } |
| 5100 } | 5331 } |
| 5101 staticElement = convertSetterToGetter(staticElement); | 5332 staticElement = convertSetterToGetter(staticElement); |
| 5102 propagatedElement = convertSetterToGetter(propagatedElement); | 5333 propagatedElement = convertSetterToGetter(propagatedElement); |
| 5334 // |
| 5335 // Record the results. |
| 5336 // |
| 5103 methodName.staticElement = staticElement; | 5337 methodName.staticElement = staticElement; |
| 5104 methodName.propagatedElement = propagatedElement; | 5338 methodName.propagatedElement = propagatedElement; |
| 5105 ArgumentList argumentList = node.argumentList; | 5339 ArgumentList argumentList = node.argumentList; |
| 5106 if (staticElement != null) { | 5340 if (staticElement != null) { |
| 5107 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, staticElement); | 5341 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, staticElement); |
| 5108 if (parameters != null) { | 5342 if (parameters != null) { |
| 5109 argumentList.correspondingStaticParameters = parameters; | 5343 argumentList.correspondingStaticParameters = parameters; |
| 5110 } | 5344 } |
| 5111 } | 5345 } |
| 5112 if (propagatedElement != null) { | 5346 if (propagatedElement != null) { |
| 5113 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, propagatedElement); | 5347 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, propagatedElement); |
| 5114 if (parameters != null) { | 5348 if (parameters != null) { |
| 5115 argumentList.correspondingPropagatedParameters = parameters; | 5349 argumentList.correspondingPropagatedParameters = parameters; |
| 5116 } | 5350 } |
| 5117 } | 5351 } |
| 5352 // |
| 5353 // Then check for error conditions. |
| 5354 // |
| 5118 ErrorCode errorCode = checkForInvocationError(target, true, staticElement); | 5355 ErrorCode errorCode = checkForInvocationError(target, true, staticElement); |
| 5119 bool generatedWithTypePropagation = false; | 5356 bool generatedWithTypePropagation = false; |
| 5120 if (_enableHints && errorCode == null && staticElement == null) { | 5357 if (_enableHints && errorCode == null && staticElement == null) { |
| 5121 errorCode = checkForInvocationError(target, false, propagatedElement); | 5358 errorCode = checkForInvocationError(target, false, propagatedElement); |
| 5122 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 5359 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 5123 ClassElement classElementContext = null; | 5360 ClassElement classElementContext = null; |
| 5124 if (target == null) { | 5361 if (target == null) { |
| 5125 classElementContext = _resolver.enclosingClass; | 5362 classElementContext = _resolver.enclosingClass; |
| 5126 } else { | 5363 } else { |
| 5127 Type2 type = target.bestType; | 5364 Type2 type = target.bestType; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5151 } else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) { | 5388 } else if (identical(errorCode, CompileTimeErrorCode.UNDEFINED_FUNCTION)) { |
| 5152 _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName
, [methodName.name]); | 5389 _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_FUNCTION, methodName
, [methodName.name]); |
| 5153 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 5390 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 5154 String targetTypeName; | 5391 String targetTypeName; |
| 5155 if (target == null) { | 5392 if (target == null) { |
| 5156 ClassElement enclosingClass = _resolver.enclosingClass; | 5393 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5157 targetTypeName = enclosingClass.displayName; | 5394 targetTypeName = enclosingClass.displayName; |
| 5158 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; | 5395 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; |
| 5159 _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingCl
ass, proxyErrorCode, methodName, [methodName.name, targetTypeName]); | 5396 _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingCl
ass, proxyErrorCode, methodName, [methodName.name, targetTypeName]); |
| 5160 } else { | 5397 } else { |
| 5398 // ignore Function "call" |
| 5399 // (if we are about to create a hint using type propagation, then we can
use type |
| 5400 // propagation here as well) |
| 5161 Type2 targetType = null; | 5401 Type2 targetType = null; |
| 5162 if (!generatedWithTypePropagation) { | 5402 if (!generatedWithTypePropagation) { |
| 5163 targetType = getStaticType(target); | 5403 targetType = getStaticType(target); |
| 5164 } else { | 5404 } else { |
| 5405 // choose the best type |
| 5165 targetType = getPropagatedType(target); | 5406 targetType = getPropagatedType(target); |
| 5166 if (targetType == null) { | 5407 if (targetType == null) { |
| 5167 targetType = getStaticType(target); | 5408 targetType = getStaticType(target); |
| 5168 } | 5409 } |
| 5169 } | 5410 } |
| 5170 if (targetType != null && targetType.isDartCoreFunction && methodName.na
me == CALL_METHOD_NAME) { | 5411 if (targetType != null && targetType.isDartCoreFunction && methodName.na
me == CALL_METHOD_NAME) { |
| 5412 // TODO(brianwilkerson) Can we ever resolve the function being invoked
? |
| 5413 //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction
); |
| 5171 return null; | 5414 return null; |
| 5172 } | 5415 } |
| 5173 targetTypeName = targetType == null ? null : targetType.displayName; | 5416 targetTypeName = targetType == null ? null : targetType.displayName; |
| 5174 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; | 5417 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; |
| 5175 _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, p
roxyErrorCode, methodName, [methodName.name, targetTypeName]); | 5418 _resolver.reportErrorProxyConditionalAnalysisError(targetType.element, p
roxyErrorCode, methodName, [methodName.name, targetTypeName]); |
| 5176 } | 5419 } |
| 5177 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD
)) { | 5420 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD
)) { |
| 5421 // Generate the type name. |
| 5422 // The error code will never be generated via type propagation |
| 5178 Type2 targetType = getStaticType(target); | 5423 Type2 targetType = getStaticType(target); |
| 5179 String targetTypeName = targetType == null ? null : targetType.name; | 5424 String targetTypeName = targetType == null ? null : targetType.name; |
| 5180 _resolver.reportError7(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, metho
dName, [methodName.name, targetTypeName]); | 5425 _resolver.reportError7(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, metho
dName, [methodName.name, targetTypeName]); |
| 5181 } | 5426 } |
| 5182 return null; | 5427 return null; |
| 5183 } | 5428 } |
| 5184 | 5429 |
| 5185 Object visitPartDirective(PartDirective node) { | 5430 Object visitPartDirective(PartDirective node) { |
| 5186 setMetadata(node.element, node); | 5431 setMetadata(node.element, node); |
| 5187 return null; | 5432 return null; |
| 5188 } | 5433 } |
| 5189 | 5434 |
| 5190 Object visitPartOfDirective(PartOfDirective node) { | 5435 Object visitPartOfDirective(PartOfDirective node) { |
| 5191 setMetadata(node.element, node); | 5436 setMetadata(node.element, node); |
| 5192 return null; | 5437 return null; |
| 5193 } | 5438 } |
| 5194 | 5439 |
| 5195 Object visitPostfixExpression(PostfixExpression node) { | 5440 Object visitPostfixExpression(PostfixExpression node) { |
| 5196 Expression operand = node.operand; | 5441 Expression operand = node.operand; |
| 5197 String methodName = getPostfixOperator(node); | 5442 String methodName = getPostfixOperator(node); |
| 5198 Type2 staticType = getStaticType(operand); | 5443 Type2 staticType = getStaticType(operand); |
| 5199 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName); | 5444 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName); |
| 5200 node.staticElement = staticMethod; | 5445 node.staticElement = staticMethod; |
| 5201 Type2 propagatedType = getPropagatedType(operand); | 5446 Type2 propagatedType = getPropagatedType(operand); |
| 5202 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho
dName); | 5447 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho
dName); |
| 5203 node.propagatedElement = propagatedMethod; | 5448 node.propagatedElement = propagatedMethod; |
| 5204 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticMethod); | 5449 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticMethod); |
| 5205 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod)
: false; | 5450 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod)
: false; |
| 5451 // |
| 5452 // If we are about to generate the hint (propagated version of this warning)
, then check |
| 5453 // that the member is not in a subtype of the propagated type. |
| 5454 // |
| 5206 if (shouldReportMissingMember_propagated) { | 5455 if (shouldReportMissingMember_propagated) { |
| 5207 if (memberFoundInSubclass(propagatedType.element, methodName, true, false)
) { | 5456 if (memberFoundInSubclass(propagatedType.element, methodName, true, false)
) { |
| 5208 shouldReportMissingMember_propagated = false; | 5457 shouldReportMissingMember_propagated = false; |
| 5209 } | 5458 } |
| 5210 } | 5459 } |
| 5211 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { | 5460 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { |
| 5212 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin
gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; | 5461 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin
gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; |
| 5213 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMem
ber_static ? staticType.element : propagatedType.element, errorCode, node.operat
or, [ | 5462 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingMem
ber_static ? staticType.element : propagatedType.element, errorCode, node.operat
or, [ |
| 5214 methodName, | 5463 methodName, |
| 5215 shouldReportMissingMember_static ? staticType.displayName : propagated
Type.displayName]); | 5464 shouldReportMissingMember_static ? staticType.displayName : propagated
Type.displayName]); |
| 5216 } | 5465 } |
| 5217 return null; | 5466 return null; |
| 5218 } | 5467 } |
| 5219 | 5468 |
| 5220 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 5469 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 5221 SimpleIdentifier prefix = node.prefix; | 5470 SimpleIdentifier prefix = node.prefix; |
| 5222 SimpleIdentifier identifier = node.identifier; | 5471 SimpleIdentifier identifier = node.identifier; |
| 5472 // |
| 5473 // First, check to see whether the prefix is really a prefix. |
| 5474 // |
| 5223 Element prefixElement = prefix.staticElement; | 5475 Element prefixElement = prefix.staticElement; |
| 5224 if (prefixElement is PrefixElement) { | 5476 if (prefixElement is PrefixElement) { |
| 5225 Element element = _resolver.nameScope.lookup(node, _definingLibrary); | 5477 Element element = _resolver.nameScope.lookup(node, _definingLibrary); |
| 5226 if (element == null && identifier.inSetterContext()) { | 5478 if (element == null && identifier.inSetterContext()) { |
| 5227 element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdenti
fier("${node.name}="), _definingLibrary); | 5479 element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdenti
fier("${node.name}="), _definingLibrary); |
| 5228 } | 5480 } |
| 5229 if (element == null) { | 5481 if (element == null) { |
| 5230 if (identifier.inSetterContext()) { | 5482 if (identifier.inSetterContext()) { |
| 5231 _resolver.reportError7(StaticWarningCode.UNDEFINED_SETTER, identifier,
[identifier.name, prefixElement.name]); | 5483 _resolver.reportError7(StaticWarningCode.UNDEFINED_SETTER, identifier,
[identifier.name, prefixElement.name]); |
| 5232 } else if (node.parent is Annotation) { | 5484 } else if (node.parent is Annotation) { |
| 5233 Annotation annotation = node.parent as Annotation; | 5485 Annotation annotation = node.parent as Annotation; |
| 5234 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annota
tion, []); | 5486 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annota
tion, []); |
| 5235 return null; | 5487 return null; |
| 5236 } else { | 5488 } else { |
| 5237 _resolver.reportError7(StaticWarningCode.UNDEFINED_GETTER, identifier,
[identifier.name, prefixElement.name]); | 5489 _resolver.reportError7(StaticWarningCode.UNDEFINED_GETTER, identifier,
[identifier.name, prefixElement.name]); |
| 5238 } | 5490 } |
| 5239 return null; | 5491 return null; |
| 5240 } | 5492 } |
| 5241 if (element is PropertyAccessorElement && identifier.inSetterContext()) { | 5493 if (element is PropertyAccessorElement && identifier.inSetterContext()) { |
| 5242 PropertyInducingElement variable = (element as PropertyAccessorElement).
variable; | 5494 PropertyInducingElement variable = (element as PropertyAccessorElement).
variable; |
| 5243 if (variable != null) { | 5495 if (variable != null) { |
| 5244 PropertyAccessorElement setter = variable.setter; | 5496 PropertyAccessorElement setter = variable.setter; |
| 5245 if (setter != null) { | 5497 if (setter != null) { |
| 5246 element = setter; | 5498 element = setter; |
| 5247 } | 5499 } |
| 5248 } | 5500 } |
| 5249 } | 5501 } |
| 5502 // TODO(brianwilkerson) The prefix needs to be resolved to the element for
the import that |
| 5503 // defines the prefix, not the prefix's element. |
| 5250 identifier.staticElement = element; | 5504 identifier.staticElement = element; |
| 5505 // Validate annotation element. |
| 5251 if (node.parent is Annotation) { | 5506 if (node.parent is Annotation) { |
| 5252 Annotation annotation = node.parent as Annotation; | 5507 Annotation annotation = node.parent as Annotation; |
| 5253 resolveAnnotationElement(annotation); | 5508 resolveAnnotationElement(annotation); |
| 5254 return null; | 5509 return null; |
| 5255 } | 5510 } |
| 5256 return null; | 5511 return null; |
| 5257 } | 5512 } |
| 5513 // May be annotation, resolve invocation of "const" constructor. |
| 5258 if (node.parent is Annotation) { | 5514 if (node.parent is Annotation) { |
| 5259 Annotation annotation = node.parent as Annotation; | 5515 Annotation annotation = node.parent as Annotation; |
| 5260 resolveAnnotationElement(annotation); | 5516 resolveAnnotationElement(annotation); |
| 5261 } | 5517 } |
| 5518 // |
| 5519 // Otherwise, the prefix is really an expression that happens to be a simple
identifier and this |
| 5520 // is really equivalent to a property access node. |
| 5521 // |
| 5262 resolvePropertyAccess(prefix, identifier); | 5522 resolvePropertyAccess(prefix, identifier); |
| 5263 return null; | 5523 return null; |
| 5264 } | 5524 } |
| 5265 | 5525 |
| 5266 Object visitPrefixExpression(PrefixExpression node) { | 5526 Object visitPrefixExpression(PrefixExpression node) { |
| 5267 sc.Token operator = node.operator; | 5527 sc.Token operator = node.operator; |
| 5268 sc.TokenType operatorType = operator.type; | 5528 sc.TokenType operatorType = operator.type; |
| 5269 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token
Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { | 5529 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token
Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { |
| 5270 Expression operand = node.operand; | 5530 Expression operand = node.operand; |
| 5271 String methodName = getPrefixOperator(node); | 5531 String methodName = getPrefixOperator(node); |
| 5272 Type2 staticType = getStaticType(operand); | 5532 Type2 staticType = getStaticType(operand); |
| 5273 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName)
; | 5533 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName)
; |
| 5274 node.staticElement = staticMethod; | 5534 node.staticElement = staticMethod; |
| 5275 Type2 propagatedType = getPropagatedType(operand); | 5535 Type2 propagatedType = getPropagatedType(operand); |
| 5276 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met
hodName); | 5536 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met
hodName); |
| 5277 node.propagatedElement = propagatedMethod; | 5537 node.propagatedElement = propagatedMethod; |
| 5278 bool shouldReportMissingMember_static = shouldReportMissingMember(staticTy
pe, staticMethod); | 5538 bool shouldReportMissingMember_static = shouldReportMissingMember(staticTy
pe, staticMethod); |
| 5279 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_sta
tic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod
) : false; | 5539 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_sta
tic && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod
) : false; |
| 5540 // |
| 5541 // If we are about to generate the hint (propagated version of this warnin
g), then check |
| 5542 // that the member is not in a subtype of the propagated type. |
| 5543 // |
| 5280 if (shouldReportMissingMember_propagated) { | 5544 if (shouldReportMissingMember_propagated) { |
| 5281 if (memberFoundInSubclass(propagatedType.element, methodName, true, fals
e)) { | 5545 if (memberFoundInSubclass(propagatedType.element, methodName, true, fals
e)) { |
| 5282 shouldReportMissingMember_propagated = false; | 5546 shouldReportMissingMember_propagated = false; |
| 5283 } | 5547 } |
| 5284 } | 5548 } |
| 5285 if (shouldReportMissingMember_static || shouldReportMissingMember_propagat
ed) { | 5549 if (shouldReportMissingMember_static || shouldReportMissingMember_propagat
ed) { |
| 5286 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarn
ingCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; | 5550 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarn
ingCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; |
| 5287 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingM
ember_static ? staticType.element : propagatedType.element, errorCode, operator,
[ | 5551 _resolver.reportErrorProxyConditionalAnalysisError3(shouldReportMissingM
ember_static ? staticType.element : propagatedType.element, errorCode, operator,
[ |
| 5288 methodName, | 5552 methodName, |
| 5289 shouldReportMissingMember_static ? staticType.displayName : propagat
edType.displayName]); | 5553 shouldReportMissingMember_static ? staticType.displayName : propagat
edType.displayName]); |
| 5290 } | 5554 } |
| 5291 } | 5555 } |
| 5292 return null; | 5556 return null; |
| 5293 } | 5557 } |
| 5294 | 5558 |
| 5295 Object visitPropertyAccess(PropertyAccess node) { | 5559 Object visitPropertyAccess(PropertyAccess node) { |
| 5296 Expression target = node.realTarget; | 5560 Expression target = node.realTarget; |
| 5297 if (target is SuperExpression && !isSuperInValidContext(target)) { | 5561 if (target is SuperExpression && !isSuperInValidContext(target)) { |
| 5298 return null; | 5562 return null; |
| 5299 } | 5563 } |
| 5300 SimpleIdentifier propertyName = node.propertyName; | 5564 SimpleIdentifier propertyName = node.propertyName; |
| 5301 resolvePropertyAccess(target, propertyName); | 5565 resolvePropertyAccess(target, propertyName); |
| 5302 return null; | 5566 return null; |
| 5303 } | 5567 } |
| 5304 | 5568 |
| 5305 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { | 5569 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { |
| 5306 ClassElement enclosingClass = _resolver.enclosingClass; | 5570 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5307 if (enclosingClass == null) { | 5571 if (enclosingClass == null) { |
| 5572 // TODO(brianwilkerson) Report this error. |
| 5308 return null; | 5573 return null; |
| 5309 } | 5574 } |
| 5310 SimpleIdentifier name = node.constructorName; | 5575 SimpleIdentifier name = node.constructorName; |
| 5311 ConstructorElement element; | 5576 ConstructorElement element; |
| 5312 if (name == null) { | 5577 if (name == null) { |
| 5313 element = enclosingClass.unnamedConstructor; | 5578 element = enclosingClass.unnamedConstructor; |
| 5314 } else { | 5579 } else { |
| 5315 element = enclosingClass.getNamedConstructor(name.name); | 5580 element = enclosingClass.getNamedConstructor(name.name); |
| 5316 } | 5581 } |
| 5317 if (element == null) { | 5582 if (element == null) { |
| 5583 // TODO(brianwilkerson) Report this error and decide what element to assoc
iate with the node. |
| 5318 return null; | 5584 return null; |
| 5319 } | 5585 } |
| 5320 if (name != null) { | 5586 if (name != null) { |
| 5321 name.staticElement = element; | 5587 name.staticElement = element; |
| 5322 } | 5588 } |
| 5323 node.staticElement = element; | 5589 node.staticElement = element; |
| 5324 ArgumentList argumentList = node.argumentList; | 5590 ArgumentList argumentList = node.argumentList; |
| 5325 List<ParameterElement> parameters = resolveArgumentsToParameters(false, argu
mentList, element); | 5591 List<ParameterElement> parameters = resolveArgumentsToParameters(false, argu
mentList, element); |
| 5326 if (parameters != null) { | 5592 if (parameters != null) { |
| 5327 argumentList.correspondingStaticParameters = parameters; | 5593 argumentList.correspondingStaticParameters = parameters; |
| 5328 } | 5594 } |
| 5329 return null; | 5595 return null; |
| 5330 } | 5596 } |
| 5331 | 5597 |
| 5332 Object visitSimpleIdentifier(SimpleIdentifier node) { | 5598 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 5599 // |
| 5600 // Synthetic identifiers have been already reported during parsing. |
| 5601 // |
| 5333 if (node.isSynthetic) { | 5602 if (node.isSynthetic) { |
| 5334 return null; | 5603 return null; |
| 5335 } | 5604 } |
| 5605 // |
| 5606 // We ignore identifiers that have already been resolved, such as identifier
s representing the |
| 5607 // name in a declaration. |
| 5608 // |
| 5336 if (node.staticElement != null) { | 5609 if (node.staticElement != null) { |
| 5337 return null; | 5610 return null; |
| 5338 } | 5611 } |
| 5612 // |
| 5613 // The name dynamic denotes a Type object even though dynamic is not a class
. |
| 5614 // |
| 5339 if (node.name == _dynamicType.name) { | 5615 if (node.name == _dynamicType.name) { |
| 5340 node.staticElement = _dynamicType.element; | 5616 node.staticElement = _dynamicType.element; |
| 5341 node.staticType = _typeType; | 5617 node.staticType = _typeType; |
| 5342 return null; | 5618 return null; |
| 5343 } | 5619 } |
| 5620 // |
| 5621 // Otherwise, the node should be resolved. |
| 5622 // |
| 5344 Element element = resolveSimpleIdentifier(node); | 5623 Element element = resolveSimpleIdentifier(node); |
| 5345 ClassElement enclosingClass = _resolver.enclosingClass; | 5624 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5346 if (isFactoryConstructorReturnType(node) && element != enclosingClass) { | 5625 if (isFactoryConstructorReturnType(node) && element != enclosingClass) { |
| 5347 _resolver.reportError7(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLA
SS, node, []); | 5626 _resolver.reportError7(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLA
SS, node, []); |
| 5348 } else if (isConstructorReturnType(node) && element != enclosingClass) { | 5627 } else if (isConstructorReturnType(node) && element != enclosingClass) { |
| 5349 _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node
, []); | 5628 _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node
, []); |
| 5350 element = null; | 5629 element = null; |
| 5351 } else if (element == null || (element is PrefixElement && !isValidAsPrefix(
node))) { | 5630 } else if (element == null || (element is PrefixElement && !isValidAsPrefix(
node))) { |
| 5631 // TODO(brianwilkerson) Recover from this error. |
| 5352 if (isConstructorReturnType(node)) { | 5632 if (isConstructorReturnType(node)) { |
| 5353 _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, no
de, []); | 5633 _resolver.reportError7(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, no
de, []); |
| 5354 } else if (node.parent is Annotation) { | 5634 } else if (node.parent is Annotation) { |
| 5355 Annotation annotation = node.parent as Annotation; | 5635 Annotation annotation = node.parent as Annotation; |
| 5356 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotati
on, []); | 5636 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotati
on, []); |
| 5357 } else { | 5637 } else { |
| 5358 _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingCl
ass, StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); | 5638 _resolver.reportErrorProxyConditionalAnalysisError(_resolver.enclosingCl
ass, StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); |
| 5359 } | 5639 } |
| 5360 } | 5640 } |
| 5361 node.staticElement = element; | 5641 node.staticElement = element; |
| 5362 if (node.inSetterContext() && node.inGetterContext() && enclosingClass != nu
ll) { | 5642 if (node.inSetterContext() && node.inGetterContext() && enclosingClass != nu
ll) { |
| 5363 InterfaceType enclosingType = enclosingClass.type; | 5643 InterfaceType enclosingType = enclosingClass.type; |
| 5364 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(lookUpGetter(n
ull, enclosingType, node.name), null); | 5644 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(lookUpGetter(n
ull, enclosingType, node.name), null); |
| 5365 node.auxiliaryElements = auxiliaryElements; | 5645 node.auxiliaryElements = auxiliaryElements; |
| 5366 } | 5646 } |
| 5647 // |
| 5648 // Validate annotation element. |
| 5649 // |
| 5367 if (node.parent is Annotation) { | 5650 if (node.parent is Annotation) { |
| 5368 Annotation annotation = node.parent as Annotation; | 5651 Annotation annotation = node.parent as Annotation; |
| 5369 resolveAnnotationElement(annotation); | 5652 resolveAnnotationElement(annotation); |
| 5370 } | 5653 } |
| 5371 return null; | 5654 return null; |
| 5372 } | 5655 } |
| 5373 | 5656 |
| 5374 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 5657 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 5375 ClassElement enclosingClass = _resolver.enclosingClass; | 5658 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5376 if (enclosingClass == null) { | 5659 if (enclosingClass == null) { |
| 5660 // TODO(brianwilkerson) Report this error. |
| 5377 return null; | 5661 return null; |
| 5378 } | 5662 } |
| 5379 InterfaceType superType = enclosingClass.supertype; | 5663 InterfaceType superType = enclosingClass.supertype; |
| 5380 if (superType == null) { | 5664 if (superType == null) { |
| 5665 // TODO(brianwilkerson) Report this error. |
| 5381 return null; | 5666 return null; |
| 5382 } | 5667 } |
| 5383 SimpleIdentifier name = node.constructorName; | 5668 SimpleIdentifier name = node.constructorName; |
| 5384 String superName = name != null ? name.name : null; | 5669 String superName = name != null ? name.name : null; |
| 5385 ConstructorElement element = superType.lookUpConstructor(superName, _definin
gLibrary); | 5670 ConstructorElement element = superType.lookUpConstructor(superName, _definin
gLibrary); |
| 5386 if (element == null) { | 5671 if (element == null) { |
| 5387 if (name != null) { | 5672 if (name != null) { |
| 5388 _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INI
TIALIZER, node, [superType.displayName, name]); | 5673 _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INI
TIALIZER, node, [superType.displayName, name]); |
| 5389 } else { | 5674 } else { |
| 5390 _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INI
TIALIZER_DEFAULT, node, [superType.displayName]); | 5675 _resolver.reportError7(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INI
TIALIZER_DEFAULT, node, [superType.displayName]); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5451 /** | 5736 /** |
| 5452 * Given that we have found code to invoke the given element, return the error
code that should be | 5737 * Given that we have found code to invoke the given element, return the error
code that should be |
| 5453 * reported, or `null` if no error should be reported. | 5738 * reported, or `null` if no error should be reported. |
| 5454 * | 5739 * |
| 5455 * @param target the target of the invocation, or `null` if there was no targe
t | 5740 * @param target the target of the invocation, or `null` if there was no targe
t |
| 5456 * @param useStaticContext | 5741 * @param useStaticContext |
| 5457 * @param element the element to be invoked | 5742 * @param element the element to be invoked |
| 5458 * @return the error code that should be reported | 5743 * @return the error code that should be reported |
| 5459 */ | 5744 */ |
| 5460 ErrorCode checkForInvocationError(Expression target, bool useStaticContext, El
ement element) { | 5745 ErrorCode checkForInvocationError(Expression target, bool useStaticContext, El
ement element) { |
| 5746 // Prefix is not declared, instead "prefix.id" are declared. |
| 5461 if (element is PrefixElement) { | 5747 if (element is PrefixElement) { |
| 5462 element = null; | 5748 element = null; |
| 5463 } | 5749 } |
| 5464 if (element is PropertyAccessorElement) { | 5750 if (element is PropertyAccessorElement) { |
| 5751 // |
| 5752 // This is really a function expression invocation. |
| 5753 // |
| 5754 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 5465 FunctionType getterType = element.type; | 5755 FunctionType getterType = element.type; |
| 5466 if (getterType != null) { | 5756 if (getterType != null) { |
| 5467 Type2 returnType = getterType.returnType; | 5757 Type2 returnType = getterType.returnType; |
| 5468 if (!isExecutableType(returnType)) { | 5758 if (!isExecutableType(returnType)) { |
| 5469 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 5759 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 5470 } | 5760 } |
| 5471 } | 5761 } |
| 5472 } else if (element is ExecutableElement) { | 5762 } else if (element is ExecutableElement) { |
| 5473 return null; | 5763 return null; |
| 5474 } else if (element == null && target is SuperExpression) { | 5764 } else if (element == null && target is SuperExpression) { |
| 5765 // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes,
this one, and |
| 5766 // a code that describes the situation where the method was found, but it
was not |
| 5767 // accessible from the current library. |
| 5475 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; | 5768 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; |
| 5476 } else { | 5769 } else { |
| 5770 // |
| 5771 // This is really a function expression invocation. |
| 5772 // |
| 5773 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 5477 if (element is PropertyInducingElement) { | 5774 if (element is PropertyInducingElement) { |
| 5478 PropertyAccessorElement getter = element.getter; | 5775 PropertyAccessorElement getter = element.getter; |
| 5479 FunctionType getterType = getter.type; | 5776 FunctionType getterType = getter.type; |
| 5480 if (getterType != null) { | 5777 if (getterType != null) { |
| 5481 Type2 returnType = getterType.returnType; | 5778 Type2 returnType = getterType.returnType; |
| 5482 if (!isExecutableType(returnType)) { | 5779 if (!isExecutableType(returnType)) { |
| 5483 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 5780 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 5484 } | 5781 } |
| 5485 } | 5782 } |
| 5486 } else if (element is VariableElement) { | 5783 } else if (element is VariableElement) { |
| 5487 Type2 variableType = element.type; | 5784 Type2 variableType = element.type; |
| 5488 if (!isExecutableType(variableType)) { | 5785 if (!isExecutableType(variableType)) { |
| 5489 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 5786 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 5490 } | 5787 } |
| 5491 } else { | 5788 } else { |
| 5492 if (target == null) { | 5789 if (target == null) { |
| 5493 ClassElement enclosingClass = _resolver.enclosingClass; | 5790 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5494 if (enclosingClass == null) { | 5791 if (enclosingClass == null) { |
| 5495 return CompileTimeErrorCode.UNDEFINED_FUNCTION; | 5792 return CompileTimeErrorCode.UNDEFINED_FUNCTION; |
| 5496 } else if (element == null) { | 5793 } else if (element == null) { |
| 5794 // Proxy-conditional warning, based on state of resolver.getEnclosin
gClass() |
| 5497 return StaticTypeWarningCode.UNDEFINED_METHOD; | 5795 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 5498 } else { | 5796 } else { |
| 5499 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 5797 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 5500 } | 5798 } |
| 5501 } else { | 5799 } else { |
| 5502 Type2 targetType; | 5800 Type2 targetType; |
| 5503 if (useStaticContext) { | 5801 if (useStaticContext) { |
| 5504 targetType = getStaticType(target); | 5802 targetType = getStaticType(target); |
| 5505 } else { | 5803 } else { |
| 5804 // Compute and use the propagated type, if it is null, then it may b
e the case that |
| 5805 // static type is some type, in which the static type should be used
. |
| 5506 targetType = target.bestType; | 5806 targetType = target.bestType; |
| 5507 } | 5807 } |
| 5508 if (targetType == null) { | 5808 if (targetType == null) { |
| 5509 return CompileTimeErrorCode.UNDEFINED_FUNCTION; | 5809 return CompileTimeErrorCode.UNDEFINED_FUNCTION; |
| 5510 } else if (!targetType.isDynamic && !targetType.isBottom) { | 5810 } else if (!targetType.isDynamic && !targetType.isBottom) { |
| 5811 // Proxy-conditional warning, based on state of targetType.getElemen
t() |
| 5511 return StaticTypeWarningCode.UNDEFINED_METHOD; | 5812 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 5512 } | 5813 } |
| 5513 } | 5814 } |
| 5514 } | 5815 } |
| 5515 } | 5816 } |
| 5516 return null; | 5817 return null; |
| 5517 } | 5818 } |
| 5518 | 5819 |
| 5519 /** | 5820 /** |
| 5520 * Check that the for some index expression that the method element was resolv
ed, otherwise a | 5821 * Check that the for some index expression that the method element was resolv
ed, otherwise a |
| 5521 * [StaticWarningCode#UNDEFINED_OPERATOR] is generated. | 5822 * [StaticWarningCode#UNDEFINED_OPERATOR] is generated. |
| 5522 * | 5823 * |
| 5523 * @param node the index expression to resolve | 5824 * @param node the index expression to resolve |
| 5524 * @param target the target of the expression | 5825 * @param target the target of the expression |
| 5525 * @param methodName the name of the operator associated with the context of u
sing of the given | 5826 * @param methodName the name of the operator associated with the context of u
sing of the given |
| 5526 * index expression | 5827 * index expression |
| 5527 * @return `true` if and only if an error code is generated on the passed node | 5828 * @return `true` if and only if an error code is generated on the passed node |
| 5528 */ | 5829 */ |
| 5529 bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, S
tring methodName, MethodElement staticMethod, MethodElement propagatedMethod, Ty
pe2 staticType, Type2 propagatedType) { | 5830 bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, S
tring methodName, MethodElement staticMethod, MethodElement propagatedMethod, Ty
pe2 staticType, Type2 propagatedType) { |
| 5530 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticMethod); | 5831 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticMethod); |
| 5531 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod)
: false; | 5832 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedMethod)
: false; |
| 5833 // |
| 5834 // If we are about to generate the hint (propagated version of this warning)
, then check |
| 5835 // that the member is not in a subtype of the propagated type. |
| 5836 // |
| 5532 if (shouldReportMissingMember_propagated) { | 5837 if (shouldReportMissingMember_propagated) { |
| 5533 if (memberFoundInSubclass(propagatedType.element, methodName, true, false)
) { | 5838 if (memberFoundInSubclass(propagatedType.element, methodName, true, false)
) { |
| 5534 shouldReportMissingMember_propagated = false; | 5839 shouldReportMissingMember_propagated = false; |
| 5535 } | 5840 } |
| 5536 } | 5841 } |
| 5537 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { | 5842 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { |
| 5538 sc.Token leftBracket = node.leftBracket; | 5843 sc.Token leftBracket = node.leftBracket; |
| 5539 sc.Token rightBracket = node.rightBracket; | 5844 sc.Token rightBracket = node.rightBracket; |
| 5540 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin
gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; | 5845 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin
gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; |
| 5541 if (leftBracket == null || rightBracket == null) { | 5846 if (leftBracket == null || rightBracket == null) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5558 * Given a list of arguments and the element that will be invoked using those
argument, compute | 5863 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 5559 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 5864 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 5560 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 5865 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 5561 * | 5866 * |
| 5562 * @param argumentList the list of arguments being passed to the element | 5867 * @param argumentList the list of arguments being passed to the element |
| 5563 * @param executableElement the element that will be invoked with the argument
s | 5868 * @param executableElement the element that will be invoked with the argument
s |
| 5564 * @return the parameters that correspond to the arguments | 5869 * @return the parameters that correspond to the arguments |
| 5565 */ | 5870 */ |
| 5566 List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentLis
t, Element element) { | 5871 List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentLis
t, Element element) { |
| 5567 if (element is PropertyAccessorElement) { | 5872 if (element is PropertyAccessorElement) { |
| 5873 // |
| 5874 // This is an invocation of the call method defined on the value returned
by the getter. |
| 5875 // |
| 5568 FunctionType getterType = element.type; | 5876 FunctionType getterType = element.type; |
| 5569 if (getterType != null) { | 5877 if (getterType != null) { |
| 5570 Type2 getterReturnType = getterType.returnType; | 5878 Type2 getterReturnType = getterType.returnType; |
| 5571 if (getterReturnType is InterfaceType) { | 5879 if (getterReturnType is InterfaceType) { |
| 5572 MethodElement callMethod = getterReturnType.lookUpMethod(CALL_METHOD_N
AME, _definingLibrary); | 5880 MethodElement callMethod = getterReturnType.lookUpMethod(CALL_METHOD_N
AME, _definingLibrary); |
| 5573 if (callMethod != null) { | 5881 if (callMethod != null) { |
| 5574 return resolveArgumentsToParameters(false, argumentList, callMethod)
; | 5882 return resolveArgumentsToParameters(false, argumentList, callMethod)
; |
| 5575 } | 5883 } |
| 5576 } else if (getterReturnType is FunctionType) { | 5884 } else if (getterReturnType is FunctionType) { |
| 5577 Element functionElement = getterReturnType.element; | 5885 Element functionElement = getterReturnType.element; |
| 5578 if (functionElement is ExecutableElement) { | 5886 if (functionElement is ExecutableElement) { |
| 5579 return resolveArgumentsToParameters(false, argumentList, functionEle
ment); | 5887 return resolveArgumentsToParameters(false, argumentList, functionEle
ment); |
| 5580 } | 5888 } |
| 5581 } | 5889 } |
| 5582 } | 5890 } |
| 5583 } else if (element is ExecutableElement) { | 5891 } else if (element is ExecutableElement) { |
| 5584 return resolveArgumentsToParameters(false, argumentList, element); | 5892 return resolveArgumentsToParameters(false, argumentList, element); |
| 5585 } else if (element is VariableElement) { | 5893 } else if (element is VariableElement) { |
| 5586 VariableElement variable = element; | 5894 VariableElement variable = element; |
| 5587 Type2 type = _promoteManager.getStaticType(variable); | 5895 Type2 type = _promoteManager.getStaticType(variable); |
| 5588 if (type is FunctionType) { | 5896 if (type is FunctionType) { |
| 5589 FunctionType functionType = type; | 5897 FunctionType functionType = type; |
| 5590 List<ParameterElement> parameters = functionType.parameters; | 5898 List<ParameterElement> parameters = functionType.parameters; |
| 5591 return resolveArgumentsToParameters2(false, argumentList, parameters); | 5899 return resolveArgumentsToParameters2(false, argumentList, parameters); |
| 5592 } else if (type is InterfaceType) { | 5900 } else if (type is InterfaceType) { |
| 5901 // "call" invocation |
| 5593 MethodElement callMethod = type.lookUpMethod(CALL_METHOD_NAME, _defining
Library); | 5902 MethodElement callMethod = type.lookUpMethod(CALL_METHOD_NAME, _defining
Library); |
| 5594 if (callMethod != null) { | 5903 if (callMethod != null) { |
| 5595 List<ParameterElement> parameters = callMethod.parameters; | 5904 List<ParameterElement> parameters = callMethod.parameters; |
| 5596 return resolveArgumentsToParameters2(false, argumentList, parameters); | 5905 return resolveArgumentsToParameters2(false, argumentList, parameters); |
| 5597 } | 5906 } |
| 5598 } | 5907 } |
| 5599 } | 5908 } |
| 5600 return null; | 5909 return null; |
| 5601 } | 5910 } |
| 5602 | 5911 |
| 5603 /** | 5912 /** |
| 5604 * If the given element is a setter, return the getter associated with it. Oth
erwise, return the | 5913 * If the given element is a setter, return the getter associated with it. Oth
erwise, return the |
| 5605 * element unchanged. | 5914 * element unchanged. |
| 5606 * | 5915 * |
| 5607 * @param element the element to be normalized | 5916 * @param element the element to be normalized |
| 5608 * @return a non-setter element derived from the given element | 5917 * @return a non-setter element derived from the given element |
| 5609 */ | 5918 */ |
| 5610 Element convertSetterToGetter(Element element) { | 5919 Element convertSetterToGetter(Element element) { |
| 5920 // TODO(brianwilkerson) Determine whether and why the element could ever be
a setter. |
| 5611 if (element is PropertyAccessorElement) { | 5921 if (element is PropertyAccessorElement) { |
| 5612 return element.variable.getter; | 5922 return element.variable.getter; |
| 5613 } | 5923 } |
| 5614 return element; | 5924 return element; |
| 5615 } | 5925 } |
| 5616 | 5926 |
| 5617 /** | 5927 /** |
| 5618 * Look for any declarations of the given identifier that are imported using a
prefix. Return the | 5928 * Look for any declarations of the given identifier that are imported using a
prefix. Return the |
| 5619 * element that was found, or `null` if the name is not imported using a prefi
x. | 5929 * element that was found, or `null` if the name is not imported using a prefi
x. |
| 5620 * | 5930 * |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5671 | 5981 |
| 5672 /** | 5982 /** |
| 5673 * Return the propagated type of the given expression that is to be used for t
ype analysis. | 5983 * Return the propagated type of the given expression that is to be used for t
ype analysis. |
| 5674 * | 5984 * |
| 5675 * @param expression the expression whose type is to be returned | 5985 * @param expression the expression whose type is to be returned |
| 5676 * @return the type of the given expression | 5986 * @return the type of the given expression |
| 5677 */ | 5987 */ |
| 5678 Type2 getPropagatedType(Expression expression) { | 5988 Type2 getPropagatedType(Expression expression) { |
| 5679 Type2 propagatedType = resolveTypeParameter(expression.propagatedType); | 5989 Type2 propagatedType = resolveTypeParameter(expression.propagatedType); |
| 5680 if (propagatedType is FunctionType) { | 5990 if (propagatedType is FunctionType) { |
| 5991 // |
| 5992 // All function types are subtypes of 'Function', which is itself a subcla
ss of 'Object'. |
| 5993 // |
| 5681 propagatedType = _resolver.typeProvider.functionType; | 5994 propagatedType = _resolver.typeProvider.functionType; |
| 5682 } | 5995 } |
| 5683 return propagatedType; | 5996 return propagatedType; |
| 5684 } | 5997 } |
| 5685 | 5998 |
| 5686 /** | 5999 /** |
| 5687 * Return the static type of the given expression that is to be used for type
analysis. | 6000 * Return the static type of the given expression that is to be used for type
analysis. |
| 5688 * | 6001 * |
| 5689 * @param expression the expression whose type is to be returned | 6002 * @param expression the expression whose type is to be returned |
| 5690 * @return the type of the given expression | 6003 * @return the type of the given expression |
| 5691 */ | 6004 */ |
| 5692 Type2 getStaticType(Expression expression) { | 6005 Type2 getStaticType(Expression expression) { |
| 5693 if (expression is NullLiteral) { | 6006 if (expression is NullLiteral) { |
| 5694 return _resolver.typeProvider.bottomType; | 6007 return _resolver.typeProvider.bottomType; |
| 5695 } | 6008 } |
| 5696 Type2 staticType = resolveTypeParameter(expression.staticType); | 6009 Type2 staticType = resolveTypeParameter(expression.staticType); |
| 5697 if (staticType is FunctionType) { | 6010 if (staticType is FunctionType) { |
| 6011 // |
| 6012 // All function types are subtypes of 'Function', which is itself a subcla
ss of 'Object'. |
| 6013 // |
| 5698 staticType = _resolver.typeProvider.functionType; | 6014 staticType = _resolver.typeProvider.functionType; |
| 5699 } | 6015 } |
| 5700 return staticType; | 6016 return staticType; |
| 5701 } | 6017 } |
| 5702 | 6018 |
| 5703 /** | 6019 /** |
| 5704 * Return `true` if the given type represents an object that could be invoked
using the call | 6020 * Return `true` if the given type represents an object that could be invoked
using the call |
| 5705 * operator '()'. | 6021 * operator '()'. |
| 5706 * | 6022 * |
| 5707 * @param type the type being tested | 6023 * @param type the type being tested |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5799 * `null` if there is no getter with the given name. | 6115 * `null` if there is no getter with the given name. |
| 5800 * | 6116 * |
| 5801 * @param targetType the type in which the getter might be defined | 6117 * @param targetType the type in which the getter might be defined |
| 5802 * @param includeTargetType `true` if the search should include the target typ
e | 6118 * @param includeTargetType `true` if the search should include the target typ
e |
| 5803 * @param getterName the name of the getter being looked up | 6119 * @param getterName the name of the getter being looked up |
| 5804 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6120 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 5805 * to prevent infinite recursion and to optimize the search | 6121 * to prevent infinite recursion and to optimize the search |
| 5806 * @return the element representing the getter that was found | 6122 * @return the element representing the getter that was found |
| 5807 */ | 6123 */ |
| 5808 PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, boo
l includeTargetType, String getterName, Set<ClassElement> visitedInterfaces) { | 6124 PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, boo
l includeTargetType, String getterName, Set<ClassElement> visitedInterfaces) { |
| 6125 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6126 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6127 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6128 // 80% case. |
| 5809 ClassElement targetClass = targetType.element; | 6129 ClassElement targetClass = targetType.element; |
| 5810 if (visitedInterfaces.contains(targetClass)) { | 6130 if (visitedInterfaces.contains(targetClass)) { |
| 5811 return null; | 6131 return null; |
| 5812 } | 6132 } |
| 5813 visitedInterfaces.add(targetClass); | 6133 visitedInterfaces.add(targetClass); |
| 5814 if (includeTargetType) { | 6134 if (includeTargetType) { |
| 5815 PropertyAccessorElement getter = targetType.getGetter(getterName); | 6135 PropertyAccessorElement getter = targetType.getGetter(getterName); |
| 5816 if (getter != null && getter.isAccessibleIn(_definingLibrary)) { | 6136 if (getter != null && getter.isAccessibleIn(_definingLibrary)) { |
| 5817 return getter; | 6137 return getter; |
| 5818 } | 6138 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5868 * was found, or `null` if there is no method or getter with the given name. | 6188 * was found, or `null` if there is no method or getter with the given name. |
| 5869 * | 6189 * |
| 5870 * @param targetType the type in which the method or getter might be defined | 6190 * @param targetType the type in which the method or getter might be defined |
| 5871 * @param includeTargetType `true` if the search should include the target typ
e | 6191 * @param includeTargetType `true` if the search should include the target typ
e |
| 5872 * @param memberName the name of the method or getter being looked up | 6192 * @param memberName the name of the method or getter being looked up |
| 5873 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6193 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 5874 * to prevent infinite recursion and to optimize the search | 6194 * to prevent infinite recursion and to optimize the search |
| 5875 * @return the element representing the method or getter that was found | 6195 * @return the element representing the method or getter that was found |
| 5876 */ | 6196 */ |
| 5877 ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, b
ool includeTargetType, String memberName, Set<ClassElement> visitedInterfaces) { | 6197 ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, b
ool includeTargetType, String memberName, Set<ClassElement> visitedInterfaces) { |
| 6198 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6199 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6200 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6201 // 80% case. |
| 5878 ClassElement targetClass = targetType.element; | 6202 ClassElement targetClass = targetType.element; |
| 5879 if (visitedInterfaces.contains(targetClass)) { | 6203 if (visitedInterfaces.contains(targetClass)) { |
| 5880 return null; | 6204 return null; |
| 5881 } | 6205 } |
| 5882 visitedInterfaces.add(targetClass); | 6206 visitedInterfaces.add(targetClass); |
| 5883 if (includeTargetType) { | 6207 if (includeTargetType) { |
| 5884 ExecutableElement member = targetType.getMethod(memberName); | 6208 ExecutableElement member = targetType.getMethod(memberName); |
| 5885 if (member != null) { | 6209 if (member != null) { |
| 5886 return member; | 6210 return member; |
| 5887 } | 6211 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5918 */ | 6242 */ |
| 5919 LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) { | 6243 LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) { |
| 5920 LabelScope labelScope = _resolver.labelScope; | 6244 LabelScope labelScope = _resolver.labelScope; |
| 5921 LabelElementImpl labelElement = null; | 6245 LabelElementImpl labelElement = null; |
| 5922 if (labelNode == null) { | 6246 if (labelNode == null) { |
| 5923 if (labelScope == null) { | 6247 if (labelScope == null) { |
| 5924 } else { | 6248 } else { |
| 5925 labelElement = labelScope.lookup2(LabelScope.EMPTY_LABEL) as LabelElemen
tImpl; | 6249 labelElement = labelScope.lookup2(LabelScope.EMPTY_LABEL) as LabelElemen
tImpl; |
| 5926 if (labelElement == null) { | 6250 if (labelElement == null) { |
| 5927 } | 6251 } |
| 6252 // |
| 6253 // The label element that was returned was a marker for look-up and isn'
t stored in the |
| 6254 // element model. |
| 6255 // |
| 5928 labelElement = null; | 6256 labelElement = null; |
| 5929 } | 6257 } |
| 5930 } else { | 6258 } else { |
| 5931 if (labelScope == null) { | 6259 if (labelScope == null) { |
| 5932 _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode,
[labelNode.name]); | 6260 _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode,
[labelNode.name]); |
| 5933 } else { | 6261 } else { |
| 5934 labelElement = labelScope.lookup(labelNode) as LabelElementImpl; | 6262 labelElement = labelScope.lookup(labelNode) as LabelElementImpl; |
| 5935 if (labelElement == null) { | 6263 if (labelElement == null) { |
| 5936 _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode
, [labelNode.name]); | 6264 _resolver.reportError7(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode
, [labelNode.name]); |
| 5937 } else { | 6265 } else { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5982 * `null` if there is no method with the given name. | 6310 * `null` if there is no method with the given name. |
| 5983 * | 6311 * |
| 5984 * @param targetType the type in which the member might be defined | 6312 * @param targetType the type in which the member might be defined |
| 5985 * @param includeTargetType `true` if the search should include the target typ
e | 6313 * @param includeTargetType `true` if the search should include the target typ
e |
| 5986 * @param methodName the name of the method being looked up | 6314 * @param methodName the name of the method being looked up |
| 5987 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6315 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 5988 * to prevent infinite recursion and to optimize the search | 6316 * to prevent infinite recursion and to optimize the search |
| 5989 * @return the element representing the method that was found | 6317 * @return the element representing the method that was found |
| 5990 */ | 6318 */ |
| 5991 MethodElement lookUpMethodInInterfaces(InterfaceType targetType, bool includeT
argetType, String methodName, Set<ClassElement> visitedInterfaces) { | 6319 MethodElement lookUpMethodInInterfaces(InterfaceType targetType, bool includeT
argetType, String methodName, Set<ClassElement> visitedInterfaces) { |
| 6320 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6321 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6322 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6323 // 80% case. |
| 5992 ClassElement targetClass = targetType.element; | 6324 ClassElement targetClass = targetType.element; |
| 5993 if (visitedInterfaces.contains(targetClass)) { | 6325 if (visitedInterfaces.contains(targetClass)) { |
| 5994 return null; | 6326 return null; |
| 5995 } | 6327 } |
| 5996 visitedInterfaces.add(targetClass); | 6328 visitedInterfaces.add(targetClass); |
| 5997 if (includeTargetType) { | 6329 if (includeTargetType) { |
| 5998 MethodElement method = targetType.getMethod(methodName); | 6330 MethodElement method = targetType.getMethod(methodName); |
| 5999 if (method != null && method.isAccessibleIn(_definingLibrary)) { | 6331 if (method != null && method.isAccessibleIn(_definingLibrary)) { |
| 6000 return method; | 6332 return method; |
| 6001 } | 6333 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6052 * `null` if there is no setter with the given name. | 6384 * `null` if there is no setter with the given name. |
| 6053 * | 6385 * |
| 6054 * @param targetType the type in which the setter might be defined | 6386 * @param targetType the type in which the setter might be defined |
| 6055 * @param includeTargetType `true` if the search should include the target typ
e | 6387 * @param includeTargetType `true` if the search should include the target typ
e |
| 6056 * @param setterName the name of the setter being looked up | 6388 * @param setterName the name of the setter being looked up |
| 6057 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6389 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 6058 * to prevent infinite recursion and to optimize the search | 6390 * to prevent infinite recursion and to optimize the search |
| 6059 * @return the element representing the setter that was found | 6391 * @return the element representing the setter that was found |
| 6060 */ | 6392 */ |
| 6061 PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, boo
l includeTargetType, String setterName, Set<ClassElement> visitedInterfaces) { | 6393 PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, boo
l includeTargetType, String setterName, Set<ClassElement> visitedInterfaces) { |
| 6394 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6395 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6396 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6397 // 80% case. |
| 6062 ClassElement targetClass = targetType.element; | 6398 ClassElement targetClass = targetType.element; |
| 6063 if (visitedInterfaces.contains(targetClass)) { | 6399 if (visitedInterfaces.contains(targetClass)) { |
| 6064 return null; | 6400 return null; |
| 6065 } | 6401 } |
| 6066 visitedInterfaces.add(targetClass); | 6402 visitedInterfaces.add(targetClass); |
| 6067 if (includeTargetType) { | 6403 if (includeTargetType) { |
| 6068 PropertyAccessorElement setter = targetType.getSetter(setterName); | 6404 PropertyAccessorElement setter = targetType.getSetter(setterName); |
| 6069 if (setter != null && setter.isAccessibleIn(_definingLibrary)) { | 6405 if (setter != null && setter.isAccessibleIn(_definingLibrary)) { |
| 6070 return setter; | 6406 return setter; |
| 6071 } | 6407 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6143 return sc.TokenType.PLUS; | 6479 return sc.TokenType.PLUS; |
| 6144 } else if (operator == sc.TokenType.SLASH_EQ) { | 6480 } else if (operator == sc.TokenType.SLASH_EQ) { |
| 6145 return sc.TokenType.SLASH; | 6481 return sc.TokenType.SLASH; |
| 6146 } else if (operator == sc.TokenType.STAR_EQ) { | 6482 } else if (operator == sc.TokenType.STAR_EQ) { |
| 6147 return sc.TokenType.STAR; | 6483 return sc.TokenType.STAR; |
| 6148 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) { | 6484 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) { |
| 6149 return sc.TokenType.TILDE_SLASH; | 6485 return sc.TokenType.TILDE_SLASH; |
| 6150 } | 6486 } |
| 6151 break; | 6487 break; |
| 6152 } | 6488 } |
| 6489 // Internal error: Unmapped assignment operator. |
| 6153 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to
it's corresponding operator"); | 6490 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to
it's corresponding operator"); |
| 6154 return operator; | 6491 return operator; |
| 6155 } | 6492 } |
| 6156 | 6493 |
| 6157 void resolveAnnotationConstructorInvocationArguments(Annotation annotation, Co
nstructorElement constructor) { | 6494 void resolveAnnotationConstructorInvocationArguments(Annotation annotation, Co
nstructorElement constructor) { |
| 6158 ArgumentList argumentList = annotation.arguments; | 6495 ArgumentList argumentList = annotation.arguments; |
| 6496 // error will be reported in ConstantVerifier |
| 6159 if (argumentList == null) { | 6497 if (argumentList == null) { |
| 6160 return; | 6498 return; |
| 6161 } | 6499 } |
| 6500 // resolve arguments to parameters |
| 6162 List<ParameterElement> parameters = resolveArgumentsToParameters(true, argum
entList, constructor); | 6501 List<ParameterElement> parameters = resolveArgumentsToParameters(true, argum
entList, constructor); |
| 6163 if (parameters != null) { | 6502 if (parameters != null) { |
| 6164 argumentList.correspondingStaticParameters = parameters; | 6503 argumentList.correspondingStaticParameters = parameters; |
| 6165 } | 6504 } |
| 6166 } | 6505 } |
| 6167 | 6506 |
| 6168 /** | 6507 /** |
| 6169 * Continues resolution of the given [Annotation]. | 6508 * Continues resolution of the given [Annotation]. |
| 6170 * | 6509 * |
| 6171 * @param annotation the [Annotation] to resolve | 6510 * @param annotation the [Annotation] to resolve |
| 6172 */ | 6511 */ |
| 6173 void resolveAnnotationElement(Annotation annotation) { | 6512 void resolveAnnotationElement(Annotation annotation) { |
| 6174 SimpleIdentifier nameNode1; | 6513 SimpleIdentifier nameNode1; |
| 6175 SimpleIdentifier nameNode2; | 6514 SimpleIdentifier nameNode2; |
| 6176 { | 6515 { |
| 6177 Identifier annName = annotation.name; | 6516 Identifier annName = annotation.name; |
| 6178 if (annName is PrefixedIdentifier) { | 6517 if (annName is PrefixedIdentifier) { |
| 6179 PrefixedIdentifier prefixed = annName; | 6518 PrefixedIdentifier prefixed = annName; |
| 6180 nameNode1 = prefixed.prefix; | 6519 nameNode1 = prefixed.prefix; |
| 6181 nameNode2 = prefixed.identifier; | 6520 nameNode2 = prefixed.identifier; |
| 6182 } else { | 6521 } else { |
| 6183 nameNode1 = annName as SimpleIdentifier; | 6522 nameNode1 = annName as SimpleIdentifier; |
| 6184 nameNode2 = null; | 6523 nameNode2 = null; |
| 6185 } | 6524 } |
| 6186 } | 6525 } |
| 6187 SimpleIdentifier nameNode3 = annotation.constructorName; | 6526 SimpleIdentifier nameNode3 = annotation.constructorName; |
| 6188 ConstructorElement constructor = null; | 6527 ConstructorElement constructor = null; |
| 6528 // |
| 6529 // CONST or Class(args) |
| 6530 // |
| 6189 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { | 6531 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { |
| 6190 Element element1 = nameNode1.staticElement; | 6532 Element element1 = nameNode1.staticElement; |
| 6533 // CONST |
| 6191 if (element1 is PropertyAccessorElement) { | 6534 if (element1 is PropertyAccessorElement) { |
| 6192 resolveAnnotationElementGetter(annotation, element1); | 6535 resolveAnnotationElementGetter(annotation, element1); |
| 6193 return; | 6536 return; |
| 6194 } | 6537 } |
| 6538 // Class(args) |
| 6195 if (element1 is ClassElement) { | 6539 if (element1 is ClassElement) { |
| 6196 ClassElement classElement = element1; | 6540 ClassElement classElement = element1; |
| 6197 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(null, _definingLibrary); | 6541 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(null, _definingLibrary); |
| 6198 } | 6542 } |
| 6199 } | 6543 } |
| 6544 // |
| 6545 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) |
| 6546 // |
| 6200 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { | 6547 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { |
| 6201 Element element1 = nameNode1.staticElement; | 6548 Element element1 = nameNode1.staticElement; |
| 6202 Element element2 = nameNode2.staticElement; | 6549 Element element2 = nameNode2.staticElement; |
| 6550 // Class.CONST - not resolved yet |
| 6203 if (element1 is ClassElement) { | 6551 if (element1 is ClassElement) { |
| 6204 ClassElement classElement = element1; | 6552 ClassElement classElement = element1; |
| 6205 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); | 6553 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); |
| 6206 } | 6554 } |
| 6555 // prefix.CONST or Class.CONST |
| 6207 if (element2 is PropertyAccessorElement) { | 6556 if (element2 is PropertyAccessorElement) { |
| 6208 nameNode2.staticElement = element2; | 6557 nameNode2.staticElement = element2; |
| 6209 annotation.element = element2; | 6558 annotation.element = element2; |
| 6210 resolveAnnotationElementGetter(annotation, element2 as PropertyAccessorE
lement); | 6559 resolveAnnotationElementGetter(annotation, element2 as PropertyAccessorE
lement); |
| 6211 return; | 6560 return; |
| 6212 } | 6561 } |
| 6562 // prefix.Class() |
| 6213 if (element2 is ClassElement) { | 6563 if (element2 is ClassElement) { |
| 6214 ClassElement classElement = element2 as ClassElement; | 6564 ClassElement classElement = element2 as ClassElement; |
| 6215 constructor = classElement.unnamedConstructor; | 6565 constructor = classElement.unnamedConstructor; |
| 6216 } | 6566 } |
| 6567 // Class.constructor(args) |
| 6217 if (element1 is ClassElement) { | 6568 if (element1 is ClassElement) { |
| 6218 ClassElement classElement = element1; | 6569 ClassElement classElement = element1; |
| 6219 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(nameNode2.name, _definingLibrary); | 6570 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(nameNode2.name, _definingLibrary); |
| 6220 nameNode2.staticElement = constructor; | 6571 nameNode2.staticElement = constructor; |
| 6221 } | 6572 } |
| 6222 } | 6573 } |
| 6574 // |
| 6575 // prefix.Class.CONST or prefix.Class.constructor(args) |
| 6576 // |
| 6223 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { | 6577 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { |
| 6224 Element element2 = nameNode2.staticElement; | 6578 Element element2 = nameNode2.staticElement; |
| 6579 // element2 should be ClassElement |
| 6225 if (element2 is ClassElement) { | 6580 if (element2 is ClassElement) { |
| 6226 ClassElement classElement = element2; | 6581 ClassElement classElement = element2; |
| 6227 String name3 = nameNode3.name; | 6582 String name3 = nameNode3.name; |
| 6583 // prefix.Class.CONST |
| 6228 PropertyAccessorElement getter = classElement.lookUpGetter(name3, _defin
ingLibrary); | 6584 PropertyAccessorElement getter = classElement.lookUpGetter(name3, _defin
ingLibrary); |
| 6229 if (getter != null) { | 6585 if (getter != null) { |
| 6230 nameNode3.staticElement = getter; | 6586 nameNode3.staticElement = getter; |
| 6231 annotation.element = element2; | 6587 annotation.element = element2; |
| 6232 resolveAnnotationElementGetter(annotation, getter); | 6588 resolveAnnotationElementGetter(annotation, getter); |
| 6233 return; | 6589 return; |
| 6234 } | 6590 } |
| 6591 // prefix.Class.constructor(args) |
| 6235 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(name3, _definingLibrary); | 6592 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(name3, _definingLibrary); |
| 6236 nameNode3.staticElement = constructor; | 6593 nameNode3.staticElement = constructor; |
| 6237 } | 6594 } |
| 6238 } | 6595 } |
| 6596 // we need constructor |
| 6239 if (constructor == null) { | 6597 if (constructor == null) { |
| 6240 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation
, []); | 6598 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation
, []); |
| 6241 return; | 6599 return; |
| 6242 } | 6600 } |
| 6601 // record element |
| 6243 annotation.element = constructor; | 6602 annotation.element = constructor; |
| 6603 // resolve arguments |
| 6244 resolveAnnotationConstructorInvocationArguments(annotation, constructor); | 6604 resolveAnnotationConstructorInvocationArguments(annotation, constructor); |
| 6245 } | 6605 } |
| 6246 | 6606 |
| 6247 void resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorEle
ment accessorElement) { | 6607 void resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorEle
ment accessorElement) { |
| 6608 // accessor should be synthetic |
| 6248 if (!accessorElement.isSynthetic) { | 6609 if (!accessorElement.isSynthetic) { |
| 6249 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation
, []); | 6610 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation
, []); |
| 6250 return; | 6611 return; |
| 6251 } | 6612 } |
| 6613 // variable should be constant |
| 6252 VariableElement variableElement = accessorElement.variable; | 6614 VariableElement variableElement = accessorElement.variable; |
| 6253 if (!variableElement.isConst) { | 6615 if (!variableElement.isConst) { |
| 6254 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation
, []); | 6616 _resolver.reportError7(CompileTimeErrorCode.INVALID_ANNOTATION, annotation
, []); |
| 6255 } | 6617 } |
| 6618 // OK |
| 6256 return; | 6619 return; |
| 6257 } | 6620 } |
| 6258 | 6621 |
| 6259 /** | 6622 /** |
| 6260 * Given a list of arguments and the element that will be invoked using those
argument, compute | 6623 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 6261 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 6624 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 6262 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 6625 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 6263 * | 6626 * |
| 6264 * @param reportError if `true` then compile-time error should be reported; if
`false` | 6627 * @param reportError if `true` then compile-time error should be reported; if
`false` |
| 6265 * then compile-time warning | 6628 * then compile-time warning |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6343 } | 6706 } |
| 6344 | 6707 |
| 6345 /** | 6708 /** |
| 6346 * Resolve the names in the given combinators in the scope of the given librar
y. | 6709 * Resolve the names in the given combinators in the scope of the given librar
y. |
| 6347 * | 6710 * |
| 6348 * @param library the library that defines the names | 6711 * @param library the library that defines the names |
| 6349 * @param combinators the combinators containing the names to be resolved | 6712 * @param combinators the combinators containing the names to be resolved |
| 6350 */ | 6713 */ |
| 6351 void resolveCombinators(LibraryElement library, NodeList<Combinator> combinato
rs) { | 6714 void resolveCombinators(LibraryElement library, NodeList<Combinator> combinato
rs) { |
| 6352 if (library == null) { | 6715 if (library == null) { |
| 6716 // |
| 6717 // The library will be null if the directive containing the combinators ha
s a URI that is not |
| 6718 // valid. |
| 6719 // |
| 6353 return; | 6720 return; |
| 6354 } | 6721 } |
| 6355 Namespace namespace = new NamespaceBuilder().createExportNamespace2(library)
; | 6722 Namespace namespace = new NamespaceBuilder().createExportNamespace2(library)
; |
| 6356 for (Combinator combinator in combinators) { | 6723 for (Combinator combinator in combinators) { |
| 6357 NodeList<SimpleIdentifier> names; | 6724 NodeList<SimpleIdentifier> names; |
| 6358 if (combinator is HideCombinator) { | 6725 if (combinator is HideCombinator) { |
| 6359 names = combinator.hiddenNames; | 6726 names = combinator.hiddenNames; |
| 6360 } else { | 6727 } else { |
| 6361 names = (combinator as ShowCombinator).shownNames; | 6728 names = (combinator as ShowCombinator).shownNames; |
| 6362 } | 6729 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6401 * @param target the target of the invocation ('e') | 6768 * @param target the target of the invocation ('e') |
| 6402 * @param targetType the type of the target | 6769 * @param targetType the type of the target |
| 6403 * @param methodName the name of the method being invoked ('m') | 6770 * @param methodName the name of the method being invoked ('m') |
| 6404 * @return the element being invoked | 6771 * @return the element being invoked |
| 6405 */ | 6772 */ |
| 6406 Element resolveInvokedElement(Expression target, Type2 targetType, SimpleIdent
ifier methodName) { | 6773 Element resolveInvokedElement(Expression target, Type2 targetType, SimpleIdent
ifier methodName) { |
| 6407 if (targetType is InterfaceType) { | 6774 if (targetType is InterfaceType) { |
| 6408 InterfaceType classType = targetType; | 6775 InterfaceType classType = targetType; |
| 6409 Element element = lookUpMethod(target, classType, methodName.name); | 6776 Element element = lookUpMethod(target, classType, methodName.name); |
| 6410 if (element == null) { | 6777 if (element == null) { |
| 6778 // |
| 6779 // If there's no method, then it's possible that 'm' is a getter that re
turns a function. |
| 6780 // |
| 6411 element = lookUpGetter(target, classType, methodName.name); | 6781 element = lookUpGetter(target, classType, methodName.name); |
| 6412 } | 6782 } |
| 6413 return element; | 6783 return element; |
| 6414 } else if (target is SimpleIdentifier) { | 6784 } else if (target is SimpleIdentifier) { |
| 6415 Element targetElement = target.staticElement; | 6785 Element targetElement = target.staticElement; |
| 6416 if (targetElement is PrefixElement) { | 6786 if (targetElement is PrefixElement) { |
| 6787 // |
| 6788 // Look to see whether the name of the method is really part of a prefix
ed identifier for an |
| 6789 // imported top-level function or top-level getter that returns a functi
on. |
| 6790 // |
| 6417 String name = "${target.name}.${methodName}"; | 6791 String name = "${target.name}.${methodName}"; |
| 6418 Identifier functionName = new ElementResolver_SyntheticIdentifier(name); | 6792 Identifier functionName = new ElementResolver_SyntheticIdentifier(name); |
| 6419 Element element = _resolver.nameScope.lookup(functionName, _definingLibr
ary); | 6793 Element element = _resolver.nameScope.lookup(functionName, _definingLibr
ary); |
| 6420 if (element != null) { | 6794 if (element != null) { |
| 6795 // TODO(brianwilkerson) This isn't a method invocation, it's a functio
n invocation where |
| 6796 // the function name is a prefixed identifier. Consider re-writing the
AST. |
| 6421 return element; | 6797 return element; |
| 6422 } | 6798 } |
| 6423 } | 6799 } |
| 6424 } | 6800 } |
| 6801 // TODO(brianwilkerson) Report this error. |
| 6425 return null; | 6802 return null; |
| 6426 } | 6803 } |
| 6427 | 6804 |
| 6428 /** | 6805 /** |
| 6429 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the elemen
t being invoked. If | 6806 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the elemen
t being invoked. If |
| 6430 * the returned element is a method, then the method will be invoked. If the r
eturned element is a | 6807 * the returned element is a method, then the method will be invoked. If the r
eturned element is a |
| 6431 * getter, the getter will be invoked without arguments and the result of that
invocation will | 6808 * getter, the getter will be invoked without arguments and the result of that
invocation will |
| 6432 * then be invoked with the arguments. | 6809 * then be invoked with the arguments. |
| 6433 * | 6810 * |
| 6434 * @param methodName the name of the method being invoked ('m') | 6811 * @param methodName the name of the method being invoked ('m') |
| 6435 * @return the element being invoked | 6812 * @return the element being invoked |
| 6436 */ | 6813 */ |
| 6437 Element resolveInvokedElement2(SimpleIdentifier methodName) { | 6814 Element resolveInvokedElement2(SimpleIdentifier methodName) { |
| 6815 // |
| 6816 // Look first in the lexical scope. |
| 6817 // |
| 6438 Element element = _resolver.nameScope.lookup(methodName, _definingLibrary); | 6818 Element element = _resolver.nameScope.lookup(methodName, _definingLibrary); |
| 6439 if (element == null) { | 6819 if (element == null) { |
| 6820 // |
| 6821 // If it isn't defined in the lexical scope, and the invocation is within
a class, then look |
| 6822 // in the inheritance scope. |
| 6823 // |
| 6440 ClassElement enclosingClass = _resolver.enclosingClass; | 6824 ClassElement enclosingClass = _resolver.enclosingClass; |
| 6441 if (enclosingClass != null) { | 6825 if (enclosingClass != null) { |
| 6442 InterfaceType enclosingType = enclosingClass.type; | 6826 InterfaceType enclosingType = enclosingClass.type; |
| 6443 element = lookUpMethod(null, enclosingType, methodName.name); | 6827 element = lookUpMethod(null, enclosingType, methodName.name); |
| 6444 if (element == null) { | 6828 if (element == null) { |
| 6829 // |
| 6830 // If there's no method, then it's possible that 'm' is a getter that
returns a function. |
| 6831 // |
| 6445 element = lookUpGetter(null, enclosingType, methodName.name); | 6832 element = lookUpGetter(null, enclosingType, methodName.name); |
| 6446 } | 6833 } |
| 6447 } | 6834 } |
| 6448 } | 6835 } |
| 6836 // TODO(brianwilkerson) Report this error. |
| 6449 return element; | 6837 return element; |
| 6450 } | 6838 } |
| 6451 | 6839 |
| 6452 /** | 6840 /** |
| 6453 * Given that we are accessing a property of the given type with the given nam
e, return the | 6841 * Given that we are accessing a property of the given type with the given nam
e, return the |
| 6454 * element that represents the property. | 6842 * element that represents the property. |
| 6455 * | 6843 * |
| 6456 * @param target the target of the invocation ('e') | 6844 * @param target the target of the invocation ('e') |
| 6457 * @param targetType the type in which the search for the property should begi
n | 6845 * @param targetType the type in which the search for the property should begi
n |
| 6458 * @param propertyName the name of the property being accessed | 6846 * @param propertyName the name of the property being accessed |
| (...skipping 11 matching lines...) Expand all Loading... |
| 6470 memberElement = lookUpMethod(target, targetType, propertyName.name); | 6858 memberElement = lookUpMethod(target, targetType, propertyName.name); |
| 6471 } | 6859 } |
| 6472 return memberElement; | 6860 return memberElement; |
| 6473 } | 6861 } |
| 6474 | 6862 |
| 6475 void resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) { | 6863 void resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) { |
| 6476 Type2 staticType = getStaticType(target); | 6864 Type2 staticType = getStaticType(target); |
| 6477 Type2 propagatedType = getPropagatedType(target); | 6865 Type2 propagatedType = getPropagatedType(target); |
| 6478 Element staticElement = null; | 6866 Element staticElement = null; |
| 6479 Element propagatedElement = null; | 6867 Element propagatedElement = null; |
| 6868 // |
| 6869 // If this property access is of the form 'C.m' where 'C' is a class, then w
e don't call |
| 6870 // resolveProperty(..) which walks up the class hierarchy, instead we just l
ook for the |
| 6871 // member in the type only. |
| 6872 // |
| 6480 ClassElementImpl typeReference = getTypeReference(target); | 6873 ClassElementImpl typeReference = getTypeReference(target); |
| 6481 if (typeReference != null) { | 6874 if (typeReference != null) { |
| 6482 staticElement = propagatedElement = resolveElement(typeReference, property
Name); | 6875 staticElement = propagatedElement = resolveElement(typeReference, property
Name); |
| 6483 } else { | 6876 } else { |
| 6484 staticElement = resolveProperty(target, staticType, propertyName); | 6877 staticElement = resolveProperty(target, staticType, propertyName); |
| 6485 propagatedElement = resolveProperty(target, propagatedType, propertyName); | 6878 propagatedElement = resolveProperty(target, propagatedType, propertyName); |
| 6486 } | 6879 } |
| 6880 // May be part of annotation, record property element only if exists. |
| 6881 // Error was already reported in validateAnnotationElement(). |
| 6487 if (target.parent.parent is Annotation) { | 6882 if (target.parent.parent is Annotation) { |
| 6488 if (staticElement != null) { | 6883 if (staticElement != null) { |
| 6489 propertyName.staticElement = staticElement; | 6884 propertyName.staticElement = staticElement; |
| 6490 } | 6885 } |
| 6491 return; | 6886 return; |
| 6492 } | 6887 } |
| 6493 propertyName.staticElement = staticElement; | 6888 propertyName.staticElement = staticElement; |
| 6494 propertyName.propagatedElement = propagatedElement; | 6889 propertyName.propagatedElement = propagatedElement; |
| 6495 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticElement); | 6890 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticElement); |
| 6496 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedElement)
: false; | 6891 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedElement)
: false; |
| 6892 // If we are about to generate the hint (propagated version of this warning)
, then check |
| 6893 // that the member is not in a subtype of the propagated type. |
| 6497 if (shouldReportMissingMember_propagated) { | 6894 if (shouldReportMissingMember_propagated) { |
| 6498 if (memberFoundInSubclass(propagatedType.element, propertyName.name, false
, true)) { | 6895 if (memberFoundInSubclass(propagatedType.element, propertyName.name, false
, true)) { |
| 6499 shouldReportMissingMember_propagated = false; | 6896 shouldReportMissingMember_propagated = false; |
| 6500 } | 6897 } |
| 6501 } | 6898 } |
| 6502 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { | 6899 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { |
| 6503 Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static
? staticType.element : propagatedType.element; | 6900 Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static
? staticType.element : propagatedType.element; |
| 6504 bool isStaticProperty = isStatic(staticOrPropagatedEnclosingElt); | 6901 if (staticOrPropagatedEnclosingElt != null) { |
| 6505 if (propertyName.inSetterContext()) { | 6902 bool isStaticProperty = isStatic(staticOrPropagatedEnclosingElt); |
| 6506 if (isStaticProperty) { | 6903 if (propertyName.inSetterContext()) { |
| 6507 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarnin
gCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; | 6904 if (isStaticProperty) { |
| 6508 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedE
nclosingElt, errorCode, propertyName, [ | 6905 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarn
ingCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; |
| 6509 propertyName.name, | 6906 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagate
dEnclosingElt, errorCode, propertyName, [ |
| 6510 staticOrPropagatedEnclosingElt.displayName]); | 6907 propertyName.name, |
| 6908 staticOrPropagatedEnclosingElt.displayName]); |
| 6909 } else { |
| 6910 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticType
WarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; |
| 6911 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagate
dEnclosingElt, errorCode, propertyName, [ |
| 6912 propertyName.name, |
| 6913 staticOrPropagatedEnclosingElt.displayName]); |
| 6914 } |
| 6915 } else if (propertyName.inGetterContext()) { |
| 6916 if (isStaticProperty) { |
| 6917 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarn
ingCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode; |
| 6918 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagate
dEnclosingElt, errorCode, propertyName, [ |
| 6919 propertyName.name, |
| 6920 staticOrPropagatedEnclosingElt.displayName]); |
| 6921 } else { |
| 6922 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticType
WarningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode; |
| 6923 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagate
dEnclosingElt, errorCode, propertyName, [ |
| 6924 propertyName.name, |
| 6925 staticOrPropagatedEnclosingElt.displayName]); |
| 6926 } |
| 6511 } else { | 6927 } else { |
| 6512 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; | 6928 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedE
nclosingElt, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName
.name]); |
| 6513 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedE
nclosingElt, errorCode, propertyName, [ | |
| 6514 propertyName.name, | |
| 6515 staticOrPropagatedEnclosingElt.displayName]); | |
| 6516 } | 6929 } |
| 6517 } else if (propertyName.inGetterContext()) { | |
| 6518 if (isStaticProperty) { | |
| 6519 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarnin
gCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode; | |
| 6520 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedE
nclosingElt, errorCode, propertyName, [ | |
| 6521 propertyName.name, | |
| 6522 staticOrPropagatedEnclosingElt.displayName]); | |
| 6523 } else { | |
| 6524 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode; | |
| 6525 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedE
nclosingElt, errorCode, propertyName, [ | |
| 6526 propertyName.name, | |
| 6527 staticOrPropagatedEnclosingElt.displayName]); | |
| 6528 } | |
| 6529 } else { | |
| 6530 _resolver.reportErrorProxyConditionalAnalysisError(staticOrPropagatedEnc
losingElt, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.n
ame]); | |
| 6531 } | 6930 } |
| 6532 } | 6931 } |
| 6533 } | 6932 } |
| 6534 | 6933 |
| 6535 /** | 6934 /** |
| 6536 * Resolve the given simple identifier if possible. Return the element to whic
h it could be | 6935 * Resolve the given simple identifier if possible. Return the element to whic
h it could be |
| 6537 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the | 6936 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the |
| 6538 * resolution. | 6937 * resolution. |
| 6539 * | 6938 * |
| 6540 * @param node the identifier to be resolved | 6939 * @param node the identifier to be resolved |
| 6541 * @return the element to which the identifier could be resolved | 6940 * @return the element to which the identifier could be resolved |
| 6542 */ | 6941 */ |
| 6543 Element resolveSimpleIdentifier(SimpleIdentifier node) { | 6942 Element resolveSimpleIdentifier(SimpleIdentifier node) { |
| 6544 Element element = _resolver.nameScope.lookup(node, _definingLibrary); | 6943 Element element = _resolver.nameScope.lookup(node, _definingLibrary); |
| 6545 if (element is PropertyAccessorElement && node.inSetterContext()) { | 6944 if (element is PropertyAccessorElement && node.inSetterContext()) { |
| 6546 PropertyInducingElement variable = (element as PropertyAccessorElement).va
riable; | 6945 PropertyInducingElement variable = (element as PropertyAccessorElement).va
riable; |
| 6547 if (variable != null) { | 6946 if (variable != null) { |
| 6548 PropertyAccessorElement setter = variable.setter; | 6947 PropertyAccessorElement setter = variable.setter; |
| 6549 if (setter == null) { | 6948 if (setter == null) { |
| 6949 // |
| 6950 // Check to see whether there might be a locally defined getter and an
inherited setter. |
| 6951 // |
| 6550 ClassElement enclosingClass = _resolver.enclosingClass; | 6952 ClassElement enclosingClass = _resolver.enclosingClass; |
| 6551 if (enclosingClass != null) { | 6953 if (enclosingClass != null) { |
| 6552 setter = lookUpSetter(null, enclosingClass.type, node.name); | 6954 setter = lookUpSetter(null, enclosingClass.type, node.name); |
| 6553 } | 6955 } |
| 6554 } | 6956 } |
| 6555 if (setter != null) { | 6957 if (setter != null) { |
| 6556 element = setter; | 6958 element = setter; |
| 6557 } | 6959 } |
| 6558 } | 6960 } |
| 6559 } else if (element == null && node.inSetterContext()) { | 6961 } else if (element == null && node.inSetterContext()) { |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6967 * @param baseFunctionType the function type that is being overridden | 7369 * @param baseFunctionType the function type that is being overridden |
| 6968 * @param memberName the name of the member, this is used to lookup the inheri
tance path of the | 7370 * @param memberName the name of the member, this is used to lookup the inheri
tance path of the |
| 6969 * override | 7371 * override |
| 6970 * @param definingType the type that is overriding the member | 7372 * @param definingType the type that is overriding the member |
| 6971 * @return the passed function type with any parameterized types substituted | 7373 * @return the passed function type with any parameterized types substituted |
| 6972 */ | 7374 */ |
| 6973 FunctionType substituteTypeArgumentsInMemberFromInheritance(FunctionType baseF
unctionType, String memberName, InterfaceType definingType) { | 7375 FunctionType substituteTypeArgumentsInMemberFromInheritance(FunctionType baseF
unctionType, String memberName, InterfaceType definingType) { |
| 6974 if (baseFunctionType == null) { | 7376 if (baseFunctionType == null) { |
| 6975 return baseFunctionType; | 7377 return baseFunctionType; |
| 6976 } | 7378 } |
| 7379 // First, generate the path from the defining type to the overridden member |
| 6977 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>(); | 7380 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>(); |
| 6978 computeInheritancePath(inheritancePath, definingType, memberName); | 7381 computeInheritancePath(inheritancePath, definingType, memberName); |
| 6979 if (inheritancePath == null || inheritancePath.isEmpty) { | 7382 if (inheritancePath == null || inheritancePath.isEmpty) { |
| 7383 // TODO(jwren) log analysis engine error |
| 6980 return baseFunctionType; | 7384 return baseFunctionType; |
| 6981 } | 7385 } |
| 6982 FunctionType functionTypeToReturn = baseFunctionType; | 7386 FunctionType functionTypeToReturn = baseFunctionType; |
| 7387 // loop backward through the list substituting as we go: |
| 6983 while (!inheritancePath.isEmpty) { | 7388 while (!inheritancePath.isEmpty) { |
| 6984 InterfaceType lastType = inheritancePath.removeLast(); | 7389 InterfaceType lastType = inheritancePath.removeLast(); |
| 6985 List<Type2> parameterTypes = lastType.element.type.typeArguments; | 7390 List<Type2> parameterTypes = lastType.element.type.typeArguments; |
| 6986 List<Type2> argumentTypes = lastType.typeArguments; | 7391 List<Type2> argumentTypes = lastType.typeArguments; |
| 6987 functionTypeToReturn = functionTypeToReturn.substitute2(argumentTypes, par
ameterTypes); | 7392 functionTypeToReturn = functionTypeToReturn.substitute2(argumentTypes, par
ameterTypes); |
| 6988 } | 7393 } |
| 6989 return functionTypeToReturn; | 7394 return functionTypeToReturn; |
| 6990 } | 7395 } |
| 6991 | 7396 |
| 6992 /** | 7397 /** |
| (...skipping 12 matching lines...) Expand all Loading... |
| 7005 if (resultMap != null) { | 7410 if (resultMap != null) { |
| 7006 return resultMap; | 7411 return resultMap; |
| 7007 } else { | 7412 } else { |
| 7008 resultMap = new MemberMap(); | 7413 resultMap = new MemberMap(); |
| 7009 } | 7414 } |
| 7010 ClassElement superclassElt = null; | 7415 ClassElement superclassElt = null; |
| 7011 InterfaceType supertype = classElt.supertype; | 7416 InterfaceType supertype = classElt.supertype; |
| 7012 if (supertype != null) { | 7417 if (supertype != null) { |
| 7013 superclassElt = supertype.element; | 7418 superclassElt = supertype.element; |
| 7014 } else { | 7419 } else { |
| 7420 // classElt is Object |
| 7015 _classLookup[classElt] = resultMap; | 7421 _classLookup[classElt] = resultMap; |
| 7016 return resultMap; | 7422 return resultMap; |
| 7017 } | 7423 } |
| 7018 if (superclassElt != null) { | 7424 if (superclassElt != null) { |
| 7019 if (!visitedClasses.contains(superclassElt)) { | 7425 if (!visitedClasses.contains(superclassElt)) { |
| 7020 visitedClasses.add(classElt); | 7426 visitedClasses.add(classElt); |
| 7021 resultMap = new MemberMap.con2(computeClassChainLookupMap(superclassElt,
visitedClasses)); | 7427 resultMap = new MemberMap.con2(computeClassChainLookupMap(superclassElt,
visitedClasses)); |
| 7022 } else { | 7428 } else { |
| 7429 // This case happens only when the superclass was previously visited and
not in the lookup, |
| 7430 // meaning this is meant to shorten the compute for recursive cases. |
| 7023 _classLookup[superclassElt] = resultMap; | 7431 _classLookup[superclassElt] = resultMap; |
| 7024 return resultMap; | 7432 return resultMap; |
| 7025 } | 7433 } |
| 7434 // |
| 7435 // Substitute the supertypes down the hierarchy |
| 7436 // |
| 7026 substituteTypeParametersDownHierarchy(supertype, resultMap); | 7437 substituteTypeParametersDownHierarchy(supertype, resultMap); |
| 7438 // |
| 7439 // Include the members from the superclass in the resultMap |
| 7440 // |
| 7027 recordMapWithClassMembers(resultMap, supertype); | 7441 recordMapWithClassMembers(resultMap, supertype); |
| 7028 } | 7442 } |
| 7443 // |
| 7444 // Include the members from the mixins in the resultMap |
| 7445 // |
| 7029 List<InterfaceType> mixins = classElt.mixins; | 7446 List<InterfaceType> mixins = classElt.mixins; |
| 7030 for (int i = mixins.length - 1; i >= 0; i--) { | 7447 for (int i = mixins.length - 1; i >= 0; i--) { |
| 7031 recordMapWithClassMembers(resultMap, mixins[i]); | 7448 recordMapWithClassMembers(resultMap, mixins[i]); |
| 7032 } | 7449 } |
| 7033 _classLookup[classElt] = resultMap; | 7450 _classLookup[classElt] = resultMap; |
| 7034 return resultMap; | 7451 return resultMap; |
| 7035 } | 7452 } |
| 7036 | 7453 |
| 7037 /** | 7454 /** |
| 7038 * Compute and return the inheritance path given the context of a type and a m
ember that is | 7455 * Compute and return the inheritance path given the context of a type and a m
ember that is |
| 7039 * overridden in the inheritance path (for which the type is in the path). | 7456 * overridden in the inheritance path (for which the type is in the path). |
| 7040 * | 7457 * |
| 7041 * @param chain the inheritance path that is built up as this method calls its
elf recursively, | 7458 * @param chain the inheritance path that is built up as this method calls its
elf recursively, |
| 7042 * when this method is called an empty [LinkedList] should be provide
d | 7459 * when this method is called an empty [LinkedList] should be provide
d |
| 7043 * @param currentType the current type in the inheritance path | 7460 * @param currentType the current type in the inheritance path |
| 7044 * @param memberName the name of the member that is being looked up the inheri
tance path | 7461 * @param memberName the name of the member that is being looked up the inheri
tance path |
| 7045 */ | 7462 */ |
| 7046 void computeInheritancePath(Queue<InterfaceType> chain, InterfaceType currentT
ype, String memberName) { | 7463 void computeInheritancePath(Queue<InterfaceType> chain, InterfaceType currentT
ype, String memberName) { |
| 7464 // TODO (jwren) create a public version of this method which doesn't require
the initial chain |
| 7465 // to be provided, then provided tests for this functionality in Inheritance
ManagerTest |
| 7047 chain.add(currentType); | 7466 chain.add(currentType); |
| 7048 ClassElement classElt = currentType.element; | 7467 ClassElement classElt = currentType.element; |
| 7049 InterfaceType supertype = classElt.supertype; | 7468 InterfaceType supertype = classElt.supertype; |
| 7469 // Base case- reached Object |
| 7050 if (supertype == null) { | 7470 if (supertype == null) { |
| 7471 // Looked up the chain all the way to Object, return null. |
| 7472 // This should never happen. |
| 7051 return; | 7473 return; |
| 7052 } | 7474 } |
| 7475 // If we are done, return the chain |
| 7476 // We are not done if this is the first recursive call on this method. |
| 7053 if (chain.length != 1) { | 7477 if (chain.length != 1) { |
| 7478 // We are done however if the member is in this classElt |
| 7054 if (lookupMemberInClass(classElt, memberName) != null) { | 7479 if (lookupMemberInClass(classElt, memberName) != null) { |
| 7055 return; | 7480 return; |
| 7056 } | 7481 } |
| 7057 } | 7482 } |
| 7483 // Mixins- note that mixins call lookupMemberInClass, not lookupMember |
| 7058 List<InterfaceType> mixins = classElt.mixins; | 7484 List<InterfaceType> mixins = classElt.mixins; |
| 7059 for (int i = mixins.length - 1; i >= 0; i--) { | 7485 for (int i = mixins.length - 1; i >= 0; i--) { |
| 7060 ClassElement mixinElement = mixins[i].element; | 7486 ClassElement mixinElement = mixins[i].element; |
| 7061 if (mixinElement != null) { | 7487 if (mixinElement != null) { |
| 7062 ExecutableElement elt = lookupMemberInClass(mixinElement, memberName); | 7488 ExecutableElement elt = lookupMemberInClass(mixinElement, memberName); |
| 7063 if (elt != null) { | 7489 if (elt != null) { |
| 7490 // this is equivalent (but faster than) calling this method recursivel
y |
| 7491 // (return computeInheritancePath(chain, mixins[i], memberName);) |
| 7064 chain.add(mixins[i]); | 7492 chain.add(mixins[i]); |
| 7065 return; | 7493 return; |
| 7066 } | 7494 } |
| 7067 } | 7495 } |
| 7068 } | 7496 } |
| 7497 // Superclass |
| 7069 ClassElement superclassElt = supertype.element; | 7498 ClassElement superclassElt = supertype.element; |
| 7070 if (lookupMember(superclassElt, memberName) != null) { | 7499 if (lookupMember(superclassElt, memberName) != null) { |
| 7071 computeInheritancePath(chain, supertype, memberName); | 7500 computeInheritancePath(chain, supertype, memberName); |
| 7072 return; | 7501 return; |
| 7073 } | 7502 } |
| 7503 // Interfaces |
| 7074 List<InterfaceType> interfaces = classElt.interfaces; | 7504 List<InterfaceType> interfaces = classElt.interfaces; |
| 7075 for (InterfaceType interfaceType in interfaces) { | 7505 for (InterfaceType interfaceType in interfaces) { |
| 7076 ClassElement interfaceElement = interfaceType.element; | 7506 ClassElement interfaceElement = interfaceType.element; |
| 7077 if (interfaceElement != null && lookupMember(interfaceElement, memberName)
!= null) { | 7507 if (interfaceElement != null && lookupMember(interfaceElement, memberName)
!= null) { |
| 7078 computeInheritancePath(chain, interfaceType, memberName); | 7508 computeInheritancePath(chain, interfaceType, memberName); |
| 7079 return; | 7509 return; |
| 7080 } | 7510 } |
| 7081 } | 7511 } |
| 7082 } | 7512 } |
| 7083 | 7513 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 7096 MemberMap resultMap = _interfaceLookup[classElt]; | 7526 MemberMap resultMap = _interfaceLookup[classElt]; |
| 7097 if (resultMap != null) { | 7527 if (resultMap != null) { |
| 7098 return resultMap; | 7528 return resultMap; |
| 7099 } else { | 7529 } else { |
| 7100 resultMap = new MemberMap(); | 7530 resultMap = new MemberMap(); |
| 7101 } | 7531 } |
| 7102 InterfaceType supertype = classElt.supertype; | 7532 InterfaceType supertype = classElt.supertype; |
| 7103 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; | 7533 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; |
| 7104 List<InterfaceType> mixins = classElt.mixins; | 7534 List<InterfaceType> mixins = classElt.mixins; |
| 7105 List<InterfaceType> interfaces = classElt.interfaces; | 7535 List<InterfaceType> interfaces = classElt.interfaces; |
| 7536 // Recursively collect the list of mappings from all of the interface types |
| 7106 List<MemberMap> lookupMaps = new List<MemberMap>(); | 7537 List<MemberMap> lookupMaps = new List<MemberMap>(); |
| 7538 // Superclass element |
| 7107 if (superclassElement != null) { | 7539 if (superclassElement != null) { |
| 7108 if (!visitedInterfaces.contains(superclassElement)) { | 7540 if (!visitedInterfaces.contains(superclassElement)) { |
| 7109 try { | 7541 try { |
| 7110 visitedInterfaces.add(superclassElement); | 7542 visitedInterfaces.add(superclassElement); |
| 7543 // |
| 7544 // Recursively compute the map for the supertype. |
| 7545 // |
| 7111 MemberMap map = computeInterfaceLookupMap(superclassElement, visitedIn
terfaces); | 7546 MemberMap map = computeInterfaceLookupMap(superclassElement, visitedIn
terfaces); |
| 7112 map = new MemberMap.con2(map); | 7547 map = new MemberMap.con2(map); |
| 7548 // |
| 7549 // Substitute the supertypes down the hierarchy |
| 7550 // |
| 7113 substituteTypeParametersDownHierarchy(supertype, map); | 7551 substituteTypeParametersDownHierarchy(supertype, map); |
| 7552 // |
| 7553 // Add any members from the supertype into the map as well. |
| 7554 // |
| 7114 recordMapWithClassMembers(map, supertype); | 7555 recordMapWithClassMembers(map, supertype); |
| 7115 lookupMaps.add(map); | 7556 lookupMaps.add(map); |
| 7116 } finally { | 7557 } finally { |
| 7117 visitedInterfaces.remove(superclassElement); | 7558 visitedInterfaces.remove(superclassElement); |
| 7118 } | 7559 } |
| 7119 } else { | 7560 } else { |
| 7120 MemberMap map = _interfaceLookup[classElt]; | 7561 MemberMap map = _interfaceLookup[classElt]; |
| 7121 if (map != null) { | 7562 if (map != null) { |
| 7122 lookupMaps.add(map); | 7563 lookupMaps.add(map); |
| 7123 } else { | 7564 } else { |
| 7124 _interfaceLookup[superclassElement] = resultMap; | 7565 _interfaceLookup[superclassElement] = resultMap; |
| 7125 return resultMap; | 7566 return resultMap; |
| 7126 } | 7567 } |
| 7127 } | 7568 } |
| 7128 } | 7569 } |
| 7570 // Mixin elements |
| 7129 for (InterfaceType mixinType in mixins) { | 7571 for (InterfaceType mixinType in mixins) { |
| 7130 MemberMap mapWithMixinMembers = new MemberMap(); | 7572 MemberMap mapWithMixinMembers = new MemberMap(); |
| 7131 recordMapWithClassMembers(mapWithMixinMembers, mixinType); | 7573 recordMapWithClassMembers(mapWithMixinMembers, mixinType); |
| 7132 lookupMaps.add(mapWithMixinMembers); | 7574 lookupMaps.add(mapWithMixinMembers); |
| 7133 } | 7575 } |
| 7576 // Interface elements |
| 7134 for (InterfaceType interfaceType in interfaces) { | 7577 for (InterfaceType interfaceType in interfaces) { |
| 7135 ClassElement interfaceElement = interfaceType.element; | 7578 ClassElement interfaceElement = interfaceType.element; |
| 7136 if (interfaceElement != null) { | 7579 if (interfaceElement != null) { |
| 7137 if (!visitedInterfaces.contains(interfaceElement)) { | 7580 if (!visitedInterfaces.contains(interfaceElement)) { |
| 7138 try { | 7581 try { |
| 7139 visitedInterfaces.add(interfaceElement); | 7582 visitedInterfaces.add(interfaceElement); |
| 7583 // |
| 7584 // Recursively compute the map for the interfaces. |
| 7585 // |
| 7140 MemberMap map = computeInterfaceLookupMap(interfaceElement, visitedI
nterfaces); | 7586 MemberMap map = computeInterfaceLookupMap(interfaceElement, visitedI
nterfaces); |
| 7141 map = new MemberMap.con2(map); | 7587 map = new MemberMap.con2(map); |
| 7588 // |
| 7589 // Substitute the supertypes down the hierarchy |
| 7590 // |
| 7142 substituteTypeParametersDownHierarchy(interfaceType, map); | 7591 substituteTypeParametersDownHierarchy(interfaceType, map); |
| 7592 // |
| 7593 // And add any members from the interface into the map as well. |
| 7594 // |
| 7143 recordMapWithClassMembers(map, interfaceType); | 7595 recordMapWithClassMembers(map, interfaceType); |
| 7144 lookupMaps.add(map); | 7596 lookupMaps.add(map); |
| 7145 } finally { | 7597 } finally { |
| 7146 visitedInterfaces.remove(interfaceElement); | 7598 visitedInterfaces.remove(interfaceElement); |
| 7147 } | 7599 } |
| 7148 } else { | 7600 } else { |
| 7149 MemberMap map = _interfaceLookup[classElt]; | 7601 MemberMap map = _interfaceLookup[classElt]; |
| 7150 if (map != null) { | 7602 if (map != null) { |
| 7151 lookupMaps.add(map); | 7603 lookupMaps.add(map); |
| 7152 } else { | 7604 } else { |
| 7153 _interfaceLookup[interfaceElement] = resultMap; | 7605 _interfaceLookup[interfaceElement] = resultMap; |
| 7154 return resultMap; | 7606 return resultMap; |
| 7155 } | 7607 } |
| 7156 } | 7608 } |
| 7157 } | 7609 } |
| 7158 } | 7610 } |
| 7159 if (lookupMaps.length == 0) { | 7611 if (lookupMaps.length == 0) { |
| 7160 _interfaceLookup[classElt] = resultMap; | 7612 _interfaceLookup[classElt] = resultMap; |
| 7161 return resultMap; | 7613 return resultMap; |
| 7162 } | 7614 } |
| 7615 // |
| 7616 // Union all of the maps together, grouping the ExecutableElements into sets
. |
| 7617 // |
| 7163 Map<String, Set<ExecutableElement>> unionMap = new Map<String, Set<Executabl
eElement>>(); | 7618 Map<String, Set<ExecutableElement>> unionMap = new Map<String, Set<Executabl
eElement>>(); |
| 7164 for (MemberMap lookupMap in lookupMaps) { | 7619 for (MemberMap lookupMap in lookupMaps) { |
| 7165 for (int i = 0; i < lookupMap.size; i++) { | 7620 for (int i = 0; i < lookupMap.size; i++) { |
| 7166 String key = lookupMap.getKey(i); | 7621 String key = lookupMap.getKey(i); |
| 7167 if (key == null) { | 7622 if (key == null) { |
| 7168 break; | 7623 break; |
| 7169 } | 7624 } |
| 7170 Set<ExecutableElement> set = unionMap[key]; | 7625 Set<ExecutableElement> set = unionMap[key]; |
| 7171 if (set == null) { | 7626 if (set == null) { |
| 7172 set = new Set<ExecutableElement>(); | 7627 set = new Set<ExecutableElement>(); |
| 7173 unionMap[key] = set; | 7628 unionMap[key] = set; |
| 7174 } | 7629 } |
| 7175 set.add(lookupMap.getValue(i)); | 7630 set.add(lookupMap.getValue(i)); |
| 7176 } | 7631 } |
| 7177 } | 7632 } |
| 7633 // |
| 7634 // Loop through the entries in the union map, adding them to the resultMap a
ppropriately. |
| 7635 // |
| 7178 for (MapEntry<String, Set<ExecutableElement>> entry in getMapEntrySet(unionM
ap)) { | 7636 for (MapEntry<String, Set<ExecutableElement>> entry in getMapEntrySet(unionM
ap)) { |
| 7179 String key = entry.getKey(); | 7637 String key = entry.getKey(); |
| 7180 Set<ExecutableElement> set = entry.getValue(); | 7638 Set<ExecutableElement> set = entry.getValue(); |
| 7181 int numOfEltsWithMatchingNames = set.length; | 7639 int numOfEltsWithMatchingNames = set.length; |
| 7182 if (numOfEltsWithMatchingNames == 1) { | 7640 if (numOfEltsWithMatchingNames == 1) { |
| 7183 resultMap.put(key, new JavaIterator(set).next()); | 7641 resultMap.put(key, new JavaIterator(set).next()); |
| 7184 } else { | 7642 } else { |
| 7185 bool allMethods = true; | 7643 bool allMethods = true; |
| 7186 bool allSetters = true; | 7644 bool allSetters = true; |
| 7187 bool allGetters = true; | 7645 bool allGetters = true; |
| 7188 for (ExecutableElement executableElement in set) { | 7646 for (ExecutableElement executableElement in set) { |
| 7189 if (executableElement is PropertyAccessorElement) { | 7647 if (executableElement is PropertyAccessorElement) { |
| 7190 allMethods = false; | 7648 allMethods = false; |
| 7191 if (executableElement.isSetter) { | 7649 if (executableElement.isSetter) { |
| 7192 allGetters = false; | 7650 allGetters = false; |
| 7193 } else { | 7651 } else { |
| 7194 allSetters = false; | 7652 allSetters = false; |
| 7195 } | 7653 } |
| 7196 } else { | 7654 } else { |
| 7197 allGetters = false; | 7655 allGetters = false; |
| 7198 allSetters = false; | 7656 allSetters = false; |
| 7199 } | 7657 } |
| 7200 } | 7658 } |
| 7201 if (allMethods || allGetters || allSetters) { | 7659 if (allMethods || allGetters || allSetters) { |
| 7660 // Compute the element whose type is the subtype of all of the other t
ypes. |
| 7202 List<ExecutableElement> elements = new List.from(set); | 7661 List<ExecutableElement> elements = new List.from(set); |
| 7203 List<FunctionType> executableElementTypes = new List<FunctionType>(num
OfEltsWithMatchingNames); | 7662 List<FunctionType> executableElementTypes = new List<FunctionType>(num
OfEltsWithMatchingNames); |
| 7204 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { | 7663 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { |
| 7205 executableElementTypes[i] = elements[i].type; | 7664 executableElementTypes[i] = elements[i].type; |
| 7206 } | 7665 } |
| 7207 bool foundSubtypeOfAllTypes = false; | 7666 bool foundSubtypeOfAllTypes = false; |
| 7208 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { | 7667 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { |
| 7209 FunctionType subtype = executableElementTypes[i]; | 7668 FunctionType subtype = executableElementTypes[i]; |
| 7210 if (subtype == null) { | 7669 if (subtype == null) { |
| 7211 continue; | 7670 continue; |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7691 Source librarySource = library.librarySource; | 8150 Source librarySource = library.librarySource; |
| 7692 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; | 8151 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; |
| 7693 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom
pilationUnit(librarySource, definingCompilationUnit); | 8152 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom
pilationUnit(librarySource, definingCompilationUnit); |
| 7694 NodeList<Directive> directives = definingCompilationUnit.directives; | 8153 NodeList<Directive> directives = definingCompilationUnit.directives; |
| 7695 LibraryIdentifier libraryNameNode = null; | 8154 LibraryIdentifier libraryNameNode = null; |
| 7696 bool hasPartDirective = false; | 8155 bool hasPartDirective = false; |
| 7697 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement); | 8156 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement); |
| 7698 List<Directive> directivesToResolve = new List<Directive>(); | 8157 List<Directive> directivesToResolve = new List<Directive>(); |
| 7699 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat
ionUnitElementImpl>(); | 8158 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat
ionUnitElementImpl>(); |
| 7700 for (Directive directive in directives) { | 8159 for (Directive directive in directives) { |
| 8160 // |
| 8161 // We do not build the elements representing the import and export directi
ves at this point. |
| 8162 // That is not done until we get to LibraryResolver.buildDirectiveModels()
because we need the |
| 8163 // LibraryElements for the referenced libraries, which might not exist at
this point (due to |
| 8164 // the possibility of circular references). |
| 8165 // |
| 7701 if (directive is LibraryDirective) { | 8166 if (directive is LibraryDirective) { |
| 7702 if (libraryNameNode == null) { | 8167 if (libraryNameNode == null) { |
| 7703 libraryNameNode = directive.name; | 8168 libraryNameNode = directive.name; |
| 7704 directivesToResolve.add(directive); | 8169 directivesToResolve.add(directive); |
| 7705 } | 8170 } |
| 7706 } else if (directive is PartDirective) { | 8171 } else if (directive is PartDirective) { |
| 7707 PartDirective partDirective = directive; | 8172 PartDirective partDirective = directive; |
| 7708 StringLiteral partUri = partDirective.uri; | 8173 StringLiteral partUri = partDirective.uri; |
| 7709 Source partSource = library.getSource(partDirective); | 8174 Source partSource = library.getSource(partDirective); |
| 7710 if (partSource != null && partSource.exists()) { | 8175 if (partSource != null && partSource.exists()) { |
| 7711 hasPartDirective = true; | 8176 hasPartDirective = true; |
| 7712 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou
rce, library.getAST(partSource)); | 8177 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou
rce, library.getAST(partSource)); |
| 7713 part.uri = library.getUri(partDirective); | 8178 part.uri = library.getUri(partDirective); |
| 8179 // |
| 8180 // Validate that the part contains a part-of directive with the same n
ame as the library. |
| 8181 // |
| 7714 String partLibraryName = getPartLibraryName(library, partSource, direc
tivesToResolve); | 8182 String partLibraryName = getPartLibraryName(library, partSource, direc
tivesToResolve); |
| 7715 if (partLibraryName == null) { | 8183 if (partLibraryName == null) { |
| 7716 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSourc
e()])); | 8184 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSourc
e()])); |
| 7717 } else if (libraryNameNode == null) { | 8185 } else if (libraryNameNode == null) { |
| 7718 } else if (libraryNameNode.name != partLibraryName) { | 8186 } else if (libraryNameNode.name != partLibraryName) { |
| 7719 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryNa
meNode.name, partLibraryName])); | 8187 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryNa
meNode.name, partLibraryName])); |
| 7720 } | 8188 } |
| 7721 if (entryPoint == null) { | 8189 if (entryPoint == null) { |
| 7722 entryPoint = findEntryPoint(part); | 8190 entryPoint = findEntryPoint(part); |
| 7723 } | 8191 } |
| 7724 directive.element = part; | 8192 directive.element = part; |
| 7725 sourcedCompilationUnits.add(part); | 8193 sourcedCompilationUnits.add(part); |
| 7726 } | 8194 } |
| 7727 } | 8195 } |
| 7728 } | 8196 } |
| 7729 if (hasPartDirective && libraryNameNode == null) { | 8197 if (hasPartDirective && libraryNameNode == null) { |
| 7730 _errorListener.onError(new AnalysisError.con1(librarySource, ResolverError
Code.MISSING_LIBRARY_DIRECTIVE_WITH_PART, [])); | 8198 _errorListener.onError(new AnalysisError.con1(librarySource, ResolverError
Code.MISSING_LIBRARY_DIRECTIVE_WITH_PART, [])); |
| 7731 } | 8199 } |
| 8200 // |
| 8201 // Create and populate the library element. |
| 8202 // |
| 7732 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext,
libraryNameNode); | 8203 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext,
libraryNameNode); |
| 7733 libraryElement.definingCompilationUnit = definingCompilationUnitElement; | 8204 libraryElement.definingCompilationUnit = definingCompilationUnitElement; |
| 7734 if (entryPoint != null) { | 8205 if (entryPoint != null) { |
| 7735 libraryElement.entryPoint = entryPoint; | 8206 libraryElement.entryPoint = entryPoint; |
| 7736 } | 8207 } |
| 7737 int sourcedUnitCount = sourcedCompilationUnits.length; | 8208 int sourcedUnitCount = sourcedCompilationUnits.length; |
| 7738 libraryElement.parts = new List.from(sourcedCompilationUnits); | 8209 libraryElement.parts = new List.from(sourcedCompilationUnits); |
| 7739 for (Directive directive in directivesToResolve) { | 8210 for (Directive directive in directivesToResolve) { |
| 7740 directive.element = libraryElement; | 8211 directive.element = libraryElement; |
| 7741 } | 8212 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7915 * @param unit the compilation unit representing the embedded library | 8386 * @param unit the compilation unit representing the embedded library |
| 7916 * @param fullAnalysis `true` if a full analysis should be performed | 8387 * @param fullAnalysis `true` if a full analysis should be performed |
| 7917 * @return the element representing the resolved library | 8388 * @return the element representing the resolved library |
| 7918 * @throws AnalysisException if the library could not be resolved for some rea
son | 8389 * @throws AnalysisException if the library could not be resolved for some rea
son |
| 7919 */ | 8390 */ |
| 7920 LibraryElement resolveEmbeddedLibrary(Source librarySource, int modificationSt
amp, CompilationUnit unit, bool fullAnalysis) { | 8391 LibraryElement resolveEmbeddedLibrary(Source librarySource, int modificationSt
amp, CompilationUnit unit, bool fullAnalysis) { |
| 7921 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi
ne.LibraryResolver.resolveEmbeddedLibrary"); | 8392 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi
ne.LibraryResolver.resolveEmbeddedLibrary"); |
| 7922 try { | 8393 try { |
| 7923 instrumentation.metric("fullAnalysis", fullAnalysis); | 8394 instrumentation.metric("fullAnalysis", fullAnalysis); |
| 7924 instrumentation.data3("fullName", librarySource.fullName); | 8395 instrumentation.data3("fullName", librarySource.fullName); |
| 8396 // |
| 8397 // Create the objects representing the library being resolved and the core
library. |
| 8398 // |
| 7925 Library targetLibrary = createLibrary2(librarySource, modificationStamp, u
nit); | 8399 Library targetLibrary = createLibrary2(librarySource, modificationStamp, u
nit); |
| 7926 _coreLibrary = _libraryMap[_coreLibrarySource]; | 8400 _coreLibrary = _libraryMap[_coreLibrarySource]; |
| 7927 if (_coreLibrary == null) { | 8401 if (_coreLibrary == null) { |
| 8402 // This will be true unless the library being analyzed is the core libra
ry. |
| 7928 _coreLibrary = createLibrary(_coreLibrarySource); | 8403 _coreLibrary = createLibrary(_coreLibrarySource); |
| 7929 } | 8404 } |
| 7930 instrumentation.metric3("createLibrary", "complete"); | 8405 instrumentation.metric3("createLibrary", "complete"); |
| 8406 // |
| 8407 // Compute the set of libraries that need to be resolved together. |
| 8408 // |
| 7931 computeLibraryDependencies2(targetLibrary, unit); | 8409 computeLibraryDependencies2(targetLibrary, unit); |
| 7932 _librariesInCycles = computeLibrariesInCycles(targetLibrary); | 8410 _librariesInCycles = computeLibrariesInCycles(targetLibrary); |
| 8411 // |
| 8412 // Build the element models representing the libraries being resolved. Thi
s is done in three |
| 8413 // steps: |
| 8414 // |
| 8415 // 1. Build the basic element models without making any connections betwee
n elements other than |
| 8416 // the basic parent/child relationships. This includes building the ele
ments representing the |
| 8417 // libraries. |
| 8418 // 2. Build the elements for the import and export directives. This requir
es that we have the |
| 8419 // elements built for the referenced libraries, but because of the poss
ibility of circular |
| 8420 // references needs to happen after all of the library elements have be
en created. |
| 8421 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This |
| 8422 // requires that we be able to compute the names visible in the librari
es being resolved, |
| 8423 // which in turn requires that we have resolved the import directives. |
| 8424 // |
| 7933 buildElementModels(); | 8425 buildElementModels(); |
| 7934 instrumentation.metric3("buildElementModels", "complete"); | 8426 instrumentation.metric3("buildElementModels", "complete"); |
| 7935 LibraryElement coreElement = _coreLibrary.libraryElement; | 8427 LibraryElement coreElement = _coreLibrary.libraryElement; |
| 7936 if (coreElement == null) { | 8428 if (coreElement == null) { |
| 7937 throw new AnalysisException.con1("Could not resolve dart:core"); | 8429 throw new AnalysisException.con1("Could not resolve dart:core"); |
| 7938 } | 8430 } |
| 7939 buildDirectiveModels(); | 8431 buildDirectiveModels(); |
| 7940 instrumentation.metric3("buildDirectiveModels", "complete"); | 8432 instrumentation.metric3("buildDirectiveModels", "complete"); |
| 7941 _typeProvider = new TypeProviderImpl(coreElement); | 8433 _typeProvider = new TypeProviderImpl(coreElement); |
| 7942 buildTypeHierarchies(); | 8434 buildTypeHierarchies(); |
| 7943 instrumentation.metric3("buildTypeHierarchies", "complete"); | 8435 instrumentation.metric3("buildTypeHierarchies", "complete"); |
| 8436 // |
| 8437 // Perform resolution and type analysis. |
| 8438 // |
| 8439 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we |
| 8440 // want to only resolve the target library. The advantage to resolving eve
rything is that we |
| 8441 // have already done part of the work so we'll avoid duplicated effort. Th
e disadvantage of |
| 8442 // resolving everything is that we might do extra work that we don't reall
y care about. Another |
| 8443 // possibility is to add a parameter to this method and punt the decision
to the clients. |
| 8444 // |
| 8445 //if (analyzeAll) { |
| 7944 resolveReferencesAndTypes(); | 8446 resolveReferencesAndTypes(); |
| 7945 instrumentation.metric3("resolveReferencesAndTypes", "complete"); | 8447 instrumentation.metric3("resolveReferencesAndTypes", "complete"); |
| 8448 //} else { |
| 8449 // resolveReferencesAndTypes(targetLibrary); |
| 8450 //} |
| 7946 performConstantEvaluation(); | 8451 performConstantEvaluation(); |
| 7947 instrumentation.metric3("performConstantEvaluation", "complete"); | 8452 instrumentation.metric3("performConstantEvaluation", "complete"); |
| 7948 return targetLibrary.libraryElement; | 8453 return targetLibrary.libraryElement; |
| 7949 } finally { | 8454 } finally { |
| 7950 instrumentation.log(); | 8455 instrumentation.log(); |
| 7951 } | 8456 } |
| 7952 } | 8457 } |
| 7953 | 8458 |
| 7954 /** | 8459 /** |
| 7955 * Resolve the library specified by the given source in the given context. | 8460 * Resolve the library specified by the given source in the given context. |
| 7956 * | 8461 * |
| 7957 * Note that because Dart allows circular imports between libraries, it is pos
sible that more than | 8462 * Note that because Dart allows circular imports between libraries, it is pos
sible that more than |
| 7958 * one library will need to be resolved. In such cases the error listener can
receive errors from | 8463 * one library will need to be resolved. In such cases the error listener can
receive errors from |
| 7959 * multiple libraries. | 8464 * multiple libraries. |
| 7960 * | 8465 * |
| 7961 * @param librarySource the source specifying the defining compilation unit of
the library to be | 8466 * @param librarySource the source specifying the defining compilation unit of
the library to be |
| 7962 * resolved | 8467 * resolved |
| 7963 * @param fullAnalysis `true` if a full analysis should be performed | 8468 * @param fullAnalysis `true` if a full analysis should be performed |
| 7964 * @return the element representing the resolved library | 8469 * @return the element representing the resolved library |
| 7965 * @throws AnalysisException if the library could not be resolved for some rea
son | 8470 * @throws AnalysisException if the library could not be resolved for some rea
son |
| 7966 */ | 8471 */ |
| 7967 LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) { | 8472 LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) { |
| 7968 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi
ne.LibraryResolver.resolveLibrary"); | 8473 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi
ne.LibraryResolver.resolveLibrary"); |
| 7969 try { | 8474 try { |
| 7970 instrumentation.metric("fullAnalysis", fullAnalysis); | 8475 instrumentation.metric("fullAnalysis", fullAnalysis); |
| 7971 instrumentation.data3("fullName", librarySource.fullName); | 8476 instrumentation.data3("fullName", librarySource.fullName); |
| 8477 // |
| 8478 // Create the objects representing the library being resolved and the core
library. |
| 8479 // |
| 7972 Library targetLibrary = createLibrary(librarySource); | 8480 Library targetLibrary = createLibrary(librarySource); |
| 7973 _coreLibrary = _libraryMap[_coreLibrarySource]; | 8481 _coreLibrary = _libraryMap[_coreLibrarySource]; |
| 7974 if (_coreLibrary == null) { | 8482 if (_coreLibrary == null) { |
| 8483 // This will be true unless the library being analyzed is the core libra
ry. |
| 7975 _coreLibrary = createLibraryOrNull(_coreLibrarySource); | 8484 _coreLibrary = createLibraryOrNull(_coreLibrarySource); |
| 7976 if (_coreLibrary == null) { | 8485 if (_coreLibrary == null) { |
| 7977 throw new AnalysisException.con1("Core library does not exist"); | 8486 throw new AnalysisException.con1("Core library does not exist"); |
| 7978 } | 8487 } |
| 7979 } | 8488 } |
| 7980 instrumentation.metric3("createLibrary", "complete"); | 8489 instrumentation.metric3("createLibrary", "complete"); |
| 8490 // |
| 8491 // Compute the set of libraries that need to be resolved together. |
| 8492 // |
| 7981 computeLibraryDependencies(targetLibrary); | 8493 computeLibraryDependencies(targetLibrary); |
| 7982 _librariesInCycles = computeLibrariesInCycles(targetLibrary); | 8494 _librariesInCycles = computeLibrariesInCycles(targetLibrary); |
| 8495 // |
| 8496 // Build the element models representing the libraries being resolved. Thi
s is done in three |
| 8497 // steps: |
| 8498 // |
| 8499 // 1. Build the basic element models without making any connections betwee
n elements other than |
| 8500 // the basic parent/child relationships. This includes building the ele
ments representing the |
| 8501 // libraries. |
| 8502 // 2. Build the elements for the import and export directives. This requir
es that we have the |
| 8503 // elements built for the referenced libraries, but because of the poss
ibility of circular |
| 8504 // references needs to happen after all of the library elements have be
en created. |
| 8505 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This |
| 8506 // requires that we be able to compute the names visible in the librari
es being resolved, |
| 8507 // which in turn requires that we have resolved the import directives. |
| 8508 // |
| 7983 buildElementModels(); | 8509 buildElementModels(); |
| 7984 instrumentation.metric3("buildElementModels", "complete"); | 8510 instrumentation.metric3("buildElementModels", "complete"); |
| 7985 LibraryElement coreElement = _coreLibrary.libraryElement; | 8511 LibraryElement coreElement = _coreLibrary.libraryElement; |
| 7986 if (coreElement == null) { | 8512 if (coreElement == null) { |
| 7987 throw new AnalysisException.con1("Could not resolve dart:core"); | 8513 throw new AnalysisException.con1("Could not resolve dart:core"); |
| 7988 } | 8514 } |
| 7989 buildDirectiveModels(); | 8515 buildDirectiveModels(); |
| 7990 instrumentation.metric3("buildDirectiveModels", "complete"); | 8516 instrumentation.metric3("buildDirectiveModels", "complete"); |
| 7991 _typeProvider = new TypeProviderImpl(coreElement); | 8517 _typeProvider = new TypeProviderImpl(coreElement); |
| 7992 buildTypeHierarchies(); | 8518 buildTypeHierarchies(); |
| 7993 instrumentation.metric3("buildTypeHierarchies", "complete"); | 8519 instrumentation.metric3("buildTypeHierarchies", "complete"); |
| 8520 // |
| 8521 // Perform resolution and type analysis. |
| 8522 // |
| 8523 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we |
| 8524 // want to only resolve the target library. The advantage to resolving eve
rything is that we |
| 8525 // have already done part of the work so we'll avoid duplicated effort. Th
e disadvantage of |
| 8526 // resolving everything is that we might do extra work that we don't reall
y care about. Another |
| 8527 // possibility is to add a parameter to this method and punt the decision
to the clients. |
| 8528 // |
| 8529 //if (analyzeAll) { |
| 7994 resolveReferencesAndTypes(); | 8530 resolveReferencesAndTypes(); |
| 7995 instrumentation.metric3("resolveReferencesAndTypes", "complete"); | 8531 instrumentation.metric3("resolveReferencesAndTypes", "complete"); |
| 8532 //} else { |
| 8533 // resolveReferencesAndTypes(targetLibrary); |
| 8534 //} |
| 7996 performConstantEvaluation(); | 8535 performConstantEvaluation(); |
| 7997 instrumentation.metric3("performConstantEvaluation", "complete"); | 8536 instrumentation.metric3("performConstantEvaluation", "complete"); |
| 7998 instrumentation.metric2("librariesInCycles", _librariesInCycles.length); | 8537 instrumentation.metric2("librariesInCycles", _librariesInCycles.length); |
| 7999 for (Library lib in _librariesInCycles) { | 8538 for (Library lib in _librariesInCycles) { |
| 8000 instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size",
lib.compilationUnitSources.length); | 8539 instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size",
lib.compilationUnitSources.length); |
| 8001 } | 8540 } |
| 8002 return targetLibrary.libraryElement; | 8541 return targetLibrary.libraryElement; |
| 8003 } finally { | 8542 } finally { |
| 8004 instrumentation.log(); | 8543 instrumentation.log(); |
| 8005 } | 8544 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8097 void buildDirectiveModels() { | 8636 void buildDirectiveModels() { |
| 8098 for (Library library in _librariesInCycles) { | 8637 for (Library library in _librariesInCycles) { |
| 8099 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle
mentImpl>(); | 8638 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle
mentImpl>(); |
| 8100 List<ImportElement> imports = new List<ImportElement>(); | 8639 List<ImportElement> imports = new List<ImportElement>(); |
| 8101 List<ExportElement> exports = new List<ExportElement>(); | 8640 List<ExportElement> exports = new List<ExportElement>(); |
| 8102 for (Directive directive in library.definingCompilationUnit.directives) { | 8641 for (Directive directive in library.definingCompilationUnit.directives) { |
| 8103 if (directive is ImportDirective) { | 8642 if (directive is ImportDirective) { |
| 8104 ImportDirective importDirective = directive; | 8643 ImportDirective importDirective = directive; |
| 8105 Source importedSource = library.getSource(importDirective); | 8644 Source importedSource = library.getSource(importDirective); |
| 8106 if (importedSource != null) { | 8645 if (importedSource != null) { |
| 8646 // The imported source will be null if the URI in the import directi
ve was invalid. |
| 8107 Library importedLibrary = _libraryMap[importedSource]; | 8647 Library importedLibrary = _libraryMap[importedSource]; |
| 8108 if (importedLibrary != null) { | 8648 if (importedLibrary != null) { |
| 8109 ImportElementImpl importElement = new ImportElementImpl(directive.
offset); | 8649 ImportElementImpl importElement = new ImportElementImpl(directive.
offset); |
| 8110 StringLiteral uriLiteral = importDirective.uri; | 8650 StringLiteral uriLiteral = importDirective.uri; |
| 8111 if (uriLiteral != null) { | 8651 if (uriLiteral != null) { |
| 8112 importElement.uriEnd = uriLiteral.end; | 8652 importElement.uriEnd = uriLiteral.end; |
| 8113 } | 8653 } |
| 8114 importElement.uri = library.getUri(importDirective); | 8654 importElement.uri = library.getUri(importDirective); |
| 8115 importElement.combinators = buildCombinators(importDirective); | 8655 importElement.combinators = buildCombinators(importDirective); |
| 8116 LibraryElement importedLibraryElement = importedLibrary.libraryEle
ment; | 8656 LibraryElement importedLibraryElement = importedLibrary.libraryEle
ment; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 8133 imports.add(importElement); | 8673 imports.add(importElement); |
| 8134 if (analysisContext.computeKindOf(importedSource) != SourceKind.LI
BRARY) { | 8674 if (analysisContext.computeKindOf(importedSource) != SourceKind.LI
BRARY) { |
| 8135 _errorListener.onError(new AnalysisError.con2(library.librarySou
rce, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LI
BRARY, [uriLiteral.toSource()])); | 8675 _errorListener.onError(new AnalysisError.con2(library.librarySou
rce, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LI
BRARY, [uriLiteral.toSource()])); |
| 8136 } | 8676 } |
| 8137 } | 8677 } |
| 8138 } | 8678 } |
| 8139 } else if (directive is ExportDirective) { | 8679 } else if (directive is ExportDirective) { |
| 8140 ExportDirective exportDirective = directive; | 8680 ExportDirective exportDirective = directive; |
| 8141 Source exportedSource = library.getSource(exportDirective); | 8681 Source exportedSource = library.getSource(exportDirective); |
| 8142 if (exportedSource != null) { | 8682 if (exportedSource != null) { |
| 8683 // The exported source will be null if the URI in the export directi
ve was invalid. |
| 8143 Library exportedLibrary = _libraryMap[exportedSource]; | 8684 Library exportedLibrary = _libraryMap[exportedSource]; |
| 8144 if (exportedLibrary != null) { | 8685 if (exportedLibrary != null) { |
| 8145 ExportElementImpl exportElement = new ExportElementImpl(); | 8686 ExportElementImpl exportElement = new ExportElementImpl(); |
| 8146 exportElement.uri = library.getUri(exportDirective); | 8687 exportElement.uri = library.getUri(exportDirective); |
| 8147 exportElement.combinators = buildCombinators(exportDirective); | 8688 exportElement.combinators = buildCombinators(exportDirective); |
| 8148 LibraryElement exportedLibraryElement = exportedLibrary.libraryEle
ment; | 8689 LibraryElement exportedLibraryElement = exportedLibrary.libraryEle
ment; |
| 8149 if (exportedLibraryElement != null) { | 8690 if (exportedLibraryElement != null) { |
| 8150 exportElement.exportedLibrary = exportedLibraryElement; | 8691 exportElement.exportedLibrary = exportedLibraryElement; |
| 8151 } | 8692 } |
| 8152 directive.element = exportElement; | 8693 directive.element = exportElement; |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8449 ast.accept(visitor); | 8990 ast.accept(visitor); |
| 8450 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondi
tionalAnalysisErrors) { | 8991 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondi
tionalAnalysisErrors) { |
| 8451 if (conditionalCode.shouldIncludeErrorCode()) { | 8992 if (conditionalCode.shouldIncludeErrorCode()) { |
| 8452 visitor.reportError(conditionalCode.analysisError); | 8993 visitor.reportError(conditionalCode.analysisError); |
| 8453 } | 8994 } |
| 8454 } | 8995 } |
| 8455 } | 8996 } |
| 8456 } finally { | 8997 } finally { |
| 8457 timeCounter.stop(); | 8998 timeCounter.stop(); |
| 8458 } | 8999 } |
| 9000 // Angular |
| 8459 timeCounter = PerformanceStatistics.angular.start(); | 9001 timeCounter = PerformanceStatistics.angular.start(); |
| 8460 try { | 9002 try { |
| 8461 for (Source source in library.compilationUnitSources) { | 9003 for (Source source in library.compilationUnitSources) { |
| 8462 CompilationUnit ast = library.getAST(source); | 9004 CompilationUnit ast = library.getAST(source); |
| 8463 new AngularCompilationUnitBuilder(_errorListener, source).build(ast); | 9005 new AngularCompilationUnitBuilder(_errorListener, source).build(ast); |
| 8464 } | 9006 } |
| 8465 } finally { | 9007 } finally { |
| 8466 timeCounter.stop(); | 9008 timeCounter.stop(); |
| 8467 } | 9009 } |
| 8468 } | 9010 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8582 ExecutableElement getValue(int i) => _values[i]; | 9124 ExecutableElement getValue(int i) => _values[i]; |
| 8583 | 9125 |
| 8584 /** | 9126 /** |
| 8585 * Given some key/value pair, store the pair in the map. If the key exists alr
eady, then the new | 9127 * Given some key/value pair, store the pair in the map. If the key exists alr
eady, then the new |
| 8586 * value overrides the old value. | 9128 * value overrides the old value. |
| 8587 * | 9129 * |
| 8588 * @param key the key to store in the map | 9130 * @param key the key to store in the map |
| 8589 * @param value the ExecutableElement value to store in the map | 9131 * @param value the ExecutableElement value to store in the map |
| 8590 */ | 9132 */ |
| 8591 void put(String key, ExecutableElement value) { | 9133 void put(String key, ExecutableElement value) { |
| 9134 // If we already have a value with this key, override the value |
| 8592 for (int i = 0; i < _size; i++) { | 9135 for (int i = 0; i < _size; i++) { |
| 8593 if (_keys[i] != null && _keys[i] == key) { | 9136 if (_keys[i] != null && _keys[i] == key) { |
| 8594 _values[i] = value; | 9137 _values[i] = value; |
| 8595 return; | 9138 return; |
| 8596 } | 9139 } |
| 8597 } | 9140 } |
| 9141 // If needed, double the size of our arrays and copy values over in both arr
ays |
| 8598 if (_size == _keys.length) { | 9142 if (_size == _keys.length) { |
| 8599 int newArrayLength = _size * 2; | 9143 int newArrayLength = _size * 2; |
| 8600 List<String> keys_new_array = new List<String>(newArrayLength); | 9144 List<String> keys_new_array = new List<String>(newArrayLength); |
| 8601 List<ExecutableElement> values_new_array = new List<ExecutableElement>(new
ArrayLength); | 9145 List<ExecutableElement> values_new_array = new List<ExecutableElement>(new
ArrayLength); |
| 8602 for (int i = 0; i < _size; i++) { | 9146 for (int i = 0; i < _size; i++) { |
| 8603 keys_new_array[i] = _keys[i]; | 9147 keys_new_array[i] = _keys[i]; |
| 8604 } | 9148 } |
| 8605 for (int i = 0; i < _size; i++) { | 9149 for (int i = 0; i < _size; i++) { |
| 8606 values_new_array[i] = _values[i]; | 9150 values_new_array[i] = _values[i]; |
| 8607 } | 9151 } |
| 8608 _keys = keys_new_array; | 9152 _keys = keys_new_array; |
| 8609 _values = values_new_array; | 9153 _values = values_new_array; |
| 8610 } | 9154 } |
| 9155 // Put new value at end of array |
| 8611 _keys[_size] = key; | 9156 _keys[_size] = key; |
| 8612 _values[_size] = value; | 9157 _values[_size] = value; |
| 8613 _size++; | 9158 _size++; |
| 8614 } | 9159 } |
| 8615 | 9160 |
| 8616 /** | 9161 /** |
| 8617 * Given some String key, this method replaces the associated key and value pa
ir with `null` | 9162 * Given some String key, this method replaces the associated key and value pa
ir with `null` |
| 8618 * . The size is not decremented with this call, instead it is expected that t
he users check for | 9163 * . The size is not decremented with this call, instead it is expected that t
he users check for |
| 8619 * `null`. | 9164 * `null`. |
| 8620 * | 9165 * |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8829 sc.TokenType operatorType = node.operator.type; | 9374 sc.TokenType operatorType = node.operator.type; |
| 8830 Expression leftOperand = node.leftOperand; | 9375 Expression leftOperand = node.leftOperand; |
| 8831 Expression rightOperand = node.rightOperand; | 9376 Expression rightOperand = node.rightOperand; |
| 8832 if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) { | 9377 if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) { |
| 8833 safelyVisit(leftOperand); | 9378 safelyVisit(leftOperand); |
| 8834 if (rightOperand != null) { | 9379 if (rightOperand != null) { |
| 8835 try { | 9380 try { |
| 8836 _overrideManager.enterScope(); | 9381 _overrideManager.enterScope(); |
| 8837 _promoteManager.enterScope(); | 9382 _promoteManager.enterScope(); |
| 8838 propagateTrueState(leftOperand); | 9383 propagateTrueState(leftOperand); |
| 9384 // Type promotion. |
| 8839 promoteTypes(leftOperand); | 9385 promoteTypes(leftOperand); |
| 8840 clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); | 9386 clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); |
| 8841 clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); | 9387 clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); |
| 8842 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(rightOper
and); | 9388 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(rightOper
and); |
| 9389 // Visit right operand. |
| 8843 rightOperand.accept(this); | 9390 rightOperand.accept(this); |
| 8844 } finally { | 9391 } finally { |
| 8845 _overrideManager.exitScope(); | 9392 _overrideManager.exitScope(); |
| 8846 _promoteManager.exitScope(); | 9393 _promoteManager.exitScope(); |
| 8847 } | 9394 } |
| 8848 } | 9395 } |
| 8849 } else if (identical(operatorType, sc.TokenType.BAR_BAR)) { | 9396 } else if (identical(operatorType, sc.TokenType.BAR_BAR)) { |
| 8850 safelyVisit(leftOperand); | 9397 safelyVisit(leftOperand); |
| 8851 if (rightOperand != null) { | 9398 if (rightOperand != null) { |
| 8852 try { | 9399 try { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 8871 try { | 9418 try { |
| 8872 _overrideManager.enterScope(); | 9419 _overrideManager.enterScope(); |
| 8873 super.visitBlockFunctionBody(node); | 9420 super.visitBlockFunctionBody(node); |
| 8874 } finally { | 9421 } finally { |
| 8875 _overrideManager.exitScope(); | 9422 _overrideManager.exitScope(); |
| 8876 } | 9423 } |
| 8877 return null; | 9424 return null; |
| 8878 } | 9425 } |
| 8879 | 9426 |
| 8880 Object visitBreakStatement(BreakStatement node) { | 9427 Object visitBreakStatement(BreakStatement node) { |
| 9428 // |
| 9429 // We do not visit the label because it needs to be visited in the context o
f the statement. |
| 9430 // |
| 8881 node.accept(_elementResolver); | 9431 node.accept(_elementResolver); |
| 8882 node.accept(_typeAnalyzer); | 9432 node.accept(_typeAnalyzer); |
| 8883 return null; | 9433 return null; |
| 8884 } | 9434 } |
| 8885 | 9435 |
| 8886 Object visitClassDeclaration(ClassDeclaration node) { | 9436 Object visitClassDeclaration(ClassDeclaration node) { |
| 8887 ClassElement outerType = _enclosingClass; | 9437 ClassElement outerType = _enclosingClass; |
| 8888 try { | 9438 try { |
| 8889 _enclosingClass = node.element; | 9439 _enclosingClass = node.element; |
| 8890 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass.
type; | 9440 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass.
type; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8902 _commentBeforeFunction = node; | 9452 _commentBeforeFunction = node; |
| 8903 return null; | 9453 return null; |
| 8904 } | 9454 } |
| 8905 } | 9455 } |
| 8906 super.visitComment(node); | 9456 super.visitComment(node); |
| 8907 _commentBeforeFunction = null; | 9457 _commentBeforeFunction = null; |
| 8908 return null; | 9458 return null; |
| 8909 } | 9459 } |
| 8910 | 9460 |
| 8911 Object visitCommentReference(CommentReference node) { | 9461 Object visitCommentReference(CommentReference node) { |
| 9462 // |
| 9463 // We do not visit the identifier because it needs to be visited in the cont
ext of the reference. |
| 9464 // |
| 8912 node.accept(_elementResolver); | 9465 node.accept(_elementResolver); |
| 8913 node.accept(_typeAnalyzer); | 9466 node.accept(_typeAnalyzer); |
| 8914 return null; | 9467 return null; |
| 8915 } | 9468 } |
| 8916 | 9469 |
| 8917 Object visitCompilationUnit(CompilationUnit node) { | 9470 Object visitCompilationUnit(CompilationUnit node) { |
| 9471 // |
| 9472 // TODO(brianwilkerson) The goal of the code below is to visit the declarati
ons in such an |
| 9473 // order that we can infer type information for top-level variables before w
e visit references |
| 9474 // to them. This is better than making no effort, but still doesn't complete
ly satisfy that |
| 9475 // goal (consider for example "final var a = b; final var b = 0;"; we'll inf
er a type of 'int' |
| 9476 // for 'b', but not for 'a' because of the order of the visits). Ideally we
would create a |
| 9477 // dependency graph, but that would require references to be resolved, which
they are not. |
| 9478 // |
| 8918 try { | 9479 try { |
| 8919 _overrideManager.enterScope(); | 9480 _overrideManager.enterScope(); |
| 8920 NodeList<Directive> directives = node.directives; | 9481 NodeList<Directive> directives = node.directives; |
| 8921 int directiveCount = directives.length; | 9482 int directiveCount = directives.length; |
| 8922 for (int i = 0; i < directiveCount; i++) { | 9483 for (int i = 0; i < directiveCount; i++) { |
| 8923 directives[i].accept(this); | 9484 directives[i].accept(this); |
| 8924 } | 9485 } |
| 8925 NodeList<CompilationUnitMember> declarations = node.declarations; | 9486 NodeList<CompilationUnitMember> declarations = node.declarations; |
| 8926 int declarationCount = declarations.length; | 9487 int declarationCount = declarations.length; |
| 8927 for (int i = 0; i < declarationCount; i++) { | 9488 for (int i = 0; i < declarationCount; i++) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 8946 | 9507 |
| 8947 Object visitConditionalExpression(ConditionalExpression node) { | 9508 Object visitConditionalExpression(ConditionalExpression node) { |
| 8948 Expression condition = node.condition; | 9509 Expression condition = node.condition; |
| 8949 safelyVisit(condition); | 9510 safelyVisit(condition); |
| 8950 Expression thenExpression = node.thenExpression; | 9511 Expression thenExpression = node.thenExpression; |
| 8951 if (thenExpression != null) { | 9512 if (thenExpression != null) { |
| 8952 try { | 9513 try { |
| 8953 _overrideManager.enterScope(); | 9514 _overrideManager.enterScope(); |
| 8954 _promoteManager.enterScope(); | 9515 _promoteManager.enterScope(); |
| 8955 propagateTrueState(condition); | 9516 propagateTrueState(condition); |
| 9517 // Type promotion. |
| 8956 promoteTypes(condition); | 9518 promoteTypes(condition); |
| 8957 clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); | 9519 clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); |
| 8958 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenExpress
ion); | 9520 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenExpress
ion); |
| 9521 // Visit "then" expression. |
| 8959 thenExpression.accept(this); | 9522 thenExpression.accept(this); |
| 8960 } finally { | 9523 } finally { |
| 8961 _overrideManager.exitScope(); | 9524 _overrideManager.exitScope(); |
| 8962 _promoteManager.exitScope(); | 9525 _promoteManager.exitScope(); |
| 8963 } | 9526 } |
| 8964 } | 9527 } |
| 8965 Expression elseExpression = node.elseExpression; | 9528 Expression elseExpression = node.elseExpression; |
| 8966 if (elseExpression != null) { | 9529 if (elseExpression != null) { |
| 8967 try { | 9530 try { |
| 8968 _overrideManager.enterScope(); | 9531 _overrideManager.enterScope(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 8991 try { | 9554 try { |
| 8992 _enclosingFunction = node.element; | 9555 _enclosingFunction = node.element; |
| 8993 super.visitConstructorDeclaration(node); | 9556 super.visitConstructorDeclaration(node); |
| 8994 } finally { | 9557 } finally { |
| 8995 _enclosingFunction = outerFunction; | 9558 _enclosingFunction = outerFunction; |
| 8996 } | 9559 } |
| 8997 return null; | 9560 return null; |
| 8998 } | 9561 } |
| 8999 | 9562 |
| 9000 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 9563 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 9564 // |
| 9565 // We visit the expression, but do not visit the field name because it needs
to be visited in |
| 9566 // the context of the constructor field initializer node. |
| 9567 // |
| 9001 safelyVisit(node.expression); | 9568 safelyVisit(node.expression); |
| 9002 node.accept(_elementResolver); | 9569 node.accept(_elementResolver); |
| 9003 node.accept(_typeAnalyzer); | 9570 node.accept(_typeAnalyzer); |
| 9004 return null; | 9571 return null; |
| 9005 } | 9572 } |
| 9006 | 9573 |
| 9007 Object visitConstructorName(ConstructorName node) { | 9574 Object visitConstructorName(ConstructorName node) { |
| 9575 // |
| 9576 // We do not visit either the type name, because it won't be visited anyway,
or the name, |
| 9577 // because it needs to be visited in the context of the constructor name. |
| 9578 // |
| 9008 node.accept(_elementResolver); | 9579 node.accept(_elementResolver); |
| 9009 node.accept(_typeAnalyzer); | 9580 node.accept(_typeAnalyzer); |
| 9010 return null; | 9581 return null; |
| 9011 } | 9582 } |
| 9012 | 9583 |
| 9013 Object visitContinueStatement(ContinueStatement node) { | 9584 Object visitContinueStatement(ContinueStatement node) { |
| 9585 // |
| 9586 // We do not visit the label because it needs to be visited in the context o
f the statement. |
| 9587 // |
| 9014 node.accept(_elementResolver); | 9588 node.accept(_elementResolver); |
| 9015 node.accept(_typeAnalyzer); | 9589 node.accept(_typeAnalyzer); |
| 9016 return null; | 9590 return null; |
| 9017 } | 9591 } |
| 9018 | 9592 |
| 9019 Object visitDoStatement(DoStatement node) { | 9593 Object visitDoStatement(DoStatement node) { |
| 9020 try { | 9594 try { |
| 9021 _overrideManager.enterScope(); | 9595 _overrideManager.enterScope(); |
| 9022 super.visitDoStatement(node); | 9596 super.visitDoStatement(node); |
| 9023 } finally { | 9597 } finally { |
| 9024 _overrideManager.exitScope(); | 9598 _overrideManager.exitScope(); |
| 9025 } | 9599 } |
| 9600 // TODO(brianwilkerson) If the loop can only be exited because the condition
is false, then |
| 9601 // propagateFalseState(node.getCondition()); |
| 9026 return null; | 9602 return null; |
| 9027 } | 9603 } |
| 9028 | 9604 |
| 9029 Object visitEmptyFunctionBody(EmptyFunctionBody node) { | 9605 Object visitEmptyFunctionBody(EmptyFunctionBody node) { |
| 9030 safelyVisit(_commentBeforeFunction); | 9606 safelyVisit(_commentBeforeFunction); |
| 9031 return super.visitEmptyFunctionBody(node); | 9607 return super.visitEmptyFunctionBody(node); |
| 9032 } | 9608 } |
| 9033 | 9609 |
| 9034 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | 9610 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 9035 safelyVisit(_commentBeforeFunction); | 9611 safelyVisit(_commentBeforeFunction); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9113 Object visitIfStatement(IfStatement node) { | 9689 Object visitIfStatement(IfStatement node) { |
| 9114 Expression condition = node.condition; | 9690 Expression condition = node.condition; |
| 9115 safelyVisit(condition); | 9691 safelyVisit(condition); |
| 9116 Map<Element, Type2> thenOverrides = null; | 9692 Map<Element, Type2> thenOverrides = null; |
| 9117 Statement thenStatement = node.thenStatement; | 9693 Statement thenStatement = node.thenStatement; |
| 9118 if (thenStatement != null) { | 9694 if (thenStatement != null) { |
| 9119 try { | 9695 try { |
| 9120 _overrideManager.enterScope(); | 9696 _overrideManager.enterScope(); |
| 9121 _promoteManager.enterScope(); | 9697 _promoteManager.enterScope(); |
| 9122 propagateTrueState(condition); | 9698 propagateTrueState(condition); |
| 9699 // Type promotion. |
| 9123 promoteTypes(condition); | 9700 promoteTypes(condition); |
| 9124 clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); | 9701 clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); |
| 9125 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStateme
nt); | 9702 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStateme
nt); |
| 9703 // Visit "then". |
| 9126 visitStatementInScope(thenStatement); | 9704 visitStatementInScope(thenStatement); |
| 9127 } finally { | 9705 } finally { |
| 9128 thenOverrides = _overrideManager.captureLocalOverrides(); | 9706 thenOverrides = _overrideManager.captureLocalOverrides(); |
| 9129 _overrideManager.exitScope(); | 9707 _overrideManager.exitScope(); |
| 9130 _promoteManager.exitScope(); | 9708 _promoteManager.exitScope(); |
| 9131 } | 9709 } |
| 9132 } | 9710 } |
| 9133 Map<Element, Type2> elseOverrides = null; | 9711 Map<Element, Type2> elseOverrides = null; |
| 9134 Statement elseStatement = node.elseStatement; | 9712 Statement elseStatement = node.elseStatement; |
| 9135 if (elseStatement != null) { | 9713 if (elseStatement != null) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9169 try { | 9747 try { |
| 9170 _enclosingFunction = node.element; | 9748 _enclosingFunction = node.element; |
| 9171 super.visitMethodDeclaration(node); | 9749 super.visitMethodDeclaration(node); |
| 9172 } finally { | 9750 } finally { |
| 9173 _enclosingFunction = outerFunction; | 9751 _enclosingFunction = outerFunction; |
| 9174 } | 9752 } |
| 9175 return null; | 9753 return null; |
| 9176 } | 9754 } |
| 9177 | 9755 |
| 9178 Object visitMethodInvocation(MethodInvocation node) { | 9756 Object visitMethodInvocation(MethodInvocation node) { |
| 9757 // |
| 9758 // We visit the target and argument list, but do not visit the method name b
ecause it needs to |
| 9759 // be visited in the context of the invocation. |
| 9760 // |
| 9179 safelyVisit(node.target); | 9761 safelyVisit(node.target); |
| 9180 node.accept(_elementResolver); | 9762 node.accept(_elementResolver); |
| 9181 inferFunctionExpressionsParametersTypes(node.argumentList); | 9763 inferFunctionExpressionsParametersTypes(node.argumentList); |
| 9182 safelyVisit(node.argumentList); | 9764 safelyVisit(node.argumentList); |
| 9183 node.accept(_typeAnalyzer); | 9765 node.accept(_typeAnalyzer); |
| 9184 return null; | 9766 return null; |
| 9185 } | 9767 } |
| 9186 | 9768 |
| 9187 Object visitNode(ASTNode node) { | 9769 Object visitNode(ASTNode node) { |
| 9188 node.visitChildren(this); | 9770 node.visitChildren(this); |
| 9189 node.accept(_elementResolver); | 9771 node.accept(_elementResolver); |
| 9190 node.accept(_typeAnalyzer); | 9772 node.accept(_typeAnalyzer); |
| 9191 return null; | 9773 return null; |
| 9192 } | 9774 } |
| 9193 | 9775 |
| 9194 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 9776 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 9777 // |
| 9778 // We visit the prefix, but do not visit the identifier because it needs to
be visited in the |
| 9779 // context of the prefix. |
| 9780 // |
| 9195 safelyVisit(node.prefix); | 9781 safelyVisit(node.prefix); |
| 9196 node.accept(_elementResolver); | 9782 node.accept(_elementResolver); |
| 9197 node.accept(_typeAnalyzer); | 9783 node.accept(_typeAnalyzer); |
| 9198 return null; | 9784 return null; |
| 9199 } | 9785 } |
| 9200 | 9786 |
| 9201 Object visitPropertyAccess(PropertyAccess node) { | 9787 Object visitPropertyAccess(PropertyAccess node) { |
| 9788 // |
| 9789 // We visit the target, but do not visit the property name because it needs
to be visited in the |
| 9790 // context of the property access node. |
| 9791 // |
| 9202 safelyVisit(node.target); | 9792 safelyVisit(node.target); |
| 9203 node.accept(_elementResolver); | 9793 node.accept(_elementResolver); |
| 9204 node.accept(_typeAnalyzer); | 9794 node.accept(_typeAnalyzer); |
| 9205 return null; | 9795 return null; |
| 9206 } | 9796 } |
| 9207 | 9797 |
| 9208 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { | 9798 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { |
| 9799 // |
| 9800 // We visit the argument list, but do not visit the optional identifier beca
use it needs to be |
| 9801 // visited in the context of the constructor invocation. |
| 9802 // |
| 9209 safelyVisit(node.argumentList); | 9803 safelyVisit(node.argumentList); |
| 9210 node.accept(_elementResolver); | 9804 node.accept(_elementResolver); |
| 9211 node.accept(_typeAnalyzer); | 9805 node.accept(_typeAnalyzer); |
| 9212 return null; | 9806 return null; |
| 9213 } | 9807 } |
| 9214 | 9808 |
| 9215 Object visitShowCombinator(ShowCombinator node) => null; | 9809 Object visitShowCombinator(ShowCombinator node) => null; |
| 9216 | 9810 |
| 9217 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 9811 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 9812 // |
| 9813 // We visit the argument list, but do not visit the optional identifier beca
use it needs to be |
| 9814 // visited in the context of the constructor invocation. |
| 9815 // |
| 9218 safelyVisit(node.argumentList); | 9816 safelyVisit(node.argumentList); |
| 9219 node.accept(_elementResolver); | 9817 node.accept(_elementResolver); |
| 9220 node.accept(_typeAnalyzer); | 9818 node.accept(_typeAnalyzer); |
| 9221 return null; | 9819 return null; |
| 9222 } | 9820 } |
| 9223 | 9821 |
| 9224 Object visitSwitchCase(SwitchCase node) { | 9822 Object visitSwitchCase(SwitchCase node) { |
| 9225 try { | 9823 try { |
| 9226 _overrideManager.enterScope(); | 9824 _overrideManager.enterScope(); |
| 9227 super.visitSwitchCase(node); | 9825 super.visitSwitchCase(node); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9261 Statement body = node.body; | 9859 Statement body = node.body; |
| 9262 if (body != null) { | 9860 if (body != null) { |
| 9263 try { | 9861 try { |
| 9264 _overrideManager.enterScope(); | 9862 _overrideManager.enterScope(); |
| 9265 propagateTrueState(condition); | 9863 propagateTrueState(condition); |
| 9266 visitStatementInScope(body); | 9864 visitStatementInScope(body); |
| 9267 } finally { | 9865 } finally { |
| 9268 _overrideManager.exitScope(); | 9866 _overrideManager.exitScope(); |
| 9269 } | 9867 } |
| 9270 } | 9868 } |
| 9869 // TODO(brianwilkerson) If the loop can only be exited because the condition
is false, then |
| 9870 // propagateFalseState(condition); |
| 9271 node.accept(_elementResolver); | 9871 node.accept(_elementResolver); |
| 9272 node.accept(_typeAnalyzer); | 9872 node.accept(_typeAnalyzer); |
| 9273 return null; | 9873 return null; |
| 9274 } | 9874 } |
| 9275 | 9875 |
| 9276 /** | 9876 /** |
| 9277 * Return the class element representing the class containing the current node
, or `null` if | 9877 * Return the class element representing the class containing the current node
, or `null` if |
| 9278 * the current node is not contained in a class. | 9878 * the current node is not contained in a class. |
| 9279 * | 9879 * |
| 9280 * @return the class element representing the class containing the current nod
e | 9880 * @return the class element representing the class containing the current nod
e |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9437 * @param enclosingElement the enclosing element | 10037 * @param enclosingElement the enclosing element |
| 9438 * @param errorCode the error code of the error to be reported | 10038 * @param errorCode the error code of the error to be reported |
| 9439 * @param token the token specifying the location of the error | 10039 * @param token the token specifying the location of the error |
| 9440 * @param arguments the arguments to the error, used to compose the error mess
age | 10040 * @param arguments the arguments to the error, used to compose the error mess
age |
| 9441 */ | 10041 */ |
| 9442 void reportErrorProxyConditionalAnalysisError3(Element enclosingElement, Error
Code errorCode, sc.Token token, List<Object> arguments) { | 10042 void reportErrorProxyConditionalAnalysisError3(Element enclosingElement, Error
Code errorCode, sc.Token token, List<Object> arguments) { |
| 9443 _proxyConditionalAnalysisErrors.add(new ProxyConditionalAnalysisError(enclos
ingElement, new AnalysisError.con2(source, token.offset, token.length, errorCode
, arguments))); | 10043 _proxyConditionalAnalysisErrors.add(new ProxyConditionalAnalysisError(enclos
ingElement, new AnalysisError.con2(source, token.offset, token.length, errorCode
, arguments))); |
| 9444 } | 10044 } |
| 9445 | 10045 |
| 9446 void visitForEachStatementInScope(ForEachStatement node) { | 10046 void visitForEachStatementInScope(ForEachStatement node) { |
| 10047 // |
| 10048 // We visit the iterator before the loop variable because the loop variable
cannot be in scope |
| 10049 // while visiting the iterator. |
| 10050 // |
| 9447 Expression iterator = node.iterator; | 10051 Expression iterator = node.iterator; |
| 9448 safelyVisit(iterator); | 10052 safelyVisit(iterator); |
| 9449 DeclaredIdentifier loopVariable = node.loopVariable; | 10053 DeclaredIdentifier loopVariable = node.loopVariable; |
| 9450 SimpleIdentifier identifier = node.identifier; | 10054 SimpleIdentifier identifier = node.identifier; |
| 9451 safelyVisit(loopVariable); | 10055 safelyVisit(loopVariable); |
| 9452 safelyVisit(identifier); | 10056 safelyVisit(identifier); |
| 9453 Statement body = node.body; | 10057 Statement body = node.body; |
| 9454 if (body != null) { | 10058 if (body != null) { |
| 9455 try { | 10059 try { |
| 9456 _overrideManager.enterScope(); | 10060 _overrideManager.enterScope(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9549 * | 10153 * |
| 9550 * @param iterator the iterator for a for-each statement | 10154 * @param iterator the iterator for a for-each statement |
| 9551 * @return the type of objects that will be assigned to the loop variable | 10155 * @return the type of objects that will be assigned to the loop variable |
| 9552 */ | 10156 */ |
| 9553 Type2 getIteratorElementType(Expression iteratorExpression) { | 10157 Type2 getIteratorElementType(Expression iteratorExpression) { |
| 9554 Type2 expressionType = iteratorExpression.staticType; | 10158 Type2 expressionType = iteratorExpression.staticType; |
| 9555 if (expressionType is InterfaceType) { | 10159 if (expressionType is InterfaceType) { |
| 9556 InterfaceType interfaceType = expressionType; | 10160 InterfaceType interfaceType = expressionType; |
| 9557 FunctionType iteratorFunction = _inheritanceManager.lookupMemberType(inter
faceType, "iterator"); | 10161 FunctionType iteratorFunction = _inheritanceManager.lookupMemberType(inter
faceType, "iterator"); |
| 9558 if (iteratorFunction == null) { | 10162 if (iteratorFunction == null) { |
| 10163 // TODO(brianwilkerson) Should we report this error? |
| 9559 return null; | 10164 return null; |
| 9560 } | 10165 } |
| 9561 Type2 iteratorType = iteratorFunction.returnType; | 10166 Type2 iteratorType = iteratorFunction.returnType; |
| 9562 if (iteratorType is InterfaceType) { | 10167 if (iteratorType is InterfaceType) { |
| 9563 InterfaceType iteratorInterfaceType = iteratorType; | 10168 InterfaceType iteratorInterfaceType = iteratorType; |
| 9564 FunctionType currentFunction = _inheritanceManager.lookupMemberType(iter
atorInterfaceType, "current"); | 10169 FunctionType currentFunction = _inheritanceManager.lookupMemberType(iter
atorInterfaceType, "current"); |
| 9565 if (currentFunction == null) { | 10170 if (currentFunction == null) { |
| 10171 // TODO(brianwilkerson) Should we report this error? |
| 9566 return null; | 10172 return null; |
| 9567 } | 10173 } |
| 9568 return currentFunction.returnType; | 10174 return currentFunction.returnType; |
| 9569 } | 10175 } |
| 9570 } | 10176 } |
| 9571 return null; | 10177 return null; |
| 9572 } | 10178 } |
| 9573 | 10179 |
| 9574 /** | 10180 /** |
| 9575 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its | 10181 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its |
| 9576 * required type is [FunctionType], then infer parameters types from [Function
Type]. | 10182 * required type is [FunctionType], then infer parameters types from [Function
Type]. |
| 9577 */ | 10183 */ |
| 9578 void inferFunctionExpressionParametersTypes(Expression mayBeClosure, Type2 may
ByFunctionType) { | 10184 void inferFunctionExpressionParametersTypes(Expression mayBeClosure, Type2 may
ByFunctionType) { |
| 10185 // prepare closure |
| 9579 if (mayBeClosure is! FunctionExpression) { | 10186 if (mayBeClosure is! FunctionExpression) { |
| 9580 return; | 10187 return; |
| 9581 } | 10188 } |
| 9582 FunctionExpression closure = mayBeClosure as FunctionExpression; | 10189 FunctionExpression closure = mayBeClosure as FunctionExpression; |
| 10190 // prepare expected closure type |
| 9583 if (mayByFunctionType is! FunctionType) { | 10191 if (mayByFunctionType is! FunctionType) { |
| 9584 return; | 10192 return; |
| 9585 } | 10193 } |
| 9586 FunctionType expectedClosureType = mayByFunctionType as FunctionType; | 10194 FunctionType expectedClosureType = mayByFunctionType as FunctionType; |
| 10195 // set propagated type for the closure |
| 9587 closure.propagatedType = expectedClosureType; | 10196 closure.propagatedType = expectedClosureType; |
| 10197 // set inferred types for parameters |
| 9588 NodeList<FormalParameter> parameters = closure.parameters.parameters; | 10198 NodeList<FormalParameter> parameters = closure.parameters.parameters; |
| 9589 List<ParameterElement> expectedParameters = expectedClosureType.parameters; | 10199 List<ParameterElement> expectedParameters = expectedClosureType.parameters; |
| 9590 for (int i = 0; i < parameters.length && i < expectedParameters.length; i++)
{ | 10200 for (int i = 0; i < parameters.length && i < expectedParameters.length; i++)
{ |
| 9591 FormalParameter parameter = parameters[i]; | 10201 FormalParameter parameter = parameters[i]; |
| 9592 ParameterElement element = parameter.element; | 10202 ParameterElement element = parameter.element; |
| 9593 Type2 currentType = getBestType(element); | 10203 Type2 currentType = getBestType(element); |
| 10204 // may be override the type |
| 9594 Type2 expectedType = expectedParameters[i].type; | 10205 Type2 expectedType = expectedParameters[i].type; |
| 9595 if (currentType == null || expectedType.isMoreSpecificThan(currentType)) { | 10206 if (currentType == null || expectedType.isMoreSpecificThan(currentType)) { |
| 9596 _overrideManager.setType(element, expectedType); | 10207 _overrideManager.setType(element, expectedType); |
| 9597 } | 10208 } |
| 9598 } | 10209 } |
| 9599 } | 10210 } |
| 9600 | 10211 |
| 9601 /** | 10212 /** |
| 9602 * Try to infer types of parameters of the [FunctionExpression] arguments. | 10213 * Try to infer types of parameters of the [FunctionExpression] arguments. |
| 9603 */ | 10214 */ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9614 } | 10225 } |
| 9615 | 10226 |
| 9616 /** | 10227 /** |
| 9617 * Return `true` if the given expression terminates abruptly (that is, if any
expression | 10228 * Return `true` if the given expression terminates abruptly (that is, if any
expression |
| 9618 * following the given expression will not be reached). | 10229 * following the given expression will not be reached). |
| 9619 * | 10230 * |
| 9620 * @param expression the expression being tested | 10231 * @param expression the expression being tested |
| 9621 * @return `true` if the given expression terminates abruptly | 10232 * @return `true` if the given expression terminates abruptly |
| 9622 */ | 10233 */ |
| 9623 bool isAbruptTermination(Expression expression) { | 10234 bool isAbruptTermination(Expression expression) { |
| 10235 // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
would eventually |
| 10236 // turn this into a method on Expression that returns a termination indicati
on (normal, abrupt |
| 10237 // with no exception, abrupt with an exception). |
| 9624 while (expression is ParenthesizedExpression) { | 10238 while (expression is ParenthesizedExpression) { |
| 9625 expression = (expression as ParenthesizedExpression).expression; | 10239 expression = (expression as ParenthesizedExpression).expression; |
| 9626 } | 10240 } |
| 9627 return expression is ThrowExpression || expression is RethrowExpression; | 10241 return expression is ThrowExpression || expression is RethrowExpression; |
| 9628 } | 10242 } |
| 9629 | 10243 |
| 9630 /** | 10244 /** |
| 9631 * Return `true` if the given statement terminates abruptly (that is, if any s
tatement | 10245 * Return `true` if the given statement terminates abruptly (that is, if any s
tatement |
| 9632 * following the given statement will not be reached). | 10246 * following the given statement will not be reached). |
| 9633 * | 10247 * |
| 9634 * @param statement the statement being tested | 10248 * @param statement the statement being tested |
| 9635 * @return `true` if the given statement terminates abruptly | 10249 * @return `true` if the given statement terminates abruptly |
| 9636 */ | 10250 */ |
| 9637 bool isAbruptTermination2(Statement statement) { | 10251 bool isAbruptTermination2(Statement statement) { |
| 10252 // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
would eventually |
| 10253 // turn this into a method on Statement that returns a termination indicatio
n (normal, abrupt |
| 10254 // with no exception, abrupt with an exception). |
| 9638 if (statement is ReturnStatement || statement is BreakStatement || statement
is ContinueStatement) { | 10255 if (statement is ReturnStatement || statement is BreakStatement || statement
is ContinueStatement) { |
| 9639 return true; | 10256 return true; |
| 9640 } else if (statement is ExpressionStatement) { | 10257 } else if (statement is ExpressionStatement) { |
| 9641 return isAbruptTermination(statement.expression); | 10258 return isAbruptTermination(statement.expression); |
| 9642 } else if (statement is Block) { | 10259 } else if (statement is Block) { |
| 9643 NodeList<Statement> statements = statement.statements; | 10260 NodeList<Statement> statements = statement.statements; |
| 9644 int size = statements.length; | 10261 int size = statements.length; |
| 9645 if (size == 0) { | 10262 if (size == 0) { |
| 9646 return false; | 10263 return false; |
| 9647 } | 10264 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9684 * the given expression with the given type. Generally speaking, it is appropr
iate if the given | 10301 * the given expression with the given type. Generally speaking, it is appropr
iate if the given |
| 9685 * type is more specific than the current type. | 10302 * type is more specific than the current type. |
| 9686 * | 10303 * |
| 9687 * @param expression the expression used to access the static element whose ty
pes might be | 10304 * @param expression the expression used to access the static element whose ty
pes might be |
| 9688 * promoted | 10305 * promoted |
| 9689 * @param potentialType the potential type of the elements | 10306 * @param potentialType the potential type of the elements |
| 9690 */ | 10307 */ |
| 9691 void promote(Expression expression, Type2 potentialType) { | 10308 void promote(Expression expression, Type2 potentialType) { |
| 9692 VariableElement element = getPromotionStaticElement(expression); | 10309 VariableElement element = getPromotionStaticElement(expression); |
| 9693 if (element != null) { | 10310 if (element != null) { |
| 10311 // may be mutated somewhere in closure |
| 9694 if ((element as VariableElementImpl).isPotentiallyMutatedInClosure) { | 10312 if ((element as VariableElementImpl).isPotentiallyMutatedInClosure) { |
| 9695 return; | 10313 return; |
| 9696 } | 10314 } |
| 10315 // prepare current variable type |
| 9697 Type2 type = _promoteManager.getType(element); | 10316 Type2 type = _promoteManager.getType(element); |
| 9698 if (type == null) { | 10317 if (type == null) { |
| 9699 type = expression.staticType; | 10318 type = expression.staticType; |
| 9700 } | 10319 } |
| 10320 // Declared type should not be "dynamic". |
| 9701 if (type == null || type.isDynamic) { | 10321 if (type == null || type.isDynamic) { |
| 9702 return; | 10322 return; |
| 9703 } | 10323 } |
| 10324 // Promoted type should not be "dynamic". |
| 9704 if (potentialType == null || potentialType.isDynamic) { | 10325 if (potentialType == null || potentialType.isDynamic) { |
| 9705 return; | 10326 return; |
| 9706 } | 10327 } |
| 10328 // Promoted type should be more specific than declared. |
| 9707 if (!potentialType.isMoreSpecificThan(type)) { | 10329 if (!potentialType.isMoreSpecificThan(type)) { |
| 9708 return; | 10330 return; |
| 9709 } | 10331 } |
| 10332 // Do promote type of variable. |
| 9710 _promoteManager.setType(element, potentialType); | 10333 _promoteManager.setType(element, potentialType); |
| 9711 } | 10334 } |
| 9712 } | 10335 } |
| 9713 | 10336 |
| 9714 /** | 10337 /** |
| 9715 * Promotes type information using given condition. | 10338 * Promotes type information using given condition. |
| 9716 */ | 10339 */ |
| 9717 void promoteTypes(Expression condition) { | 10340 void promoteTypes(Expression condition) { |
| 9718 if (condition is BinaryExpression) { | 10341 if (condition is BinaryExpression) { |
| 9719 BinaryExpression binary = condition; | 10342 BinaryExpression binary = condition; |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10098 visitForEachStatementInScope(node); | 10721 visitForEachStatementInScope(node); |
| 10099 } finally { | 10722 } finally { |
| 10100 _labelScope = outerLabelScope; | 10723 _labelScope = outerLabelScope; |
| 10101 _nameScope = outerNameScope; | 10724 _nameScope = outerNameScope; |
| 10102 } | 10725 } |
| 10103 return null; | 10726 return null; |
| 10104 } | 10727 } |
| 10105 | 10728 |
| 10106 Object visitFormalParameterList(FormalParameterList node) { | 10729 Object visitFormalParameterList(FormalParameterList node) { |
| 10107 super.visitFormalParameterList(node); | 10730 super.visitFormalParameterList(node); |
| 10731 // We finished resolving function signature, now include formal parameters s
cope. |
| 10108 if (_nameScope is FunctionScope) { | 10732 if (_nameScope is FunctionScope) { |
| 10109 (_nameScope as FunctionScope).defineParameters(); | 10733 (_nameScope as FunctionScope).defineParameters(); |
| 10110 } | 10734 } |
| 10111 if (_nameScope is FunctionTypeScope) { | 10735 if (_nameScope is FunctionTypeScope) { |
| 10112 (_nameScope as FunctionTypeScope).defineParameters(); | 10736 (_nameScope as FunctionTypeScope).defineParameters(); |
| 10113 } | 10737 } |
| 10114 return null; | 10738 return null; |
| 10115 } | 10739 } |
| 10116 | 10740 |
| 10117 Object visitForStatement(ForStatement node) { | 10741 Object visitForStatement(ForStatement node) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 10138 _nameScope = outerScope; | 10762 _nameScope = outerScope; |
| 10139 } | 10763 } |
| 10140 if (function.enclosingElement is! CompilationUnitElement) { | 10764 if (function.enclosingElement is! CompilationUnitElement) { |
| 10141 _nameScope.define(function); | 10765 _nameScope.define(function); |
| 10142 } | 10766 } |
| 10143 return null; | 10767 return null; |
| 10144 } | 10768 } |
| 10145 | 10769 |
| 10146 Object visitFunctionExpression(FunctionExpression node) { | 10770 Object visitFunctionExpression(FunctionExpression node) { |
| 10147 if (node.parent is FunctionDeclaration) { | 10771 if (node.parent is FunctionDeclaration) { |
| 10772 // We have already created a function scope and don't need to do so again. |
| 10148 super.visitFunctionExpression(node); | 10773 super.visitFunctionExpression(node); |
| 10149 } else { | 10774 } else { |
| 10150 Scope outerScope = _nameScope; | 10775 Scope outerScope = _nameScope; |
| 10151 try { | 10776 try { |
| 10152 ExecutableElement functionElement = node.element; | 10777 ExecutableElement functionElement = node.element; |
| 10153 if (functionElement == null) { | 10778 if (functionElement == null) { |
| 10154 } else { | 10779 } else { |
| 10155 _nameScope = new FunctionScope(_nameScope, functionElement); | 10780 _nameScope = new FunctionScope(_nameScope, functionElement); |
| 10156 } | 10781 } |
| 10157 super.visitFunctionExpression(node); | 10782 super.visitFunctionExpression(node); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10325 } | 10950 } |
| 10326 | 10951 |
| 10327 /** | 10952 /** |
| 10328 * Visit the given statement after it's scope has been created. This replaces
the normal call to | 10953 * Visit the given statement after it's scope has been created. This replaces
the normal call to |
| 10329 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is | 10954 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is |
| 10330 * enabled. | 10955 * enabled. |
| 10331 * | 10956 * |
| 10332 * @param node the statement to be visited | 10957 * @param node the statement to be visited |
| 10333 */ | 10958 */ |
| 10334 void visitForEachStatementInScope(ForEachStatement node) { | 10959 void visitForEachStatementInScope(ForEachStatement node) { |
| 10960 // |
| 10961 // We visit the iterator before the loop variable because the loop variable
cannot be in scope |
| 10962 // while visiting the iterator. |
| 10963 // |
| 10335 safelyVisit(node.identifier); | 10964 safelyVisit(node.identifier); |
| 10336 safelyVisit(node.iterator); | 10965 safelyVisit(node.iterator); |
| 10337 safelyVisit(node.loopVariable); | 10966 safelyVisit(node.loopVariable); |
| 10338 visitStatementInScope(node.body); | 10967 visitStatementInScope(node.body); |
| 10339 } | 10968 } |
| 10340 | 10969 |
| 10341 /** | 10970 /** |
| 10342 * Visit the given statement after it's scope has been created. This replaces
the normal call to | 10971 * Visit the given statement after it's scope has been created. This replaces
the normal call to |
| 10343 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is | 10972 * the inherited visit method so that ResolverVisitor can intervene when type
propagation is |
| 10344 * enabled. | 10973 * enabled. |
| 10345 * | 10974 * |
| 10346 * @param node the statement to be visited | 10975 * @param node the statement to be visited |
| 10347 */ | 10976 */ |
| 10348 void visitForStatementInScope(ForStatement node) { | 10977 void visitForStatementInScope(ForStatement node) { |
| 10349 safelyVisit(node.variables); | 10978 safelyVisit(node.variables); |
| 10350 safelyVisit(node.initialization); | 10979 safelyVisit(node.initialization); |
| 10351 safelyVisit(node.condition); | 10980 safelyVisit(node.condition); |
| 10352 node.updaters.accept(this); | 10981 node.updaters.accept(this); |
| 10353 visitStatementInScope(node.body); | 10982 visitStatementInScope(node.body); |
| 10354 } | 10983 } |
| 10355 | 10984 |
| 10356 /** | 10985 /** |
| 10357 * Visit the given statement after it's scope has been created. This is used b
y ResolverVisitor to | 10986 * Visit the given statement after it's scope has been created. This is used b
y ResolverVisitor to |
| 10358 * correctly visit the 'then' and 'else' statements of an 'if' statement. | 10987 * correctly visit the 'then' and 'else' statements of an 'if' statement. |
| 10359 * | 10988 * |
| 10360 * @param node the statement to be visited | 10989 * @param node the statement to be visited |
| 10361 */ | 10990 */ |
| 10362 void visitStatementInScope(Statement node) { | 10991 void visitStatementInScope(Statement node) { |
| 10363 if (node is Block) { | 10992 if (node is Block) { |
| 10993 // Don't create a scope around a block because the block will create it's
own scope. |
| 10364 visitBlock(node); | 10994 visitBlock(node); |
| 10365 } else if (node != null) { | 10995 } else if (node != null) { |
| 10366 Scope outerNameScope = _nameScope; | 10996 Scope outerNameScope = _nameScope; |
| 10367 try { | 10997 try { |
| 10368 _nameScope = new EnclosedScope(_nameScope); | 10998 _nameScope = new EnclosedScope(_nameScope); |
| 10369 node.accept(this); | 10999 node.accept(this); |
| 10370 } finally { | 11000 } finally { |
| 10371 _nameScope = outerNameScope; | 11001 _nameScope = outerNameScope; |
| 10372 } | 11002 } |
| 10373 } | 11003 } |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10738 * | 11368 * |
| 10739 * It is a static type warning if the type of e<sub>1</sub> may not be assigne
d to `bool`. | 11369 * It is a static type warning if the type of e<sub>1</sub> may not be assigne
d to `bool`. |
| 10740 * | 11370 * |
| 10741 * The static type of <i>c</i> is the least upper bound of the static type of
<i>e<sub>2</sub></i> | 11371 * The static type of <i>c</i> is the least upper bound of the static type of
<i>e<sub>2</sub></i> |
| 10742 * and the static type of <i>e<sub>3</sub></i>.</blockquote> | 11372 * and the static type of <i>e<sub>3</sub></i>.</blockquote> |
| 10743 */ | 11373 */ |
| 10744 Object visitConditionalExpression(ConditionalExpression node) { | 11374 Object visitConditionalExpression(ConditionalExpression node) { |
| 10745 Type2 staticThenType = getStaticType(node.thenExpression); | 11375 Type2 staticThenType = getStaticType(node.thenExpression); |
| 10746 Type2 staticElseType = getStaticType(node.elseExpression); | 11376 Type2 staticElseType = getStaticType(node.elseExpression); |
| 10747 if (staticThenType == null) { | 11377 if (staticThenType == null) { |
| 11378 // TODO(brianwilkerson) Determine whether this can still happen. |
| 10748 staticThenType = _dynamicType; | 11379 staticThenType = _dynamicType; |
| 10749 } | 11380 } |
| 10750 if (staticElseType == null) { | 11381 if (staticElseType == null) { |
| 11382 // TODO(brianwilkerson) Determine whether this can still happen. |
| 10751 staticElseType = _dynamicType; | 11383 staticElseType = _dynamicType; |
| 10752 } | 11384 } |
| 10753 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType); | 11385 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType); |
| 10754 if (staticType == null) { | 11386 if (staticType == null) { |
| 10755 staticType = _dynamicType; | 11387 staticType = _dynamicType; |
| 10756 } | 11388 } |
| 10757 recordStaticType(node, staticType); | 11389 recordStaticType(node, staticType); |
| 10758 Type2 propagatedThenType = node.thenExpression.propagatedType; | 11390 Type2 propagatedThenType = node.thenExpression.propagatedType; |
| 10759 Type2 propagatedElseType = node.elseExpression.propagatedType; | 11391 Type2 propagatedElseType = node.elseExpression.propagatedType; |
| 10760 if (propagatedThenType != null || propagatedElseType != null) { | 11392 if (propagatedThenType != null || propagatedElseType != null) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10815 * | 11447 * |
| 10816 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1
</sub>, …, | 11448 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1
</sub>, …, |
| 10817 * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip
;, T<sub>n+k</sub> | 11449 * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip
;, T<sub>n+k</sub> |
| 10818 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, …, T<sub>n</sub
>, {T<sub>n+1</sub> | 11450 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, …, T<sub>n</sub
>, {T<sub>n+1</sub> |
| 10819 * x<sub>n+1</sub>, …, T<sub>n+k</sub> x<sub>n+k</sub>}) → dynamic
</i>. In any case | 11451 * x<sub>n+1</sub>, …, T<sub>n+k</sub> x<sub>n+k</sub>}) → dynamic
</i>. In any case |
| 10820 * where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not specified, it is cons
idered to have been | 11452 * where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not specified, it is cons
idered to have been |
| 10821 * specified as dynamic.</blockquote> | 11453 * specified as dynamic.</blockquote> |
| 10822 */ | 11454 */ |
| 10823 Object visitFunctionExpression(FunctionExpression node) { | 11455 Object visitFunctionExpression(FunctionExpression node) { |
| 10824 if (node.parent is FunctionDeclaration) { | 11456 if (node.parent is FunctionDeclaration) { |
| 11457 // The function type will be resolved and set when we visit the parent nod
e. |
| 10825 return null; | 11458 return null; |
| 10826 } | 11459 } |
| 10827 ExecutableElementImpl functionElement = node.element as ExecutableElementImp
l; | 11460 ExecutableElementImpl functionElement = node.element as ExecutableElementImp
l; |
| 10828 functionElement.returnType = computeStaticReturnType3(node); | 11461 functionElement.returnType = computeStaticReturnType3(node); |
| 10829 recordPropagatedType(functionElement, node.body); | 11462 recordPropagatedType(functionElement, node.body); |
| 10830 recordStaticType(node, node.element.type); | 11463 recordStaticType(node, node.element.type); |
| 10831 return null; | 11464 return null; |
| 10832 } | 11465 } |
| 10833 | 11466 |
| 10834 /** | 11467 /** |
| 10835 * The Dart Language Specification, 12.14.4: <blockquote>A function expression
invocation <i>i</i> | 11468 * The Dart Language Specification, 12.14.4: <blockquote>A function expression
invocation <i>i</i> |
| 10836 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub
>n+1</sub>: | 11469 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub
>n+1</sub>: |
| 10837 * a<sub>n+1</sub>, …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>
e<sub>f</sub></i> is | 11470 * a<sub>n+1</sub>, …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>
e<sub>f</sub></i> is |
| 10838 * an expression. | 11471 * an expression. |
| 10839 * | 11472 * |
| 10840 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub>
</i> may not be | 11473 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub>
</i> may not be |
| 10841 * assigned to a function type. | 11474 * assigned to a function type. |
| 10842 * | 11475 * |
| 10843 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic.
Otherwise the | 11476 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic.
Otherwise the |
| 10844 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot
e> | 11477 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot
e> |
| 10845 */ | 11478 */ |
| 10846 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 11479 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 10847 ExecutableElement staticMethodElement = node.staticElement; | 11480 ExecutableElement staticMethodElement = node.staticElement; |
| 11481 // Record static return type of the static element. |
| 10848 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); | 11482 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); |
| 10849 recordStaticType(node, staticStaticType); | 11483 recordStaticType(node, staticStaticType); |
| 11484 // Record propagated return type of the static element. |
| 10850 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); | 11485 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); |
| 10851 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 11486 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 10852 recordPropagatedType2(node, staticPropagatedType); | 11487 recordPropagatedType2(node, staticPropagatedType); |
| 10853 } | 11488 } |
| 10854 ExecutableElement propagatedMethodElement = node.propagatedElement; | 11489 ExecutableElement propagatedMethodElement = node.propagatedElement; |
| 10855 if (propagatedMethodElement != staticMethodElement) { | 11490 if (propagatedMethodElement != staticMethodElement) { |
| 11491 // Record static return type of the propagated element. |
| 10856 Type2 propagatedStaticType = computeStaticReturnType(propagatedMethodEleme
nt); | 11492 Type2 propagatedStaticType = computeStaticReturnType(propagatedMethodEleme
nt); |
| 10857 if (propagatedStaticType != null && (staticStaticType == null || propagate
dStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == nu
ll || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { | 11493 if (propagatedStaticType != null && (staticStaticType == null || propagate
dStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == nu
ll || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { |
| 10858 recordPropagatedType2(node, propagatedStaticType); | 11494 recordPropagatedType2(node, propagatedStaticType); |
| 10859 } | 11495 } |
| 11496 // Record propagated return type of the propagated element. |
| 10860 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedMet
hodElement); | 11497 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedMet
hodElement); |
| 10861 if (propagatedPropagatedType != null && (staticStaticType == null || propa
gatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedTy
pe == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType))
&& (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan
(propagatedStaticType))) { | 11498 if (propagatedPropagatedType != null && (staticStaticType == null || propa
gatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedTy
pe == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType))
&& (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan
(propagatedStaticType))) { |
| 10862 recordPropagatedType2(node, propagatedPropagatedType); | 11499 recordPropagatedType2(node, propagatedPropagatedType); |
| 10863 } | 11500 } |
| 10864 } | 11501 } |
| 10865 return null; | 11502 return null; |
| 10866 } | 11503 } |
| 10867 | 11504 |
| 10868 /** | 11505 /** |
| 10869 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio
n of the form | 11506 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio
n of the form |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11099 * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i
> may not be | 11736 * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i
> may not be |
| 11100 * assigned to a function type. | 11737 * assigned to a function type. |
| 11101 * | 11738 * |
| 11102 * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the st
atic type of | 11739 * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the st
atic type of |
| 11103 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared
return type of | 11740 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared
return type of |
| 11104 * <i>F</i>.</blockquote> | 11741 * <i>F</i>.</blockquote> |
| 11105 */ | 11742 */ |
| 11106 Object visitMethodInvocation(MethodInvocation node) { | 11743 Object visitMethodInvocation(MethodInvocation node) { |
| 11107 SimpleIdentifier methodNameNode = node.methodName; | 11744 SimpleIdentifier methodNameNode = node.methodName; |
| 11108 Element staticMethodElement = methodNameNode.staticElement; | 11745 Element staticMethodElement = methodNameNode.staticElement; |
| 11746 // Record types of the local variable invoked as a function. |
| 11109 if (staticMethodElement is LocalVariableElement) { | 11747 if (staticMethodElement is LocalVariableElement) { |
| 11110 LocalVariableElement variable = staticMethodElement; | 11748 LocalVariableElement variable = staticMethodElement; |
| 11111 Type2 staticType = variable.type; | 11749 Type2 staticType = variable.type; |
| 11112 recordStaticType(methodNameNode, staticType); | 11750 recordStaticType(methodNameNode, staticType); |
| 11113 Type2 propagatedType = _overrideManager.getType(variable); | 11751 Type2 propagatedType = _overrideManager.getType(variable); |
| 11114 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { | 11752 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { |
| 11115 recordPropagatedType2(methodNameNode, propagatedType); | 11753 recordPropagatedType2(methodNameNode, propagatedType); |
| 11116 } | 11754 } |
| 11117 } | 11755 } |
| 11756 // Record static return type of the static element. |
| 11118 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); | 11757 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); |
| 11119 recordStaticType(node, staticStaticType); | 11758 recordStaticType(node, staticStaticType); |
| 11759 // Record propagated return type of the static element. |
| 11120 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); | 11760 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); |
| 11121 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 11761 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 11122 recordPropagatedType2(node, staticPropagatedType); | 11762 recordPropagatedType2(node, staticPropagatedType); |
| 11123 } | 11763 } |
| 11124 String methodName = methodNameNode.name; | 11764 String methodName = methodNameNode.name; |
| 11765 // Future.then(closure) return type is: |
| 11766 // 1) the returned Future type, if the closure returns a Future; |
| 11767 // 2) Future<valueType>, if the closure returns a value. |
| 11125 if (methodName == "then") { | 11768 if (methodName == "then") { |
| 11126 Expression target = node.realTarget; | 11769 Expression target = node.realTarget; |
| 11127 Type2 targetType = target == null ? null : target.bestType; | 11770 Type2 targetType = target == null ? null : target.bestType; |
| 11128 if (isAsyncFutureType(targetType)) { | 11771 if (isAsyncFutureType(targetType)) { |
| 11129 NodeList<Expression> arguments = node.argumentList.arguments; | 11772 NodeList<Expression> arguments = node.argumentList.arguments; |
| 11130 if (arguments.length == 1) { | 11773 if (arguments.length == 1) { |
| 11774 // TODO(brianwilkerson) Handle the case where both arguments are provi
ded. |
| 11131 Expression closureArg = arguments[0]; | 11775 Expression closureArg = arguments[0]; |
| 11132 if (closureArg is FunctionExpression) { | 11776 if (closureArg is FunctionExpression) { |
| 11133 FunctionExpression closureExpr = closureArg; | 11777 FunctionExpression closureExpr = closureArg; |
| 11134 Type2 returnType = computePropagatedReturnType(closureExpr.element); | 11778 Type2 returnType = computePropagatedReturnType(closureExpr.element); |
| 11135 if (returnType != null) { | 11779 if (returnType != null) { |
| 11780 // prepare the type of the returned Future |
| 11136 InterfaceTypeImpl newFutureType; | 11781 InterfaceTypeImpl newFutureType; |
| 11137 if (isAsyncFutureType(returnType)) { | 11782 if (isAsyncFutureType(returnType)) { |
| 11138 newFutureType = returnType as InterfaceTypeImpl; | 11783 newFutureType = returnType as InterfaceTypeImpl; |
| 11139 } else { | 11784 } else { |
| 11140 InterfaceType futureType = targetType as InterfaceType; | 11785 InterfaceType futureType = targetType as InterfaceType; |
| 11141 newFutureType = new InterfaceTypeImpl.con1(futureType.element); | 11786 newFutureType = new InterfaceTypeImpl.con1(futureType.element); |
| 11142 newFutureType.typeArguments = <Type2> [returnType]; | 11787 newFutureType.typeArguments = <Type2> [returnType]; |
| 11143 } | 11788 } |
| 11789 // set the 'then' invocation type |
| 11144 recordPropagatedType2(node, newFutureType); | 11790 recordPropagatedType2(node, newFutureType); |
| 11145 return null; | 11791 return null; |
| 11146 } | 11792 } |
| 11147 } | 11793 } |
| 11148 } | 11794 } |
| 11149 } | 11795 } |
| 11150 } | 11796 } |
| 11151 if (methodName == "\$dom_createEvent") { | 11797 if (methodName == "\$dom_createEvent") { |
| 11152 Expression target = node.realTarget; | 11798 Expression target = node.realTarget; |
| 11153 if (target != null) { | 11799 if (target != null) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11200 } | 11846 } |
| 11201 } | 11847 } |
| 11202 } else if (methodName == "JS") { | 11848 } else if (methodName == "JS") { |
| 11203 Type2 returnType = getFirstArgumentAsType(_typeProvider.objectType.element
.library, node.argumentList); | 11849 Type2 returnType = getFirstArgumentAsType(_typeProvider.objectType.element
.library, node.argumentList); |
| 11204 if (returnType != null) { | 11850 if (returnType != null) { |
| 11205 recordPropagatedType2(node, returnType); | 11851 recordPropagatedType2(node, returnType); |
| 11206 } | 11852 } |
| 11207 } else { | 11853 } else { |
| 11208 Element propagatedElement = methodNameNode.propagatedElement; | 11854 Element propagatedElement = methodNameNode.propagatedElement; |
| 11209 if (propagatedElement != staticMethodElement) { | 11855 if (propagatedElement != staticMethodElement) { |
| 11856 // Record static return type of the propagated element. |
| 11210 Type2 propagatedStaticType = computeStaticReturnType(propagatedElement); | 11857 Type2 propagatedStaticType = computeStaticReturnType(propagatedElement); |
| 11211 if (propagatedStaticType != null && (staticStaticType == null || propaga
tedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType ==
null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { | 11858 if (propagatedStaticType != null && (staticStaticType == null || propaga
tedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType ==
null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { |
| 11212 recordPropagatedType2(node, propagatedStaticType); | 11859 recordPropagatedType2(node, propagatedStaticType); |
| 11213 } | 11860 } |
| 11861 // Record propagated return type of the propagated element. |
| 11214 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedE
lement); | 11862 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedE
lement); |
| 11215 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { | 11863 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { |
| 11216 recordPropagatedType2(node, propagatedPropagatedType); | 11864 recordPropagatedType2(node, propagatedPropagatedType); |
| 11217 } | 11865 } |
| 11218 } | 11866 } |
| 11219 } | 11867 } |
| 11220 return null; | 11868 return null; |
| 11221 } | 11869 } |
| 11222 | 11870 |
| 11223 Object visitNamedExpression(NamedExpression node) { | 11871 Object visitNamedExpression(NamedExpression node) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11351 /** | 11999 /** |
| 11352 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u
</i> of the form | 12000 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u
</i> of the form |
| 11353 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>.
An expression of the | 12001 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>.
An expression of the |
| 11354 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i
>.</blockquote> | 12002 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i
>.</blockquote> |
| 11355 */ | 12003 */ |
| 11356 Object visitPrefixExpression(PrefixExpression node) { | 12004 Object visitPrefixExpression(PrefixExpression node) { |
| 11357 sc.TokenType operator = node.operator.type; | 12005 sc.TokenType operator = node.operator.type; |
| 11358 if (identical(operator, sc.TokenType.BANG)) { | 12006 if (identical(operator, sc.TokenType.BANG)) { |
| 11359 recordStaticType(node, _typeProvider.boolType); | 12007 recordStaticType(node, _typeProvider.boolType); |
| 11360 } else { | 12008 } else { |
| 12009 // The other cases are equivalent to invoking a method. |
| 11361 ExecutableElement staticMethodElement = node.staticElement; | 12010 ExecutableElement staticMethodElement = node.staticElement; |
| 11362 Type2 staticType = computeStaticReturnType(staticMethodElement); | 12011 Type2 staticType = computeStaticReturnType(staticMethodElement); |
| 11363 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, s
c.TokenType.PLUS_PLUS)) { | 12012 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, s
c.TokenType.PLUS_PLUS)) { |
| 11364 Type2 intType = _typeProvider.intType; | 12013 Type2 intType = _typeProvider.intType; |
| 11365 if (identical(getStaticType(node.operand), intType)) { | 12014 if (identical(getStaticType(node.operand), intType)) { |
| 11366 staticType = intType; | 12015 staticType = intType; |
| 11367 } | 12016 } |
| 11368 } | 12017 } |
| 11369 recordStaticType(node, staticType); | 12018 recordStaticType(node, staticType); |
| 11370 MethodElement propagatedMethodElement = node.propagatedElement; | 12019 MethodElement propagatedMethodElement = node.propagatedElement; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11426 Element element = propertyName.staticElement; | 12075 Element element = propertyName.staticElement; |
| 11427 Type2 staticType = _dynamicType; | 12076 Type2 staticType = _dynamicType; |
| 11428 if (element is MethodElement) { | 12077 if (element is MethodElement) { |
| 11429 staticType = element.type; | 12078 staticType = element.type; |
| 11430 } else if (element is PropertyAccessorElement) { | 12079 } else if (element is PropertyAccessorElement) { |
| 11431 staticType = getType(element, node.target != null ? getStaticType(node.tar
get) : null); | 12080 staticType = getType(element, node.target != null ? getStaticType(node.tar
get) : null); |
| 11432 } else { | 12081 } else { |
| 11433 } | 12082 } |
| 11434 recordStaticType(propertyName, staticType); | 12083 recordStaticType(propertyName, staticType); |
| 11435 recordStaticType(node, staticType); | 12084 recordStaticType(node, staticType); |
| 12085 // TODO(brianwilkerson) I think we want to repeat the logic above using the
propagated element |
| 12086 // to get another candidate for the propagated type. |
| 11436 Type2 propagatedType = _overrideManager.getType(element); | 12087 Type2 propagatedType = _overrideManager.getType(element); |
| 11437 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ | 12088 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ |
| 11438 recordPropagatedType2(node, propagatedType); | 12089 recordPropagatedType2(node, propagatedType); |
| 11439 } | 12090 } |
| 11440 return null; | 12091 return null; |
| 11441 } | 12092 } |
| 11442 | 12093 |
| 11443 /** | 12094 /** |
| 11444 * The Dart Language Specification, 12.9: <blockquote>The static type of a ret
hrow expression is | 12095 * The Dart Language Specification, 12.9: <blockquote>The static type of a ret
hrow expression is |
| 11445 * bottom.</blockquote> | 12096 * bottom.</blockquote> |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11506 } else { | 12157 } else { |
| 11507 staticType = _typeProvider.typeType; | 12158 staticType = _typeProvider.typeType; |
| 11508 } | 12159 } |
| 11509 } else if (element is MethodElement) { | 12160 } else if (element is MethodElement) { |
| 11510 staticType = element.type; | 12161 staticType = element.type; |
| 11511 } else if (element is PropertyAccessorElement) { | 12162 } else if (element is PropertyAccessorElement) { |
| 11512 staticType = getType(element, null); | 12163 staticType = getType(element, null); |
| 11513 } else if (element is ExecutableElement) { | 12164 } else if (element is ExecutableElement) { |
| 11514 staticType = element.type; | 12165 staticType = element.type; |
| 11515 } else if (element is TypeParameterElement) { | 12166 } else if (element is TypeParameterElement) { |
| 12167 // if (isTypeName(node)) { |
| 11516 staticType = element.type; | 12168 staticType = element.type; |
| 11517 } else if (element is VariableElement) { | 12169 } else if (element is VariableElement) { |
| 11518 VariableElement variable = element; | 12170 VariableElement variable = element; |
| 11519 staticType = _promoteManager.getStaticType(variable); | 12171 staticType = _promoteManager.getStaticType(variable); |
| 11520 } else if (element is PrefixElement) { | 12172 } else if (element is PrefixElement) { |
| 11521 return null; | 12173 return null; |
| 11522 } else { | 12174 } else { |
| 11523 staticType = _dynamicType; | 12175 staticType = _dynamicType; |
| 11524 } | 12176 } |
| 11525 recordStaticType(node, staticType); | 12177 recordStaticType(node, staticType); |
| 12178 // TODO(brianwilkerson) I think we want to repeat the logic above using the
propagated element |
| 12179 // to get another candidate for the propagated type. |
| 11526 Type2 propagatedType = _overrideManager.getType(element); | 12180 Type2 propagatedType = _overrideManager.getType(element); |
| 11527 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ | 12181 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ |
| 11528 recordPropagatedType2(node, propagatedType); | 12182 recordPropagatedType2(node, propagatedType); |
| 11529 } | 12183 } |
| 11530 return null; | 12184 return null; |
| 11531 } | 12185 } |
| 11532 | 12186 |
| 11533 /** | 12187 /** |
| 11534 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is | 12188 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is |
| 11535 * `String`.</blockquote> | 12189 * `String`.</blockquote> |
| 11536 */ | 12190 */ |
| 11537 Object visitSimpleStringLiteral(SimpleStringLiteral node) { | 12191 Object visitSimpleStringLiteral(SimpleStringLiteral node) { |
| 11538 recordStaticType(node, _typeProvider.stringType); | 12192 recordStaticType(node, _typeProvider.stringType); |
| 11539 return null; | 12193 return null; |
| 11540 } | 12194 } |
| 11541 | 12195 |
| 11542 /** | 12196 /** |
| 11543 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is | 12197 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is |
| 11544 * `String`.</blockquote> | 12198 * `String`.</blockquote> |
| 11545 */ | 12199 */ |
| 11546 Object visitStringInterpolation(StringInterpolation node) { | 12200 Object visitStringInterpolation(StringInterpolation node) { |
| 11547 recordStaticType(node, _typeProvider.stringType); | 12201 recordStaticType(node, _typeProvider.stringType); |
| 11548 return null; | 12202 return null; |
| 11549 } | 12203 } |
| 11550 | 12204 |
| 11551 Object visitSuperExpression(SuperExpression node) { | 12205 Object visitSuperExpression(SuperExpression node) { |
| 11552 if (_thisType == null) { | 12206 if (_thisType == null) { |
| 12207 // TODO(brianwilkerson) Report this error if it hasn't already been report
ed |
| 11553 recordStaticType(node, _dynamicType); | 12208 recordStaticType(node, _dynamicType); |
| 11554 } else { | 12209 } else { |
| 11555 recordStaticType(node, _thisType); | 12210 recordStaticType(node, _thisType); |
| 11556 } | 12211 } |
| 11557 return null; | 12212 return null; |
| 11558 } | 12213 } |
| 11559 | 12214 |
| 11560 Object visitSymbolLiteral(SymbolLiteral node) { | 12215 Object visitSymbolLiteral(SymbolLiteral node) { |
| 11561 recordStaticType(node, _typeProvider.symbolType); | 12216 recordStaticType(node, _typeProvider.symbolType); |
| 11562 return null; | 12217 return null; |
| 11563 } | 12218 } |
| 11564 | 12219 |
| 11565 /** | 12220 /** |
| 11566 * The Dart Language Specification, 12.10: <blockquote>The static type of `thi
s` is the | 12221 * The Dart Language Specification, 12.10: <blockquote>The static type of `thi
s` is the |
| 11567 * interface of the immediately enclosing class.</blockquote> | 12222 * interface of the immediately enclosing class.</blockquote> |
| 11568 */ | 12223 */ |
| 11569 Object visitThisExpression(ThisExpression node) { | 12224 Object visitThisExpression(ThisExpression node) { |
| 11570 if (_thisType == null) { | 12225 if (_thisType == null) { |
| 12226 // TODO(brianwilkerson) Report this error if it hasn't already been report
ed |
| 11571 recordStaticType(node, _dynamicType); | 12227 recordStaticType(node, _dynamicType); |
| 11572 } else { | 12228 } else { |
| 11573 recordStaticType(node, _thisType); | 12229 recordStaticType(node, _thisType); |
| 11574 } | 12230 } |
| 11575 return null; | 12231 return null; |
| 11576 } | 12232 } |
| 11577 | 12233 |
| 11578 /** | 12234 /** |
| 11579 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr
ow expression is | 12235 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr
ow expression is |
| 11580 * bottom.</blockquote> | 12236 * bottom.</blockquote> |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11649 } | 12305 } |
| 11650 | 12306 |
| 11651 /** | 12307 /** |
| 11652 * Compute the static return type of the method or function represented by the
given element. | 12308 * Compute the static return type of the method or function represented by the
given element. |
| 11653 * | 12309 * |
| 11654 * @param element the element representing the method or function invoked by t
he given node | 12310 * @param element the element representing the method or function invoked by t
he given node |
| 11655 * @return the static return type that was computed | 12311 * @return the static return type that was computed |
| 11656 */ | 12312 */ |
| 11657 Type2 computeStaticReturnType(Element element) { | 12313 Type2 computeStaticReturnType(Element element) { |
| 11658 if (element is PropertyAccessorElement) { | 12314 if (element is PropertyAccessorElement) { |
| 12315 // |
| 12316 // This is a function invocation expression disguised as something else. W
e are invoking a |
| 12317 // getter and then invoking the returned function. |
| 12318 // |
| 11659 FunctionType propertyType = element.type; | 12319 FunctionType propertyType = element.type; |
| 11660 if (propertyType != null) { | 12320 if (propertyType != null) { |
| 11661 Type2 returnType = propertyType.returnType; | 12321 Type2 returnType = propertyType.returnType; |
| 11662 if (returnType.isDartCoreFunction) { | 12322 if (returnType.isDartCoreFunction) { |
| 11663 return _dynamicType; | 12323 return _dynamicType; |
| 11664 } else if (returnType is InterfaceType) { | 12324 } else if (returnType is InterfaceType) { |
| 11665 MethodElement callMethod = returnType.lookUpMethod(ElementResolver.CAL
L_METHOD_NAME, _resolver.definingLibrary); | 12325 MethodElement callMethod = returnType.lookUpMethod(ElementResolver.CAL
L_METHOD_NAME, _resolver.definingLibrary); |
| 11666 if (callMethod != null) { | 12326 if (callMethod != null) { |
| 11667 return callMethod.type.returnType; | 12327 return callMethod.type.returnType; |
| 11668 } | 12328 } |
| 11669 } else if (returnType is FunctionType) { | 12329 } else if (returnType is FunctionType) { |
| 11670 Type2 innerReturnType = returnType.returnType; | 12330 Type2 innerReturnType = returnType.returnType; |
| 11671 if (innerReturnType != null) { | 12331 if (innerReturnType != null) { |
| 11672 return innerReturnType; | 12332 return innerReturnType; |
| 11673 } | 12333 } |
| 11674 } | 12334 } |
| 11675 if (returnType != null) { | 12335 if (returnType != null) { |
| 11676 return returnType; | 12336 return returnType; |
| 11677 } | 12337 } |
| 11678 } | 12338 } |
| 11679 } else if (element is ExecutableElement) { | 12339 } else if (element is ExecutableElement) { |
| 11680 FunctionType type = element.type; | 12340 FunctionType type = element.type; |
| 11681 if (type != null) { | 12341 if (type != null) { |
| 12342 // TODO(brianwilkerson) Figure out the conditions under which the type i
s null. |
| 11682 return type.returnType; | 12343 return type.returnType; |
| 11683 } | 12344 } |
| 11684 } else if (element is VariableElement) { | 12345 } else if (element is VariableElement) { |
| 11685 VariableElement variable = element; | 12346 VariableElement variable = element; |
| 11686 Type2 variableType = _promoteManager.getStaticType(variable); | 12347 Type2 variableType = _promoteManager.getStaticType(variable); |
| 11687 if (variableType is FunctionType) { | 12348 if (variableType is FunctionType) { |
| 11688 return variableType.returnType; | 12349 return variableType.returnType; |
| 11689 } | 12350 } |
| 11690 } | 12351 } |
| 11691 return _dynamicType; | 12352 return _dynamicType; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11750 * string literal, then parse that argument as a query string and return the t
ype specified by the | 12411 * string literal, then parse that argument as a query string and return the t
ype specified by the |
| 11751 * argument. | 12412 * argument. |
| 11752 * | 12413 * |
| 11753 * @param library the library in which the specified type would be defined | 12414 * @param library the library in which the specified type would be defined |
| 11754 * @param argumentList the list of arguments from which a type is to be extrac
ted | 12415 * @param argumentList the list of arguments from which a type is to be extrac
ted |
| 11755 * @return the type specified by the first argument in the argument list | 12416 * @return the type specified by the first argument in the argument list |
| 11756 */ | 12417 */ |
| 11757 Type2 getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentLis
t) { | 12418 Type2 getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentLis
t) { |
| 11758 String argumentValue = getFirstArgumentAsString(argumentList); | 12419 String argumentValue = getFirstArgumentAsString(argumentList); |
| 11759 if (argumentValue != null) { | 12420 if (argumentValue != null) { |
| 12421 // |
| 12422 // If the query has spaces, full parsing is required because it might be: |
| 12423 // E[text='warning text'] |
| 12424 // |
| 11760 if (argumentValue.contains(" ")) { | 12425 if (argumentValue.contains(" ")) { |
| 11761 return null; | 12426 return null; |
| 11762 } | 12427 } |
| 12428 // |
| 12429 // Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/se
lector.html. |
| 12430 // |
| 11763 String tag = argumentValue; | 12431 String tag = argumentValue; |
| 11764 tag = StringUtilities.substringBefore(tag, ":"); | 12432 tag = StringUtilities.substringBefore(tag, ":"); |
| 11765 tag = StringUtilities.substringBefore(tag, "["); | 12433 tag = StringUtilities.substringBefore(tag, "["); |
| 11766 tag = StringUtilities.substringBefore(tag, "."); | 12434 tag = StringUtilities.substringBefore(tag, "."); |
| 11767 tag = StringUtilities.substringBefore(tag, "#"); | 12435 tag = StringUtilities.substringBefore(tag, "#"); |
| 11768 tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()]; | 12436 tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()]; |
| 11769 ClassElement returnType = library.getType(tag); | 12437 ClassElement returnType = library.getType(tag); |
| 11770 if (returnType != null) { | 12438 if (returnType != null) { |
| 11771 return returnType.type; | 12439 return returnType.type; |
| 11772 } | 12440 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11817 | 12485 |
| 11818 /** | 12486 /** |
| 11819 * Return the static type of the given expression. | 12487 * Return the static type of the given expression. |
| 11820 * | 12488 * |
| 11821 * @param expression the expression whose type is to be returned | 12489 * @param expression the expression whose type is to be returned |
| 11822 * @return the static type of the given expression | 12490 * @return the static type of the given expression |
| 11823 */ | 12491 */ |
| 11824 Type2 getStaticType(Expression expression) { | 12492 Type2 getStaticType(Expression expression) { |
| 11825 Type2 type = expression.staticType; | 12493 Type2 type = expression.staticType; |
| 11826 if (type == null) { | 12494 if (type == null) { |
| 12495 // TODO(brianwilkerson) Determine the conditions for which the static type
is null. |
| 11827 return _dynamicType; | 12496 return _dynamicType; |
| 11828 } | 12497 } |
| 11829 return type; | 12498 return type; |
| 11830 } | 12499 } |
| 11831 | 12500 |
| 11832 /** | 12501 /** |
| 11833 * Return the type that should be recorded for a node that resolved to the giv
en accessor. | 12502 * Return the type that should be recorded for a node that resolved to the giv
en accessor. |
| 11834 * | 12503 * |
| 11835 * @param accessor the accessor that the node resolved to | 12504 * @param accessor the accessor that the node resolved to |
| 11836 * @param context if the accessor element has context [by being the RHS of a | 12505 * @param context if the accessor element has context [by being the RHS of a |
| 11837 * [PrefixedIdentifier] or [PropertyAccess]], and the return type of
the | 12506 * [PrefixedIdentifier] or [PropertyAccess]], and the return type of
the |
| 11838 * accessor is a parameter type, then the type of the LHS can be used
to get more | 12507 * accessor is a parameter type, then the type of the LHS can be used
to get more |
| 11839 * specific type information | 12508 * specific type information |
| 11840 * @return the type that should be recorded for a node that resolved to the gi
ven accessor | 12509 * @return the type that should be recorded for a node that resolved to the gi
ven accessor |
| 11841 */ | 12510 */ |
| 11842 Type2 getType(PropertyAccessorElement accessor, Type2 context) { | 12511 Type2 getType(PropertyAccessorElement accessor, Type2 context) { |
| 11843 FunctionType functionType = accessor.type; | 12512 FunctionType functionType = accessor.type; |
| 11844 if (functionType == null) { | 12513 if (functionType == null) { |
| 12514 // TODO(brianwilkerson) Report this internal error. This happens when we a
re analyzing a |
| 12515 // reference to a property before we have analyzed the declaration of the
property or when |
| 12516 // the property does not have a defined type. |
| 11845 return _dynamicType; | 12517 return _dynamicType; |
| 11846 } | 12518 } |
| 11847 if (accessor.isSetter) { | 12519 if (accessor.isSetter) { |
| 11848 List<Type2> parameterTypes = functionType.normalParameterTypes; | 12520 List<Type2> parameterTypes = functionType.normalParameterTypes; |
| 11849 if (parameterTypes != null && parameterTypes.length > 0) { | 12521 if (parameterTypes != null && parameterTypes.length > 0) { |
| 11850 return parameterTypes[0]; | 12522 return parameterTypes[0]; |
| 11851 } | 12523 } |
| 11852 PropertyAccessorElement getter = accessor.variable.getter; | 12524 PropertyAccessorElement getter = accessor.variable.getter; |
| 11853 if (getter != null) { | 12525 if (getter != null) { |
| 11854 functionType = getter.type; | 12526 functionType = getter.type; |
| 11855 if (functionType != null) { | 12527 if (functionType != null) { |
| 11856 return functionType.returnType; | 12528 return functionType.returnType; |
| 11857 } | 12529 } |
| 11858 } | 12530 } |
| 11859 return _dynamicType; | 12531 return _dynamicType; |
| 11860 } | 12532 } |
| 11861 Type2 returnType = functionType.returnType; | 12533 Type2 returnType = functionType.returnType; |
| 11862 if (returnType is TypeParameterType && context is InterfaceType) { | 12534 if (returnType is TypeParameterType && context is InterfaceType) { |
| 12535 // if the return type is a TypeParameter, we try to use the context [that
the function is being |
| 12536 // called on] to get a more accurate returnType type |
| 11863 InterfaceType interfaceTypeContext = context; | 12537 InterfaceType interfaceTypeContext = context; |
| 12538 // Type[] argumentTypes = interfaceTypeContext.getTypeArguments(); |
| 11864 List<TypeParameterElement> typeParameterElements = interfaceTypeContext.el
ement != null ? interfaceTypeContext.element.typeParameters : null; | 12539 List<TypeParameterElement> typeParameterElements = interfaceTypeContext.el
ement != null ? interfaceTypeContext.element.typeParameters : null; |
| 11865 if (typeParameterElements != null) { | 12540 if (typeParameterElements != null) { |
| 11866 for (int i = 0; i < typeParameterElements.length; i++) { | 12541 for (int i = 0; i < typeParameterElements.length; i++) { |
| 11867 TypeParameterElement typeParameterElement = typeParameterElements[i]; | 12542 TypeParameterElement typeParameterElement = typeParameterElements[i]; |
| 11868 if (returnType.name == typeParameterElement.name) { | 12543 if (returnType.name == typeParameterElement.name) { |
| 11869 return interfaceTypeContext.typeArguments[i]; | 12544 return interfaceTypeContext.typeArguments[i]; |
| 11870 } | 12545 } |
| 11871 } | 12546 } |
| 11872 } | 12547 } |
| 11873 } | 12548 } |
| 11874 return returnType; | 12549 return returnType; |
| 11875 } | 12550 } |
| 11876 | 12551 |
| 11877 /** | 12552 /** |
| 11878 * Return the type represented by the given type name. | 12553 * Return the type represented by the given type name. |
| 11879 * | 12554 * |
| 11880 * @param typeName the type name representing the type to be returned | 12555 * @param typeName the type name representing the type to be returned |
| 11881 * @return the type represented by the type name | 12556 * @return the type represented by the type name |
| 11882 */ | 12557 */ |
| 11883 Type2 getType2(TypeName typeName) { | 12558 Type2 getType2(TypeName typeName) { |
| 11884 Type2 type = typeName.type; | 12559 Type2 type = typeName.type; |
| 11885 if (type == null) { | 12560 if (type == null) { |
| 12561 //TODO(brianwilkerson) Determine the conditions for which the type is null
. |
| 11886 return _dynamicType; | 12562 return _dynamicType; |
| 11887 } | 12563 } |
| 11888 return type; | 12564 return type; |
| 11889 } | 12565 } |
| 11890 | 12566 |
| 11891 /** | 12567 /** |
| 11892 * Return `true` if the given [Type] is the `Future` form the 'dart:async' | 12568 * Return `true` if the given [Type] is the `Future` form the 'dart:async' |
| 11893 * library. | 12569 * library. |
| 11894 */ | 12570 */ |
| 11895 bool isAsyncFutureType(Type2 type) => type is InterfaceType && type.name == "F
uture" && isAsyncLibrary(type.element.library); | 12571 bool isAsyncFutureType(Type2 type) => type is InterfaceType && type.name == "F
uture" && isAsyncLibrary(type.element.library); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11928 * @param functionElement the function element to record propagated return typ
e for | 12604 * @param functionElement the function element to record propagated return typ
e for |
| 11929 * @param body the boy of the function whose propagated return type is to be c
omputed | 12605 * @param body the boy of the function whose propagated return type is to be c
omputed |
| 11930 * @return the propagated return type that was computed, may be `null` if it i
s not more | 12606 * @return the propagated return type that was computed, may be `null` if it i
s not more |
| 11931 * specific than the static return type. | 12607 * specific than the static return type. |
| 11932 */ | 12608 */ |
| 11933 void recordPropagatedType(ExecutableElement functionElement, FunctionBody body
) { | 12609 void recordPropagatedType(ExecutableElement functionElement, FunctionBody body
) { |
| 11934 Type2 propagatedReturnType = computePropagatedReturnType2(body); | 12610 Type2 propagatedReturnType = computePropagatedReturnType2(body); |
| 11935 if (propagatedReturnType == null) { | 12611 if (propagatedReturnType == null) { |
| 11936 return; | 12612 return; |
| 11937 } | 12613 } |
| 12614 // Ignore 'bottom' type. |
| 11938 if (propagatedReturnType.isBottom) { | 12615 if (propagatedReturnType.isBottom) { |
| 11939 return; | 12616 return; |
| 11940 } | 12617 } |
| 12618 // Record only if we inferred more specific type. |
| 11941 Type2 staticReturnType = functionElement.returnType; | 12619 Type2 staticReturnType = functionElement.returnType; |
| 11942 if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) { | 12620 if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) { |
| 11943 return; | 12621 return; |
| 11944 } | 12622 } |
| 12623 // OK, do record. |
| 11945 _propagatedReturnTypes[functionElement] = propagatedReturnType; | 12624 _propagatedReturnTypes[functionElement] = propagatedReturnType; |
| 11946 } | 12625 } |
| 11947 | 12626 |
| 11948 /** | 12627 /** |
| 11949 * Record that the propagated type of the given node is the given type. | 12628 * Record that the propagated type of the given node is the given type. |
| 11950 * | 12629 * |
| 11951 * @param expression the node whose type is to be recorded | 12630 * @param expression the node whose type is to be recorded |
| 11952 * @param type the propagated type of the node | 12631 * @param type the propagated type of the node |
| 11953 */ | 12632 */ |
| 11954 void recordPropagatedType2(Expression expression, Type2 type) { | 12633 void recordPropagatedType2(Expression expression, Type2 type) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 11973 | 12652 |
| 11974 /** | 12653 /** |
| 11975 * Attempts to make a better guess for the static type of the given binary exp
ression. | 12654 * Attempts to make a better guess for the static type of the given binary exp
ression. |
| 11976 * | 12655 * |
| 11977 * @param node the binary expression to analyze | 12656 * @param node the binary expression to analyze |
| 11978 * @param staticType the static type of the expression as resolved | 12657 * @param staticType the static type of the expression as resolved |
| 11979 * @return the better type guess, or the same static type as given | 12658 * @return the better type guess, or the same static type as given |
| 11980 */ | 12659 */ |
| 11981 Type2 refineBinaryExpressionType(BinaryExpression node, Type2 staticType) { | 12660 Type2 refineBinaryExpressionType(BinaryExpression node, Type2 staticType) { |
| 11982 sc.TokenType operator = node.operator.type; | 12661 sc.TokenType operator = node.operator.type; |
| 12662 // bool |
| 11983 if (identical(operator, sc.TokenType.AMPERSAND_AMPERSAND) || identical(opera
tor, sc.TokenType.BAR_BAR) || identical(operator, sc.TokenType.EQ_EQ) || identic
al(operator, sc.TokenType.BANG_EQ)) { | 12663 if (identical(operator, sc.TokenType.AMPERSAND_AMPERSAND) || identical(opera
tor, sc.TokenType.BAR_BAR) || identical(operator, sc.TokenType.EQ_EQ) || identic
al(operator, sc.TokenType.BANG_EQ)) { |
| 11984 return _typeProvider.boolType; | 12664 return _typeProvider.boolType; |
| 11985 } | 12665 } |
| 11986 Type2 intType = _typeProvider.intType; | 12666 Type2 intType = _typeProvider.intType; |
| 11987 if (getStaticType(node.leftOperand) == intType) { | 12667 if (getStaticType(node.leftOperand) == intType) { |
| 12668 // int op double |
| 11988 if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.Toke
nType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator,
sc.TokenType.STAR)) { | 12669 if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.Toke
nType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator,
sc.TokenType.STAR)) { |
| 11989 Type2 doubleType = _typeProvider.doubleType; | 12670 Type2 doubleType = _typeProvider.doubleType; |
| 11990 if (getStaticType(node.rightOperand) == doubleType) { | 12671 if (getStaticType(node.rightOperand) == doubleType) { |
| 11991 return doubleType; | 12672 return doubleType; |
| 11992 } | 12673 } |
| 11993 } | 12674 } |
| 12675 // int op int |
| 11994 if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.Toke
nType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator,
sc.TokenType.STAR) || identical(operator, sc.TokenType.TILDE_SLASH)) { | 12676 if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.Toke
nType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator,
sc.TokenType.STAR) || identical(operator, sc.TokenType.TILDE_SLASH)) { |
| 11995 if (getStaticType(node.rightOperand) == intType) { | 12677 if (getStaticType(node.rightOperand) == intType) { |
| 11996 staticType = intType; | 12678 staticType = intType; |
| 11997 } | 12679 } |
| 11998 } | 12680 } |
| 11999 } | 12681 } |
| 12682 // default |
| 12000 return staticType; | 12683 return staticType; |
| 12001 } | 12684 } |
| 12002 | 12685 |
| 12003 get thisType_J2DAccessor => _thisType; | 12686 get thisType_J2DAccessor => _thisType; |
| 12004 | 12687 |
| 12005 set thisType_J2DAccessor(__v) => _thisType = __v; | 12688 set thisType_J2DAccessor(__v) => _thisType = __v; |
| 12006 } | 12689 } |
| 12007 | 12690 |
| 12008 class GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2 ext
ends GeneralizingASTVisitor<Object> { | 12691 class GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2 ext
ends GeneralizingASTVisitor<Object> { |
| 12009 List<Type2> result; | 12692 List<Type2> result; |
| 12010 | 12693 |
| 12011 GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2(this.re
sult) : super(); | 12694 GeneralizingASTVisitor_StaticTypeAnalyzer_computePropagatedReturnType2(this.re
sult) : super(); |
| 12012 | 12695 |
| 12013 Object visitExpression(Expression node) => null; | 12696 Object visitExpression(Expression node) => null; |
| 12014 | 12697 |
| 12015 Object visitReturnStatement(ReturnStatement node) { | 12698 Object visitReturnStatement(ReturnStatement node) { |
| 12699 // prepare this 'return' type |
| 12016 Type2 type; | 12700 Type2 type; |
| 12017 Expression expression = node.expression; | 12701 Expression expression = node.expression; |
| 12018 if (expression != null) { | 12702 if (expression != null) { |
| 12019 type = expression.bestType; | 12703 type = expression.bestType; |
| 12020 } else { | 12704 } else { |
| 12021 type = BottomTypeImpl.instance; | 12705 type = BottomTypeImpl.instance; |
| 12022 } | 12706 } |
| 12707 // merge types |
| 12023 if (result[0] == null) { | 12708 if (result[0] == null) { |
| 12024 result[0] = type; | 12709 result[0] = type; |
| 12025 } else { | 12710 } else { |
| 12026 result[0] = result[0].getLeastUpperBound(type); | 12711 result[0] = result[0].getLeastUpperBound(type); |
| 12027 } | 12712 } |
| 12028 return null; | 12713 return null; |
| 12029 } | 12714 } |
| 12030 } | 12715 } |
| 12031 | 12716 |
| 12032 /** | 12717 /** |
| (...skipping 12 matching lines...) Expand all Loading... |
| 12045 * libraries visited by this manager. | 12730 * libraries visited by this manager. |
| 12046 */ | 12731 */ |
| 12047 Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>(); | 12732 Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>(); |
| 12048 | 12733 |
| 12049 /** | 12734 /** |
| 12050 * Given some [ClassElement], return the set of all subtypes, and subtypes of
subtypes. | 12735 * Given some [ClassElement], return the set of all subtypes, and subtypes of
subtypes. |
| 12051 * | 12736 * |
| 12052 * @param classElement the class to recursively return the set of subtypes of | 12737 * @param classElement the class to recursively return the set of subtypes of |
| 12053 */ | 12738 */ |
| 12054 Set<ClassElement> computeAllSubtypes(ClassElement classElement) { | 12739 Set<ClassElement> computeAllSubtypes(ClassElement classElement) { |
| 12740 // Ensure that we have generated the subtype map for the library |
| 12055 computeSubtypesInLibrary(classElement.library); | 12741 computeSubtypesInLibrary(classElement.library); |
| 12742 // use the subtypeMap to compute the set of all subtypes and subtype's subty
pes |
| 12056 Set<ClassElement> allSubtypes = new Set<ClassElement>(); | 12743 Set<ClassElement> allSubtypes = new Set<ClassElement>(); |
| 12057 computeAllSubtypes2(classElement, new Set<ClassElement>(), allSubtypes); | 12744 computeAllSubtypes2(classElement, new Set<ClassElement>(), allSubtypes); |
| 12058 return allSubtypes; | 12745 return allSubtypes; |
| 12059 } | 12746 } |
| 12060 | 12747 |
| 12061 /** | 12748 /** |
| 12062 * Given some [LibraryElement], visit all of the types in the library, the pas
sed library, | 12749 * Given some [LibraryElement], visit all of the types in the library, the pas
sed library, |
| 12063 * and any imported libraries, will be in the [visitedLibraries] set. | 12750 * and any imported libraries, will be in the [visitedLibraries] set. |
| 12064 * | 12751 * |
| 12065 * @param libraryElement the library to visit, it it hasn't been visited alrea
dy | 12752 * @param libraryElement the library to visit, it it hasn't been visited alrea
dy |
| 12066 */ | 12753 */ |
| 12067 void ensureLibraryVisited(LibraryElement libraryElement) { | 12754 void ensureLibraryVisited(LibraryElement libraryElement) { |
| 12068 computeSubtypesInLibrary(libraryElement); | 12755 computeSubtypesInLibrary(libraryElement); |
| 12069 } | 12756 } |
| 12070 | 12757 |
| 12071 /** | 12758 /** |
| 12072 * Given some [ClassElement] and a [HashSet<ClassElement>], this method recurs
ively | 12759 * Given some [ClassElement] and a [HashSet<ClassElement>], this method recurs
ively |
| 12073 * adds all of the subtypes of the [ClassElement] to the passed array. | 12760 * adds all of the subtypes of the [ClassElement] to the passed array. |
| 12074 * | 12761 * |
| 12075 * @param classElement the type to compute the set of subtypes of | 12762 * @param classElement the type to compute the set of subtypes of |
| 12076 * @param visitedClasses the set of class elements that this method has alread
y recursively seen | 12763 * @param visitedClasses the set of class elements that this method has alread
y recursively seen |
| 12077 * @param allSubtypes the computed set of subtypes of the passed class element | 12764 * @param allSubtypes the computed set of subtypes of the passed class element |
| 12078 */ | 12765 */ |
| 12079 void computeAllSubtypes2(ClassElement classElement, Set<ClassElement> visitedC
lasses, Set<ClassElement> allSubtypes) { | 12766 void computeAllSubtypes2(ClassElement classElement, Set<ClassElement> visitedC
lasses, Set<ClassElement> allSubtypes) { |
| 12080 if (!visitedClasses.add(classElement)) { | 12767 if (!visitedClasses.add(classElement)) { |
| 12768 // if this class has already been called on this class element |
| 12081 return; | 12769 return; |
| 12082 } | 12770 } |
| 12083 Set<ClassElement> subtypes = _subtypeMap[classElement]; | 12771 Set<ClassElement> subtypes = _subtypeMap[classElement]; |
| 12084 if (subtypes == null) { | 12772 if (subtypes == null) { |
| 12085 return; | 12773 return; |
| 12086 } | 12774 } |
| 12087 for (ClassElement subtype in subtypes) { | 12775 for (ClassElement subtype in subtypes) { |
| 12088 computeAllSubtypes2(subtype, visitedClasses, allSubtypes); | 12776 computeAllSubtypes2(subtype, visitedClasses, allSubtypes); |
| 12089 } | 12777 } |
| 12090 allSubtypes.addAll(subtypes); | 12778 allSubtypes.addAll(subtypes); |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12873 * during resolution | 13561 * during resolution |
| 12874 */ | 13562 */ |
| 12875 TypeResolverVisitor.con3(LibraryElement definingLibrary, Source source, TypePr
ovider typeProvider, Scope nameScope, AnalysisErrorListener errorListener) : sup
er.con3(definingLibrary, source, typeProvider, nameScope, errorListener) { | 13563 TypeResolverVisitor.con3(LibraryElement definingLibrary, Source source, TypePr
ovider typeProvider, Scope nameScope, AnalysisErrorListener errorListener) : sup
er.con3(definingLibrary, source, typeProvider, nameScope, errorListener) { |
| 12876 _dynamicType = typeProvider.dynamicType; | 13564 _dynamicType = typeProvider.dynamicType; |
| 12877 } | 13565 } |
| 12878 | 13566 |
| 12879 Object visitCatchClause(CatchClause node) { | 13567 Object visitCatchClause(CatchClause node) { |
| 12880 super.visitCatchClause(node); | 13568 super.visitCatchClause(node); |
| 12881 SimpleIdentifier exception = node.exceptionParameter; | 13569 SimpleIdentifier exception = node.exceptionParameter; |
| 12882 if (exception != null) { | 13570 if (exception != null) { |
| 13571 // If an 'on' clause is provided the type of the exception parameter is th
e type in the 'on' |
| 13572 // clause. Otherwise, the type of the exception parameter is 'Object'. |
| 12883 TypeName exceptionTypeName = node.exceptionType; | 13573 TypeName exceptionTypeName = node.exceptionType; |
| 12884 Type2 exceptionType; | 13574 Type2 exceptionType; |
| 12885 if (exceptionTypeName == null) { | 13575 if (exceptionTypeName == null) { |
| 12886 exceptionType = typeProvider.dynamicType; | 13576 exceptionType = typeProvider.dynamicType; |
| 12887 } else { | 13577 } else { |
| 12888 exceptionType = getType3(exceptionTypeName); | 13578 exceptionType = getType3(exceptionTypeName); |
| 12889 } | 13579 } |
| 12890 recordType(exception, exceptionType); | 13580 recordType(exception, exceptionType); |
| 12891 Element element = exception.staticElement; | 13581 Element element = exception.staticElement; |
| 12892 if (element is VariableElementImpl) { | 13582 if (element is VariableElementImpl) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12963 } else { | 13653 } else { |
| 12964 declaredType = getType3(typeName); | 13654 declaredType = getType3(typeName); |
| 12965 } | 13655 } |
| 12966 LocalVariableElementImpl element = node.element as LocalVariableElementImpl; | 13656 LocalVariableElementImpl element = node.element as LocalVariableElementImpl; |
| 12967 element.type = declaredType; | 13657 element.type = declaredType; |
| 12968 return null; | 13658 return null; |
| 12969 } | 13659 } |
| 12970 | 13660 |
| 12971 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 13661 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 12972 super.visitDefaultFormalParameter(node); | 13662 super.visitDefaultFormalParameter(node); |
| 13663 // Expression defaultValue = node.getDefaultValue(); |
| 13664 // if (defaultValue != null) { |
| 13665 // Type valueType = getType(defaultValue); |
| 13666 // Type parameterType = getType(node.getParameter()); |
| 13667 // if (!valueType.isAssignableTo(parameterType)) { |
| 13668 // TODO(brianwilkerson) Determine whether this is really an error. I can't f
ind in the spec |
| 13669 // anything that says it is, but a side comment from Gilad states that it sh
ould be a static |
| 13670 // warning. |
| 13671 // resolver.reportError(ResolverErrorCode.?, defaultValue); |
| 13672 // } |
| 13673 // } |
| 12973 return null; | 13674 return null; |
| 12974 } | 13675 } |
| 12975 | 13676 |
| 12976 Object visitFieldFormalParameter(FieldFormalParameter node) { | 13677 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 12977 super.visitFieldFormalParameter(node); | 13678 super.visitFieldFormalParameter(node); |
| 12978 Element element = node.identifier.staticElement; | 13679 Element element = node.identifier.staticElement; |
| 12979 if (element is ParameterElementImpl) { | 13680 if (element is ParameterElementImpl) { |
| 12980 ParameterElementImpl parameter = element; | 13681 ParameterElementImpl parameter = element; |
| 12981 FormalParameterList parameterList = node.parameters; | 13682 FormalParameterList parameterList = node.parameters; |
| 12982 if (parameterList == null) { | 13683 if (parameterList == null) { |
| 12983 Type2 type; | 13684 Type2 type; |
| 12984 TypeName typeName = node.type; | 13685 TypeName typeName = node.type; |
| 12985 if (typeName == null) { | 13686 if (typeName == null) { |
| 13687 // TODO(brianwilkerson) Find the field's declaration and use it's type
. |
| 12986 type = _dynamicType; | 13688 type = _dynamicType; |
| 12987 } else { | 13689 } else { |
| 12988 type = getType3(typeName); | 13690 type = getType3(typeName); |
| 12989 } | 13691 } |
| 12990 parameter.type = type; | 13692 parameter.type = type; |
| 12991 } else { | 13693 } else { |
| 12992 setFunctionTypedParameterType(parameter, node.type, node.parameters); | 13694 setFunctionTypedParameterType(parameter, node.type, node.parameters); |
| 12993 } | 13695 } |
| 12994 } else { | 13696 } else { |
| 12995 } | 13697 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13072 _hasReferenceToSuper = true; | 13774 _hasReferenceToSuper = true; |
| 13073 return super.visitSuperExpression(node); | 13775 return super.visitSuperExpression(node); |
| 13074 } | 13776 } |
| 13075 | 13777 |
| 13076 Object visitTypeName(TypeName node) { | 13778 Object visitTypeName(TypeName node) { |
| 13077 super.visitTypeName(node); | 13779 super.visitTypeName(node); |
| 13078 Identifier typeName = node.name; | 13780 Identifier typeName = node.name; |
| 13079 TypeArgumentList argumentList = node.typeArguments; | 13781 TypeArgumentList argumentList = node.typeArguments; |
| 13080 Element element = nameScope.lookup(typeName, definingLibrary); | 13782 Element element = nameScope.lookup(typeName, definingLibrary); |
| 13081 if (element == null) { | 13783 if (element == null) { |
| 13784 // |
| 13785 // Check to see whether the type name is either 'dynamic' or 'void', neith
er of which are in |
| 13786 // the name scope and hence will not be found by normal means. |
| 13787 // |
| 13082 if (typeName.name == this._dynamicType.name) { | 13788 if (typeName.name == this._dynamicType.name) { |
| 13083 setElement(typeName, this._dynamicType.element); | 13789 setElement(typeName, this._dynamicType.element); |
| 13084 if (argumentList != null) { | 13790 if (argumentList != null) { |
| 13085 } | 13791 } |
| 13086 typeName.staticType = this._dynamicType; | 13792 typeName.staticType = this._dynamicType; |
| 13087 node.type = this._dynamicType; | 13793 node.type = this._dynamicType; |
| 13088 return null; | 13794 return null; |
| 13089 } | 13795 } |
| 13090 VoidTypeImpl voidType = VoidTypeImpl.instance; | 13796 VoidTypeImpl voidType = VoidTypeImpl.instance; |
| 13091 if (typeName.name == voidType.name) { | 13797 if (typeName.name == voidType.name) { |
| 13798 // There is no element for 'void'. |
| 13092 if (argumentList != null) { | 13799 if (argumentList != null) { |
| 13093 } | 13800 } |
| 13094 typeName.staticType = voidType; | 13801 typeName.staticType = voidType; |
| 13095 node.type = voidType; | 13802 node.type = voidType; |
| 13096 return null; | 13803 return null; |
| 13097 } | 13804 } |
| 13805 // |
| 13806 // If not, the look to see whether we might have created the wrong AST str
ucture for a |
| 13807 // constructor name. If so, fix the AST structure and then proceed. |
| 13808 // |
| 13098 ASTNode parent = node.parent; | 13809 ASTNode parent = node.parent; |
| 13099 if (typeName is PrefixedIdentifier && parent is ConstructorName && argumen
tList == null) { | 13810 if (typeName is PrefixedIdentifier && parent is ConstructorName && argumen
tList == null) { |
| 13100 ConstructorName name = parent; | 13811 ConstructorName name = parent; |
| 13101 if (name.name == null) { | 13812 if (name.name == null) { |
| 13102 PrefixedIdentifier prefixedIdentifier = typeName as PrefixedIdentifier
; | 13813 PrefixedIdentifier prefixedIdentifier = typeName as PrefixedIdentifier
; |
| 13103 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 13814 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
| 13104 element = nameScope.lookup(prefix, definingLibrary); | 13815 element = nameScope.lookup(prefix, definingLibrary); |
| 13105 if (element is PrefixElement) { | 13816 if (element is PrefixElement) { |
| 13106 if (parent.parent is InstanceCreationExpression && (parent.parent as
InstanceCreationExpression).isConst) { | 13817 if (parent.parent is InstanceCreationExpression && (parent.parent as
InstanceCreationExpression).isConst) { |
| 13818 // If, if this is a const expression, then generate a |
| 13819 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. |
| 13107 reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIde
ntifier.identifier, [prefixedIdentifier.identifier.name]); | 13820 reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefixedIde
ntifier.identifier, [prefixedIdentifier.identifier.name]); |
| 13108 } else { | 13821 } else { |
| 13822 // Else, if this expression is a new expression, report a NEW_WITH
_NON_TYPE warning. |
| 13109 reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifi
er.identifier, [prefixedIdentifier.identifier.name]); | 13823 reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedIdentifi
er.identifier, [prefixedIdentifier.identifier.name]); |
| 13110 } | 13824 } |
| 13111 setElement(prefix, element); | 13825 setElement(prefix, element); |
| 13112 return null; | 13826 return null; |
| 13113 } else if (element != null) { | 13827 } else if (element != null) { |
| 13828 // |
| 13829 // Rewrite the constructor name. The parser, when it sees a construc
tor named "a.b", |
| 13830 // cannot tell whether "a" is a prefix and "b" is a class name, or w
hether "a" is a |
| 13831 // class name and "b" is a constructor name. It arbitrarily chooses
the former, but |
| 13832 // in this case was wrong. |
| 13833 // |
| 13114 name.name = prefixedIdentifier.identifier; | 13834 name.name = prefixedIdentifier.identifier; |
| 13115 name.period = prefixedIdentifier.period; | 13835 name.period = prefixedIdentifier.period; |
| 13116 node.name = prefix; | 13836 node.name = prefix; |
| 13117 typeName = prefix; | 13837 typeName = prefix; |
| 13118 } | 13838 } |
| 13119 } | 13839 } |
| 13120 } | 13840 } |
| 13121 } | 13841 } |
| 13842 // check element |
| 13122 bool elementValid = element is! MultiplyDefinedElement; | 13843 bool elementValid = element is! MultiplyDefinedElement; |
| 13123 if (elementValid && element is! ClassElement && isTypeNameInInstanceCreation
Expression(node)) { | 13844 if (elementValid && element is! ClassElement && isTypeNameInInstanceCreation
Expression(node)) { |
| 13124 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName); | 13845 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName); |
| 13125 InstanceCreationExpression creation = node.parent.parent as InstanceCreati
onExpression; | 13846 InstanceCreationExpression creation = node.parent.parent as InstanceCreati
onExpression; |
| 13126 if (creation.isConst) { | 13847 if (creation.isConst) { |
| 13127 if (element == null) { | 13848 if (element == null) { |
| 13128 reportError7(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [ty
peName]); | 13849 reportError7(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [ty
peName]); |
| 13129 } else { | 13850 } else { |
| 13130 reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple,
[typeName]); | 13851 reportError7(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple,
[typeName]); |
| 13131 } | 13852 } |
| 13132 elementValid = false; | 13853 elementValid = false; |
| 13133 } else { | 13854 } else { |
| 13134 if (element != null) { | 13855 if (element != null) { |
| 13135 reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typ
eName]); | 13856 reportError7(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typ
eName]); |
| 13136 elementValid = false; | 13857 elementValid = false; |
| 13137 } | 13858 } |
| 13138 } | 13859 } |
| 13139 } | 13860 } |
| 13140 if (elementValid && element == null) { | 13861 if (elementValid && element == null) { |
| 13862 // We couldn't resolve the type name. |
| 13863 // TODO(jwren) Consider moving the check for CompileTimeErrorCode.BUILT_IN
_IDENTIFIER_AS_TYPE |
| 13864 // from the ErrorVerifier, so that we don't have two errors on a built in
identifier being |
| 13865 // used as a class name. See CompileTimeErrorCodeTest.test_builtInIdentifi
erAsType(). |
| 13141 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName); | 13866 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName); |
| 13142 RedirectingConstructorKind redirectingConstructorKind; | 13867 RedirectingConstructorKind redirectingConstructorKind; |
| 13143 if (isBuiltInIdentifier(node) && isTypeAnnotation(node)) { | 13868 if (isBuiltInIdentifier(node) && isTypeAnnotation(node)) { |
| 13144 reportError7(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typeName,
[typeName.name]); | 13869 reportError7(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typeName,
[typeName.name]); |
| 13145 } else if (typeNameSimple.name == "boolean") { | 13870 } else if (typeNameSimple.name == "boolean") { |
| 13146 reportError7(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple,
[]); | 13871 reportError7(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple,
[]); |
| 13147 } else if (isTypeNameInCatchClause(node)) { | 13872 } else if (isTypeNameInCatchClause(node)) { |
| 13148 reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [type
Name.name]); | 13873 reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [type
Name.name]); |
| 13149 } else if (isTypeNameInAsExpression(node)) { | 13874 } else if (isTypeNameInAsExpression(node)) { |
| 13150 reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.nam
e]); | 13875 reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.nam
e]); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13182 type = (element as TypeParameterElement).type; | 13907 type = (element as TypeParameterElement).type; |
| 13183 if (argumentList != null) { | 13908 if (argumentList != null) { |
| 13184 } | 13909 } |
| 13185 } else if (element is MultiplyDefinedElement) { | 13910 } else if (element is MultiplyDefinedElement) { |
| 13186 List<Element> elements = (element as MultiplyDefinedElement).conflictingEl
ements; | 13911 List<Element> elements = (element as MultiplyDefinedElement).conflictingEl
ements; |
| 13187 type = getType(elements); | 13912 type = getType(elements); |
| 13188 if (type != null) { | 13913 if (type != null) { |
| 13189 node.type = type; | 13914 node.type = type; |
| 13190 } | 13915 } |
| 13191 } else { | 13916 } else { |
| 13917 // The name does not represent a type. |
| 13192 RedirectingConstructorKind redirectingConstructorKind; | 13918 RedirectingConstructorKind redirectingConstructorKind; |
| 13193 if (isTypeNameInCatchClause(node)) { | 13919 if (isTypeNameInCatchClause(node)) { |
| 13194 reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [type
Name.name]); | 13920 reportError7(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName, [type
Name.name]); |
| 13195 } else if (isTypeNameInAsExpression(node)) { | 13921 } else if (isTypeNameInAsExpression(node)) { |
| 13196 reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.nam
e]); | 13922 reportError7(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.nam
e]); |
| 13197 } else if (isTypeNameInIsExpression(node)) { | 13923 } else if (isTypeNameInIsExpression(node)) { |
| 13198 reportError7(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.n
ame]); | 13924 reportError7(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [typeName.n
ame]); |
| 13199 } else if ((redirectingConstructorKind = getRedirectingConstructorKind(nod
e)) != null) { | 13925 } else if ((redirectingConstructorKind = getRedirectingConstructorKind(nod
e)) != null) { |
| 13200 ErrorCode errorCode = (identical(redirectingConstructorKind, Redirecting
ConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarn
ingCode.REDIRECT_TO_NON_CLASS) as ErrorCode; | 13926 ErrorCode errorCode = (identical(redirectingConstructorKind, Redirecting
ConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarn
ingCode.REDIRECT_TO_NON_CLASS) as ErrorCode; |
| 13201 reportError7(errorCode, typeName, [typeName.name]); | 13927 reportError7(errorCode, typeName, [typeName.name]); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 13227 Type2 argumentType = getType3(arguments[i]); | 13953 Type2 argumentType = getType3(arguments[i]); |
| 13228 if (argumentType != null) { | 13954 if (argumentType != null) { |
| 13229 typeArguments.add(argumentType); | 13955 typeArguments.add(argumentType); |
| 13230 } | 13956 } |
| 13231 } | 13957 } |
| 13232 if (argumentCount != parameterCount) { | 13958 if (argumentCount != parameterCount) { |
| 13233 reportError7(getInvalidTypeParametersErrorCode(node), node, [typeName.na
me, parameterCount, argumentCount]); | 13959 reportError7(getInvalidTypeParametersErrorCode(node), node, [typeName.na
me, parameterCount, argumentCount]); |
| 13234 } | 13960 } |
| 13235 argumentCount = typeArguments.length; | 13961 argumentCount = typeArguments.length; |
| 13236 if (argumentCount < parameterCount) { | 13962 if (argumentCount < parameterCount) { |
| 13963 // |
| 13964 // If there were too many arguments, we already handled it by not adding
the values of the |
| 13965 // extra arguments to the list. If there are too few, we handle it by ad
ding 'dynamic' |
| 13966 // enough times to make the count equal. |
| 13967 // |
| 13237 for (int i = argumentCount; i < parameterCount; i++) { | 13968 for (int i = argumentCount; i < parameterCount; i++) { |
| 13238 typeArguments.add(this._dynamicType); | 13969 typeArguments.add(this._dynamicType); |
| 13239 } | 13970 } |
| 13240 } | 13971 } |
| 13241 if (type is InterfaceTypeImpl) { | 13972 if (type is InterfaceTypeImpl) { |
| 13242 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl; | 13973 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl; |
| 13243 type = interfaceType.substitute4(new List.from(typeArguments)); | 13974 type = interfaceType.substitute4(new List.from(typeArguments)); |
| 13244 } else if (type is FunctionTypeImpl) { | 13975 } else if (type is FunctionTypeImpl) { |
| 13245 FunctionTypeImpl functionType = type as FunctionTypeImpl; | 13976 FunctionTypeImpl functionType = type as FunctionTypeImpl; |
| 13246 type = functionType.substitute3(new List.from(typeArguments)); | 13977 type = functionType.substitute3(new List.from(typeArguments)); |
| 13247 } else { | 13978 } else { |
| 13248 } | 13979 } |
| 13249 } else { | 13980 } else { |
| 13981 // |
| 13982 // Check for the case where there are no type arguments given for a parame
terized type. |
| 13983 // |
| 13250 List<Type2> parameters = getTypeArguments(type); | 13984 List<Type2> parameters = getTypeArguments(type); |
| 13251 int parameterCount = parameters.length; | 13985 int parameterCount = parameters.length; |
| 13252 if (parameterCount > 0) { | 13986 if (parameterCount > 0) { |
| 13253 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; | 13987 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; |
| 13254 List<Type2> arguments = new List<Type2>(parameterCount); | 13988 List<Type2> arguments = new List<Type2>(parameterCount); |
| 13255 for (int i = 0; i < parameterCount; i++) { | 13989 for (int i = 0; i < parameterCount; i++) { |
| 13256 arguments[i] = dynamicType; | 13990 arguments[i] = dynamicType; |
| 13257 } | 13991 } |
| 13258 type = type.substitute2(arguments, parameters); | 13992 type = type.substitute2(arguments, parameters); |
| 13259 } | 13993 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13319 } | 14053 } |
| 13320 } | 14054 } |
| 13321 | 14055 |
| 13322 /** | 14056 /** |
| 13323 * Return the class element that represents the class whose name was provided. | 14057 * Return the class element that represents the class whose name was provided. |
| 13324 * | 14058 * |
| 13325 * @param identifier the name from the declaration of a class | 14059 * @param identifier the name from the declaration of a class |
| 13326 * @return the class element that represents the class | 14060 * @return the class element that represents the class |
| 13327 */ | 14061 */ |
| 13328 ClassElementImpl getClassElement(SimpleIdentifier identifier) { | 14062 ClassElementImpl getClassElement(SimpleIdentifier identifier) { |
| 14063 // TODO(brianwilkerson) Seems like we should be using ClassDeclaration.getEl
ement(). |
| 13329 if (identifier == null) { | 14064 if (identifier == null) { |
| 14065 // TODO(brianwilkerson) Report this |
| 14066 // Internal error: We should never build a class declaration without a nam
e. |
| 13330 return null; | 14067 return null; |
| 13331 } | 14068 } |
| 13332 Element element = identifier.staticElement; | 14069 Element element = identifier.staticElement; |
| 13333 if (element is! ClassElementImpl) { | 14070 if (element is! ClassElementImpl) { |
| 14071 // TODO(brianwilkerson) Report this |
| 14072 // Internal error: Failed to create an element for a class declaration. |
| 13334 return null; | 14073 return null; |
| 13335 } | 14074 } |
| 13336 return element as ClassElementImpl; | 14075 return element as ClassElementImpl; |
| 13337 } | 14076 } |
| 13338 | 14077 |
| 13339 /** | 14078 /** |
| 13340 * Return an array containing all of the elements associated with the paramete
rs in the given | 14079 * Return an array containing all of the elements associated with the paramete
rs in the given |
| 13341 * list. | 14080 * list. |
| 13342 * | 14081 * |
| 13343 * @param parameterList the list of parameters whose elements are to be return
ed | 14082 * @param parameterList the list of parameters whose elements are to be return
ed |
| 13344 * @return the elements associated with the parameters | 14083 * @return the elements associated with the parameters |
| 13345 */ | 14084 */ |
| 13346 List<ParameterElement> getElements(FormalParameterList parameterList) { | 14085 List<ParameterElement> getElements(FormalParameterList parameterList) { |
| 13347 List<ParameterElement> elements = new List<ParameterElement>(); | 14086 List<ParameterElement> elements = new List<ParameterElement>(); |
| 13348 for (FormalParameter parameter in parameterList.parameters) { | 14087 for (FormalParameter parameter in parameterList.parameters) { |
| 13349 ParameterElement element = parameter.identifier.staticElement as Parameter
Element; | 14088 ParameterElement element = parameter.identifier.staticElement as Parameter
Element; |
| 14089 // TODO(brianwilkerson) Understand why the element would be null. |
| 13350 if (element != null) { | 14090 if (element != null) { |
| 13351 elements.add(element); | 14091 elements.add(element); |
| 13352 } | 14092 } |
| 13353 } | 14093 } |
| 13354 return new List.from(elements); | 14094 return new List.from(elements); |
| 13355 } | 14095 } |
| 13356 | 14096 |
| 13357 /** | 14097 /** |
| 13358 * The number of type arguments in the given type name does not match the numb
er of parameters in | 14098 * The number of type arguments in the given type name does not match the numb
er of parameters in |
| 13359 * the corresponding class element. Return the error code that should be used
to report this | 14099 * the corresponding class element. Return the error code that should be used
to report this |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13565 if (classElement != null) { | 14305 if (classElement != null) { |
| 13566 classElement.mixins = mixinTypes; | 14306 classElement.mixins = mixinTypes; |
| 13567 } | 14307 } |
| 13568 } | 14308 } |
| 13569 if (implementsClause != null) { | 14309 if (implementsClause != null) { |
| 13570 NodeList<TypeName> interfaces = implementsClause.interfaces; | 14310 NodeList<TypeName> interfaces = implementsClause.interfaces; |
| 13571 List<InterfaceType> interfaceTypes = resolveTypes(interfaces, CompileTimeE
rrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_DYNAMIC); | 14311 List<InterfaceType> interfaceTypes = resolveTypes(interfaces, CompileTimeE
rrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_DYNAMIC); |
| 13572 if (classElement != null) { | 14312 if (classElement != null) { |
| 13573 classElement.interfaces = interfaceTypes; | 14313 classElement.interfaces = interfaceTypes; |
| 13574 } | 14314 } |
| 14315 // TODO(brianwilkerson) Move the following checks to ErrorVerifier. |
| 13575 List<TypeName> typeNames = new List.from(interfaces); | 14316 List<TypeName> typeNames = new List.from(interfaces); |
| 13576 List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length,
false); | 14317 List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length,
false); |
| 13577 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { | 14318 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { |
| 13578 detectedRepeatOnIndex[i] = false; | 14319 detectedRepeatOnIndex[i] = false; |
| 13579 } | 14320 } |
| 13580 for (int i = 0; i < typeNames.length; i++) { | 14321 for (int i = 0; i < typeNames.length; i++) { |
| 13581 TypeName typeName = typeNames[i]; | 14322 TypeName typeName = typeNames[i]; |
| 13582 if (!detectedRepeatOnIndex[i]) { | 14323 if (!detectedRepeatOnIndex[i]) { |
| 13583 Element element = typeName.name.staticElement; | 14324 Element element = typeName.name.staticElement; |
| 13584 for (int j = i + 1; j < typeNames.length; j++) { | 14325 for (int j = i + 1; j < typeNames.length; j++) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 13603 * @param nonTypeError the error to produce if the type name is defined to be
something other than | 14344 * @param nonTypeError the error to produce if the type name is defined to be
something other than |
| 13604 * a type | 14345 * a type |
| 13605 * @param dynamicTypeError the error to produce if the type name is "dynamic" | 14346 * @param dynamicTypeError the error to produce if the type name is "dynamic" |
| 13606 * @return the type specified by the type name | 14347 * @return the type specified by the type name |
| 13607 */ | 14348 */ |
| 13608 InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCode
dynamicTypeError) { | 14349 InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCode
dynamicTypeError) { |
| 13609 Type2 type = typeName.type; | 14350 Type2 type = typeName.type; |
| 13610 if (type is InterfaceType) { | 14351 if (type is InterfaceType) { |
| 13611 return type; | 14352 return type; |
| 13612 } | 14353 } |
| 14354 // If the type is not an InterfaceType, then visitTypeName() sets the type t
o be a DynamicTypeImpl |
| 13613 Identifier name = typeName.name; | 14355 Identifier name = typeName.name; |
| 13614 if (name.name == sc.Keyword.DYNAMIC.syntax) { | 14356 if (name.name == sc.Keyword.DYNAMIC.syntax) { |
| 13615 reportError7(dynamicTypeError, name, [name.name]); | 14357 reportError7(dynamicTypeError, name, [name.name]); |
| 13616 } else { | 14358 } else { |
| 13617 reportError7(nonTypeError, name, [name.name]); | 14359 reportError7(nonTypeError, name, [name.name]); |
| 13618 } | 14360 } |
| 13619 return null; | 14361 return null; |
| 13620 } | 14362 } |
| 13621 | 14363 |
| 13622 /** | 14364 /** |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13755 return super.visitFunctionExpression(node); | 14497 return super.visitFunctionExpression(node); |
| 13756 } finally { | 14498 } finally { |
| 13757 _enclosingFunction = outerFunction; | 14499 _enclosingFunction = outerFunction; |
| 13758 } | 14500 } |
| 13759 } else { | 14501 } else { |
| 13760 return super.visitFunctionExpression(node); | 14502 return super.visitFunctionExpression(node); |
| 13761 } | 14503 } |
| 13762 } | 14504 } |
| 13763 | 14505 |
| 13764 Object visitSimpleIdentifier(SimpleIdentifier node) { | 14506 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 14507 // Ignore if already resolved - declaration or type. |
| 13765 if (node.staticElement != null) { | 14508 if (node.staticElement != null) { |
| 13766 return null; | 14509 return null; |
| 13767 } | 14510 } |
| 14511 // Ignore if qualified. |
| 13768 ASTNode parent = node.parent; | 14512 ASTNode parent = node.parent; |
| 13769 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { | 14513 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { |
| 13770 return null; | 14514 return null; |
| 13771 } | 14515 } |
| 13772 if (parent is PropertyAccess && identical(parent.propertyName, node)) { | 14516 if (parent is PropertyAccess && identical(parent.propertyName, node)) { |
| 13773 return null; | 14517 return null; |
| 13774 } | 14518 } |
| 13775 if (parent is MethodInvocation && identical(parent.methodName, node)) { | 14519 if (parent is MethodInvocation && identical(parent.methodName, node)) { |
| 13776 return null; | 14520 return null; |
| 13777 } | 14521 } |
| 13778 if (parent is ConstructorName) { | 14522 if (parent is ConstructorName) { |
| 13779 return null; | 14523 return null; |
| 13780 } | 14524 } |
| 13781 if (parent is Label) { | 14525 if (parent is Label) { |
| 13782 return null; | 14526 return null; |
| 13783 } | 14527 } |
| 14528 // Prepare VariableElement. |
| 13784 Element element = nameScope.lookup(node, definingLibrary); | 14529 Element element = nameScope.lookup(node, definingLibrary); |
| 13785 if (element is! VariableElement) { | 14530 if (element is! VariableElement) { |
| 13786 return null; | 14531 return null; |
| 13787 } | 14532 } |
| 14533 // Must be local or parameter. |
| 13788 ElementKind kind = element.kind; | 14534 ElementKind kind = element.kind; |
| 13789 if (identical(kind, ElementKind.LOCAL_VARIABLE)) { | 14535 if (identical(kind, ElementKind.LOCAL_VARIABLE)) { |
| 13790 node.staticElement = element; | 14536 node.staticElement = element; |
| 13791 if (node.inSetterContext()) { | 14537 if (node.inSetterContext()) { |
| 13792 LocalVariableElementImpl variableImpl = element as LocalVariableElementI
mpl; | 14538 LocalVariableElementImpl variableImpl = element as LocalVariableElementI
mpl; |
| 13793 variableImpl.markPotentiallyMutatedInScope(); | 14539 variableImpl.markPotentiallyMutatedInScope(); |
| 13794 if (element.enclosingElement != _enclosingFunction) { | 14540 if (element.enclosingElement != _enclosingFunction) { |
| 13795 variableImpl.markPotentiallyMutatedInClosure(); | 14541 variableImpl.markPotentiallyMutatedInClosure(); |
| 13796 } | 14542 } |
| 13797 } | 14543 } |
| 13798 } else if (identical(kind, ElementKind.PARAMETER)) { | 14544 } else if (identical(kind, ElementKind.PARAMETER)) { |
| 13799 node.staticElement = element; | 14545 node.staticElement = element; |
| 13800 if (node.inSetterContext()) { | 14546 if (node.inSetterContext()) { |
| 13801 ParameterElementImpl parameterImpl = element as ParameterElementImpl; | 14547 ParameterElementImpl parameterImpl = element as ParameterElementImpl; |
| 13802 parameterImpl.markPotentiallyMutatedInScope(); | 14548 parameterImpl.markPotentiallyMutatedInScope(); |
| 14549 // If we are in some closure, check if it is not the same as where varia
ble is declared. |
| 13803 if (_enclosingFunction != null && (element.enclosingElement != _enclosin
gFunction)) { | 14550 if (_enclosingFunction != null && (element.enclosingElement != _enclosin
gFunction)) { |
| 13804 parameterImpl.markPotentiallyMutatedInClosure(); | 14551 parameterImpl.markPotentiallyMutatedInClosure(); |
| 13805 } | 14552 } |
| 13806 } | 14553 } |
| 13807 } | 14554 } |
| 13808 return null; | 14555 return null; |
| 13809 } | 14556 } |
| 13810 } | 14557 } |
| 13811 | 14558 |
| 13812 /** | 14559 /** |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13912 _hasHiddenName = true; | 14659 _hasHiddenName = true; |
| 13913 } | 14660 } |
| 13914 } | 14661 } |
| 13915 } | 14662 } |
| 13916 | 14663 |
| 13917 Element lookup3(Identifier identifier, String name, LibraryElement referencing
Library) { | 14664 Element lookup3(Identifier identifier, String name, LibraryElement referencing
Library) { |
| 13918 Element element = localLookup(name, referencingLibrary); | 14665 Element element = localLookup(name, referencingLibrary); |
| 13919 if (element != null) { | 14666 if (element != null) { |
| 13920 return element; | 14667 return element; |
| 13921 } | 14668 } |
| 14669 // May be there is a hidden Element. |
| 13922 if (_hasHiddenName) { | 14670 if (_hasHiddenName) { |
| 13923 Element hiddenElement = _hiddenElements[name]; | 14671 Element hiddenElement = _hiddenElements[name]; |
| 13924 if (hiddenElement != null) { | 14672 if (hiddenElement != null) { |
| 13925 errorListener.onError(new AnalysisError.con2(getSource(identifier), iden
tifier.offset, identifier.length, CompileTimeErrorCode.REFERENCED_BEFORE_DECLARA
TION, [])); | 14673 errorListener.onError(new AnalysisError.con2(getSource(identifier), iden
tifier.offset, identifier.length, CompileTimeErrorCode.REFERENCED_BEFORE_DECLARA
TION, [])); |
| 13926 return hiddenElement; | 14674 return hiddenElement; |
| 13927 } | 14675 } |
| 13928 } | 14676 } |
| 14677 // Check enclosing scope. |
| 13929 return enclosingScope.lookup3(identifier, name, referencingLibrary); | 14678 return enclosingScope.lookup3(identifier, name, referencingLibrary); |
| 13930 } | 14679 } |
| 13931 } | 14680 } |
| 13932 | 14681 |
| 13933 /** | 14682 /** |
| 13934 * Instances of the class `FunctionScope` implement the scope defined by a funct
ion. | 14683 * Instances of the class `FunctionScope` implement the scope defined by a funct
ion. |
| 13935 * | 14684 * |
| 13936 * @coverage dart.engine.resolver | 14685 * @coverage dart.engine.resolver |
| 13937 */ | 14686 */ |
| 13938 class FunctionScope extends EnclosedScope { | 14687 class FunctionScope extends EnclosedScope { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14163 } | 14912 } |
| 14164 } | 14913 } |
| 14165 if (foundElement is MultiplyDefinedElementImpl) { | 14914 if (foundElement is MultiplyDefinedElementImpl) { |
| 14166 foundElement = removeSdkElements(identifier, name, foundElement as Multipl
yDefinedElementImpl); | 14915 foundElement = removeSdkElements(identifier, name, foundElement as Multipl
yDefinedElementImpl); |
| 14167 } | 14916 } |
| 14168 if (foundElement is MultiplyDefinedElementImpl) { | 14917 if (foundElement is MultiplyDefinedElementImpl) { |
| 14169 String foundEltName = foundElement.displayName; | 14918 String foundEltName = foundElement.displayName; |
| 14170 List<Element> conflictingMembers = (foundElement as MultiplyDefinedElement
Impl).conflictingElements; | 14919 List<Element> conflictingMembers = (foundElement as MultiplyDefinedElement
Impl).conflictingElements; |
| 14171 String libName1 = getLibraryName(conflictingMembers[0], ""); | 14920 String libName1 = getLibraryName(conflictingMembers[0], ""); |
| 14172 String libName2 = getLibraryName(conflictingMembers[1], ""); | 14921 String libName2 = getLibraryName(conflictingMembers[1], ""); |
| 14922 // TODO (jwren) Change the error message to include a list of all library
names instead of |
| 14923 // just the first two |
| 14173 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltNam
e, libName1, libName2])); | 14924 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltNam
e, libName1, libName2])); |
| 14174 return foundElement; | 14925 return foundElement; |
| 14175 } | 14926 } |
| 14176 if (foundElement != null) { | 14927 if (foundElement != null) { |
| 14177 defineWithoutChecking2(name, foundElement); | 14928 defineWithoutChecking2(name, foundElement); |
| 14178 } | 14929 } |
| 14179 return foundElement; | 14930 return foundElement; |
| 14180 } | 14931 } |
| 14181 | 14932 |
| 14182 /** | 14933 /** |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14235 } else { | 14986 } else { |
| 14236 conflictingMembers[to++] = member; | 14987 conflictingMembers[to++] = member; |
| 14237 } | 14988 } |
| 14238 } | 14989 } |
| 14239 if (sdkElement != null && to > 0) { | 14990 if (sdkElement != null && to > 0) { |
| 14240 String sdkLibName = getLibraryName(sdkElement, ""); | 14991 String sdkLibName = getLibraryName(sdkElement, ""); |
| 14241 String otherLibName = getLibraryName(conflictingMembers[0], ""); | 14992 String otherLibName = getLibraryName(conflictingMembers[0], ""); |
| 14242 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.CONFLICTING_DART_IMPORT, [name
, sdkLibName, otherLibName])); | 14993 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.CONFLICTING_DART_IMPORT, [name
, sdkLibName, otherLibName])); |
| 14243 } | 14994 } |
| 14244 if (to == length) { | 14995 if (to == length) { |
| 14996 // None of the members were removed |
| 14245 return foundElement; | 14997 return foundElement; |
| 14246 } else if (to == 1) { | 14998 } else if (to == 1) { |
| 14999 // All but one member was removed |
| 14247 return conflictingMembers[0]; | 15000 return conflictingMembers[0]; |
| 14248 } else if (to == 0) { | 15001 } else if (to == 0) { |
| 15002 // All members were removed |
| 14249 AnalysisEngine.instance.logger.logInformation("Multiply defined SDK elemen
t: ${foundElement}"); | 15003 AnalysisEngine.instance.logger.logInformation("Multiply defined SDK elemen
t: ${foundElement}"); |
| 14250 return foundElement; | 15004 return foundElement; |
| 14251 } | 15005 } |
| 14252 List<Element> remaining = new List<Element>(to); | 15006 List<Element> remaining = new List<Element>(to); |
| 14253 JavaSystem.arraycopy(conflictingMembers, 0, remaining, 0, to); | 15007 JavaSystem.arraycopy(conflictingMembers, 0, remaining, 0, to); |
| 14254 return new MultiplyDefinedElementImpl(_definingLibrary.context, remaining); | 15008 return new MultiplyDefinedElementImpl(_definingLibrary.context, remaining); |
| 14255 } | 15009 } |
| 14256 } | 15010 } |
| 14257 | 15011 |
| 14258 /** | 15012 /** |
| 14259 * Instances of the class `LibraryScope` implement a scope containing all of the
names defined | 15013 * Instances of the class `LibraryScope` implement a scope containing all of the
names defined |
| 14260 * in a given library. | 15014 * in a given library. |
| 14261 * | 15015 * |
| 14262 * @coverage dart.engine.resolver | 15016 * @coverage dart.engine.resolver |
| 14263 */ | 15017 */ |
| 14264 class LibraryScope extends EnclosedScope { | 15018 class LibraryScope extends EnclosedScope { |
| 14265 /** | 15019 /** |
| 14266 * Initialize a newly created scope representing the names defined in the give
n library. | 15020 * Initialize a newly created scope representing the names defined in the give
n library. |
| 14267 * | 15021 * |
| 14268 * @param definingLibrary the element representing the library represented by
this scope | 15022 * @param definingLibrary the element representing the library represented by
this scope |
| 14269 * @param errorListener the listener that is to be informed when an error is e
ncountered | 15023 * @param errorListener the listener that is to be informed when an error is e
ncountered |
| 14270 */ | 15024 */ |
| 14271 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen
er) : super(new LibraryImportScope(definingLibrary, errorListener)) { | 15025 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen
er) : super(new LibraryImportScope(definingLibrary, errorListener)) { |
| 14272 defineTopLevelNames(definingLibrary); | 15026 defineTopLevelNames(definingLibrary); |
| 14273 } | 15027 } |
| 14274 | 15028 |
| 14275 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 15029 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
| 14276 if (existing is PrefixElement) { | 15030 if (existing is PrefixElement) { |
| 15031 // TODO(scheglov) consider providing actual 'nameOffset' from the syntheti
c accessor |
| 14277 int offset = duplicate.nameOffset; | 15032 int offset = duplicate.nameOffset; |
| 14278 if (duplicate is PropertyAccessorElement) { | 15033 if (duplicate is PropertyAccessorElement) { |
| 14279 PropertyAccessorElement accessor = duplicate; | 15034 PropertyAccessorElement accessor = duplicate; |
| 14280 if (accessor.isSynthetic) { | 15035 if (accessor.isSynthetic) { |
| 14281 offset = accessor.variable.nameOffset; | 15036 offset = accessor.variable.nameOffset; |
| 14282 } | 15037 } |
| 14283 } | 15038 } |
| 14284 return new AnalysisError.con2(duplicate.source, offset, duplicate.displayN
ame.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existin
g.displayName]); | 15039 return new AnalysisError.con2(duplicate.source, offset, duplicate.displayN
ame.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existin
g.displayName]); |
| 14285 } | 15040 } |
| 14286 return super.getErrorForDuplicate(existing, duplicate); | 15041 return super.getErrorForDuplicate(existing, duplicate); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14379 class NamespaceBuilder { | 15134 class NamespaceBuilder { |
| 14380 /** | 15135 /** |
| 14381 * Create a namespace representing the export namespace of the given [ExportEl
ement]. | 15136 * Create a namespace representing the export namespace of the given [ExportEl
ement]. |
| 14382 * | 15137 * |
| 14383 * @param element the export element whose export namespace is to be created | 15138 * @param element the export element whose export namespace is to be created |
| 14384 * @return the export namespace that was created | 15139 * @return the export namespace that was created |
| 14385 */ | 15140 */ |
| 14386 Namespace createExportNamespace(ExportElement element) { | 15141 Namespace createExportNamespace(ExportElement element) { |
| 14387 LibraryElement exportedLibrary = element.exportedLibrary; | 15142 LibraryElement exportedLibrary = element.exportedLibrary; |
| 14388 if (exportedLibrary == null) { | 15143 if (exportedLibrary == null) { |
| 15144 // |
| 15145 // The exported library will be null if the URI does not reference a valid
library. |
| 15146 // |
| 14389 return Namespace.EMPTY; | 15147 return Namespace.EMPTY; |
| 14390 } | 15148 } |
| 14391 Map<String, Element> definedNames = createExportMapping(exportedLibrary, new
Set<LibraryElement>()); | 15149 Map<String, Element> definedNames = createExportMapping(exportedLibrary, new
Set<LibraryElement>()); |
| 14392 definedNames = apply(definedNames, element.combinators); | 15150 definedNames = apply(definedNames, element.combinators); |
| 14393 return new Namespace(definedNames); | 15151 return new Namespace(definedNames); |
| 14394 } | 15152 } |
| 14395 | 15153 |
| 14396 /** | 15154 /** |
| 14397 * Create a namespace representing the export namespace of the given library. | 15155 * Create a namespace representing the export namespace of the given library. |
| 14398 * | 15156 * |
| 14399 * @param library the library whose export namespace is to be created | 15157 * @param library the library whose export namespace is to be created |
| 14400 * @return the export namespace that was created | 15158 * @return the export namespace that was created |
| 14401 */ | 15159 */ |
| 14402 Namespace createExportNamespace2(LibraryElement library) => new Namespace(crea
teExportMapping(library, new Set<LibraryElement>())); | 15160 Namespace createExportNamespace2(LibraryElement library) => new Namespace(crea
teExportMapping(library, new Set<LibraryElement>())); |
| 14403 | 15161 |
| 14404 /** | 15162 /** |
| 14405 * Create a namespace representing the import namespace of the given library. | 15163 * Create a namespace representing the import namespace of the given library. |
| 14406 * | 15164 * |
| 14407 * @param library the library whose import namespace is to be created | 15165 * @param library the library whose import namespace is to be created |
| 14408 * @return the import namespace that was created | 15166 * @return the import namespace that was created |
| 14409 */ | 15167 */ |
| 14410 Namespace createImportNamespace(ImportElement element) { | 15168 Namespace createImportNamespace(ImportElement element) { |
| 14411 LibraryElement importedLibrary = element.importedLibrary; | 15169 LibraryElement importedLibrary = element.importedLibrary; |
| 14412 if (importedLibrary == null) { | 15170 if (importedLibrary == null) { |
| 15171 // |
| 15172 // The imported library will be null if the URI does not reference a valid
library. |
| 15173 // |
| 14413 return Namespace.EMPTY; | 15174 return Namespace.EMPTY; |
| 14414 } | 15175 } |
| 14415 Map<String, Element> definedNames = createExportMapping(importedLibrary, new
Set<LibraryElement>()); | 15176 Map<String, Element> definedNames = createExportMapping(importedLibrary, new
Set<LibraryElement>()); |
| 14416 definedNames = apply(definedNames, element.combinators); | 15177 definedNames = apply(definedNames, element.combinators); |
| 14417 definedNames = apply2(definedNames, element.prefix); | 15178 definedNames = apply2(definedNames, element.prefix); |
| 14418 return new Namespace(definedNames); | 15179 return new Namespace(definedNames); |
| 14419 } | 15180 } |
| 14420 | 15181 |
| 14421 /** | 15182 /** |
| 14422 * Create a namespace representing the public namespace of the given library. | 15183 * Create a namespace representing the public namespace of the given library. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14499 * @param definedNames the mapping table to which the namespace operations are
to be applied | 15260 * @param definedNames the mapping table to which the namespace operations are
to be applied |
| 14500 * @param combinators the combinators to be applied | 15261 * @param combinators the combinators to be applied |
| 14501 */ | 15262 */ |
| 14502 Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCo
mbinator> combinators) { | 15263 Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCo
mbinator> combinators) { |
| 14503 for (NamespaceCombinator combinator in combinators) { | 15264 for (NamespaceCombinator combinator in combinators) { |
| 14504 if (combinator is HideElementCombinator) { | 15265 if (combinator is HideElementCombinator) { |
| 14505 hide(definedNames, combinator.hiddenNames); | 15266 hide(definedNames, combinator.hiddenNames); |
| 14506 } else if (combinator is ShowElementCombinator) { | 15267 } else if (combinator is ShowElementCombinator) { |
| 14507 definedNames = show(definedNames, combinator.shownNames); | 15268 definedNames = show(definedNames, combinator.shownNames); |
| 14508 } else { | 15269 } else { |
| 15270 // Internal error. |
| 14509 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c
ombinator.runtimeType.toString()}"); | 15271 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c
ombinator.runtimeType.toString()}"); |
| 14510 } | 15272 } |
| 14511 } | 15273 } |
| 14512 return definedNames; | 15274 return definedNames; |
| 14513 } | 15275 } |
| 14514 | 15276 |
| 14515 /** | 15277 /** |
| 14516 * Apply the given prefix to all of the names in the table of defined names. | 15278 * Apply the given prefix to all of the names in the table of defined names. |
| 14517 * | 15279 * |
| 14518 * @param definedNames the names that were defined before this operation | 15280 * @param definedNames the names that were defined before this operation |
| (...skipping 21 matching lines...) Expand all Loading... |
| 14540 * be added by another library | 15302 * be added by another library |
| 14541 * @return the mapping table that was created | 15303 * @return the mapping table that was created |
| 14542 */ | 15304 */ |
| 14543 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl
ement> visitedElements) { | 15305 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl
ement> visitedElements) { |
| 14544 visitedElements.add(library); | 15306 visitedElements.add(library); |
| 14545 try { | 15307 try { |
| 14546 Map<String, Element> definedNames = new Map<String, Element>(); | 15308 Map<String, Element> definedNames = new Map<String, Element>(); |
| 14547 for (ExportElement element in library.exports) { | 15309 for (ExportElement element in library.exports) { |
| 14548 LibraryElement exportedLibrary = element.exportedLibrary; | 15310 LibraryElement exportedLibrary = element.exportedLibrary; |
| 14549 if (exportedLibrary != null && !visitedElements.contains(exportedLibrary
)) { | 15311 if (exportedLibrary != null && !visitedElements.contains(exportedLibrary
)) { |
| 15312 // |
| 15313 // The exported library will be null if the URI does not reference a v
alid library. |
| 15314 // |
| 14550 Map<String, Element> exportedNames = createExportMapping(exportedLibra
ry, visitedElements); | 15315 Map<String, Element> exportedNames = createExportMapping(exportedLibra
ry, visitedElements); |
| 14551 exportedNames = apply(exportedNames, element.combinators); | 15316 exportedNames = apply(exportedNames, element.combinators); |
| 14552 addAll(definedNames, exportedNames); | 15317 addAll(definedNames, exportedNames); |
| 14553 } | 15318 } |
| 14554 } | 15319 } |
| 14555 addAll2(definedNames, (library.context as InternalAnalysisContext).getPubl
icNamespace(library)); | 15320 addAll2(definedNames, (library.context as InternalAnalysisContext).getPubl
icNamespace(library)); |
| 14556 return definedNames; | 15321 return definedNames; |
| 14557 } finally { | 15322 } finally { |
| 14558 visitedElements.remove(library); | 15323 visitedElements.remove(library); |
| 14559 } | 15324 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14700 | 15465 |
| 14701 /** | 15466 /** |
| 14702 * Return the error code to be used when reporting that a name being defined l
ocally conflicts | 15467 * Return the error code to be used when reporting that a name being defined l
ocally conflicts |
| 14703 * with another element of the same name in the local scope. | 15468 * with another element of the same name in the local scope. |
| 14704 * | 15469 * |
| 14705 * @param existing the first element to be declared with the conflicting name | 15470 * @param existing the first element to be declared with the conflicting name |
| 14706 * @param duplicate another element declared with the conflicting name | 15471 * @param duplicate another element declared with the conflicting name |
| 14707 * @return the error code used to report duplicate names within a scope | 15472 * @return the error code used to report duplicate names within a scope |
| 14708 */ | 15473 */ |
| 14709 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 15474 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
| 15475 // TODO(brianwilkerson) Customize the error message based on the types of el
ements that share |
| 15476 // the same name. |
| 15477 // TODO(jwren) There are 4 error codes for duplicate, but only 1 is being ge
nerated. |
| 14710 Source source = duplicate.source; | 15478 Source source = duplicate.source; |
| 14711 return new AnalysisError.con2(source, duplicate.nameOffset, duplicate.displa
yName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName])
; | 15479 return new AnalysisError.con2(source, duplicate.nameOffset, duplicate.displa
yName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName])
; |
| 14712 } | 15480 } |
| 14713 | 15481 |
| 14714 /** | 15482 /** |
| 14715 * Return the listener that is to be informed when an error is encountered. | 15483 * Return the listener that is to be informed when an error is encountered. |
| 14716 * | 15484 * |
| 14717 * @return the listener that is to be informed when an error is encountered | 15485 * @return the listener that is to be informed when an error is encountered |
| 14718 */ | 15486 */ |
| 14719 AnalysisErrorListener get errorListener; | 15487 AnalysisErrorListener get errorListener; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14929 this._errorReporter = errorReporter; | 15697 this._errorReporter = errorReporter; |
| 14930 this._typeProvider = typeProvider; | 15698 this._typeProvider = typeProvider; |
| 14931 this._boolType = typeProvider.boolType; | 15699 this._boolType = typeProvider.boolType; |
| 14932 this._intType = typeProvider.intType; | 15700 this._intType = typeProvider.intType; |
| 14933 this._numType = typeProvider.numType; | 15701 this._numType = typeProvider.numType; |
| 14934 this._stringType = typeProvider.stringType; | 15702 this._stringType = typeProvider.stringType; |
| 14935 } | 15703 } |
| 14936 | 15704 |
| 14937 Object visitAnnotation(Annotation node) { | 15705 Object visitAnnotation(Annotation node) { |
| 14938 super.visitAnnotation(node); | 15706 super.visitAnnotation(node); |
| 15707 // check annotation creation |
| 14939 Element element = node.element; | 15708 Element element = node.element; |
| 14940 if (element is ConstructorElement) { | 15709 if (element is ConstructorElement) { |
| 14941 ConstructorElement constructorElement = element; | 15710 ConstructorElement constructorElement = element; |
| 15711 // should 'const' constructor |
| 14942 if (!constructorElement.isConst) { | 15712 if (!constructorElement.isConst) { |
| 14943 _errorReporter.reportError3(CompileTimeErrorCode.NON_CONSTANT_ANNOTATION
_CONSTRUCTOR, node, []); | 15713 _errorReporter.reportError3(CompileTimeErrorCode.NON_CONSTANT_ANNOTATION
_CONSTRUCTOR, node, []); |
| 14944 return null; | 15714 return null; |
| 14945 } | 15715 } |
| 15716 // should have arguments |
| 14946 ArgumentList argumentList = node.arguments; | 15717 ArgumentList argumentList = node.arguments; |
| 14947 if (argumentList == null) { | 15718 if (argumentList == null) { |
| 14948 _errorReporter.reportError3(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCT
OR_ARGUMENTS, node, []); | 15719 _errorReporter.reportError3(CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCT
OR_ARGUMENTS, node, []); |
| 14949 return null; | 15720 return null; |
| 14950 } | 15721 } |
| 15722 // arguments should be constants |
| 14951 validateConstantArguments(argumentList); | 15723 validateConstantArguments(argumentList); |
| 14952 } | 15724 } |
| 14953 return null; | 15725 return null; |
| 14954 } | 15726 } |
| 14955 | 15727 |
| 14956 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 15728 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 14957 if (node.constKeyword != null) { | 15729 if (node.constKeyword != null) { |
| 14958 validateInitializers(node); | 15730 validateInitializers(node); |
| 14959 } | 15731 } |
| 14960 validateDefaultValues(node.parameters); | 15732 validateDefaultValues(node.parameters); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15035 return null; | 15807 return null; |
| 15036 } | 15808 } |
| 15037 | 15809 |
| 15038 Object visitVariableDeclaration(VariableDeclaration node) { | 15810 Object visitVariableDeclaration(VariableDeclaration node) { |
| 15039 super.visitVariableDeclaration(node); | 15811 super.visitVariableDeclaration(node); |
| 15040 Expression initializer = node.initializer; | 15812 Expression initializer = node.initializer; |
| 15041 if (initializer != null && node.isConst) { | 15813 if (initializer != null && node.isConst) { |
| 15042 VariableElementImpl element = node.element as VariableElementImpl; | 15814 VariableElementImpl element = node.element as VariableElementImpl; |
| 15043 EvaluationResultImpl result = element.evaluationResult; | 15815 EvaluationResultImpl result = element.evaluationResult; |
| 15044 if (result == null) { | 15816 if (result == null) { |
| 15817 // |
| 15818 // Normally we don't need to visit const variable declarations because w
e have already |
| 15819 // computed their values. But if we missed it for some reason, this give
s us a second |
| 15820 // chance. |
| 15821 // |
| 15045 result = validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_WI
TH_NON_CONSTANT_VALUE); | 15822 result = validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_WI
TH_NON_CONSTANT_VALUE); |
| 15046 element.evaluationResult = result; | 15823 element.evaluationResult = result; |
| 15047 } else if (result is ErrorResult) { | 15824 } else if (result is ErrorResult) { |
| 15048 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON
STANT_VALUE); | 15825 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON
STANT_VALUE); |
| 15049 } | 15826 } |
| 15050 } | 15827 } |
| 15051 return null; | 15828 return null; |
| 15052 } | 15829 } |
| 15053 | 15830 |
| 15054 /** | 15831 /** |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15503 checkForNoDefaultSuperConstructorImplicit(node); | 16280 checkForNoDefaultSuperConstructorImplicit(node); |
| 15504 checkForAllMixinErrorCodes(withClause); | 16281 checkForAllMixinErrorCodes(withClause); |
| 15505 checkForConflictingTypeVariableErrorCodes(node); | 16282 checkForConflictingTypeVariableErrorCodes(node); |
| 15506 if (implementsClause != null || extendsClause != null) { | 16283 if (implementsClause != null || extendsClause != null) { |
| 15507 if (!checkForImplementsDisallowedClass(implementsClause) && !checkForExt
endsDisallowedClass(extendsClause)) { | 16284 if (!checkForImplementsDisallowedClass(implementsClause) && !checkForExt
endsDisallowedClass(extendsClause)) { |
| 15508 checkForNonAbstractClassInheritsAbstractMember(node); | 16285 checkForNonAbstractClassInheritsAbstractMember(node); |
| 15509 checkForInconsistentMethodInheritance(); | 16286 checkForInconsistentMethodInheritance(); |
| 15510 checkForRecursiveInterfaceInheritance(_enclosingClass); | 16287 checkForRecursiveInterfaceInheritance(_enclosingClass); |
| 15511 } | 16288 } |
| 15512 } | 16289 } |
| 16290 // initialize initialFieldElementsMap |
| 15513 ClassElement classElement = node.element; | 16291 ClassElement classElement = node.element; |
| 15514 if (classElement != null) { | 16292 if (classElement != null) { |
| 15515 List<FieldElement> fieldElements = classElement.fields; | 16293 List<FieldElement> fieldElements = classElement.fields; |
| 15516 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>(); | 16294 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>(); |
| 15517 for (FieldElement fieldElement in fieldElements) { | 16295 for (FieldElement fieldElement in fieldElements) { |
| 15518 if (!fieldElement.isSynthetic) { | 16296 if (!fieldElement.isSynthetic) { |
| 15519 _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; | 16297 _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; |
| 15520 } | 16298 } |
| 15521 } | 16299 } |
| 15522 } | 16300 } |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15667 checkForNonVoidReturnTypeForSetter(returnType); | 16445 checkForNonVoidReturnTypeForSetter(returnType); |
| 15668 } | 16446 } |
| 15669 } | 16447 } |
| 15670 return super.visitFunctionDeclaration(node); | 16448 return super.visitFunctionDeclaration(node); |
| 15671 } finally { | 16449 } finally { |
| 15672 _enclosingFunction = outerFunction; | 16450 _enclosingFunction = outerFunction; |
| 15673 } | 16451 } |
| 15674 } | 16452 } |
| 15675 | 16453 |
| 15676 Object visitFunctionExpression(FunctionExpression node) { | 16454 Object visitFunctionExpression(FunctionExpression node) { |
| 16455 // If this function expression is wrapped in a function declaration, don't c
hange the |
| 16456 // enclosingFunction field. |
| 15677 if (node.parent is! FunctionDeclaration) { | 16457 if (node.parent is! FunctionDeclaration) { |
| 15678 ExecutableElement outerFunction = _enclosingFunction; | 16458 ExecutableElement outerFunction = _enclosingFunction; |
| 15679 try { | 16459 try { |
| 15680 _enclosingFunction = node.element; | 16460 _enclosingFunction = node.element; |
| 15681 return super.visitFunctionExpression(node); | 16461 return super.visitFunctionExpression(node); |
| 15682 } finally { | 16462 } finally { |
| 15683 _enclosingFunction = outerFunction; | 16463 _enclosingFunction = outerFunction; |
| 15684 } | 16464 } |
| 15685 } else { | 16465 } else { |
| 15686 return super.visitFunctionExpression(node); | 16466 return super.visitFunctionExpression(node); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15826 ClassElement typeReference = ElementResolver.getTypeReference(target); | 16606 ClassElement typeReference = ElementResolver.getTypeReference(target); |
| 15827 checkForStaticAccessToInstanceMember(typeReference, methodName); | 16607 checkForStaticAccessToInstanceMember(typeReference, methodName); |
| 15828 checkForInstanceAccessToStaticMember(typeReference, methodName); | 16608 checkForInstanceAccessToStaticMember(typeReference, methodName); |
| 15829 } else { | 16609 } else { |
| 15830 checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 16610 checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); |
| 15831 } | 16611 } |
| 15832 return super.visitMethodInvocation(node); | 16612 return super.visitMethodInvocation(node); |
| 15833 } | 16613 } |
| 15834 | 16614 |
| 15835 Object visitNativeClause(NativeClause node) { | 16615 Object visitNativeClause(NativeClause node) { |
| 16616 // TODO(brianwilkerson) Figure out the right rule for when 'native' is allow
ed. |
| 15836 if (!_isInSystemLibrary) { | 16617 if (!_isInSystemLibrary) { |
| 15837 _errorReporter.reportError3(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE,
node, []); | 16618 _errorReporter.reportError3(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE,
node, []); |
| 15838 } | 16619 } |
| 15839 return super.visitNativeClause(node); | 16620 return super.visitNativeClause(node); |
| 15840 } | 16621 } |
| 15841 | 16622 |
| 15842 Object visitNativeFunctionBody(NativeFunctionBody node) { | 16623 Object visitNativeFunctionBody(NativeFunctionBody node) { |
| 15843 checkForNativeFunctionBodyInNonSDKCode(node); | 16624 checkForNativeFunctionBodyInNonSDKCode(node); |
| 15844 return super.visitNativeFunctionBody(node); | 16625 return super.visitNativeFunctionBody(node); |
| 15845 } | 16626 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15957 | 16738 |
| 15958 Object visitTypeParameter(TypeParameter node) { | 16739 Object visitTypeParameter(TypeParameter node) { |
| 15959 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE
NTIFIER_AS_TYPE_PARAMETER_NAME); | 16740 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE
NTIFIER_AS_TYPE_PARAMETER_NAME); |
| 15960 checkForTypeParameterSupertypeOfItsBound(node); | 16741 checkForTypeParameterSupertypeOfItsBound(node); |
| 15961 return super.visitTypeParameter(node); | 16742 return super.visitTypeParameter(node); |
| 15962 } | 16743 } |
| 15963 | 16744 |
| 15964 Object visitVariableDeclaration(VariableDeclaration node) { | 16745 Object visitVariableDeclaration(VariableDeclaration node) { |
| 15965 SimpleIdentifier nameNode = node.name; | 16746 SimpleIdentifier nameNode = node.name; |
| 15966 Expression initializerNode = node.initializer; | 16747 Expression initializerNode = node.initializer; |
| 16748 // do checks |
| 15967 checkForInvalidAssignment2(nameNode, initializerNode); | 16749 checkForInvalidAssignment2(nameNode, initializerNode); |
| 16750 // visit name |
| 15968 nameNode.accept(this); | 16751 nameNode.accept(this); |
| 16752 // visit initializer |
| 15969 String name = nameNode.name; | 16753 String name = nameNode.name; |
| 15970 _namesForReferenceToDeclaredVariableInInitializer.add(name); | 16754 _namesForReferenceToDeclaredVariableInInitializer.add(name); |
| 15971 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; | 16755 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; |
| 15972 try { | 16756 try { |
| 15973 if (initializerNode != null) { | 16757 if (initializerNode != null) { |
| 15974 initializerNode.accept(this); | 16758 initializerNode.accept(this); |
| 15975 } | 16759 } |
| 15976 } finally { | 16760 } finally { |
| 15977 _isInInstanceVariableInitializer = false; | 16761 _isInInstanceVariableInitializer = false; |
| 15978 _namesForReferenceToDeclaredVariableInInitializer.remove(name); | 16762 _namesForReferenceToDeclaredVariableInInitializer.remove(name); |
| 15979 } | 16763 } |
| 16764 // done |
| 15980 return null; | 16765 return null; |
| 15981 } | 16766 } |
| 15982 | 16767 |
| 15983 Object visitVariableDeclarationList(VariableDeclarationList node) => super.vis
itVariableDeclarationList(node); | 16768 Object visitVariableDeclarationList(VariableDeclarationList node) => super.vis
itVariableDeclarationList(node); |
| 15984 | 16769 |
| 15985 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { | 16770 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { |
| 15986 checkForFinalNotInitialized2(node.variables); | 16771 checkForFinalNotInitialized2(node.variables); |
| 15987 return super.visitVariableDeclarationStatement(node); | 16772 return super.visitVariableDeclarationStatement(node); |
| 15988 } | 16773 } |
| 15989 | 16774 |
| 15990 Object visitWhileStatement(WhileStatement node) { | 16775 Object visitWhileStatement(WhileStatement node) { |
| 15991 checkForNonBoolCondition(node.condition); | 16776 checkForNonBoolCondition(node.condition); |
| 15992 return super.visitWhileStatement(node); | 16777 return super.visitWhileStatement(node); |
| 15993 } | 16778 } |
| 15994 | 16779 |
| 15995 /** | 16780 /** |
| 15996 * This verifies if the passed map literal has type arguments then there is ex
actly two. | 16781 * This verifies if the passed map literal has type arguments then there is ex
actly two. |
| 15997 * | 16782 * |
| 15998 * @param node the map literal to evaluate | 16783 * @param node the map literal to evaluate |
| 15999 * @return `true` if and only if an error code is generated on the passed node | 16784 * @return `true` if and only if an error code is generated on the passed node |
| 16000 * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS | 16785 * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS |
| 16001 */ | 16786 */ |
| 16002 bool checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { | 16787 bool checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { |
| 16788 // has type arguments |
| 16003 if (typeArguments == null) { | 16789 if (typeArguments == null) { |
| 16004 return false; | 16790 return false; |
| 16005 } | 16791 } |
| 16792 // check number of type arguments |
| 16006 int num = typeArguments.arguments.length; | 16793 int num = typeArguments.arguments.length; |
| 16007 if (num == 2) { | 16794 if (num == 2) { |
| 16008 return false; | 16795 return false; |
| 16009 } | 16796 } |
| 16797 // report problem |
| 16010 _errorReporter.reportError3(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGU
MENTS, typeArguments, [num]); | 16798 _errorReporter.reportError3(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGU
MENTS, typeArguments, [num]); |
| 16011 return true; | 16799 return true; |
| 16012 } | 16800 } |
| 16013 | 16801 |
| 16014 /** | 16802 /** |
| 16015 * This verifies that the passed constructor declaration does not violate any
of the error codes | 16803 * This verifies that the passed constructor declaration does not violate any
of the error codes |
| 16016 * relating to the initialization of fields in the enclosing class. | 16804 * relating to the initialization of fields in the enclosing class. |
| 16017 * | 16805 * |
| 16018 * @param node the [ConstructorDeclaration] to evaluate | 16806 * @param node the [ConstructorDeclaration] to evaluate |
| 16019 * @return `true` if and only if an error code is generated on the passed node | 16807 * @return `true` if and only if an error code is generated on the passed node |
| 16020 * @see #initialFieldElementsMap | 16808 * @see #initialFieldElementsMap |
| 16021 * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR | 16809 * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR |
| 16022 * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES | 16810 * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES |
| 16023 */ | 16811 */ |
| 16024 bool checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { | 16812 bool checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { |
| 16025 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod
e.externalKeyword != null) { | 16813 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod
e.externalKeyword != null) { |
| 16026 return false; | 16814 return false; |
| 16027 } | 16815 } |
| 16816 // Ignore if native class. |
| 16028 if (_isInNativeClass) { | 16817 if (_isInNativeClass) { |
| 16029 return false; | 16818 return false; |
| 16030 } | 16819 } |
| 16031 bool foundError = false; | 16820 bool foundError = false; |
| 16032 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_
STATE>.from(_initialFieldElementsMap); | 16821 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_
STATE>.from(_initialFieldElementsMap); |
| 16822 // Visit all of the field formal parameters |
| 16033 NodeList<FormalParameter> formalParameters = node.parameters.parameters; | 16823 NodeList<FormalParameter> formalParameters = node.parameters.parameters; |
| 16034 for (FormalParameter formalParameter in formalParameters) { | 16824 for (FormalParameter formalParameter in formalParameters) { |
| 16035 FormalParameter parameter = formalParameter; | 16825 FormalParameter parameter = formalParameter; |
| 16036 if (parameter is DefaultFormalParameter) { | 16826 if (parameter is DefaultFormalParameter) { |
| 16037 parameter = (parameter as DefaultFormalParameter).parameter; | 16827 parameter = (parameter as DefaultFormalParameter).parameter; |
| 16038 } | 16828 } |
| 16039 if (parameter is FieldFormalParameter) { | 16829 if (parameter is FieldFormalParameter) { |
| 16040 FieldElement fieldElement = (parameter.element as FieldFormalParameterEl
ementImpl).field; | 16830 FieldElement fieldElement = (parameter.element as FieldFormalParameterEl
ementImpl).field; |
| 16041 INIT_STATE state = fieldElementsMap[fieldElement]; | 16831 INIT_STATE state = fieldElementsMap[fieldElement]; |
| 16042 if (identical(state, INIT_STATE.NOT_INIT)) { | 16832 if (identical(state, INIT_STATE.NOT_INIT)) { |
| 16043 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; | 16833 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; |
| 16044 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) { | 16834 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) { |
| 16045 if (fieldElement.isFinal || fieldElement.isConst) { | 16835 if (fieldElement.isFinal || fieldElement.isConst) { |
| 16046 _errorReporter.reportError3(StaticWarningCode.FINAL_INITIALIZED_IN_D
ECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayNam
e]); | 16836 _errorReporter.reportError3(StaticWarningCode.FINAL_INITIALIZED_IN_D
ECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayNam
e]); |
| 16047 foundError = true; | 16837 foundError = true; |
| 16048 } | 16838 } |
| 16049 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) { | 16839 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) { |
| 16050 if (fieldElement.isFinal || fieldElement.isConst) { | 16840 if (fieldElement.isFinal || fieldElement.isConst) { |
| 16051 _errorReporter.reportError3(CompileTimeErrorCode.FINAL_INITIALIZED_M
ULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]); | 16841 _errorReporter.reportError3(CompileTimeErrorCode.FINAL_INITIALIZED_M
ULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]); |
| 16052 foundError = true; | 16842 foundError = true; |
| 16053 } | 16843 } |
| 16054 } | 16844 } |
| 16055 } | 16845 } |
| 16056 } | 16846 } |
| 16847 // Visit all of the initializers |
| 16057 NodeList<ConstructorInitializer> initializers = node.initializers; | 16848 NodeList<ConstructorInitializer> initializers = node.initializers; |
| 16058 for (ConstructorInitializer constructorInitializer in initializers) { | 16849 for (ConstructorInitializer constructorInitializer in initializers) { |
| 16059 if (constructorInitializer is RedirectingConstructorInvocation) { | 16850 if (constructorInitializer is RedirectingConstructorInvocation) { |
| 16060 return false; | 16851 return false; |
| 16061 } | 16852 } |
| 16062 if (constructorInitializer is ConstructorFieldInitializer) { | 16853 if (constructorInitializer is ConstructorFieldInitializer) { |
| 16063 ConstructorFieldInitializer constructorFieldInitializer = constructorIni
tializer; | 16854 ConstructorFieldInitializer constructorFieldInitializer = constructorIni
tializer; |
| 16064 SimpleIdentifier fieldName = constructorFieldInitializer.fieldName; | 16855 SimpleIdentifier fieldName = constructorFieldInitializer.fieldName; |
| 16065 Element element = fieldName.staticElement; | 16856 Element element = fieldName.staticElement; |
| 16066 if (element is FieldElement) { | 16857 if (element is FieldElement) { |
| 16067 FieldElement fieldElement = element; | 16858 FieldElement fieldElement = element; |
| 16068 INIT_STATE state = fieldElementsMap[fieldElement]; | 16859 INIT_STATE state = fieldElementsMap[fieldElement]; |
| 16069 if (identical(state, INIT_STATE.NOT_INIT)) { | 16860 if (identical(state, INIT_STATE.NOT_INIT)) { |
| 16070 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS; | 16861 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS; |
| 16071 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) { | 16862 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) { |
| 16072 if (fieldElement.isFinal || fieldElement.isConst) { | 16863 if (fieldElement.isFinal || fieldElement.isConst) { |
| 16073 _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZED_IN
_INITIALIZER_AND_DECLARATION, fieldName, []); | 16864 _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZED_IN
_INITIALIZER_AND_DECLARATION, fieldName, []); |
| 16074 foundError = true; | 16865 foundError = true; |
| 16075 } | 16866 } |
| 16076 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) { | 16867 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) { |
| 16077 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZED_I
N_PARAMETER_AND_INITIALIZER, fieldName, []); | 16868 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZED_I
N_PARAMETER_AND_INITIALIZER, fieldName, []); |
| 16078 foundError = true; | 16869 foundError = true; |
| 16079 } else if (identical(state, INIT_STATE.INIT_IN_INITIALIZERS)) { | 16870 } else if (identical(state, INIT_STATE.INIT_IN_INITIALIZERS)) { |
| 16080 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZED_B
Y_MULTIPLE_INITIALIZERS, fieldName, [fieldElement.displayName]); | 16871 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZED_B
Y_MULTIPLE_INITIALIZERS, fieldName, [fieldElement.displayName]); |
| 16081 foundError = true; | 16872 foundError = true; |
| 16082 } | 16873 } |
| 16083 } | 16874 } |
| 16084 } | 16875 } |
| 16085 } | 16876 } |
| 16877 // Visit all of the states in the map to ensure that none were never initial
ized. |
| 16086 for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElement
sMap)) { | 16878 for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElement
sMap)) { |
| 16087 if (identical(entry.getValue(), INIT_STATE.NOT_INIT)) { | 16879 if (identical(entry.getValue(), INIT_STATE.NOT_INIT)) { |
| 16088 FieldElement fieldElement = entry.getKey(); | 16880 FieldElement fieldElement = entry.getKey(); |
| 16089 if (fieldElement.isConst) { | 16881 if (fieldElement.isConst) { |
| 16090 _errorReporter.reportError3(CompileTimeErrorCode.CONST_NOT_INITIALIZED
, node.returnType, [fieldElement.name]); | 16882 _errorReporter.reportError3(CompileTimeErrorCode.CONST_NOT_INITIALIZED
, node.returnType, [fieldElement.name]); |
| 16091 foundError = true; | 16883 foundError = true; |
| 16092 } else if (fieldElement.isFinal) { | 16884 } else if (fieldElement.isFinal) { |
| 16093 _errorReporter.reportError3(StaticWarningCode.FINAL_NOT_INITIALIZED, n
ode.returnType, [fieldElement.name]); | 16885 _errorReporter.reportError3(StaticWarningCode.FINAL_NOT_INITIALIZED, n
ode.returnType, [fieldElement.name]); |
| 16094 foundError = true; | 16886 foundError = true; |
| 16095 } | 16887 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 16121 String executableElementName = executableElement.name; | 16913 String executableElementName = executableElement.name; |
| 16122 bool executableElementPrivate = Identifier.isPrivateName(executableElementNa
me); | 16914 bool executableElementPrivate = Identifier.isPrivateName(executableElementNa
me); |
| 16123 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan
ce(_enclosingClass, executableElementName); | 16915 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan
ce(_enclosingClass, executableElementName); |
| 16124 bool isGetter = false; | 16916 bool isGetter = false; |
| 16125 bool isSetter = false; | 16917 bool isSetter = false; |
| 16126 if (executableElement is PropertyAccessorElement) { | 16918 if (executableElement is PropertyAccessorElement) { |
| 16127 PropertyAccessorElement accessorElement = executableElement; | 16919 PropertyAccessorElement accessorElement = executableElement; |
| 16128 isGetter = accessorElement.isGetter; | 16920 isGetter = accessorElement.isGetter; |
| 16129 isSetter = accessorElement.isSetter; | 16921 isSetter = accessorElement.isSetter; |
| 16130 } | 16922 } |
| 16923 // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC |
| 16131 if (overriddenExecutable == null) { | 16924 if (overriddenExecutable == null) { |
| 16132 if (!isGetter && !isSetter && !executableElement.isOperator) { | 16925 if (!isGetter && !isSetter && !executableElement.isOperator) { |
| 16133 Set<ClassElement> visitedClasses = new Set<ClassElement>(); | 16926 Set<ClassElement> visitedClasses = new Set<ClassElement>(); |
| 16134 InterfaceType superclassType = _enclosingClass.supertype; | 16927 InterfaceType superclassType = _enclosingClass.supertype; |
| 16135 ClassElement superclassElement = superclassType == null ? null : supercl
assType.element; | 16928 ClassElement superclassElement = superclassType == null ? null : supercl
assType.element; |
| 16136 while (superclassElement != null && !visitedClasses.contains(superclassE
lement)) { | 16929 while (superclassElement != null && !visitedClasses.contains(superclassE
lement)) { |
| 16137 visitedClasses.add(superclassElement); | 16930 visitedClasses.add(superclassElement); |
| 16138 LibraryElement superclassLibrary = superclassElement.library; | 16931 LibraryElement superclassLibrary = superclassElement.library; |
| 16932 // Check fields. |
| 16139 List<FieldElement> fieldElts = superclassElement.fields; | 16933 List<FieldElement> fieldElts = superclassElement.fields; |
| 16140 for (FieldElement fieldElt in fieldElts) { | 16934 for (FieldElement fieldElt in fieldElts) { |
| 16935 // We need the same name. |
| 16141 if (fieldElt.name != executableElementName) { | 16936 if (fieldElt.name != executableElementName) { |
| 16142 continue; | 16937 continue; |
| 16143 } | 16938 } |
| 16939 // Ignore if private in a different library - cannot collide. |
| 16144 if (executableElementPrivate && _currentLibrary != superclassLibrary
) { | 16940 if (executableElementPrivate && _currentLibrary != superclassLibrary
) { |
| 16145 continue; | 16941 continue; |
| 16146 } | 16942 } |
| 16943 // instance vs. static |
| 16147 if (fieldElt.isStatic) { | 16944 if (fieldElt.isStatic) { |
| 16148 _errorReporter.reportError3(StaticWarningCode.INSTANCE_METHOD_NAME
_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ | 16945 _errorReporter.reportError3(StaticWarningCode.INSTANCE_METHOD_NAME
_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ |
| 16149 executableElementName, | 16946 executableElementName, |
| 16150 fieldElt.enclosingElement.displayName]); | 16947 fieldElt.enclosingElement.displayName]); |
| 16151 return true; | 16948 return true; |
| 16152 } | 16949 } |
| 16153 } | 16950 } |
| 16951 // Check methods. |
| 16154 List<MethodElement> methodElements = superclassElement.methods; | 16952 List<MethodElement> methodElements = superclassElement.methods; |
| 16155 for (MethodElement methodElement in methodElements) { | 16953 for (MethodElement methodElement in methodElements) { |
| 16954 // We need the same name. |
| 16156 if (methodElement.name != executableElementName) { | 16955 if (methodElement.name != executableElementName) { |
| 16157 continue; | 16956 continue; |
| 16158 } | 16957 } |
| 16958 // Ignore if private in a different library - cannot collide. |
| 16159 if (executableElementPrivate && _currentLibrary != superclassLibrary
) { | 16959 if (executableElementPrivate && _currentLibrary != superclassLibrary
) { |
| 16160 continue; | 16960 continue; |
| 16161 } | 16961 } |
| 16962 // instance vs. static |
| 16162 if (methodElement.isStatic) { | 16963 if (methodElement.isStatic) { |
| 16163 _errorReporter.reportError3(StaticWarningCode.INSTANCE_METHOD_NAME
_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ | 16964 _errorReporter.reportError3(StaticWarningCode.INSTANCE_METHOD_NAME
_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ |
| 16164 executableElementName, | 16965 executableElementName, |
| 16165 methodElement.enclosingElement.displayName]); | 16966 methodElement.enclosingElement.displayName]); |
| 16166 return true; | 16967 return true; |
| 16167 } | 16968 } |
| 16168 } | 16969 } |
| 16169 superclassType = superclassElement.supertype; | 16970 superclassType = superclassElement.supertype; |
| 16170 superclassElement = superclassType == null ? null : superclassType.ele
ment; | 16971 superclassElement = superclassType == null ? null : superclassType.ele
ment; |
| 16171 } | 16972 } |
| 16172 } | 16973 } |
| 16173 return false; | 16974 return false; |
| 16174 } | 16975 } |
| 16175 FunctionType overridingFT = executableElement.type; | 16976 FunctionType overridingFT = executableElement.type; |
| 16176 FunctionType overriddenFT = overriddenExecutable.type; | 16977 FunctionType overriddenFT = overriddenExecutable.type; |
| 16177 InterfaceType enclosingType = _enclosingClass.type; | 16978 InterfaceType enclosingType = _enclosingClass.type; |
| 16178 overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheri
tance(overriddenFT, executableElementName, enclosingType); | 16979 overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheri
tance(overriddenFT, executableElementName, enclosingType); |
| 16179 if (overridingFT == null || overriddenFT == null) { | 16980 if (overridingFT == null || overriddenFT == null) { |
| 16180 return false; | 16981 return false; |
| 16181 } | 16982 } |
| 16182 Type2 overridingFTReturnType = overridingFT.returnType; | 16983 Type2 overridingFTReturnType = overridingFT.returnType; |
| 16183 Type2 overriddenFTReturnType = overriddenFT.returnType; | 16984 Type2 overriddenFTReturnType = overriddenFT.returnType; |
| 16184 List<Type2> overridingNormalPT = overridingFT.normalParameterTypes; | 16985 List<Type2> overridingNormalPT = overridingFT.normalParameterTypes; |
| 16185 List<Type2> overriddenNormalPT = overriddenFT.normalParameterTypes; | 16986 List<Type2> overriddenNormalPT = overriddenFT.normalParameterTypes; |
| 16186 List<Type2> overridingPositionalPT = overridingFT.optionalParameterTypes; | 16987 List<Type2> overridingPositionalPT = overridingFT.optionalParameterTypes; |
| 16187 List<Type2> overriddenPositionalPT = overriddenFT.optionalParameterTypes; | 16988 List<Type2> overriddenPositionalPT = overriddenFT.optionalParameterTypes; |
| 16188 Map<String, Type2> overridingNamedPT = overridingFT.namedParameterTypes; | 16989 Map<String, Type2> overridingNamedPT = overridingFT.namedParameterTypes; |
| 16189 Map<String, Type2> overriddenNamedPT = overriddenFT.namedParameterTypes; | 16990 Map<String, Type2> overriddenNamedPT = overriddenFT.namedParameterTypes; |
| 16991 // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and CTEC
.INVALID_OVERRIDE_NAMED |
| 16190 if (overridingNormalPT.length > overriddenNormalPT.length) { | 16992 if (overridingNormalPT.length > overriddenNormalPT.length) { |
| 16191 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, e
rrorNameTarget, [ | 16993 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, e
rrorNameTarget, [ |
| 16192 overriddenNormalPT.length, | 16994 overriddenNormalPT.length, |
| 16193 overriddenExecutable.enclosingElement.displayName]); | 16995 overriddenExecutable.enclosingElement.displayName]); |
| 16194 return true; | 16996 return true; |
| 16195 } | 16997 } |
| 16196 if (overridingNormalPT.length + overridingPositionalPT.length < overriddenPo
sitionalPT.length + overriddenNormalPT.length) { | 16998 if (overridingNormalPT.length + overridingPositionalPT.length < overriddenPo
sitionalPT.length + overriddenNormalPT.length) { |
| 16197 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL,
errorNameTarget, [ | 16999 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL,
errorNameTarget, [ |
| 16198 overriddenPositionalPT.length + overriddenNormalPT.length, | 17000 overriddenPositionalPT.length + overriddenNormalPT.length, |
| 16199 overriddenExecutable.enclosingElement.displayName]); | 17001 overriddenExecutable.enclosingElement.displayName]); |
| 16200 return true; | 17002 return true; |
| 16201 } | 17003 } |
| 17004 // For each named parameter in the overridden method, verify that there is t
he same name in |
| 17005 // the overriding method, and in the same order. |
| 16202 Set<String> overridingParameterNameSet = overridingNamedPT.keys.toSet(); | 17006 Set<String> overridingParameterNameSet = overridingNamedPT.keys.toSet(); |
| 16203 JavaIterator<String> overriddenParameterNameIterator = new JavaIterator(over
riddenNamedPT.keys.toSet()); | 17007 JavaIterator<String> overriddenParameterNameIterator = new JavaIterator(over
riddenNamedPT.keys.toSet()); |
| 16204 while (overriddenParameterNameIterator.hasNext) { | 17008 while (overriddenParameterNameIterator.hasNext) { |
| 16205 String overriddenParamName = overriddenParameterNameIterator.next(); | 17009 String overriddenParamName = overriddenParameterNameIterator.next(); |
| 16206 if (!overridingParameterNameSet.contains(overriddenParamName)) { | 17010 if (!overridingParameterNameSet.contains(overriddenParamName)) { |
| 17011 // The overridden method expected the overriding method to have overridi
ngParamName, |
| 17012 // but it does not. |
| 16207 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_NAMED, er
rorNameTarget, [ | 17013 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_NAMED, er
rorNameTarget, [ |
| 16208 overriddenParamName, | 17014 overriddenParamName, |
| 16209 overriddenExecutable.enclosingElement.displayName]); | 17015 overriddenExecutable.enclosingElement.displayName]); |
| 16210 return true; | 17016 return true; |
| 16211 } | 17017 } |
| 16212 } | 17018 } |
| 17019 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE |
| 16213 if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnTy
pe.isAssignableTo(overriddenFTReturnType)) { | 17020 if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnTy
pe.isAssignableTo(overriddenFTReturnType)) { |
| 16214 _errorReporter.reportError3(!isGetter ? StaticWarningCode.INVALID_METHOD_O
VERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, err
orNameTarget, [ | 17021 _errorReporter.reportError3(!isGetter ? StaticWarningCode.INVALID_METHOD_O
VERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, err
orNameTarget, [ |
| 16215 overridingFTReturnType.displayName, | 17022 overridingFTReturnType.displayName, |
| 16216 overriddenFTReturnType.displayName, | 17023 overriddenFTReturnType.displayName, |
| 16217 overriddenExecutable.enclosingElement.displayName]); | 17024 overriddenExecutable.enclosingElement.displayName]); |
| 16218 return true; | 17025 return true; |
| 16219 } | 17026 } |
| 17027 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE |
| 16220 if (parameterLocations == null) { | 17028 if (parameterLocations == null) { |
| 16221 return false; | 17029 return false; |
| 16222 } | 17030 } |
| 16223 int parameterIndex = 0; | 17031 int parameterIndex = 0; |
| 16224 for (int i = 0; i < overridingNormalPT.length; i++) { | 17032 for (int i = 0; i < overridingNormalPT.length; i++) { |
| 16225 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) { | 17033 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) { |
| 16226 _errorReporter.reportError3(!isSetter ? StaticWarningCode.INVALID_METHOD
_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_P
ARAM_TYPE, parameterLocations[parameterIndex], [ | 17034 _errorReporter.reportError3(!isSetter ? StaticWarningCode.INVALID_METHOD
_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_P
ARAM_TYPE, parameterLocations[parameterIndex], [ |
| 16227 overridingNormalPT[i].displayName, | 17035 overridingNormalPT[i].displayName, |
| 16228 overriddenNormalPT[i].displayName, | 17036 overriddenNormalPT[i].displayName, |
| 16229 overriddenExecutable.enclosingElement.displayName]); | 17037 overriddenExecutable.enclosingElement.displayName]); |
| 16230 return true; | 17038 return true; |
| 16231 } | 17039 } |
| 16232 parameterIndex++; | 17040 parameterIndex++; |
| 16233 } | 17041 } |
| 17042 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE |
| 16234 for (int i = 0; i < overriddenPositionalPT.length; i++) { | 17043 for (int i = 0; i < overriddenPositionalPT.length; i++) { |
| 16235 if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i]))
{ | 17044 if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i]))
{ |
| 16236 _errorReporter.reportError3(StaticWarningCode.INVALID_METHOD_OVERRIDE_OP
TIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [ | 17045 _errorReporter.reportError3(StaticWarningCode.INVALID_METHOD_OVERRIDE_OP
TIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [ |
| 16237 overridingPositionalPT[i].displayName, | 17046 overridingPositionalPT[i].displayName, |
| 16238 overriddenPositionalPT[i].displayName, | 17047 overriddenPositionalPT[i].displayName, |
| 16239 overriddenExecutable.enclosingElement.displayName]); | 17048 overriddenExecutable.enclosingElement.displayName]); |
| 16240 return true; | 17049 return true; |
| 16241 } | 17050 } |
| 16242 parameterIndex++; | 17051 parameterIndex++; |
| 16243 } | 17052 } |
| 17053 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFE
RENT_DEFAULT_VALUES |
| 16244 JavaIterator<MapEntry<String, Type2>> overriddenNamedPTIterator = new JavaIt
erator(getMapEntrySet(overriddenNamedPT)); | 17054 JavaIterator<MapEntry<String, Type2>> overriddenNamedPTIterator = new JavaIt
erator(getMapEntrySet(overriddenNamedPT)); |
| 16245 while (overriddenNamedPTIterator.hasNext) { | 17055 while (overriddenNamedPTIterator.hasNext) { |
| 16246 MapEntry<String, Type2> overriddenNamedPTEntry = overriddenNamedPTIterator
.next(); | 17056 MapEntry<String, Type2> overriddenNamedPTEntry = overriddenNamedPTIterator
.next(); |
| 16247 Type2 overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()]; | 17057 Type2 overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()]; |
| 16248 if (overridingType == null) { | 17058 if (overridingType == null) { |
| 17059 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
created above if |
| 17060 // this could be reached. |
| 16249 continue; | 17061 continue; |
| 16250 } | 17062 } |
| 16251 if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) { | 17063 if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) { |
| 17064 // lookup the parameter for the error to select |
| 16252 ParameterElement parameterToSelect = null; | 17065 ParameterElement parameterToSelect = null; |
| 16253 ASTNode parameterLocationToSelect = null; | 17066 ASTNode parameterLocationToSelect = null; |
| 16254 for (int i = 0; i < parameters.length; i++) { | 17067 for (int i = 0; i < parameters.length; i++) { |
| 16255 ParameterElement parameter = parameters[i]; | 17068 ParameterElement parameter = parameters[i]; |
| 16256 if (identical(parameter.parameterKind, ParameterKind.NAMED) && overrid
denNamedPTEntry.getKey() == parameter.name) { | 17069 if (identical(parameter.parameterKind, ParameterKind.NAMED) && overrid
denNamedPTEntry.getKey() == parameter.name) { |
| 16257 parameterToSelect = parameter; | 17070 parameterToSelect = parameter; |
| 16258 parameterLocationToSelect = parameterLocations[i]; | 17071 parameterLocationToSelect = parameterLocations[i]; |
| 16259 break; | 17072 break; |
| 16260 } | 17073 } |
| 16261 } | 17074 } |
| 16262 if (parameterToSelect != null) { | 17075 if (parameterToSelect != null) { |
| 16263 _errorReporter.reportError3(StaticWarningCode.INVALID_METHOD_OVERRIDE_
NAMED_PARAM_TYPE, parameterLocationToSelect, [ | 17076 _errorReporter.reportError3(StaticWarningCode.INVALID_METHOD_OVERRIDE_
NAMED_PARAM_TYPE, parameterLocationToSelect, [ |
| 16264 overridingType.displayName, | 17077 overridingType.displayName, |
| 16265 overriddenNamedPTEntry.getValue().displayName, | 17078 overriddenNamedPTEntry.getValue().displayName, |
| 16266 overriddenExecutable.enclosingElement.displayName]); | 17079 overriddenExecutable.enclosingElement.displayName]); |
| 16267 return true; | 17080 return true; |
| 16268 } | 17081 } |
| 16269 } | 17082 } |
| 16270 } | 17083 } |
| 17084 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES |
| 17085 // |
| 17086 // Create three arrays: an array of the optional parameter ASTs (FormalParam
eters), an array of |
| 17087 // the optional parameters elements from our method, and finally an array of
the optional |
| 17088 // parameter elements from the method we are overriding. |
| 17089 // |
| 16271 bool foundError = false; | 17090 bool foundError = false; |
| 16272 List<ASTNode> formalParameters = new List<ASTNode>(); | 17091 List<ASTNode> formalParameters = new List<ASTNode>(); |
| 16273 List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>(); | 17092 List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>(); |
| 16274 List<ParameterElementImpl> overriddenParameterElts = new List<ParameterEleme
ntImpl>(); | 17093 List<ParameterElementImpl> overriddenParameterElts = new List<ParameterEleme
ntImpl>(); |
| 16275 List<ParameterElement> overriddenPEs = overriddenExecutable.parameters; | 17094 List<ParameterElement> overriddenPEs = overriddenExecutable.parameters; |
| 16276 for (int i = 0; i < parameters.length; i++) { | 17095 for (int i = 0; i < parameters.length; i++) { |
| 16277 ParameterElement parameter = parameters[i]; | 17096 ParameterElement parameter = parameters[i]; |
| 16278 if (parameter.parameterKind.isOptional) { | 17097 if (parameter.parameterKind.isOptional) { |
| 16279 formalParameters.add(parameterLocations[i]); | 17098 formalParameters.add(parameterLocations[i]); |
| 16280 parameterElts.add(parameter as ParameterElementImpl); | 17099 parameterElts.add(parameter as ParameterElementImpl); |
| 16281 } | 17100 } |
| 16282 } | 17101 } |
| 16283 for (ParameterElement parameterElt in overriddenPEs) { | 17102 for (ParameterElement parameterElt in overriddenPEs) { |
| 16284 if (parameterElt.parameterKind.isOptional) { | 17103 if (parameterElt.parameterKind.isOptional) { |
| 16285 if (parameterElt is ParameterElementImpl) { | 17104 if (parameterElt is ParameterElementImpl) { |
| 16286 overriddenParameterElts.add(parameterElt); | 17105 overriddenParameterElts.add(parameterElt); |
| 16287 } | 17106 } |
| 16288 } | 17107 } |
| 16289 } | 17108 } |
| 17109 // |
| 17110 // Next compare the list of optional parameter elements to the list of overr
idden optional |
| 17111 // parameter elements. |
| 17112 // |
| 16290 if (parameterElts.length > 0) { | 17113 if (parameterElts.length > 0) { |
| 16291 if (identical(parameterElts[0].parameterKind, ParameterKind.NAMED)) { | 17114 if (identical(parameterElts[0].parameterKind, ParameterKind.NAMED)) { |
| 17115 // Named parameters, consider the names when matching the parameterElts
to the overriddenParameterElts |
| 16292 for (int i = 0; i < parameterElts.length; i++) { | 17116 for (int i = 0; i < parameterElts.length; i++) { |
| 16293 ParameterElementImpl parameterElt = parameterElts[i]; | 17117 ParameterElementImpl parameterElt = parameterElts[i]; |
| 16294 EvaluationResultImpl result = parameterElt.evaluationResult; | 17118 EvaluationResultImpl result = parameterElt.evaluationResult; |
| 17119 // TODO (jwren) Ignore Object types, see Dart bug 11287 |
| 16295 if (isUserDefinedObject(result)) { | 17120 if (isUserDefinedObject(result)) { |
| 16296 continue; | 17121 continue; |
| 16297 } | 17122 } |
| 16298 String parameterName = parameterElt.name; | 17123 String parameterName = parameterElt.name; |
| 16299 for (int j = 0; j < overriddenParameterElts.length; j++) { | 17124 for (int j = 0; j < overriddenParameterElts.length; j++) { |
| 16300 ParameterElementImpl overriddenParameterElt = overriddenParameterElt
s[j]; | 17125 ParameterElementImpl overriddenParameterElt = overriddenParameterElt
s[j]; |
| 16301 String overriddenParameterName = overriddenParameterElt.name; | 17126 String overriddenParameterName = overriddenParameterElt.name; |
| 16302 if (parameterName != null && parameterName == overriddenParameterNam
e) { | 17127 if (parameterName != null && parameterName == overriddenParameterNam
e) { |
| 16303 EvaluationResultImpl overriddenResult = overriddenParameterElt.eva
luationResult; | 17128 EvaluationResultImpl overriddenResult = overriddenParameterElt.eva
luationResult; |
| 16304 if (isUserDefinedObject(overriddenResult)) { | 17129 if (isUserDefinedObject(overriddenResult)) { |
| 16305 break; | 17130 break; |
| 16306 } | 17131 } |
| 16307 if (!result.equalValues(_typeProvider, overriddenResult)) { | 17132 if (!result.equalValues(_typeProvider, overriddenResult)) { |
| 16308 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_D
IFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [ | 17133 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_D
IFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [ |
| 16309 overriddenExecutable.enclosingElement.displayName, | 17134 overriddenExecutable.enclosingElement.displayName, |
| 16310 overriddenExecutable.displayName, | 17135 overriddenExecutable.displayName, |
| 16311 parameterName]); | 17136 parameterName]); |
| 16312 foundError = true; | 17137 foundError = true; |
| 16313 } | 17138 } |
| 16314 } | 17139 } |
| 16315 } | 17140 } |
| 16316 } | 17141 } |
| 16317 } else { | 17142 } else { |
| 17143 // Positional parameters, consider the positions when matching the param
eterElts to the overriddenParameterElts |
| 16318 for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.
length; i++) { | 17144 for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.
length; i++) { |
| 16319 ParameterElementImpl parameterElt = parameterElts[i]; | 17145 ParameterElementImpl parameterElt = parameterElts[i]; |
| 16320 EvaluationResultImpl result = parameterElt.evaluationResult; | 17146 EvaluationResultImpl result = parameterElt.evaluationResult; |
| 17147 // TODO (jwren) Ignore Object types, see Dart bug 11287 |
| 16321 if (isUserDefinedObject(result)) { | 17148 if (isUserDefinedObject(result)) { |
| 16322 continue; | 17149 continue; |
| 16323 } | 17150 } |
| 16324 ParameterElementImpl overriddenParameterElt = overriddenParameterElts[
i]; | 17151 ParameterElementImpl overriddenParameterElt = overriddenParameterElts[
i]; |
| 16325 EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluat
ionResult; | 17152 EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluat
ionResult; |
| 16326 if (isUserDefinedObject(overriddenResult)) { | 17153 if (isUserDefinedObject(overriddenResult)) { |
| 16327 continue; | 17154 continue; |
| 16328 } | 17155 } |
| 16329 if (!result.equalValues(_typeProvider, overriddenResult)) { | 17156 if (!result.equalValues(_typeProvider, overriddenResult)) { |
| 16330 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_DIFFE
RENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [ | 17157 _errorReporter.reportError3(StaticWarningCode.INVALID_OVERRIDE_DIFFE
RENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [ |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16428 /** | 17255 /** |
| 16429 * This checks error related to the redirected constructors. | 17256 * This checks error related to the redirected constructors. |
| 16430 * | 17257 * |
| 16431 * @param node the constructor declaration to evaluate | 17258 * @param node the constructor declaration to evaluate |
| 16432 * @return `true` if and only if an error code is generated on the passed node | 17259 * @return `true` if and only if an error code is generated on the passed node |
| 16433 * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE | 17260 * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE |
| 16434 * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE | 17261 * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE |
| 16435 * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR | 17262 * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR |
| 16436 */ | 17263 */ |
| 16437 bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { | 17264 bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { |
| 17265 // |
| 17266 // Prepare redirected constructor node |
| 17267 // |
| 16438 ConstructorName redirectedConstructor = node.redirectedConstructor; | 17268 ConstructorName redirectedConstructor = node.redirectedConstructor; |
| 16439 if (redirectedConstructor == null) { | 17269 if (redirectedConstructor == null) { |
| 16440 return false; | 17270 return false; |
| 16441 } | 17271 } |
| 17272 // |
| 17273 // Prepare redirected constructor type |
| 17274 // |
| 16442 ConstructorElement redirectedElement = redirectedConstructor.staticElement; | 17275 ConstructorElement redirectedElement = redirectedConstructor.staticElement; |
| 16443 if (redirectedElement == null) { | 17276 if (redirectedElement == null) { |
| 17277 // |
| 17278 // If the element is null, we check for the REDIRECT_TO_MISSING_CONSTRUCTO
R case |
| 17279 // |
| 16444 TypeName constructorTypeName = redirectedConstructor.type; | 17280 TypeName constructorTypeName = redirectedConstructor.type; |
| 16445 Type2 redirectedType = constructorTypeName.type; | 17281 Type2 redirectedType = constructorTypeName.type; |
| 16446 if (redirectedType != null && redirectedType.element != null && !redirecte
dType.isDynamic) { | 17282 if (redirectedType != null && redirectedType.element != null && !redirecte
dType.isDynamic) { |
| 17283 // |
| 17284 // Prepare the constructor name |
| 17285 // |
| 16447 String constructorStrName = constructorTypeName.name.name; | 17286 String constructorStrName = constructorTypeName.name.name; |
| 16448 if (redirectedConstructor.name != null) { | 17287 if (redirectedConstructor.name != null) { |
| 16449 constructorStrName += ".${redirectedConstructor.name.name}"; | 17288 constructorStrName += ".${redirectedConstructor.name.name}"; |
| 16450 } | 17289 } |
| 16451 ErrorCode errorCode = (node.constKeyword != null ? CompileTimeErrorCode.
REDIRECT_TO_MISSING_CONSTRUCTOR : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUC
TOR) as ErrorCode; | 17290 ErrorCode errorCode = (node.constKeyword != null ? CompileTimeErrorCode.
REDIRECT_TO_MISSING_CONSTRUCTOR : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUC
TOR) as ErrorCode; |
| 16452 _errorReporter.reportError3(errorCode, redirectedConstructor, [construct
orStrName, redirectedType.displayName]); | 17291 _errorReporter.reportError3(errorCode, redirectedConstructor, [construct
orStrName, redirectedType.displayName]); |
| 16453 return true; | 17292 return true; |
| 16454 } | 17293 } |
| 16455 return false; | 17294 return false; |
| 16456 } | 17295 } |
| 16457 FunctionType redirectedType = redirectedElement.type; | 17296 FunctionType redirectedType = redirectedElement.type; |
| 16458 Type2 redirectedReturnType = redirectedType.returnType; | 17297 Type2 redirectedReturnType = redirectedType.returnType; |
| 17298 // |
| 17299 // Report specific problem when return type is incompatible |
| 17300 // |
| 16459 FunctionType constructorType = node.element.type; | 17301 FunctionType constructorType = node.element.type; |
| 16460 Type2 constructorReturnType = constructorType.returnType; | 17302 Type2 constructorReturnType = constructorType.returnType; |
| 16461 if (!redirectedReturnType.isAssignableTo(constructorReturnType)) { | 17303 if (!redirectedReturnType.isAssignableTo(constructorReturnType)) { |
| 16462 _errorReporter.reportError3(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_T
YPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]); | 17304 _errorReporter.reportError3(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_T
YPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]); |
| 16463 return true; | 17305 return true; |
| 16464 } | 17306 } |
| 17307 // |
| 17308 // Check parameters |
| 17309 // |
| 16465 if (!redirectedType.isSubtypeOf(constructorType)) { | 17310 if (!redirectedType.isSubtypeOf(constructorType)) { |
| 16466 _errorReporter.reportError3(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION
_TYPE, redirectedConstructor, [redirectedType, constructorType]); | 17311 _errorReporter.reportError3(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION
_TYPE, redirectedConstructor, [redirectedType, constructorType]); |
| 16467 return true; | 17312 return true; |
| 16468 } | 17313 } |
| 16469 return false; | 17314 return false; |
| 16470 } | 17315 } |
| 16471 | 17316 |
| 16472 /** | 17317 /** |
| 16473 * This checks that the return statement of the form <i>return e;</i> is not i
n a generative | 17318 * This checks that the return statement of the form <i>return e;</i> is not i
n a generative |
| 16474 * constructor. | 17319 * constructor. |
| 16475 * | 17320 * |
| 16476 * This checks that return statements without expressions are not in a generat
ive constructor and | 17321 * This checks that return statements without expressions are not in a generat
ive constructor and |
| 16477 * the return type is not assignable to `null`; that is, we don't have `return
;` if | 17322 * the return type is not assignable to `null`; that is, we don't have `return
;` if |
| 16478 * the enclosing method has a return type. | 17323 * the enclosing method has a return type. |
| 16479 * | 17324 * |
| 16480 * This checks that the return type matches the type of the declared return ty
pe in the enclosing | 17325 * This checks that the return type matches the type of the declared return ty
pe in the enclosing |
| 16481 * method or function. | 17326 * method or function. |
| 16482 * | 17327 * |
| 16483 * @param node the return statement to evaluate | 17328 * @param node the return statement to evaluate |
| 16484 * @return `true` if and only if an error code is generated on the passed node | 17329 * @return `true` if and only if an error code is generated on the passed node |
| 16485 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR | 17330 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 16486 * @see StaticWarningCode#RETURN_WITHOUT_VALUE | 17331 * @see StaticWarningCode#RETURN_WITHOUT_VALUE |
| 16487 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE | 17332 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE |
| 16488 */ | 17333 */ |
| 16489 bool checkForAllReturnStatementErrorCodes(ReturnStatement node) { | 17334 bool checkForAllReturnStatementErrorCodes(ReturnStatement node) { |
| 16490 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu
nction.type; | 17335 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu
nction.type; |
| 16491 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance :
functionType.returnType; | 17336 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance :
functionType.returnType; |
| 16492 Expression returnExpression = node.expression; | 17337 Expression returnExpression = node.expression; |
| 17338 // RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 16493 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !
(_enclosingFunction as ConstructorElement).isFactory; | 17339 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !
(_enclosingFunction as ConstructorElement).isFactory; |
| 16494 if (isGenerativeConstructor) { | 17340 if (isGenerativeConstructor) { |
| 16495 if (returnExpression == null) { | 17341 if (returnExpression == null) { |
| 16496 return false; | 17342 return false; |
| 16497 } | 17343 } |
| 16498 _errorReporter.reportError3(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONS
TRUCTOR, returnExpression, []); | 17344 _errorReporter.reportError3(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONS
TRUCTOR, returnExpression, []); |
| 16499 return true; | 17345 return true; |
| 16500 } | 17346 } |
| 17347 // RETURN_WITHOUT_VALUE |
| 16501 if (returnExpression == null) { | 17348 if (returnExpression == null) { |
| 16502 if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) { | 17349 if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) { |
| 16503 return false; | 17350 return false; |
| 16504 } | 17351 } |
| 16505 _errorReporter.reportError3(StaticWarningCode.RETURN_WITHOUT_VALUE, node,
[]); | 17352 _errorReporter.reportError3(StaticWarningCode.RETURN_WITHOUT_VALUE, node,
[]); |
| 16506 return true; | 17353 return true; |
| 16507 } | 17354 } |
| 17355 // RETURN_OF_INVALID_TYPE |
| 16508 return checkForReturnOfInvalidType(returnExpression, expectedReturnType); | 17356 return checkForReturnOfInvalidType(returnExpression, expectedReturnType); |
| 16509 } | 17357 } |
| 16510 | 17358 |
| 16511 /** | 17359 /** |
| 16512 * This verifies that the export namespace of the passed export directive does
not export any name | 17360 * This verifies that the export namespace of the passed export directive does
not export any name |
| 16513 * already exported by other export directive. | 17361 * already exported by other export directive. |
| 16514 * | 17362 * |
| 16515 * @param node the export directive node to report problem on | 17363 * @param node the export directive node to report problem on |
| 16516 * @return `true` if and only if an error code is generated on the passed node | 17364 * @return `true` if and only if an error code is generated on the passed node |
| 16517 * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT | 17365 * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT |
| 16518 */ | 17366 */ |
| 16519 bool checkForAmbiguousExport(ExportDirective node) { | 17367 bool checkForAmbiguousExport(ExportDirective node) { |
| 17368 // prepare ExportElement |
| 16520 if (node.element is! ExportElement) { | 17369 if (node.element is! ExportElement) { |
| 16521 return false; | 17370 return false; |
| 16522 } | 17371 } |
| 16523 ExportElement exportElement = node.element as ExportElement; | 17372 ExportElement exportElement = node.element as ExportElement; |
| 17373 // prepare exported library |
| 16524 LibraryElement exportedLibrary = exportElement.exportedLibrary; | 17374 LibraryElement exportedLibrary = exportElement.exportedLibrary; |
| 16525 if (exportedLibrary == null) { | 17375 if (exportedLibrary == null) { |
| 16526 return false; | 17376 return false; |
| 16527 } | 17377 } |
| 17378 // check exported names |
| 16528 Namespace namespace = new NamespaceBuilder().createExportNamespace(exportEle
ment); | 17379 Namespace namespace = new NamespaceBuilder().createExportNamespace(exportEle
ment); |
| 16529 Map<String, Element> definedNames = namespace.definedNames; | 17380 Map<String, Element> definedNames = namespace.definedNames; |
| 16530 for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames))
{ | 17381 for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames))
{ |
| 16531 String name = definedEntry.getKey(); | 17382 String name = definedEntry.getKey(); |
| 16532 Element element = definedEntry.getValue(); | 17383 Element element = definedEntry.getValue(); |
| 16533 Element prevElement = _exportedElements[name]; | 17384 Element prevElement = _exportedElements[name]; |
| 16534 if (element != null && prevElement != null && prevElement != element) { | 17385 if (element != null && prevElement != null && prevElement != element) { |
| 16535 _errorReporter.reportError3(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node,
[ | 17386 _errorReporter.reportError3(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node,
[ |
| 16536 name, | 17387 name, |
| 16537 prevElement.library.definingCompilationUnit.displayName, | 17388 prevElement.library.definingCompilationUnit.displayName, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16569 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 17420 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 16570 */ | 17421 */ |
| 16571 bool checkForArgumentTypeNotAssignable(ArgumentList argumentList) { | 17422 bool checkForArgumentTypeNotAssignable(ArgumentList argumentList) { |
| 16572 if (argumentList == null) { | 17423 if (argumentList == null) { |
| 16573 return false; | 17424 return false; |
| 16574 } | 17425 } |
| 16575 bool problemReported = false; | 17426 bool problemReported = false; |
| 16576 for (Expression argument in argumentList.arguments) { | 17427 for (Expression argument in argumentList.arguments) { |
| 16577 problemReported = javaBooleanOr(problemReported, checkForArgumentTypeNotAs
signable2(argument)); | 17428 problemReported = javaBooleanOr(problemReported, checkForArgumentTypeNotAs
signable2(argument)); |
| 16578 } | 17429 } |
| 17430 // done |
| 16579 return problemReported; | 17431 return problemReported; |
| 16580 } | 17432 } |
| 16581 | 17433 |
| 16582 /** | 17434 /** |
| 16583 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 17435 * This verifies that the passed argument can be assigned to its corresponding
parameter. |
| 16584 * | 17436 * |
| 16585 * @param argument the argument to evaluate | 17437 * @param argument the argument to evaluate |
| 16586 * @return `true` if and only if an error code is generated on the passed node | 17438 * @return `true` if and only if an error code is generated on the passed node |
| 16587 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 17439 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 16588 */ | 17440 */ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 16614 * @param expression the expression to evaluate | 17466 * @param expression the expression to evaluate |
| 16615 * @param expectedStaticType the expected static type of the parameter | 17467 * @param expectedStaticType the expected static type of the parameter |
| 16616 * @param actualStaticType the actual static type of the argument | 17468 * @param actualStaticType the actual static type of the argument |
| 16617 * @param expectedPropagatedType the expected propagated type of the parameter
, may be | 17469 * @param expectedPropagatedType the expected propagated type of the parameter
, may be |
| 16618 * `null` | 17470 * `null` |
| 16619 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` | 17471 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` |
| 16620 * @return `true` if and only if an error code is generated on the passed node | 17472 * @return `true` if and only if an error code is generated on the passed node |
| 16621 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 17473 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 16622 */ | 17474 */ |
| 16623 bool checkForArgumentTypeNotAssignable4(Expression expression, Type2 expectedS
taticType, Type2 actualStaticType, Type2 expectedPropagatedType, Type2 actualPro
pagatedType, ErrorCode errorCode) { | 17475 bool checkForArgumentTypeNotAssignable4(Expression expression, Type2 expectedS
taticType, Type2 actualStaticType, Type2 expectedPropagatedType, Type2 actualPro
pagatedType, ErrorCode errorCode) { |
| 17476 // |
| 17477 // Test static type information |
| 17478 // |
| 16624 if (actualStaticType == null || expectedStaticType == null) { | 17479 if (actualStaticType == null || expectedStaticType == null) { |
| 16625 return false; | 17480 return false; |
| 16626 } | 17481 } |
| 16627 if (actualStaticType.isAssignableTo(expectedStaticType)) { | 17482 if (actualStaticType.isAssignableTo(expectedStaticType)) { |
| 16628 return false; | 17483 return false; |
| 16629 } | 17484 } |
| 16630 _errorReporter.reportError3(errorCode, expression, [ | 17485 _errorReporter.reportError3(errorCode, expression, [ |
| 16631 actualStaticType.displayName, | 17486 actualStaticType.displayName, |
| 16632 expectedStaticType.displayName]); | 17487 expectedStaticType.displayName]); |
| 16633 return true; | 17488 return true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 16648 /** | 17503 /** |
| 16649 * This verifies that the passed expression is not final. | 17504 * This verifies that the passed expression is not final. |
| 16650 * | 17505 * |
| 16651 * @param node the expression to evaluate | 17506 * @param node the expression to evaluate |
| 16652 * @return `true` if and only if an error code is generated on the passed node | 17507 * @return `true` if and only if an error code is generated on the passed node |
| 16653 * @see StaticWarningCode#ASSIGNMENT_TO_CONST | 17508 * @see StaticWarningCode#ASSIGNMENT_TO_CONST |
| 16654 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL | 17509 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL |
| 16655 * @see StaticWarningCode#ASSIGNMENT_TO_METHOD | 17510 * @see StaticWarningCode#ASSIGNMENT_TO_METHOD |
| 16656 */ | 17511 */ |
| 16657 bool checkForAssignmentToFinal2(Expression expression) { | 17512 bool checkForAssignmentToFinal2(Expression expression) { |
| 17513 // prepare element |
| 16658 Element element = null; | 17514 Element element = null; |
| 16659 if (expression is Identifier) { | 17515 if (expression is Identifier) { |
| 16660 element = expression.staticElement; | 17516 element = expression.staticElement; |
| 16661 } | 17517 } |
| 16662 if (expression is PropertyAccess) { | 17518 if (expression is PropertyAccess) { |
| 16663 element = expression.propertyName.staticElement; | 17519 element = expression.propertyName.staticElement; |
| 16664 } | 17520 } |
| 17521 // check if element is assignable |
| 16665 if (element is PropertyAccessorElement) { | 17522 if (element is PropertyAccessorElement) { |
| 16666 PropertyAccessorElement accessor = element as PropertyAccessorElement; | 17523 PropertyAccessorElement accessor = element as PropertyAccessorElement; |
| 16667 element = accessor.variable; | 17524 element = accessor.variable; |
| 16668 } | 17525 } |
| 16669 if (element is VariableElement) { | 17526 if (element is VariableElement) { |
| 16670 VariableElement variable = element as VariableElement; | 17527 VariableElement variable = element as VariableElement; |
| 16671 if (variable.isConst) { | 17528 if (variable.isConst) { |
| 16672 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_CONST, expre
ssion, []); | 17529 _errorReporter.reportError3(StaticWarningCode.ASSIGNMENT_TO_CONST, expre
ssion, []); |
| 16673 return true; | 17530 return true; |
| 16674 } | 17531 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16713 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or | 17570 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or |
| 16714 * 'throw'. | 17571 * 'throw'. |
| 16715 * | 17572 * |
| 16716 * @param node the switch case to evaluate | 17573 * @param node the switch case to evaluate |
| 16717 * @return `true` if and only if an error code is generated on the passed node | 17574 * @return `true` if and only if an error code is generated on the passed node |
| 16718 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED | 17575 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED |
| 16719 */ | 17576 */ |
| 16720 bool checkForCaseBlockNotTerminated(SwitchCase node) { | 17577 bool checkForCaseBlockNotTerminated(SwitchCase node) { |
| 16721 NodeList<Statement> statements = node.statements; | 17578 NodeList<Statement> statements = node.statements; |
| 16722 if (statements.isEmpty) { | 17579 if (statements.isEmpty) { |
| 17580 // fall-through without statements at all |
| 16723 ASTNode parent = node.parent; | 17581 ASTNode parent = node.parent; |
| 16724 if (parent is SwitchStatement) { | 17582 if (parent is SwitchStatement) { |
| 16725 SwitchStatement switchStatement = parent; | 17583 SwitchStatement switchStatement = parent; |
| 16726 NodeList<SwitchMember> members = switchStatement.members; | 17584 NodeList<SwitchMember> members = switchStatement.members; |
| 16727 int index = members.indexOf(node); | 17585 int index = members.indexOf(node); |
| 16728 if (index != -1 && index < members.length - 1) { | 17586 if (index != -1 && index < members.length - 1) { |
| 16729 return false; | 17587 return false; |
| 16730 } | 17588 } |
| 16731 } | 17589 } |
| 16732 } else { | 17590 } else { |
| 16733 Statement statement = statements[statements.length - 1]; | 17591 Statement statement = statements[statements.length - 1]; |
| 17592 // terminated with statement |
| 16734 if (statement is BreakStatement || statement is ContinueStatement || state
ment is ReturnStatement) { | 17593 if (statement is BreakStatement || statement is ContinueStatement || state
ment is ReturnStatement) { |
| 16735 return false; | 17594 return false; |
| 16736 } | 17595 } |
| 17596 // terminated with 'throw' expression |
| 16737 if (statement is ExpressionStatement) { | 17597 if (statement is ExpressionStatement) { |
| 16738 Expression expression = statement.expression; | 17598 Expression expression = statement.expression; |
| 16739 if (expression is ThrowExpression) { | 17599 if (expression is ThrowExpression) { |
| 16740 return false; | 17600 return false; |
| 16741 } | 17601 } |
| 16742 } | 17602 } |
| 16743 } | 17603 } |
| 17604 // report error |
| 16744 _errorReporter.reportError6(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, nod
e.keyword, []); | 17605 _errorReporter.reportError6(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, nod
e.keyword, []); |
| 16745 return true; | 17606 return true; |
| 16746 } | 17607 } |
| 16747 | 17608 |
| 16748 /** | 17609 /** |
| 16749 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', | 17610 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', |
| 16750 * 'continue', 'return' or 'throw'. | 17611 * 'continue', 'return' or 'throw'. |
| 16751 * | 17612 * |
| 16752 * @param node the switch statement containing the cases to be checked | 17613 * @param node the switch statement containing the cases to be checked |
| 16753 * @return `true` if and only if an error code is generated on the passed node | 17614 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 18 matching lines...) Expand all Loading... |
| 16772 * | 17633 * |
| 16773 * @param node the switch statement to evaluate | 17634 * @param node the switch statement to evaluate |
| 16774 * @param type the common type of all 'case' expressions | 17635 * @param type the common type of all 'case' expressions |
| 16775 * @return `true` if and only if an error code is generated on the passed node | 17636 * @return `true` if and only if an error code is generated on the passed node |
| 16776 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS | 17637 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS |
| 16777 */ | 17638 */ |
| 16778 bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 ty
pe) { | 17639 bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 ty
pe) { |
| 16779 if (!implementsEqualsWhenNotAllowed(type)) { | 17640 if (!implementsEqualsWhenNotAllowed(type)) { |
| 16780 return false; | 17641 return false; |
| 16781 } | 17642 } |
| 17643 // report error |
| 16782 _errorReporter.reportError6(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEM
ENTS_EQUALS, node.keyword, [type.displayName]); | 17644 _errorReporter.reportError6(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEM
ENTS_EQUALS, node.keyword, [type.displayName]); |
| 16783 return true; | 17645 return true; |
| 16784 } | 17646 } |
| 16785 | 17647 |
| 16786 /** | 17648 /** |
| 16787 * This verifies that the passed method declaration is abstract only if the en
closing class is | 17649 * This verifies that the passed method declaration is abstract only if the en
closing class is |
| 16788 * also abstract. | 17650 * also abstract. |
| 16789 * | 17651 * |
| 16790 * @param node the method declaration to evaluate | 17652 * @param node the method declaration to evaluate |
| 16791 * @return `true` if and only if an error code is generated on the passed node | 17653 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 17 matching lines...) Expand all Loading... |
| 16809 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT | 17671 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT |
| 16810 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME | 17672 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME |
| 16811 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD | 17673 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD |
| 16812 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD | 17674 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD |
| 16813 */ | 17675 */ |
| 16814 bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node)
{ | 17676 bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node)
{ |
| 16815 ConstructorElement constructorElement = node.element; | 17677 ConstructorElement constructorElement = node.element; |
| 16816 SimpleIdentifier constructorName = node.name; | 17678 SimpleIdentifier constructorName = node.name; |
| 16817 String name = constructorElement.name; | 17679 String name = constructorElement.name; |
| 16818 ClassElement classElement = constructorElement.enclosingElement; | 17680 ClassElement classElement = constructorElement.enclosingElement; |
| 17681 // constructors |
| 16819 List<ConstructorElement> constructors = classElement.constructors; | 17682 List<ConstructorElement> constructors = classElement.constructors; |
| 16820 for (ConstructorElement otherConstructor in constructors) { | 17683 for (ConstructorElement otherConstructor in constructors) { |
| 16821 if (identical(otherConstructor, constructorElement)) { | 17684 if (identical(otherConstructor, constructorElement)) { |
| 16822 continue; | 17685 continue; |
| 16823 } | 17686 } |
| 16824 if (name == otherConstructor.name) { | 17687 if (name == otherConstructor.name) { |
| 16825 if (name == null || name.length == 0) { | 17688 if (name == null || name.length == 0) { |
| 16826 _errorReporter.reportError3(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_DEFAULT, node, []); | 17689 _errorReporter.reportError3(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_DEFAULT, node, []); |
| 16827 } else { | 17690 } else { |
| 16828 _errorReporter.reportError3(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_NAME, node, [name]); | 17691 _errorReporter.reportError3(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_NAME, node, [name]); |
| 16829 } | 17692 } |
| 16830 return true; | 17693 return true; |
| 16831 } | 17694 } |
| 16832 } | 17695 } |
| 17696 // conflict with class member |
| 16833 if (constructorName != null && constructorElement != null && !constructorNam
e.isSynthetic) { | 17697 if (constructorName != null && constructorElement != null && !constructorNam
e.isSynthetic) { |
| 17698 // fields |
| 16834 FieldElement field = classElement.getField(name); | 17699 FieldElement field = classElement.getField(name); |
| 16835 if (field != null) { | 17700 if (field != null) { |
| 16836 _errorReporter.reportError3(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR
_NAME_AND_FIELD, node, [name]); | 17701 _errorReporter.reportError3(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR
_NAME_AND_FIELD, node, [name]); |
| 16837 return true; | 17702 return true; |
| 16838 } | 17703 } |
| 17704 // methods |
| 16839 MethodElement method = classElement.getMethod(name); | 17705 MethodElement method = classElement.getMethod(name); |
| 16840 if (method != null) { | 17706 if (method != null) { |
| 16841 _errorReporter.reportError3(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR
_NAME_AND_METHOD, node, [name]); | 17707 _errorReporter.reportError3(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR
_NAME_AND_METHOD, node, [name]); |
| 16842 return true; | 17708 return true; |
| 16843 } | 17709 } |
| 16844 } | 17710 } |
| 16845 return false; | 17711 return false; |
| 16846 } | 17712 } |
| 16847 | 17713 |
| 16848 /** | 17714 /** |
| 16849 * This verifies that the [enclosingClass] does not have method and getter wit
h the same | 17715 * This verifies that the [enclosingClass] does not have method and getter wit
h the same |
| 16850 * names. | 17716 * names. |
| 16851 * | 17717 * |
| 16852 * @return `true` if and only if an error code is generated on the passed node | 17718 * @return `true` if and only if an error code is generated on the passed node |
| 16853 * @see CompileTimeErrorCode#CONFLICTING_GETTER_AND_METHOD | 17719 * @see CompileTimeErrorCode#CONFLICTING_GETTER_AND_METHOD |
| 16854 * @see CompileTimeErrorCode#CONFLICTING_METHOD_AND_GETTER | 17720 * @see CompileTimeErrorCode#CONFLICTING_METHOD_AND_GETTER |
| 16855 */ | 17721 */ |
| 16856 bool checkForConflictingGetterAndMethod() { | 17722 bool checkForConflictingGetterAndMethod() { |
| 16857 if (_enclosingClass == null) { | 17723 if (_enclosingClass == null) { |
| 16858 return false; | 17724 return false; |
| 16859 } | 17725 } |
| 16860 bool hasProblem = false; | 17726 bool hasProblem = false; |
| 17727 // method declared in the enclosing class vs. inherited getter |
| 16861 for (MethodElement method in _enclosingClass.methods) { | 17728 for (MethodElement method in _enclosingClass.methods) { |
| 16862 String name = method.name; | 17729 String name = method.name; |
| 17730 // find inherited property accessor (and can be only getter) |
| 16863 ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclo
singClass, name); | 17731 ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclo
singClass, name); |
| 16864 if (inherited is! PropertyAccessorElement) { | 17732 if (inherited is! PropertyAccessorElement) { |
| 16865 continue; | 17733 continue; |
| 16866 } | 17734 } |
| 17735 // report problem |
| 16867 hasProblem = true; | 17736 hasProblem = true; |
| 16868 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_GETTER_AND_ME
THOD, method.nameOffset, name.length, [ | 17737 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_GETTER_AND_ME
THOD, method.nameOffset, name.length, [ |
| 16869 _enclosingClass.displayName, | 17738 _enclosingClass.displayName, |
| 16870 inherited.enclosingElement.displayName, | 17739 inherited.enclosingElement.displayName, |
| 16871 name]); | 17740 name]); |
| 16872 } | 17741 } |
| 17742 // getter declared in the enclosing class vs. inherited method |
| 16873 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 17743 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
| 16874 if (!accessor.isGetter) { | 17744 if (!accessor.isGetter) { |
| 16875 continue; | 17745 continue; |
| 16876 } | 17746 } |
| 16877 String name = accessor.name; | 17747 String name = accessor.name; |
| 17748 // find inherited method |
| 16878 ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclo
singClass, name); | 17749 ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclo
singClass, name); |
| 16879 if (inherited is! MethodElement) { | 17750 if (inherited is! MethodElement) { |
| 16880 continue; | 17751 continue; |
| 16881 } | 17752 } |
| 17753 // report problem |
| 16882 hasProblem = true; | 17754 hasProblem = true; |
| 16883 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_METHOD_AND_GE
TTER, accessor.nameOffset, name.length, [ | 17755 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_METHOD_AND_GE
TTER, accessor.nameOffset, name.length, [ |
| 16884 _enclosingClass.displayName, | 17756 _enclosingClass.displayName, |
| 16885 inherited.enclosingElement.displayName, | 17757 inherited.enclosingElement.displayName, |
| 16886 name]); | 17758 name]); |
| 16887 } | 17759 } |
| 17760 // done |
| 16888 return hasProblem; | 17761 return hasProblem; |
| 16889 } | 17762 } |
| 16890 | 17763 |
| 16891 /** | 17764 /** |
| 16892 * This verifies that the superclass of the [enclosingClass] does not declare
accessible | 17765 * This verifies that the superclass of the [enclosingClass] does not declare
accessible |
| 16893 * static members with the same name as the instance getters/setters declared
in | 17766 * static members with the same name as the instance getters/setters declared
in |
| 16894 * [enclosingClass]. | 17767 * [enclosingClass]. |
| 16895 * | 17768 * |
| 16896 * @param node the method declaration to evaluate | 17769 * @param node the method declaration to evaluate |
| 16897 * @return `true` if and only if an error code is generated on the passed node | 17770 * @return `true` if and only if an error code is generated on the passed node |
| 16898 * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER | 17771 * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER |
| 16899 * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER | 17772 * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER |
| 16900 */ | 17773 */ |
| 16901 bool checkForConflictingInstanceGetterAndSuperclassMember() { | 17774 bool checkForConflictingInstanceGetterAndSuperclassMember() { |
| 16902 if (_enclosingClass == null) { | 17775 if (_enclosingClass == null) { |
| 16903 return false; | 17776 return false; |
| 16904 } | 17777 } |
| 16905 InterfaceType enclosingType = _enclosingClass.type; | 17778 InterfaceType enclosingType = _enclosingClass.type; |
| 17779 // check every accessor |
| 16906 bool hasProblem = false; | 17780 bool hasProblem = false; |
| 16907 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 17781 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
| 17782 // we analyze instance accessors here |
| 16908 if (accessor.isStatic) { | 17783 if (accessor.isStatic) { |
| 16909 continue; | 17784 continue; |
| 16910 } | 17785 } |
| 17786 // prepare accessor properties |
| 16911 String name = accessor.displayName; | 17787 String name = accessor.displayName; |
| 16912 bool getter = accessor.isGetter; | 17788 bool getter = accessor.isGetter; |
| 17789 // if non-final variable, ignore setter - we alreay reported problem for g
etter |
| 16913 if (accessor.isSetter && accessor.isSynthetic) { | 17790 if (accessor.isSetter && accessor.isSynthetic) { |
| 16914 continue; | 17791 continue; |
| 16915 } | 17792 } |
| 17793 // try to find super element |
| 16916 ExecutableElement superElement; | 17794 ExecutableElement superElement; |
| 16917 superElement = enclosingType.lookUpGetterInSuperclass(name, _currentLibrar
y); | 17795 superElement = enclosingType.lookUpGetterInSuperclass(name, _currentLibrar
y); |
| 16918 if (superElement == null) { | 17796 if (superElement == null) { |
| 16919 superElement = enclosingType.lookUpSetterInSuperclass(name, _currentLibr
ary); | 17797 superElement = enclosingType.lookUpSetterInSuperclass(name, _currentLibr
ary); |
| 16920 } | 17798 } |
| 16921 if (superElement == null) { | 17799 if (superElement == null) { |
| 16922 superElement = enclosingType.lookUpMethodInSuperclass(name, _currentLibr
ary); | 17800 superElement = enclosingType.lookUpMethodInSuperclass(name, _currentLibr
ary); |
| 16923 } | 17801 } |
| 16924 if (superElement == null) { | 17802 if (superElement == null) { |
| 16925 continue; | 17803 continue; |
| 16926 } | 17804 } |
| 17805 // OK, not static |
| 16927 if (!superElement.isStatic) { | 17806 if (!superElement.isStatic) { |
| 16928 continue; | 17807 continue; |
| 16929 } | 17808 } |
| 17809 // prepare "super" type to report its name |
| 16930 ClassElement superElementClass = superElement.enclosingElement as ClassEle
ment; | 17810 ClassElement superElementClass = superElement.enclosingElement as ClassEle
ment; |
| 16931 InterfaceType superElementType = superElementClass.type; | 17811 InterfaceType superElementType = superElementClass.type; |
| 17812 // report problem |
| 16932 hasProblem = true; | 17813 hasProblem = true; |
| 16933 if (getter) { | 17814 if (getter) { |
| 16934 _errorReporter.reportError4(StaticWarningCode.CONFLICTING_INSTANCE_GETTE
R_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]); | 17815 _errorReporter.reportError4(StaticWarningCode.CONFLICTING_INSTANCE_GETTE
R_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]); |
| 16935 } else { | 17816 } else { |
| 16936 _errorReporter.reportError4(StaticWarningCode.CONFLICTING_INSTANCE_SETTE
R_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]); | 17817 _errorReporter.reportError4(StaticWarningCode.CONFLICTING_INSTANCE_SETTE
R_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]); |
| 16937 } | 17818 } |
| 16938 } | 17819 } |
| 17820 // done |
| 16939 return hasProblem; | 17821 return hasProblem; |
| 16940 } | 17822 } |
| 16941 | 17823 |
| 16942 /** | 17824 /** |
| 16943 * This verifies that the enclosing class does not have a setter with the same
name as the passed | 17825 * This verifies that the enclosing class does not have a setter with the same
name as the passed |
| 16944 * instance method declaration. | 17826 * instance method declaration. |
| 16945 * | 17827 * |
| 16946 * @param node the method declaration to evaluate | 17828 * @param node the method declaration to evaluate |
| 16947 * @return `true` if and only if an error code is generated on the passed node | 17829 * @return `true` if and only if an error code is generated on the passed node |
| 16948 * @see StaticWarningCode#CONFLICTING_INSTANCE_METHOD_SETTER | 17830 * @see StaticWarningCode#CONFLICTING_INSTANCE_METHOD_SETTER |
| 16949 */ | 17831 */ |
| 16950 bool checkForConflictingInstanceMethodSetter(MethodDeclaration node) { | 17832 bool checkForConflictingInstanceMethodSetter(MethodDeclaration node) { |
| 16951 if (node.isStatic) { | 17833 if (node.isStatic) { |
| 16952 return false; | 17834 return false; |
| 16953 } | 17835 } |
| 17836 // prepare name |
| 16954 SimpleIdentifier nameNode = node.name; | 17837 SimpleIdentifier nameNode = node.name; |
| 16955 if (nameNode == null) { | 17838 if (nameNode == null) { |
| 16956 return false; | 17839 return false; |
| 16957 } | 17840 } |
| 16958 String name = nameNode.name; | 17841 String name = nameNode.name; |
| 17842 // ensure that we have enclosing class |
| 16959 if (_enclosingClass == null) { | 17843 if (_enclosingClass == null) { |
| 16960 return false; | 17844 return false; |
| 16961 } | 17845 } |
| 17846 // try to find setter |
| 16962 ExecutableElement setter = _inheritanceManager.lookupMember(_enclosingClass,
"${name}="); | 17847 ExecutableElement setter = _inheritanceManager.lookupMember(_enclosingClass,
"${name}="); |
| 16963 if (setter == null) { | 17848 if (setter == null) { |
| 16964 return false; | 17849 return false; |
| 16965 } | 17850 } |
| 17851 // report problem |
| 16966 _errorReporter.reportError3(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SE
TTER, nameNode, [ | 17852 _errorReporter.reportError3(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SE
TTER, nameNode, [ |
| 16967 _enclosingClass.displayName, | 17853 _enclosingClass.displayName, |
| 16968 name, | 17854 name, |
| 16969 setter.enclosingElement.displayName]); | 17855 setter.enclosingElement.displayName]); |
| 16970 return true; | 17856 return true; |
| 16971 } | 17857 } |
| 16972 | 17858 |
| 16973 /** | 17859 /** |
| 16974 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 17860 * This verifies that the enclosing class does not have an instance member wit
h the same name as |
| 16975 * the passed static getter method declaration. | 17861 * the passed static getter method declaration. |
| 16976 * | 17862 * |
| 16977 * @param node the method declaration to evaluate | 17863 * @param node the method declaration to evaluate |
| 16978 * @return `true` if and only if an error code is generated on the passed node | 17864 * @return `true` if and only if an error code is generated on the passed node |
| 16979 * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER | 17865 * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER |
| 16980 */ | 17866 */ |
| 16981 bool checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node)
{ | 17867 bool checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node)
{ |
| 16982 if (!node.isStatic) { | 17868 if (!node.isStatic) { |
| 16983 return false; | 17869 return false; |
| 16984 } | 17870 } |
| 17871 // prepare name |
| 16985 SimpleIdentifier nameNode = node.name; | 17872 SimpleIdentifier nameNode = node.name; |
| 16986 if (nameNode == null) { | 17873 if (nameNode == null) { |
| 16987 return false; | 17874 return false; |
| 16988 } | 17875 } |
| 16989 String name = nameNode.name; | 17876 String name = nameNode.name; |
| 17877 // prepare enclosing type |
| 16990 if (_enclosingClass == null) { | 17878 if (_enclosingClass == null) { |
| 16991 return false; | 17879 return false; |
| 16992 } | 17880 } |
| 16993 InterfaceType enclosingType = _enclosingClass.type; | 17881 InterfaceType enclosingType = _enclosingClass.type; |
| 17882 // try to find setter |
| 16994 ExecutableElement setter = enclosingType.lookUpSetter(name, _currentLibrary)
; | 17883 ExecutableElement setter = enclosingType.lookUpSetter(name, _currentLibrary)
; |
| 16995 if (setter == null) { | 17884 if (setter == null) { |
| 16996 return false; | 17885 return false; |
| 16997 } | 17886 } |
| 17887 // OK, also static |
| 16998 if (setter.isStatic) { | 17888 if (setter.isStatic) { |
| 16999 return false; | 17889 return false; |
| 17000 } | 17890 } |
| 17891 // prepare "setter" type to report its name |
| 17001 ClassElement setterClass = setter.enclosingElement as ClassElement; | 17892 ClassElement setterClass = setter.enclosingElement as ClassElement; |
| 17002 InterfaceType setterType = setterClass.type; | 17893 InterfaceType setterType = setterClass.type; |
| 17894 // report problem |
| 17003 _errorReporter.reportError3(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_
INSTANCE_SETTER, nameNode, [setterType.displayName]); | 17895 _errorReporter.reportError3(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_
INSTANCE_SETTER, nameNode, [setterType.displayName]); |
| 17004 return true; | 17896 return true; |
| 17005 } | 17897 } |
| 17006 | 17898 |
| 17007 /** | 17899 /** |
| 17008 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 17900 * This verifies that the enclosing class does not have an instance member wit
h the same name as |
| 17009 * the passed static getter method declaration. | 17901 * the passed static getter method declaration. |
| 17010 * | 17902 * |
| 17011 * @param node the method declaration to evaluate | 17903 * @param node the method declaration to evaluate |
| 17012 * @return `true` if and only if an error code is generated on the passed node | 17904 * @return `true` if and only if an error code is generated on the passed node |
| 17013 * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER | 17905 * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER |
| 17014 */ | 17906 */ |
| 17015 bool checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node)
{ | 17907 bool checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node)
{ |
| 17016 if (!node.isStatic) { | 17908 if (!node.isStatic) { |
| 17017 return false; | 17909 return false; |
| 17018 } | 17910 } |
| 17911 // prepare name |
| 17019 SimpleIdentifier nameNode = node.name; | 17912 SimpleIdentifier nameNode = node.name; |
| 17020 if (nameNode == null) { | 17913 if (nameNode == null) { |
| 17021 return false; | 17914 return false; |
| 17022 } | 17915 } |
| 17023 String name = nameNode.name; | 17916 String name = nameNode.name; |
| 17917 // prepare enclosing type |
| 17024 if (_enclosingClass == null) { | 17918 if (_enclosingClass == null) { |
| 17025 return false; | 17919 return false; |
| 17026 } | 17920 } |
| 17027 InterfaceType enclosingType = _enclosingClass.type; | 17921 InterfaceType enclosingType = _enclosingClass.type; |
| 17922 // try to find member |
| 17028 ExecutableElement member; | 17923 ExecutableElement member; |
| 17029 member = enclosingType.lookUpMethod(name, _currentLibrary); | 17924 member = enclosingType.lookUpMethod(name, _currentLibrary); |
| 17030 if (member == null) { | 17925 if (member == null) { |
| 17031 member = enclosingType.lookUpGetter(name, _currentLibrary); | 17926 member = enclosingType.lookUpGetter(name, _currentLibrary); |
| 17032 } | 17927 } |
| 17033 if (member == null) { | 17928 if (member == null) { |
| 17034 member = enclosingType.lookUpSetter(name, _currentLibrary); | 17929 member = enclosingType.lookUpSetter(name, _currentLibrary); |
| 17035 } | 17930 } |
| 17036 if (member == null) { | 17931 if (member == null) { |
| 17037 return false; | 17932 return false; |
| 17038 } | 17933 } |
| 17934 // OK, also static |
| 17039 if (member.isStatic) { | 17935 if (member.isStatic) { |
| 17040 return false; | 17936 return false; |
| 17041 } | 17937 } |
| 17938 // prepare "member" type to report its name |
| 17042 ClassElement memberClass = member.enclosingElement as ClassElement; | 17939 ClassElement memberClass = member.enclosingElement as ClassElement; |
| 17043 InterfaceType memberType = memberClass.type; | 17940 InterfaceType memberType = memberClass.type; |
| 17941 // report problem |
| 17044 _errorReporter.reportError3(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_
INSTANCE_MEMBER, nameNode, [memberType.displayName]); | 17942 _errorReporter.reportError3(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_
INSTANCE_MEMBER, nameNode, [memberType.displayName]); |
| 17045 return true; | 17943 return true; |
| 17046 } | 17944 } |
| 17047 | 17945 |
| 17048 /** | 17946 /** |
| 17049 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) | 17947 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) |
| 17050 * | 17948 * |
| 17051 * @param node the class declaration to evaluate | 17949 * @param node the class declaration to evaluate |
| 17052 * @return `true` if and only if an error code is generated on the passed node | 17950 * @return `true` if and only if an error code is generated on the passed node |
| 17053 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_CLASS | 17951 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_CLASS |
| 17054 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_MEMBER | 17952 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_MEMBER |
| 17055 */ | 17953 */ |
| 17056 bool checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { | 17954 bool checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { |
| 17057 bool problemReported = false; | 17955 bool problemReported = false; |
| 17058 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { | 17956 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { |
| 17059 String name = typeParameter.name; | 17957 String name = typeParameter.name; |
| 17958 // name is same as the name of the enclosing class |
| 17060 if (_enclosingClass.name == name) { | 17959 if (_enclosingClass.name == name) { |
| 17061 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_TYPE_VARIAB
LE_AND_CLASS, typeParameter.nameOffset, name.length, [name]); | 17960 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_TYPE_VARIAB
LE_AND_CLASS, typeParameter.nameOffset, name.length, [name]); |
| 17062 problemReported = true; | 17961 problemReported = true; |
| 17063 } | 17962 } |
| 17963 // check members |
| 17064 if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(n
ame) != null || _enclosingClass.getSetter(name) != null) { | 17964 if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(n
ame) != null || _enclosingClass.getSetter(name) != null) { |
| 17065 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_TYPE_VARIAB
LE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]); | 17965 _errorReporter.reportError5(CompileTimeErrorCode.CONFLICTING_TYPE_VARIAB
LE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]); |
| 17066 problemReported = true; | 17966 problemReported = true; |
| 17067 } | 17967 } |
| 17068 } | 17968 } |
| 17069 return problemReported; | 17969 return problemReported; |
| 17070 } | 17970 } |
| 17071 | 17971 |
| 17072 /** | 17972 /** |
| 17073 * This verifies that if the passed constructor declaration is 'const' then th
ere are no | 17973 * This verifies that if the passed constructor declaration is 'const' then th
ere are no |
| 17074 * invocations of non-'const' super constructors. | 17974 * invocations of non-'const' super constructors. |
| 17075 * | 17975 * |
| 17076 * @param node the constructor declaration to evaluate | 17976 * @param node the constructor declaration to evaluate |
| 17077 * @return `true` if and only if an error code is generated on the passed node | 17977 * @return `true` if and only if an error code is generated on the passed node |
| 17078 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER | 17978 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER |
| 17079 */ | 17979 */ |
| 17080 bool checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { | 17980 bool checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { |
| 17081 if (!_isEnclosingConstructorConst) { | 17981 if (!_isEnclosingConstructorConst) { |
| 17082 return false; | 17982 return false; |
| 17083 } | 17983 } |
| 17984 // OK, const factory, checked elsewhere |
| 17084 if (node.factoryKeyword != null) { | 17985 if (node.factoryKeyword != null) { |
| 17085 return false; | 17986 return false; |
| 17086 } | 17987 } |
| 17988 // try to find and check super constructor invocation |
| 17087 for (ConstructorInitializer initializer in node.initializers) { | 17989 for (ConstructorInitializer initializer in node.initializers) { |
| 17088 if (initializer is SuperConstructorInvocation) { | 17990 if (initializer is SuperConstructorInvocation) { |
| 17089 SuperConstructorInvocation superInvocation = initializer; | 17991 SuperConstructorInvocation superInvocation = initializer; |
| 17090 ConstructorElement element = superInvocation.staticElement; | 17992 ConstructorElement element = superInvocation.staticElement; |
| 17091 if (element == null || element.isConst) { | 17993 if (element == null || element.isConst) { |
| 17092 return false; | 17994 return false; |
| 17093 } | 17995 } |
| 17094 _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_
NON_CONST_SUPER, superInvocation, []); | 17996 _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_
NON_CONST_SUPER, superInvocation, []); |
| 17095 return true; | 17997 return true; |
| 17096 } | 17998 } |
| 17097 } | 17999 } |
| 18000 // no explicit super constructor invocation, check default constructor |
| 17098 InterfaceType supertype = _enclosingClass.supertype; | 18001 InterfaceType supertype = _enclosingClass.supertype; |
| 17099 if (supertype == null) { | 18002 if (supertype == null) { |
| 17100 return false; | 18003 return false; |
| 17101 } | 18004 } |
| 17102 if (supertype.isObject) { | 18005 if (supertype.isObject) { |
| 17103 return false; | 18006 return false; |
| 17104 } | 18007 } |
| 17105 ConstructorElement unnamedConstructor = supertype.element.unnamedConstructor
; | 18008 ConstructorElement unnamedConstructor = supertype.element.unnamedConstructor
; |
| 17106 if (unnamedConstructor == null) { | 18009 if (unnamedConstructor == null) { |
| 17107 return false; | 18010 return false; |
| 17108 } | 18011 } |
| 17109 if (unnamedConstructor.isConst) { | 18012 if (unnamedConstructor.isConst) { |
| 17110 return false; | 18013 return false; |
| 17111 } | 18014 } |
| 18015 // default constructor is not 'const', report problem |
| 17112 _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_
CONST_SUPER, node, []); | 18016 _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_
CONST_SUPER, node, []); |
| 17113 return true; | 18017 return true; |
| 17114 } | 18018 } |
| 17115 | 18019 |
| 17116 /** | 18020 /** |
| 17117 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final | 18021 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final |
| 17118 * instance variable. | 18022 * instance variable. |
| 17119 * | 18023 * |
| 17120 * @param node the constructor declaration to evaluate | 18024 * @param node the constructor declaration to evaluate |
| 17121 * @return `true` if and only if an error code is generated on the passed node | 18025 * @return `true` if and only if an error code is generated on the passed node |
| 17122 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD | 18026 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD |
| 17123 */ | 18027 */ |
| 17124 bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) { | 18028 bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) { |
| 17125 if (!_isEnclosingConstructorConst) { | 18029 if (!_isEnclosingConstructorConst) { |
| 17126 return false; | 18030 return false; |
| 17127 } | 18031 } |
| 18032 // check if there is non-final field |
| 17128 ConstructorElement constructorElement = node.element; | 18033 ConstructorElement constructorElement = node.element; |
| 17129 ClassElement classElement = constructorElement.enclosingElement; | 18034 ClassElement classElement = constructorElement.enclosingElement; |
| 17130 if (!classElement.hasNonFinalField()) { | 18035 if (!classElement.hasNonFinalField()) { |
| 17131 return false; | 18036 return false; |
| 17132 } | 18037 } |
| 18038 // report problem |
| 17133 _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_
FINAL_FIELD, node, []); | 18039 _errorReporter.reportError3(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_
FINAL_FIELD, node, []); |
| 17134 return true; | 18040 return true; |
| 17135 } | 18041 } |
| 17136 | 18042 |
| 17137 /** | 18043 /** |
| 17138 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor | 18044 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor |
| 17139 * declaration. | 18045 * declaration. |
| 17140 * | 18046 * |
| 17141 * @param node the throw expression expression to evaluate | 18047 * @param node the throw expression expression to evaluate |
| 17142 * @return `true` if and only if an error code is generated on the passed node | 18048 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 28 matching lines...) Expand all Loading... |
| 17171 * | 18077 * |
| 17172 * @param key the expression to evaluate | 18078 * @param key the expression to evaluate |
| 17173 * @return `true` if and only if an error code is generated on the passed node | 18079 * @return `true` if and only if an error code is generated on the passed node |
| 17174 * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS | 18080 * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS |
| 17175 */ | 18081 */ |
| 17176 bool checkForConstMapKeyExpressionTypeImplementsEquals(Expression key) { | 18082 bool checkForConstMapKeyExpressionTypeImplementsEquals(Expression key) { |
| 17177 Type2 type = key.staticType; | 18083 Type2 type = key.staticType; |
| 17178 if (!implementsEqualsWhenNotAllowed(type)) { | 18084 if (!implementsEqualsWhenNotAllowed(type)) { |
| 17179 return false; | 18085 return false; |
| 17180 } | 18086 } |
| 18087 // report error |
| 17181 _errorReporter.reportError3(CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TY
PE_IMPLEMENTS_EQUALS, key, [type.displayName]); | 18088 _errorReporter.reportError3(CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TY
PE_IMPLEMENTS_EQUALS, key, [type.displayName]); |
| 17182 return true; | 18089 return true; |
| 17183 } | 18090 } |
| 17184 | 18091 |
| 17185 /** | 18092 /** |
| 17186 * This verifies that the all keys of the passed map literal have class type t
hat does not declare | 18093 * This verifies that the all keys of the passed map literal have class type t
hat does not declare |
| 17187 * operator <i>==<i>. | 18094 * operator <i>==<i>. |
| 17188 * | 18095 * |
| 17189 * @param key the map literal to evaluate | 18096 * @param key the map literal to evaluate |
| 17190 * @return `true` if and only if an error code is generated on the passed node | 18097 * @return `true` if and only if an error code is generated on the passed node |
| 17191 * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS | 18098 * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS |
| 17192 */ | 18099 */ |
| 17193 bool checkForConstMapKeyExpressionTypeImplementsEquals2(MapLiteral node) { | 18100 bool checkForConstMapKeyExpressionTypeImplementsEquals2(MapLiteral node) { |
| 18101 // OK, not const. |
| 17194 if (node.constKeyword == null) { | 18102 if (node.constKeyword == null) { |
| 17195 return false; | 18103 return false; |
| 17196 } | 18104 } |
| 18105 // Check every map entry. |
| 17197 bool hasProblems = false; | 18106 bool hasProblems = false; |
| 17198 for (MapLiteralEntry entry in node.entries) { | 18107 for (MapLiteralEntry entry in node.entries) { |
| 17199 Expression key = entry.key; | 18108 Expression key = entry.key; |
| 17200 hasProblems = javaBooleanOr(hasProblems, checkForConstMapKeyExpressionType
ImplementsEquals(key)); | 18109 hasProblems = javaBooleanOr(hasProblems, checkForConstMapKeyExpressionType
ImplementsEquals(key)); |
| 17201 } | 18110 } |
| 17202 return hasProblems; | 18111 return hasProblems; |
| 17203 } | 18112 } |
| 17204 | 18113 |
| 17205 /** | 18114 /** |
| 17206 * This verifies that the passed instance creation expression is not being inv
oked on an abstract | 18115 * This verifies that the passed instance creation expression is not being inv
oked on an abstract |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17268 } | 18177 } |
| 17269 | 18178 |
| 17270 /** | 18179 /** |
| 17271 * This verifies that the passed type name does not reference any type paramet
ers. | 18180 * This verifies that the passed type name does not reference any type paramet
ers. |
| 17272 * | 18181 * |
| 17273 * @param typeName the type name to evaluate | 18182 * @param typeName the type name to evaluate |
| 17274 * @return `true` if and only if an error code is generated on the passed node | 18183 * @return `true` if and only if an error code is generated on the passed node |
| 17275 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS | 18184 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS |
| 17276 */ | 18185 */ |
| 17277 bool checkForConstWithTypeParameters2(TypeName typeName) { | 18186 bool checkForConstWithTypeParameters2(TypeName typeName) { |
| 18187 // something wrong with AST |
| 17278 if (typeName == null) { | 18188 if (typeName == null) { |
| 17279 return false; | 18189 return false; |
| 17280 } | 18190 } |
| 17281 Identifier name = typeName.name; | 18191 Identifier name = typeName.name; |
| 17282 if (name == null) { | 18192 if (name == null) { |
| 17283 return false; | 18193 return false; |
| 17284 } | 18194 } |
| 18195 // should not be a type parameter |
| 17285 if (name.staticElement is TypeParameterElement) { | 18196 if (name.staticElement is TypeParameterElement) { |
| 17286 _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETER
S, name, []); | 18197 _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETER
S, name, []); |
| 17287 } | 18198 } |
| 18199 // check type arguments |
| 17288 TypeArgumentList typeArguments = typeName.typeArguments; | 18200 TypeArgumentList typeArguments = typeName.typeArguments; |
| 17289 if (typeArguments != null) { | 18201 if (typeArguments != null) { |
| 17290 bool hasError = false; | 18202 bool hasError = false; |
| 17291 for (TypeName argument in typeArguments.arguments) { | 18203 for (TypeName argument in typeArguments.arguments) { |
| 17292 hasError = javaBooleanOr(hasError, checkForConstWithTypeParameters2(argu
ment)); | 18204 hasError = javaBooleanOr(hasError, checkForConstWithTypeParameters2(argu
ment)); |
| 17293 } | 18205 } |
| 17294 return hasError; | 18206 return hasError; |
| 17295 } | 18207 } |
| 18208 // OK |
| 17296 return false; | 18209 return false; |
| 17297 } | 18210 } |
| 17298 | 18211 |
| 17299 /** | 18212 /** |
| 17300 * This verifies that if the passed 'const' instance creation expression is be
ing invoked on the | 18213 * This verifies that if the passed 'const' instance creation expression is be
ing invoked on the |
| 17301 * resolved constructor. | 18214 * resolved constructor. |
| 17302 * | 18215 * |
| 17303 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 18216 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. |
| 17304 * | 18217 * |
| 17305 * @param node the instance creation expression to evaluate | 18218 * @param node the instance creation expression to evaluate |
| 17306 * @return `true` if and only if an error code is generated on the passed node | 18219 * @return `true` if and only if an error code is generated on the passed node |
| 17307 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR | 18220 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR |
| 17308 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT | 18221 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT |
| 17309 */ | 18222 */ |
| 17310 bool checkForConstWithUndefinedConstructor(InstanceCreationExpression node) { | 18223 bool checkForConstWithUndefinedConstructor(InstanceCreationExpression node) { |
| 18224 // OK if resolved |
| 17311 if (node.staticElement != null) { | 18225 if (node.staticElement != null) { |
| 17312 return false; | 18226 return false; |
| 17313 } | 18227 } |
| 18228 // prepare constructor name |
| 17314 ConstructorName constructorName = node.constructorName; | 18229 ConstructorName constructorName = node.constructorName; |
| 17315 if (constructorName == null) { | 18230 if (constructorName == null) { |
| 17316 return false; | 18231 return false; |
| 17317 } | 18232 } |
| 18233 // prepare class name |
| 17318 TypeName type = constructorName.type; | 18234 TypeName type = constructorName.type; |
| 17319 if (type == null) { | 18235 if (type == null) { |
| 17320 return false; | 18236 return false; |
| 17321 } | 18237 } |
| 17322 Identifier className = type.name; | 18238 Identifier className = type.name; |
| 18239 // report as named or default constructor absence |
| 17323 SimpleIdentifier name = constructorName.name; | 18240 SimpleIdentifier name = constructorName.name; |
| 17324 if (name != null) { | 18241 if (name != null) { |
| 17325 _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONS
TRUCTOR, name, [className, name]); | 18242 _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONS
TRUCTOR, name, [className, name]); |
| 17326 } else { | 18243 } else { |
| 17327 _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONS
TRUCTOR_DEFAULT, constructorName, [className]); | 18244 _errorReporter.reportError3(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONS
TRUCTOR_DEFAULT, constructorName, [className]); |
| 17328 } | 18245 } |
| 17329 return true; | 18246 return true; |
| 17330 } | 18247 } |
| 17331 | 18248 |
| 17332 /** | 18249 /** |
| (...skipping 21 matching lines...) Expand all Loading... |
| 17354 | 18271 |
| 17355 /** | 18272 /** |
| 17356 * This verifies that the given default formal parameter is not part of a func
tion typed | 18273 * This verifies that the given default formal parameter is not part of a func
tion typed |
| 17357 * parameter. | 18274 * parameter. |
| 17358 * | 18275 * |
| 17359 * @param node the default formal parameter to evaluate | 18276 * @param node the default formal parameter to evaluate |
| 17360 * @return `true` if and only if an error code is generated on the passed node | 18277 * @return `true` if and only if an error code is generated on the passed node |
| 17361 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER | 18278 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER |
| 17362 */ | 18279 */ |
| 17363 bool checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node)
{ | 18280 bool checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node)
{ |
| 18281 // OK, not in a function typed parameter. |
| 17364 if (!_isInFunctionTypedFormalParameter) { | 18282 if (!_isInFunctionTypedFormalParameter) { |
| 17365 return false; | 18283 return false; |
| 17366 } | 18284 } |
| 18285 // OK, no default value. |
| 17367 if (node.defaultValue == null) { | 18286 if (node.defaultValue == null) { |
| 17368 return false; | 18287 return false; |
| 17369 } | 18288 } |
| 18289 // Report problem. |
| 17370 _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_T
YPED_PARAMETER, node, []); | 18290 _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_T
YPED_PARAMETER, node, []); |
| 17371 return true; | 18291 return true; |
| 17372 } | 18292 } |
| 17373 | 18293 |
| 17374 /** | 18294 /** |
| 17375 * This verifies that the enclosing class does not have an instance member wit
h the given name of | 18295 * This verifies that the enclosing class does not have an instance member wit
h the given name of |
| 17376 * the static member. | 18296 * the static member. |
| 17377 * | 18297 * |
| 17378 * @return `true` if and only if an error code is generated on the passed node | 18298 * @return `true` if and only if an error code is generated on the passed node |
| 17379 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE | 18299 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE |
| (...skipping 20 matching lines...) Expand all Loading... |
| 17400 | 18320 |
| 17401 /** | 18321 /** |
| 17402 * This verifies that the enclosing class does not have an instance member wit
h the given name of | 18322 * This verifies that the enclosing class does not have an instance member wit
h the given name of |
| 17403 * the static member. | 18323 * the static member. |
| 17404 * | 18324 * |
| 17405 * @param staticMember the static member to check conflict for | 18325 * @param staticMember the static member to check conflict for |
| 17406 * @return `true` if and only if an error code is generated on the passed node | 18326 * @return `true` if and only if an error code is generated on the passed node |
| 17407 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE | 18327 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE |
| 17408 */ | 18328 */ |
| 17409 bool checkForDuplicateDefinitionInheritance2(ExecutableElement staticMember) { | 18329 bool checkForDuplicateDefinitionInheritance2(ExecutableElement staticMember) { |
| 18330 // prepare name |
| 17410 String name = staticMember.name; | 18331 String name = staticMember.name; |
| 17411 if (name == null) { | 18332 if (name == null) { |
| 17412 return false; | 18333 return false; |
| 17413 } | 18334 } |
| 18335 // try to find member |
| 17414 ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_e
nclosingClass, name); | 18336 ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_e
nclosingClass, name); |
| 17415 if (inheritedMember == null) { | 18337 if (inheritedMember == null) { |
| 17416 return false; | 18338 return false; |
| 17417 } | 18339 } |
| 18340 // OK, also static |
| 17418 if (inheritedMember.isStatic) { | 18341 if (inheritedMember.isStatic) { |
| 17419 return false; | 18342 return false; |
| 17420 } | 18343 } |
| 18344 // report problem |
| 17421 _errorReporter.reportError5(CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERI
TANCE, staticMember.nameOffset, name.length, [name, inheritedMember.enclosingEle
ment.displayName]); | 18345 _errorReporter.reportError5(CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERI
TANCE, staticMember.nameOffset, name.length, [name, inheritedMember.enclosingEle
ment.displayName]); |
| 17422 return true; | 18346 return true; |
| 17423 } | 18347 } |
| 17424 | 18348 |
| 17425 /** | 18349 /** |
| 17426 * This verifies if the passed list literal has type arguments then there is e
xactly one. | 18350 * This verifies if the passed list literal has type arguments then there is e
xactly one. |
| 17427 * | 18351 * |
| 17428 * @param node the list literal to evaluate | 18352 * @param node the list literal to evaluate |
| 17429 * @return `true` if and only if an error code is generated on the passed node | 18353 * @return `true` if and only if an error code is generated on the passed node |
| 17430 * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS | 18354 * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS |
| 17431 */ | 18355 */ |
| 17432 bool checkForExpectedOneListTypeArgument(ListLiteral node) { | 18356 bool checkForExpectedOneListTypeArgument(ListLiteral node) { |
| 18357 // prepare type arguments |
| 17433 TypeArgumentList typeArguments = node.typeArguments; | 18358 TypeArgumentList typeArguments = node.typeArguments; |
| 17434 if (typeArguments == null) { | 18359 if (typeArguments == null) { |
| 17435 return false; | 18360 return false; |
| 17436 } | 18361 } |
| 18362 // check number of type arguments |
| 17437 int num = typeArguments.arguments.length; | 18363 int num = typeArguments.arguments.length; |
| 17438 if (num == 1) { | 18364 if (num == 1) { |
| 17439 return false; | 18365 return false; |
| 17440 } | 18366 } |
| 18367 // report problem |
| 17441 _errorReporter.reportError3(StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARG
UMENTS, typeArguments, [num]); | 18368 _errorReporter.reportError3(StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARG
UMENTS, typeArguments, [num]); |
| 17442 return true; | 18369 return true; |
| 17443 } | 18370 } |
| 17444 | 18371 |
| 17445 /** | 18372 /** |
| 17446 * This verifies the passed import has unique name among other exported librar
ies. | 18373 * This verifies the passed import has unique name among other exported librar
ies. |
| 17447 * | 18374 * |
| 17448 * @param node the export directive to evaluate | 18375 * @param node the export directive to evaluate |
| 17449 * @return `true` if and only if an error code is generated on the passed node | 18376 * @return `true` if and only if an error code is generated on the passed node |
| 17450 * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME | 18377 * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME |
| 17451 */ | 18378 */ |
| 17452 bool checkForExportDuplicateLibraryName(ExportDirective node) { | 18379 bool checkForExportDuplicateLibraryName(ExportDirective node) { |
| 18380 // prepare import element |
| 17453 Element nodeElement = node.element; | 18381 Element nodeElement = node.element; |
| 17454 if (nodeElement is! ExportElement) { | 18382 if (nodeElement is! ExportElement) { |
| 17455 return false; | 18383 return false; |
| 17456 } | 18384 } |
| 17457 ExportElement nodeExportElement = nodeElement as ExportElement; | 18385 ExportElement nodeExportElement = nodeElement as ExportElement; |
| 18386 // prepare exported library |
| 17458 LibraryElement nodeLibrary = nodeExportElement.exportedLibrary; | 18387 LibraryElement nodeLibrary = nodeExportElement.exportedLibrary; |
| 17459 if (nodeLibrary == null) { | 18388 if (nodeLibrary == null) { |
| 17460 return false; | 18389 return false; |
| 17461 } | 18390 } |
| 17462 String name = nodeLibrary.name; | 18391 String name = nodeLibrary.name; |
| 18392 // check if there is other exported library with the same name |
| 17463 LibraryElement prevLibrary = _nameToExportElement[name]; | 18393 LibraryElement prevLibrary = _nameToExportElement[name]; |
| 17464 if (prevLibrary != null) { | 18394 if (prevLibrary != null) { |
| 17465 if (prevLibrary != nodeLibrary) { | 18395 if (prevLibrary != nodeLibrary) { |
| 17466 _errorReporter.reportError3(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_
NAME, node, [ | 18396 _errorReporter.reportError3(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_
NAME, node, [ |
| 17467 prevLibrary.definingCompilationUnit.displayName, | 18397 prevLibrary.definingCompilationUnit.displayName, |
| 17468 nodeLibrary.definingCompilationUnit.displayName, | 18398 nodeLibrary.definingCompilationUnit.displayName, |
| 17469 name]); | 18399 name]); |
| 17470 return true; | 18400 return true; |
| 17471 } | 18401 } |
| 17472 } else { | 18402 } else { |
| 17473 _nameToExportElement[name] = nodeLibrary; | 18403 _nameToExportElement[name] = nodeLibrary; |
| 17474 } | 18404 } |
| 18405 // OK |
| 17475 return false; | 18406 return false; |
| 17476 } | 18407 } |
| 17477 | 18408 |
| 17478 /** | 18409 /** |
| 17479 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 18410 * Check that if the visiting library is not system, then any passed library s
hould not be SDK |
| 17480 * internal library. | 18411 * internal library. |
| 17481 * | 18412 * |
| 17482 * @param node the export directive to evaluate | 18413 * @param node the export directive to evaluate |
| 17483 * @return `true` if and only if an error code is generated on the passed node | 18414 * @return `true` if and only if an error code is generated on the passed node |
| 17484 * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY | 18415 * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY |
| 17485 */ | 18416 */ |
| 17486 bool checkForExportInternalLibrary(ExportDirective node) { | 18417 bool checkForExportInternalLibrary(ExportDirective node) { |
| 17487 if (_isInSystemLibrary) { | 18418 if (_isInSystemLibrary) { |
| 17488 return false; | 18419 return false; |
| 17489 } | 18420 } |
| 18421 // prepare export element |
| 17490 Element element = node.element; | 18422 Element element = node.element; |
| 17491 if (element is! ExportElement) { | 18423 if (element is! ExportElement) { |
| 17492 return false; | 18424 return false; |
| 17493 } | 18425 } |
| 17494 ExportElement exportElement = element as ExportElement; | 18426 ExportElement exportElement = element as ExportElement; |
| 18427 // should be private |
| 17495 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 18428 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 17496 String uri = exportElement.uri; | 18429 String uri = exportElement.uri; |
| 17497 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 18430 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 17498 if (sdkLibrary == null) { | 18431 if (sdkLibrary == null) { |
| 17499 return false; | 18432 return false; |
| 17500 } | 18433 } |
| 17501 if (!sdkLibrary.isInternal) { | 18434 if (!sdkLibrary.isInternal) { |
| 17502 return false; | 18435 return false; |
| 17503 } | 18436 } |
| 18437 // report problem |
| 17504 _errorReporter.reportError3(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, no
de, [node.uri]); | 18438 _errorReporter.reportError3(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, no
de, [node.uri]); |
| 17505 return true; | 18439 return true; |
| 17506 } | 18440 } |
| 17507 | 18441 |
| 17508 /** | 18442 /** |
| 17509 * This verifies that the passed extends clause does not extend classes such a
s num or String. | 18443 * This verifies that the passed extends clause does not extend classes such a
s num or String. |
| 17510 * | 18444 * |
| 17511 * @param node the extends clause to test | 18445 * @param node the extends clause to test |
| 17512 * @return `true` if and only if an error code is generated on the passed node | 18446 * @return `true` if and only if an error code is generated on the passed node |
| 17513 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS | 18447 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS |
| (...skipping 16 matching lines...) Expand all Loading... |
| 17530 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS | 18464 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS |
| 17531 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS | 18465 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS |
| 17532 */ | 18466 */ |
| 17533 bool checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode e
rrorCode) { | 18467 bool checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode e
rrorCode) { |
| 17534 if (typeName.isSynthetic) { | 18468 if (typeName.isSynthetic) { |
| 17535 return false; | 18469 return false; |
| 17536 } | 18470 } |
| 17537 Type2 superType = typeName.type; | 18471 Type2 superType = typeName.type; |
| 17538 for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMEN
T) { | 18472 for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMEN
T) { |
| 17539 if (superType != null && superType == disallowedType) { | 18473 if (superType != null && superType == disallowedType) { |
| 18474 // if the violating type happens to be 'num', we need to rule out the ca
se where the |
| 18475 // enclosing class is 'int' or 'double' |
| 17540 if (superType == _typeProvider.numType) { | 18476 if (superType == _typeProvider.numType) { |
| 17541 ASTNode grandParent = typeName.parent.parent; | 18477 ASTNode grandParent = typeName.parent.parent; |
| 18478 // Note: this is a corner case that won't happen often, so adding a fi
eld currentClass |
| 18479 // (see currentFunction) to ErrorVerifier isn't worth if for this case
, but if the field |
| 18480 // currentClass is added, then this message should become a todo to no
t lookup the |
| 18481 // grandparent node |
| 17542 if (grandParent is ClassDeclaration) { | 18482 if (grandParent is ClassDeclaration) { |
| 17543 ClassElement classElement = grandParent.element; | 18483 ClassElement classElement = grandParent.element; |
| 17544 Type2 classType = classElement.type; | 18484 Type2 classType = classElement.type; |
| 17545 if (classType != null && (classType == _typeProvider.intType || clas
sType == _typeProvider.doubleType)) { | 18485 if (classType != null && (classType == _typeProvider.intType || clas
sType == _typeProvider.doubleType)) { |
| 17546 return false; | 18486 return false; |
| 17547 } | 18487 } |
| 17548 } | 18488 } |
| 17549 } | 18489 } |
| 18490 // otherwise, report the error |
| 17550 _errorReporter.reportError3(errorCode, typeName, [disallowedType.display
Name]); | 18491 _errorReporter.reportError3(errorCode, typeName, [disallowedType.display
Name]); |
| 17551 return true; | 18492 return true; |
| 17552 } | 18493 } |
| 17553 } | 18494 } |
| 17554 return false; | 18495 return false; |
| 17555 } | 18496 } |
| 17556 | 18497 |
| 17557 /** | 18498 /** |
| 17558 * This verifies that the passed constructor field initializer has compatible
field and | 18499 * This verifies that the passed constructor field initializer has compatible
field and |
| 17559 * initializer expression types. | 18500 * initializer expression types. |
| 17560 * | 18501 * |
| 17561 * @param node the constructor field initializer to test | 18502 * @param node the constructor field initializer to test |
| 17562 * @return `true` if and only if an error code is generated on the passed node | 18503 * @return `true` if and only if an error code is generated on the passed node |
| 17563 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE | 18504 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE |
| 17564 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE | 18505 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE |
| 17565 */ | 18506 */ |
| 17566 bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) { | 18507 bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) { |
| 18508 // prepare field element |
| 17567 Element fieldNameElement = node.fieldName.staticElement; | 18509 Element fieldNameElement = node.fieldName.staticElement; |
| 17568 if (fieldNameElement is! FieldElement) { | 18510 if (fieldNameElement is! FieldElement) { |
| 17569 return false; | 18511 return false; |
| 17570 } | 18512 } |
| 17571 FieldElement fieldElement = fieldNameElement as FieldElement; | 18513 FieldElement fieldElement = fieldNameElement as FieldElement; |
| 18514 // prepare field type |
| 17572 Type2 fieldType = fieldElement.type; | 18515 Type2 fieldType = fieldElement.type; |
| 18516 // prepare expression type |
| 17573 Expression expression = node.expression; | 18517 Expression expression = node.expression; |
| 17574 if (expression == null) { | 18518 if (expression == null) { |
| 17575 return false; | 18519 return false; |
| 17576 } | 18520 } |
| 18521 // test the static type of the expression |
| 17577 Type2 staticType = getStaticType(expression); | 18522 Type2 staticType = getStaticType(expression); |
| 17578 if (staticType == null) { | 18523 if (staticType == null) { |
| 17579 return false; | 18524 return false; |
| 17580 } | 18525 } |
| 17581 if (staticType.isAssignableTo(fieldType)) { | 18526 if (staticType.isAssignableTo(fieldType)) { |
| 17582 return false; | 18527 return false; |
| 17583 } | 18528 } |
| 18529 // report problem |
| 17584 if (_isEnclosingConstructorConst) { | 18530 if (_isEnclosingConstructorConst) { |
| 17585 _errorReporter.reportError3(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_N
OT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); | 18531 _errorReporter.reportError3(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_N
OT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); |
| 17586 } else { | 18532 } else { |
| 17587 _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGN
ABLE, expression, [staticType.displayName, fieldType.displayName]); | 18533 _errorReporter.reportError3(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGN
ABLE, expression, [staticType.displayName, fieldType.displayName]); |
| 17588 } | 18534 } |
| 17589 return true; | 18535 return true; |
| 17590 } | 18536 } |
| 17591 | 18537 |
| 17592 /** | 18538 /** |
| 17593 * This verifies that the passed field formal parameter is in a constructor de
claration. | 18539 * This verifies that the passed field formal parameter is in a constructor de
claration. |
| 17594 * | 18540 * |
| 17595 * @param node the field formal parameter to test | 18541 * @param node the field formal parameter to test |
| 17596 * @return `true` if and only if an error code is generated on the passed node | 18542 * @return `true` if and only if an error code is generated on the passed node |
| 17597 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR | 18543 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR |
| 17598 */ | 18544 */ |
| 17599 bool checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParamete
r node) { | 18545 bool checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParamete
r node) { |
| 17600 ConstructorDeclaration constructor = node.getAncestor(ConstructorDeclaration
); | 18546 ConstructorDeclaration constructor = node.getAncestor(ConstructorDeclaration
); |
| 17601 if (constructor == null) { | 18547 if (constructor == null) { |
| 17602 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE
_CONSTRUCTOR, node, []); | 18548 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE
_CONSTRUCTOR, node, []); |
| 17603 return true; | 18549 return true; |
| 17604 } | 18550 } |
| 18551 // constructor cannot be a factory |
| 17605 if (constructor.factoryKeyword != null) { | 18552 if (constructor.factoryKeyword != null) { |
| 17606 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY
_CONSTRUCTOR, node, []); | 18553 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY
_CONSTRUCTOR, node, []); |
| 17607 return true; | 18554 return true; |
| 17608 } | 18555 } |
| 18556 // constructor cannot have a redirection |
| 17609 for (ConstructorInitializer initializer in constructor.initializers) { | 18557 for (ConstructorInitializer initializer in constructor.initializers) { |
| 17610 if (initializer is RedirectingConstructorInvocation) { | 18558 if (initializer is RedirectingConstructorInvocation) { |
| 17611 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_REDIR
ECTING_CONSTRUCTOR, node, []); | 18559 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_REDIR
ECTING_CONSTRUCTOR, node, []); |
| 17612 return true; | 18560 return true; |
| 17613 } | 18561 } |
| 17614 } | 18562 } |
| 18563 // OK |
| 17615 return false; | 18564 return false; |
| 17616 } | 18565 } |
| 17617 | 18566 |
| 17618 /** | 18567 /** |
| 17619 * This verifies that final fields that are declared, without any constructors
in the enclosing | 18568 * This verifies that final fields that are declared, without any constructors
in the enclosing |
| 17620 * class, are initialized. Cases in which there is at least one constructor ar
e handled at the end | 18569 * class, are initialized. Cases in which there is at least one constructor ar
e handled at the end |
| 17621 * of [checkForAllFinalInitializedErrorCodes]. | 18570 * of [checkForAllFinalInitializedErrorCodes]. |
| 17622 * | 18571 * |
| 17623 * @param node the class declaration to test | 18572 * @param node the class declaration to test |
| 17624 * @return `true` if and only if an error code is generated on the passed node | 18573 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17700 * | 18649 * |
| 17701 * @param node the simple identifier to test | 18650 * @param node the simple identifier to test |
| 17702 * @return `true` if and only if an error code is generated on the passed node | 18651 * @return `true` if and only if an error code is generated on the passed node |
| 17703 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER | 18652 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER |
| 17704 * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov)
rename thid method | 18653 * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov)
rename thid method |
| 17705 */ | 18654 */ |
| 17706 bool checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { | 18655 bool checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { |
| 17707 if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInInstanceVari
ableInitializer && !_isInStaticVariableDeclaration) { | 18656 if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInInstanceVari
ableInitializer && !_isInStaticVariableDeclaration) { |
| 17708 return false; | 18657 return false; |
| 17709 } | 18658 } |
| 18659 // prepare element |
| 17710 Element element = node.staticElement; | 18660 Element element = node.staticElement; |
| 17711 if (!(element is MethodElement || element is PropertyAccessorElement)) { | 18661 if (!(element is MethodElement || element is PropertyAccessorElement)) { |
| 17712 return false; | 18662 return false; |
| 17713 } | 18663 } |
| 18664 // static element |
| 17714 ExecutableElement executableElement = element as ExecutableElement; | 18665 ExecutableElement executableElement = element as ExecutableElement; |
| 17715 if (executableElement.isStatic) { | 18666 if (executableElement.isStatic) { |
| 17716 return false; | 18667 return false; |
| 17717 } | 18668 } |
| 18669 // not a class member |
| 17718 Element enclosingElement = element.enclosingElement; | 18670 Element enclosingElement = element.enclosingElement; |
| 17719 if (enclosingElement is! ClassElement) { | 18671 if (enclosingElement is! ClassElement) { |
| 17720 return false; | 18672 return false; |
| 17721 } | 18673 } |
| 18674 // comment |
| 17722 ASTNode parent = node.parent; | 18675 ASTNode parent = node.parent; |
| 17723 if (parent is CommentReference) { | 18676 if (parent is CommentReference) { |
| 17724 return false; | 18677 return false; |
| 17725 } | 18678 } |
| 18679 // qualified method invocation |
| 17726 if (parent is MethodInvocation) { | 18680 if (parent is MethodInvocation) { |
| 17727 MethodInvocation invocation = parent; | 18681 MethodInvocation invocation = parent; |
| 17728 if (identical(invocation.methodName, node) && invocation.realTarget != nul
l) { | 18682 if (identical(invocation.methodName, node) && invocation.realTarget != nul
l) { |
| 17729 return false; | 18683 return false; |
| 17730 } | 18684 } |
| 17731 } | 18685 } |
| 18686 // qualified property access |
| 17732 if (parent is PropertyAccess) { | 18687 if (parent is PropertyAccess) { |
| 17733 PropertyAccess access = parent; | 18688 PropertyAccess access = parent; |
| 17734 if (identical(access.propertyName, node) && access.realTarget != null) { | 18689 if (identical(access.propertyName, node) && access.realTarget != null) { |
| 17735 return false; | 18690 return false; |
| 17736 } | 18691 } |
| 17737 } | 18692 } |
| 17738 if (parent is PrefixedIdentifier) { | 18693 if (parent is PrefixedIdentifier) { |
| 17739 PrefixedIdentifier prefixed = parent; | 18694 PrefixedIdentifier prefixed = parent; |
| 17740 if (identical(prefixed.identifier, node)) { | 18695 if (identical(prefixed.identifier, node)) { |
| 17741 return false; | 18696 return false; |
| 17742 } | 18697 } |
| 17743 } | 18698 } |
| 18699 // report problem |
| 17744 if (_isInStaticMethod) { | 18700 if (_isInStaticMethod) { |
| 17745 _errorReporter.reportError3(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FR
OM_STATIC, node, []); | 18701 _errorReporter.reportError3(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FR
OM_STATIC, node, []); |
| 17746 } else { | 18702 } else { |
| 17747 _errorReporter.reportError3(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_I
N_INITIALIZER, node, []); | 18703 _errorReporter.reportError3(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_I
N_INITIALIZER, node, []); |
| 17748 } | 18704 } |
| 17749 return true; | 18705 return true; |
| 17750 } | 18706 } |
| 17751 | 18707 |
| 17752 /** | 18708 /** |
| 17753 * This verifies the passed import has unique name among other imported librar
ies. | 18709 * This verifies the passed import has unique name among other imported librar
ies. |
| 17754 * | 18710 * |
| 17755 * @param node the import directive to evaluate | 18711 * @param node the import directive to evaluate |
| 17756 * @return `true` if and only if an error code is generated on the passed node | 18712 * @return `true` if and only if an error code is generated on the passed node |
| 17757 * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME | 18713 * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME |
| 17758 */ | 18714 */ |
| 17759 bool checkForImportDuplicateLibraryName(ImportDirective node) { | 18715 bool checkForImportDuplicateLibraryName(ImportDirective node) { |
| 18716 // prepare import element |
| 17760 ImportElement nodeImportElement = node.element; | 18717 ImportElement nodeImportElement = node.element; |
| 17761 if (nodeImportElement == null) { | 18718 if (nodeImportElement == null) { |
| 17762 return false; | 18719 return false; |
| 17763 } | 18720 } |
| 18721 // prepare imported library |
| 17764 LibraryElement nodeLibrary = nodeImportElement.importedLibrary; | 18722 LibraryElement nodeLibrary = nodeImportElement.importedLibrary; |
| 17765 if (nodeLibrary == null) { | 18723 if (nodeLibrary == null) { |
| 17766 return false; | 18724 return false; |
| 17767 } | 18725 } |
| 17768 String name = nodeLibrary.name; | 18726 String name = nodeLibrary.name; |
| 18727 // check if there is other imported library with the same name |
| 17769 LibraryElement prevLibrary = _nameToImportElement[name]; | 18728 LibraryElement prevLibrary = _nameToImportElement[name]; |
| 17770 if (prevLibrary != null) { | 18729 if (prevLibrary != null) { |
| 17771 if (prevLibrary != nodeLibrary) { | 18730 if (prevLibrary != nodeLibrary) { |
| 17772 _errorReporter.reportError3(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_
NAME, node, [ | 18731 _errorReporter.reportError3(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_
NAME, node, [ |
| 17773 prevLibrary.definingCompilationUnit.displayName, | 18732 prevLibrary.definingCompilationUnit.displayName, |
| 17774 nodeLibrary.definingCompilationUnit.displayName, | 18733 nodeLibrary.definingCompilationUnit.displayName, |
| 17775 name]); | 18734 name]); |
| 17776 return true; | 18735 return true; |
| 17777 } | 18736 } |
| 17778 } else { | 18737 } else { |
| 17779 _nameToImportElement[name] = nodeLibrary; | 18738 _nameToImportElement[name] = nodeLibrary; |
| 17780 } | 18739 } |
| 18740 // OK |
| 17781 return false; | 18741 return false; |
| 17782 } | 18742 } |
| 17783 | 18743 |
| 17784 /** | 18744 /** |
| 17785 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 18745 * Check that if the visiting library is not system, then any passed library s
hould not be SDK |
| 17786 * internal library. | 18746 * internal library. |
| 17787 * | 18747 * |
| 17788 * @param node the import directive to evaluate | 18748 * @param node the import directive to evaluate |
| 17789 * @return `true` if and only if an error code is generated on the passed node | 18749 * @return `true` if and only if an error code is generated on the passed node |
| 17790 * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY | 18750 * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY |
| 17791 */ | 18751 */ |
| 17792 bool checkForImportInternalLibrary(ImportDirective node) { | 18752 bool checkForImportInternalLibrary(ImportDirective node) { |
| 17793 if (_isInSystemLibrary) { | 18753 if (_isInSystemLibrary) { |
| 17794 return false; | 18754 return false; |
| 17795 } | 18755 } |
| 18756 // prepare import element |
| 17796 ImportElement importElement = node.element; | 18757 ImportElement importElement = node.element; |
| 17797 if (importElement == null) { | 18758 if (importElement == null) { |
| 17798 return false; | 18759 return false; |
| 17799 } | 18760 } |
| 18761 // should be private |
| 17800 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 18762 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 17801 String uri = importElement.uri; | 18763 String uri = importElement.uri; |
| 17802 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 18764 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 17803 if (sdkLibrary == null) { | 18765 if (sdkLibrary == null) { |
| 17804 return false; | 18766 return false; |
| 17805 } | 18767 } |
| 17806 if (!sdkLibrary.isInternal) { | 18768 if (!sdkLibrary.isInternal) { |
| 17807 return false; | 18769 return false; |
| 17808 } | 18770 } |
| 18771 // report problem |
| 17809 _errorReporter.reportError3(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, no
de, [node.uri]); | 18772 _errorReporter.reportError3(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, no
de, [node.uri]); |
| 17810 return true; | 18773 return true; |
| 17811 } | 18774 } |
| 17812 | 18775 |
| 17813 /** | 18776 /** |
| 17814 * This verifies that the passed switch statement case expressions all have th
e same type. | 18777 * This verifies that the passed switch statement case expressions all have th
e same type. |
| 17815 * | 18778 * |
| 17816 * @param node the switch statement to evaluate | 18779 * @param node the switch statement to evaluate |
| 17817 * @return `true` if and only if an error code is generated on the passed node | 18780 * @return `true` if and only if an error code is generated on the passed node |
| 17818 * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES | 18781 * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES |
| 17819 */ | 18782 */ |
| 17820 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) { | 18783 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) { |
| 18784 // TODO(jwren) Revisit this algorithm, should there up to n-1 errors? |
| 17821 NodeList<SwitchMember> switchMembers = node.members; | 18785 NodeList<SwitchMember> switchMembers = node.members; |
| 17822 bool foundError = false; | 18786 bool foundError = false; |
| 17823 Type2 firstType = null; | 18787 Type2 firstType = null; |
| 17824 for (SwitchMember switchMember in switchMembers) { | 18788 for (SwitchMember switchMember in switchMembers) { |
| 17825 if (switchMember is SwitchCase) { | 18789 if (switchMember is SwitchCase) { |
| 17826 SwitchCase switchCase = switchMember; | 18790 SwitchCase switchCase = switchMember; |
| 17827 Expression expression = switchCase.expression; | 18791 Expression expression = switchCase.expression; |
| 17828 if (firstType == null) { | 18792 if (firstType == null) { |
| 18793 // TODO(brianwilkerson) This is failing with const variables whose dec
lared type is |
| 18794 // dynamic. The problem is that we don't have any way to propagate typ
e information for |
| 18795 // the variable. |
| 17829 firstType = expression.bestType; | 18796 firstType = expression.bestType; |
| 17830 } else { | 18797 } else { |
| 17831 Type2 nType = expression.bestType; | 18798 Type2 nType = expression.bestType; |
| 17832 if (firstType != nType) { | 18799 if (firstType != nType) { |
| 17833 _errorReporter.reportError3(CompileTimeErrorCode.INCONSISTENT_CASE_E
XPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName]); | 18800 _errorReporter.reportError3(CompileTimeErrorCode.INCONSISTENT_CASE_E
XPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName]); |
| 17834 foundError = true; | 18801 foundError = true; |
| 17835 } | 18802 } |
| 17836 } | 18803 } |
| 17837 } | 18804 } |
| 17838 } | 18805 } |
| 17839 if (!foundError) { | 18806 if (!foundError) { |
| 17840 checkForCaseExpressionTypeImplementsEquals(node, firstType); | 18807 checkForCaseExpressionTypeImplementsEquals(node, firstType); |
| 17841 } | 18808 } |
| 17842 return foundError; | 18809 return foundError; |
| 17843 } | 18810 } |
| 17844 | 18811 |
| 17845 /** | 18812 /** |
| 17846 * For each class declaration, this method is called which verifies that all i
nherited members are | 18813 * For each class declaration, this method is called which verifies that all i
nherited members are |
| 17847 * inherited consistently. | 18814 * inherited consistently. |
| 17848 * | 18815 * |
| 17849 * @return `true` if and only if an error code is generated on the passed node | 18816 * @return `true` if and only if an error code is generated on the passed node |
| 17850 * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE | 18817 * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE |
| 17851 */ | 18818 */ |
| 17852 bool checkForInconsistentMethodInheritance() { | 18819 bool checkForInconsistentMethodInheritance() { |
| 18820 // Ensure that the inheritance manager has a chance to generate all errors w
e may care about, |
| 18821 // note that we ensure that the interfaces data since there are no errors. |
| 17853 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); | 18822 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); |
| 17854 Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass); | 18823 Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass); |
| 17855 if (errors == null || errors.isEmpty) { | 18824 if (errors == null || errors.isEmpty) { |
| 17856 return false; | 18825 return false; |
| 17857 } | 18826 } |
| 17858 for (AnalysisError error in errors) { | 18827 for (AnalysisError error in errors) { |
| 17859 _errorReporter.reportError(error); | 18828 _errorReporter.reportError(error); |
| 17860 } | 18829 } |
| 17861 return true; | 18830 return true; |
| 17862 } | 18831 } |
| 17863 | 18832 |
| 17864 /** | 18833 /** |
| 17865 * This checks the given "typeReference" is not a type reference and that then
the "name" is | 18834 * This checks the given "typeReference" is not a type reference and that then
the "name" is |
| 17866 * reference to an instance member. | 18835 * reference to an instance member. |
| 17867 * | 18836 * |
| 17868 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 18837 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
| 17869 * or `null`, aka, the class element of 'C' in 'C.x', see | 18838 * or `null`, aka, the class element of 'C' in 'C.x', see |
| 17870 * [getTypeReference] | 18839 * [getTypeReference] |
| 17871 * @param name the accessed name to evaluate | 18840 * @param name the accessed name to evaluate |
| 17872 * @return `true` if and only if an error code is generated on the passed node | 18841 * @return `true` if and only if an error code is generated on the passed node |
| 17873 * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER | 18842 * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER |
| 17874 */ | 18843 */ |
| 17875 bool checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleId
entifier name) { | 18844 bool checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleId
entifier name) { |
| 18845 // OK, in comment |
| 17876 if (_isInComment) { | 18846 if (_isInComment) { |
| 17877 return false; | 18847 return false; |
| 17878 } | 18848 } |
| 18849 // OK, target is a type |
| 17879 if (typeReference != null) { | 18850 if (typeReference != null) { |
| 17880 return false; | 18851 return false; |
| 17881 } | 18852 } |
| 18853 // prepare member Element |
| 17882 Element element = name.staticElement; | 18854 Element element = name.staticElement; |
| 17883 if (element is! ExecutableElement) { | 18855 if (element is! ExecutableElement) { |
| 17884 return false; | 18856 return false; |
| 17885 } | 18857 } |
| 17886 ExecutableElement executableElement = element as ExecutableElement; | 18858 ExecutableElement executableElement = element as ExecutableElement; |
| 18859 // OK, top-level element |
| 17887 if (executableElement.enclosingElement is! ClassElement) { | 18860 if (executableElement.enclosingElement is! ClassElement) { |
| 17888 return false; | 18861 return false; |
| 17889 } | 18862 } |
| 18863 // OK, instance member |
| 17890 if (!executableElement.isStatic) { | 18864 if (!executableElement.isStatic) { |
| 17891 return false; | 18865 return false; |
| 17892 } | 18866 } |
| 18867 // report problem |
| 17893 _errorReporter.reportError3(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_
MEMBER, name, [name.name]); | 18868 _errorReporter.reportError3(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_
MEMBER, name, [name.name]); |
| 17894 return true; | 18869 return true; |
| 17895 } | 18870 } |
| 17896 | 18871 |
| 17897 /** | 18872 /** |
| 17898 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given | 18873 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given |
| 17899 * expression. This is used for prefix and postfix expressions where the argum
ent value is | 18874 * expression. This is used for prefix and postfix expressions where the argum
ent value is |
| 17900 * implicit. | 18875 * implicit. |
| 17901 * | 18876 * |
| 17902 * @param argument the expression to which the operator is being applied | 18877 * @param argument the expression to which the operator is being applied |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17957 return false; | 18932 return false; |
| 17958 } | 18933 } |
| 17959 VariableElement leftElement = getVariableElement(lhs); | 18934 VariableElement leftElement = getVariableElement(lhs); |
| 17960 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; | 18935 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; |
| 17961 Type2 staticRightType = getStaticType(rhs); | 18936 Type2 staticRightType = getStaticType(rhs); |
| 17962 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); | 18937 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); |
| 17963 if (!isStaticAssignable) { | 18938 if (!isStaticAssignable) { |
| 17964 _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs,
[staticRightType.displayName, leftType.displayName]); | 18939 _errorReporter.reportError3(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs,
[staticRightType.displayName, leftType.displayName]); |
| 17965 return true; | 18940 return true; |
| 17966 } | 18941 } |
| 18942 // TODO(brianwilkerson) Define a hint corresponding to the warning and repor
t it if appropriate. |
| 18943 // Type propagatedRightType = rhs.getPropagatedType(); |
| 18944 // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(le
ftType); |
| 18945 // if (!isStaticAssignable && !isPropagatedAssignable) { |
| 18946 // errorReporter.reportError( |
| 18947 // StaticTypeWarningCode.INVALID_ASSIGNMENT, |
| 18948 // rhs, |
| 18949 // staticRightType.getDisplayName(), |
| 18950 // leftType.getDisplayName()); |
| 18951 // return true; |
| 18952 // } |
| 17967 return false; | 18953 return false; |
| 17968 } | 18954 } |
| 17969 | 18955 |
| 17970 /** | 18956 /** |
| 17971 * This verifies that the usage of the passed 'this' is valid. | 18957 * This verifies that the usage of the passed 'this' is valid. |
| 17972 * | 18958 * |
| 17973 * @param node the 'this' expression to evaluate | 18959 * @param node the 'this' expression to evaluate |
| 17974 * @return `true` if and only if an error code is generated on the passed node | 18960 * @return `true` if and only if an error code is generated on the passed node |
| 17975 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS | 18961 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS |
| 17976 */ | 18962 */ |
| (...skipping 29 matching lines...) Expand all Loading... |
| 18006 /** | 18992 /** |
| 18007 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element | 18993 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element |
| 18008 * type. | 18994 * type. |
| 18009 * | 18995 * |
| 18010 * @param node the list literal to evaluate | 18996 * @param node the list literal to evaluate |
| 18011 * @return `true` if and only if an error code is generated on the passed node | 18997 * @return `true` if and only if an error code is generated on the passed node |
| 18012 * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE | 18998 * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE |
| 18013 * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE | 18999 * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE |
| 18014 */ | 19000 */ |
| 18015 bool checkForListElementTypeNotAssignable(ListLiteral node) { | 19001 bool checkForListElementTypeNotAssignable(ListLiteral node) { |
| 19002 // Prepare list element type. |
| 18016 TypeArgumentList typeArgumentList = node.typeArguments; | 19003 TypeArgumentList typeArgumentList = node.typeArguments; |
| 18017 if (typeArgumentList == null) { | 19004 if (typeArgumentList == null) { |
| 18018 return false; | 19005 return false; |
| 18019 } | 19006 } |
| 18020 NodeList<TypeName> typeArguments = typeArgumentList.arguments; | 19007 NodeList<TypeName> typeArguments = typeArgumentList.arguments; |
| 18021 if (typeArguments.length < 1) { | 19008 if (typeArguments.length < 1) { |
| 18022 return false; | 19009 return false; |
| 18023 } | 19010 } |
| 18024 Type2 listElementType = typeArguments[0].type; | 19011 Type2 listElementType = typeArguments[0].type; |
| 19012 // Prepare problem to report. |
| 18025 ErrorCode errorCode; | 19013 ErrorCode errorCode; |
| 18026 if (node.constKeyword != null) { | 19014 if (node.constKeyword != null) { |
| 18027 errorCode = CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; | 19015 errorCode = CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; |
| 18028 } else { | 19016 } else { |
| 18029 errorCode = StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; | 19017 errorCode = StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; |
| 18030 } | 19018 } |
| 19019 // Check every list element. |
| 18031 bool hasProblems = false; | 19020 bool hasProblems = false; |
| 18032 for (Expression element in node.elements) { | 19021 for (Expression element in node.elements) { |
| 18033 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
3(element, listElementType, null, errorCode)); | 19022 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
3(element, listElementType, null, errorCode)); |
| 18034 } | 19023 } |
| 18035 return hasProblems; | 19024 return hasProblems; |
| 18036 } | 19025 } |
| 18037 | 19026 |
| 18038 /** | 19027 /** |
| 18039 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the | 19028 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the |
| 18040 * key/value types specified in the type arguments. | 19029 * key/value types specified in the type arguments. |
| 18041 * | 19030 * |
| 18042 * @param node the map literal to evaluate | 19031 * @param node the map literal to evaluate |
| 18043 * @return `true` if and only if an error code is generated on the passed node | 19032 * @return `true` if and only if an error code is generated on the passed node |
| 18044 * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE | 19033 * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE |
| 18045 * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE | 19034 * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE |
| 18046 * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE | 19035 * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE |
| 18047 * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE | 19036 * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE |
| 18048 */ | 19037 */ |
| 18049 bool checkForMapTypeNotAssignable(MapLiteral node) { | 19038 bool checkForMapTypeNotAssignable(MapLiteral node) { |
| 19039 // Prepare maps key/value types. |
| 18050 TypeArgumentList typeArgumentList = node.typeArguments; | 19040 TypeArgumentList typeArgumentList = node.typeArguments; |
| 18051 if (typeArgumentList == null) { | 19041 if (typeArgumentList == null) { |
| 18052 return false; | 19042 return false; |
| 18053 } | 19043 } |
| 18054 NodeList<TypeName> typeArguments = typeArgumentList.arguments; | 19044 NodeList<TypeName> typeArguments = typeArgumentList.arguments; |
| 18055 if (typeArguments.length < 2) { | 19045 if (typeArguments.length < 2) { |
| 18056 return false; | 19046 return false; |
| 18057 } | 19047 } |
| 18058 Type2 keyType = typeArguments[0].type; | 19048 Type2 keyType = typeArguments[0].type; |
| 18059 Type2 valueType = typeArguments[1].type; | 19049 Type2 valueType = typeArguments[1].type; |
| 19050 // Prepare problem to report. |
| 18060 ErrorCode keyErrorCode; | 19051 ErrorCode keyErrorCode; |
| 18061 ErrorCode valueErrorCode; | 19052 ErrorCode valueErrorCode; |
| 18062 if (node.constKeyword != null) { | 19053 if (node.constKeyword != null) { |
| 18063 keyErrorCode = CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; | 19054 keyErrorCode = CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; |
| 18064 valueErrorCode = CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; | 19055 valueErrorCode = CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; |
| 18065 } else { | 19056 } else { |
| 18066 keyErrorCode = StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; | 19057 keyErrorCode = StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; |
| 18067 valueErrorCode = StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; | 19058 valueErrorCode = StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; |
| 18068 } | 19059 } |
| 19060 // Check every map entry. |
| 18069 bool hasProblems = false; | 19061 bool hasProblems = false; |
| 18070 NodeList<MapLiteralEntry> entries = node.entries; | 19062 NodeList<MapLiteralEntry> entries = node.entries; |
| 18071 for (MapLiteralEntry entry in entries) { | 19063 for (MapLiteralEntry entry in entries) { |
| 18072 Expression key = entry.key; | 19064 Expression key = entry.key; |
| 18073 Expression value = entry.value; | 19065 Expression value = entry.value; |
| 18074 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
3(key, keyType, null, keyErrorCode)); | 19066 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
3(key, keyType, null, keyErrorCode)); |
| 18075 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
3(value, valueType, null, valueErrorCode)); | 19067 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
3(value, valueType, null, valueErrorCode)); |
| 18076 } | 19068 } |
| 18077 return hasProblems; | 19069 return hasProblems; |
| 18078 } | 19070 } |
| 18079 | 19071 |
| 18080 /** | 19072 /** |
| 18081 * This verifies that the [enclosingClass] does not define members with the sa
me name as | 19073 * This verifies that the [enclosingClass] does not define members with the sa
me name as |
| 18082 * the enclosing class. | 19074 * the enclosing class. |
| 18083 * | 19075 * |
| 18084 * @return `true` if and only if an error code is generated on the passed node | 19076 * @return `true` if and only if an error code is generated on the passed node |
| 18085 * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME | 19077 * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME |
| 18086 */ | 19078 */ |
| 18087 bool checkForMemberWithClassName() { | 19079 bool checkForMemberWithClassName() { |
| 18088 if (_enclosingClass == null) { | 19080 if (_enclosingClass == null) { |
| 18089 return false; | 19081 return false; |
| 18090 } | 19082 } |
| 18091 String className = _enclosingClass.name; | 19083 String className = _enclosingClass.name; |
| 18092 if (className == null) { | 19084 if (className == null) { |
| 18093 return false; | 19085 return false; |
| 18094 } | 19086 } |
| 18095 bool problemReported = false; | 19087 bool problemReported = false; |
| 19088 // check accessors |
| 18096 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 19089 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
| 18097 if (className == accessor.name) { | 19090 if (className == accessor.name) { |
| 18098 _errorReporter.reportError5(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME,
accessor.nameOffset, className.length, []); | 19091 _errorReporter.reportError5(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME,
accessor.nameOffset, className.length, []); |
| 18099 problemReported = true; | 19092 problemReported = true; |
| 18100 } | 19093 } |
| 18101 } | 19094 } |
| 19095 // don't check methods, they would be constructors |
| 19096 // done |
| 18102 return problemReported; | 19097 return problemReported; |
| 18103 } | 19098 } |
| 18104 | 19099 |
| 18105 /** | 19100 /** |
| 18106 * Check to make sure that all similarly typed accessors are of the same type
(including inherited | 19101 * Check to make sure that all similarly typed accessors are of the same type
(including inherited |
| 18107 * accessors). | 19102 * accessors). |
| 18108 * | 19103 * |
| 18109 * @param node the accessor currently being visited | 19104 * @param node the accessor currently being visited |
| 18110 * @return `true` if and only if an error code is generated on the passed node | 19105 * @return `true` if and only if an error code is generated on the passed node |
| 18111 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES | 19106 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES |
| 18112 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE | 19107 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE |
| 18113 */ | 19108 */ |
| 18114 bool checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String a
ccessorTextName) { | 19109 bool checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String a
ccessorTextName) { |
| 18115 ExecutableElement accessorElement = accessorDeclaration.element as Executabl
eElement; | 19110 ExecutableElement accessorElement = accessorDeclaration.element as Executabl
eElement; |
| 18116 if (accessorElement is! PropertyAccessorElement) { | 19111 if (accessorElement is! PropertyAccessorElement) { |
| 18117 return false; | 19112 return false; |
| 18118 } | 19113 } |
| 18119 PropertyAccessorElement propertyAccessorElement = accessorElement as Propert
yAccessorElement; | 19114 PropertyAccessorElement propertyAccessorElement = accessorElement as Propert
yAccessorElement; |
| 18120 PropertyAccessorElement counterpartAccessor = null; | 19115 PropertyAccessorElement counterpartAccessor = null; |
| 18121 ClassElement enclosingClassForCounterpart = null; | 19116 ClassElement enclosingClassForCounterpart = null; |
| 18122 if (propertyAccessorElement.isGetter) { | 19117 if (propertyAccessorElement.isGetter) { |
| 18123 counterpartAccessor = propertyAccessorElement.correspondingSetter; | 19118 counterpartAccessor = propertyAccessorElement.correspondingSetter; |
| 18124 } else { | 19119 } else { |
| 18125 counterpartAccessor = propertyAccessorElement.correspondingGetter; | 19120 counterpartAccessor = propertyAccessorElement.correspondingGetter; |
| 19121 // If the setter and getter are in the same enclosing element, return, thi
s prevents having |
| 19122 // MISMATCHED_GETTER_AND_SETTER_TYPES reported twice. |
| 18126 if (counterpartAccessor != null && identical(counterpartAccessor.enclosing
Element, propertyAccessorElement.enclosingElement)) { | 19123 if (counterpartAccessor != null && identical(counterpartAccessor.enclosing
Element, propertyAccessorElement.enclosingElement)) { |
| 18127 return false; | 19124 return false; |
| 18128 } | 19125 } |
| 18129 } | 19126 } |
| 18130 if (counterpartAccessor == null) { | 19127 if (counterpartAccessor == null) { |
| 19128 // If the accessor is declared in a class, check the superclasses. |
| 18131 if (_enclosingClass != null) { | 19129 if (_enclosingClass != null) { |
| 19130 // Figure out the correct identifier to lookup in the inheritance graph,
if 'x', then 'x=', |
| 19131 // or if 'x=', then 'x'. |
| 18132 String lookupIdentifier = propertyAccessorElement.name; | 19132 String lookupIdentifier = propertyAccessorElement.name; |
| 18133 if (lookupIdentifier.endsWith("=")) { | 19133 if (lookupIdentifier.endsWith("=")) { |
| 18134 lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.leng
th - 1); | 19134 lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.leng
th - 1); |
| 18135 } else { | 19135 } else { |
| 18136 lookupIdentifier += "="; | 19136 lookupIdentifier += "="; |
| 18137 } | 19137 } |
| 19138 // lookup with the identifier. |
| 18138 ExecutableElement elementFromInheritance = _inheritanceManager.lookupInh
eritance(_enclosingClass, lookupIdentifier); | 19139 ExecutableElement elementFromInheritance = _inheritanceManager.lookupInh
eritance(_enclosingClass, lookupIdentifier); |
| 19140 // Verify that we found something, and that it is an accessor |
| 18139 if (elementFromInheritance != null && elementFromInheritance is Property
AccessorElement) { | 19141 if (elementFromInheritance != null && elementFromInheritance is Property
AccessorElement) { |
| 18140 enclosingClassForCounterpart = elementFromInheritance.enclosingElement
as ClassElement; | 19142 enclosingClassForCounterpart = elementFromInheritance.enclosingElement
as ClassElement; |
| 18141 counterpartAccessor = elementFromInheritance; | 19143 counterpartAccessor = elementFromInheritance; |
| 18142 } | 19144 } |
| 18143 } | 19145 } |
| 18144 if (counterpartAccessor == null) { | 19146 if (counterpartAccessor == null) { |
| 18145 return false; | 19147 return false; |
| 18146 } | 19148 } |
| 18147 } | 19149 } |
| 19150 // Default of null == no accessor or no type (dynamic) |
| 18148 Type2 getterType = null; | 19151 Type2 getterType = null; |
| 18149 Type2 setterType = null; | 19152 Type2 setterType = null; |
| 19153 // Get an existing counterpart accessor if any. |
| 18150 if (propertyAccessorElement.isGetter) { | 19154 if (propertyAccessorElement.isGetter) { |
| 18151 getterType = getGetterType(propertyAccessorElement); | 19155 getterType = getGetterType(propertyAccessorElement); |
| 18152 setterType = getSetterType(counterpartAccessor); | 19156 setterType = getSetterType(counterpartAccessor); |
| 18153 } else if (propertyAccessorElement.isSetter) { | 19157 } else if (propertyAccessorElement.isSetter) { |
| 18154 setterType = getSetterType(propertyAccessorElement); | 19158 setterType = getSetterType(propertyAccessorElement); |
| 18155 getterType = getGetterType(counterpartAccessor); | 19159 getterType = getGetterType(counterpartAccessor); |
| 18156 } | 19160 } |
| 19161 // If either types are not assignable to each other, report an error (if the
getter is null, |
| 19162 // it is dynamic which is assignable to everything). |
| 18157 if (setterType != null && getterType != null && !getterType.isAssignableTo(s
etterType)) { | 19163 if (setterType != null && getterType != null && !getterType.isAssignableTo(s
etterType)) { |
| 18158 if (enclosingClassForCounterpart == null) { | 19164 if (enclosingClassForCounterpart == null) { |
| 18159 _errorReporter.reportError3(StaticWarningCode.MISMATCHED_GETTER_AND_SETT
ER_TYPES, accessorDeclaration, [ | 19165 _errorReporter.reportError3(StaticWarningCode.MISMATCHED_GETTER_AND_SETT
ER_TYPES, accessorDeclaration, [ |
| 18160 accessorTextName, | 19166 accessorTextName, |
| 18161 setterType.displayName, | 19167 setterType.displayName, |
| 18162 getterType.displayName]); | 19168 getterType.displayName]); |
| 18163 return true; | 19169 return true; |
| 18164 } else { | 19170 } else { |
| 18165 _errorReporter.reportError3(StaticWarningCode.MISMATCHED_GETTER_AND_SETT
ER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [ | 19171 _errorReporter.reportError3(StaticWarningCode.MISMATCHED_GETTER_AND_SETT
ER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [ |
| 18166 accessorTextName, | 19172 accessorTextName, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18261 } | 19267 } |
| 18262 | 19268 |
| 18263 /** | 19269 /** |
| 18264 * Checks to ensure that native function bodies can only in SDK code. | 19270 * Checks to ensure that native function bodies can only in SDK code. |
| 18265 * | 19271 * |
| 18266 * @param node the native function body to test | 19272 * @param node the native function body to test |
| 18267 * @return `true` if and only if an error code is generated on the passed node | 19273 * @return `true` if and only if an error code is generated on the passed node |
| 18268 * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE | 19274 * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE |
| 18269 */ | 19275 */ |
| 18270 bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { | 19276 bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { |
| 19277 // TODO(brianwilkerson) Figure out the right rule for when 'native' is allow
ed. |
| 18271 if (!_isInSystemLibrary) { | 19278 if (!_isInSystemLibrary) { |
| 18272 _errorReporter.reportError3(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SD
K_CODE, node, []); | 19279 _errorReporter.reportError3(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SD
K_CODE, node, []); |
| 18273 return true; | 19280 return true; |
| 18274 } | 19281 } |
| 18275 return false; | 19282 return false; |
| 18276 } | 19283 } |
| 18277 | 19284 |
| 18278 /** | 19285 /** |
| 18279 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. | 19286 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. |
| 18280 * | 19287 * |
| 18281 * This method assumes that the instance creation was tested to be 'new' befor
e being called. | 19288 * This method assumes that the instance creation was tested to be 'new' befor
e being called. |
| 18282 * | 19289 * |
| 18283 * @param node the instance creation expression to evaluate | 19290 * @param node the instance creation expression to evaluate |
| 18284 * @return `true` if and only if an error code is generated on the passed node | 19291 * @return `true` if and only if an error code is generated on the passed node |
| 18285 * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR | 19292 * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR |
| 18286 */ | 19293 */ |
| 18287 bool checkForNewWithUndefinedConstructor(InstanceCreationExpression node) { | 19294 bool checkForNewWithUndefinedConstructor(InstanceCreationExpression node) { |
| 19295 // OK if resolved |
| 18288 if (node.staticElement != null) { | 19296 if (node.staticElement != null) { |
| 18289 return false; | 19297 return false; |
| 18290 } | 19298 } |
| 19299 // prepare constructor name |
| 18291 ConstructorName constructorName = node.constructorName; | 19300 ConstructorName constructorName = node.constructorName; |
| 18292 if (constructorName == null) { | 19301 if (constructorName == null) { |
| 18293 return false; | 19302 return false; |
| 18294 } | 19303 } |
| 19304 // prepare class name |
| 18295 TypeName type = constructorName.type; | 19305 TypeName type = constructorName.type; |
| 18296 if (type == null) { | 19306 if (type == null) { |
| 18297 return false; | 19307 return false; |
| 18298 } | 19308 } |
| 18299 Identifier className = type.name; | 19309 Identifier className = type.name; |
| 19310 // report as named or default constructor absence |
| 18300 SimpleIdentifier name = constructorName.name; | 19311 SimpleIdentifier name = constructorName.name; |
| 18301 if (name != null) { | 19312 if (name != null) { |
| 18302 _errorReporter.reportError3(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCT
OR, name, [className, name]); | 19313 _errorReporter.reportError3(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCT
OR, name, [className, name]); |
| 18303 } else { | 19314 } else { |
| 18304 _errorReporter.reportError3(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCT
OR_DEFAULT, constructorName, [className]); | 19315 _errorReporter.reportError3(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCT
OR_DEFAULT, constructorName, [className]); |
| 18305 } | 19316 } |
| 18306 return true; | 19317 return true; |
| 18307 } | 19318 } |
| 18308 | 19319 |
| 18309 /** | 19320 /** |
| 18310 * This checks that if the passed class declaration implicitly calls default c
onstructor of its | 19321 * This checks that if the passed class declaration implicitly calls default c
onstructor of its |
| 18311 * superclass, there should be such default constructor - implicit or explicit
. | 19322 * superclass, there should be such default constructor - implicit or explicit
. |
| 18312 * | 19323 * |
| 18313 * @param node the [ClassDeclaration] to evaluate | 19324 * @param node the [ClassDeclaration] to evaluate |
| 18314 * @return `true` if and only if an error code is generated on the passed node | 19325 * @return `true` if and only if an error code is generated on the passed node |
| 18315 * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT | 19326 * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT |
| 18316 */ | 19327 */ |
| 18317 bool checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { | 19328 bool checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { |
| 19329 // do nothing if there is explicit constructor |
| 18318 List<ConstructorElement> constructors = _enclosingClass.constructors; | 19330 List<ConstructorElement> constructors = _enclosingClass.constructors; |
| 18319 if (!constructors[0].isSynthetic) { | 19331 if (!constructors[0].isSynthetic) { |
| 18320 return false; | 19332 return false; |
| 18321 } | 19333 } |
| 19334 // prepare super |
| 18322 InterfaceType superType = _enclosingClass.supertype; | 19335 InterfaceType superType = _enclosingClass.supertype; |
| 18323 if (superType == null) { | 19336 if (superType == null) { |
| 18324 return false; | 19337 return false; |
| 18325 } | 19338 } |
| 18326 ClassElement superElement = superType.element; | 19339 ClassElement superElement = superType.element; |
| 19340 // try to find default generative super constructor |
| 18327 ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor
; | 19341 ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor
; |
| 18328 if (superUnnamedConstructor != null) { | 19342 if (superUnnamedConstructor != null) { |
| 18329 if (superUnnamedConstructor.isFactory) { | 19343 if (superUnnamedConstructor.isFactory) { |
| 18330 _errorReporter.reportError3(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUC
TOR, node.name, [superUnnamedConstructor]); | 19344 _errorReporter.reportError3(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUC
TOR, node.name, [superUnnamedConstructor]); |
| 18331 return true; | 19345 return true; |
| 18332 } | 19346 } |
| 18333 if (superUnnamedConstructor.isDefaultConstructor) { | 19347 if (superUnnamedConstructor.isDefaultConstructor) { |
| 18334 return true; | 19348 return true; |
| 18335 } | 19349 } |
| 18336 } | 19350 } |
| 19351 // report problem |
| 18337 _errorReporter.reportError3(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTO
R_IMPLICIT, node.name, [superType.displayName]); | 19352 _errorReporter.reportError3(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTO
R_IMPLICIT, node.name, [superType.displayName]); |
| 18338 return true; | 19353 return true; |
| 18339 } | 19354 } |
| 18340 | 19355 |
| 18341 /** | 19356 /** |
| 18342 * This checks that passed class declaration overrides all members required by
its superclasses | 19357 * This checks that passed class declaration overrides all members required by
its superclasses |
| 18343 * and interfaces. | 19358 * and interfaces. |
| 18344 * | 19359 * |
| 18345 * @param node the [ClassDeclaration] to evaluate | 19360 * @param node the [ClassDeclaration] to evaluate |
| 18346 * @return `true` if and only if an error code is generated on the passed node | 19361 * @return `true` if and only if an error code is generated on the passed node |
| 18347 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE | 19362 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE |
| 18348 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO | 19363 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO |
| 18349 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE | 19364 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE |
| 18350 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR | 19365 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR |
| 18351 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S | 19366 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S |
| 18352 */ | 19367 */ |
| 18353 bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) { | 19368 bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) { |
| 18354 if (_enclosingClass.isAbstract) { | 19369 if (_enclosingClass.isAbstract) { |
| 18355 return false; | 19370 return false; |
| 18356 } | 19371 } |
| 19372 // |
| 19373 // Store in local sets the set of all method and accessor names |
| 19374 // |
| 18357 List<MethodElement> methods = _enclosingClass.methods; | 19375 List<MethodElement> methods = _enclosingClass.methods; |
| 18358 List<PropertyAccessorElement> accessors = _enclosingClass.accessors; | 19376 List<PropertyAccessorElement> accessors = _enclosingClass.accessors; |
| 18359 Set<String> methodsInEnclosingClass = new Set<String>(); | 19377 Set<String> methodsInEnclosingClass = new Set<String>(); |
| 18360 for (MethodElement method in methods) { | 19378 for (MethodElement method in methods) { |
| 18361 String methodName = method.name; | 19379 String methodName = method.name; |
| 19380 // If the enclosing class declares the method noSuchMethod(), then return. |
| 19381 // From Spec: It is a static warning if a concrete class does not have an
implementation for |
| 19382 // a method in any of its superinterfaces unless it declares its own noSuc
hMethod |
| 19383 // method (7.10). |
| 18362 if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) { | 19384 if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) { |
| 18363 return false; | 19385 return false; |
| 18364 } | 19386 } |
| 18365 methodsInEnclosingClass.add(methodName); | 19387 methodsInEnclosingClass.add(methodName); |
| 18366 } | 19388 } |
| 18367 Set<String> accessorsInEnclosingClass = new Set<String>(); | 19389 Set<String> accessorsInEnclosingClass = new Set<String>(); |
| 18368 for (PropertyAccessorElement accessor in accessors) { | 19390 for (PropertyAccessorElement accessor in accessors) { |
| 18369 accessorsInEnclosingClass.add(accessor.name); | 19391 accessorsInEnclosingClass.add(accessor.name); |
| 18370 } | 19392 } |
| 18371 Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>(); | 19393 Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>(); |
| 19394 // |
| 19395 // Loop through the set of all executable elements declared in the implicit
interface. |
| 19396 // |
| 18372 MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembe
rsInheritedFromInterfaces(_enclosingClass); | 19397 MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembe
rsInheritedFromInterfaces(_enclosingClass); |
| 18373 MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMem
bersInheritedFromClasses(_enclosingClass); | 19398 MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMem
bersInheritedFromClasses(_enclosingClass); |
| 18374 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) { | 19399 for (int i = 0; i < membersInheritedFromInterfaces.size; i++) { |
| 18375 String memberName = membersInheritedFromInterfaces.getKey(i); | 19400 String memberName = membersInheritedFromInterfaces.getKey(i); |
| 18376 ExecutableElement executableElt = membersInheritedFromInterfaces.getValue(
i); | 19401 ExecutableElement executableElt = membersInheritedFromInterfaces.getValue(
i); |
| 18377 if (memberName == null) { | 19402 if (memberName == null) { |
| 18378 break; | 19403 break; |
| 18379 } | 19404 } |
| 19405 // If the element is defined in Object, skip it. |
| 18380 if ((executableElt.enclosingElement as ClassElement).type.isObject) { | 19406 if ((executableElt.enclosingElement as ClassElement).type.isObject) { |
| 18381 continue; | 19407 continue; |
| 18382 } | 19408 } |
| 19409 // Reference the type of the enclosing class |
| 18383 InterfaceType enclosingType = _enclosingClass.type; | 19410 InterfaceType enclosingType = _enclosingClass.type; |
| 19411 // Check to see if some element is in local enclosing class that matches t
he name of the |
| 19412 // required member. |
| 18384 if (isMemberInClassOrMixin(executableElt, _enclosingClass)) { | 19413 if (isMemberInClassOrMixin(executableElt, _enclosingClass)) { |
| 19414 // We do not have to verify that this implementation of the found method
matches the |
| 19415 // required function type: the set of StaticWarningCode.INVALID_METHOD_O
VERRIDE_* warnings |
| 19416 // break out the different specific situations. |
| 18385 continue; | 19417 continue; |
| 18386 } | 19418 } |
| 19419 // First check to see if this element was declared in the superclass chain
, in which case |
| 19420 // there is already a concrete implementation. |
| 18387 ExecutableElement elt = membersInheritedFromSuperclasses.get(executableElt
.name); | 19421 ExecutableElement elt = membersInheritedFromSuperclasses.get(executableElt
.name); |
| 19422 // Check to see if an element was found in the superclass chain with the c
orrect name. |
| 18388 if (elt != null) { | 19423 if (elt != null) { |
| 19424 // Some element was found in the superclass chain that matches the name
of the required |
| 19425 // member. |
| 19426 // If it is not abstract and it is the correct one (types match- the ver
sion of this method |
| 19427 // that we have has the correct number of parameters, etc), then this cl
ass has a valid |
| 19428 // implementation of this method, so skip it. |
| 18389 if ((elt is MethodElement && !elt.isAbstract) || (elt is PropertyAccesso
rElement && !elt.isAbstract)) { | 19429 if ((elt is MethodElement && !elt.isAbstract) || (elt is PropertyAccesso
rElement && !elt.isAbstract)) { |
| 19430 // Since we are comparing two function types, we need to do the approp
riate type |
| 19431 // substitutions first (). |
| 18390 FunctionType foundConcreteFT = _inheritanceManager.substituteTypeArgum
entsInMemberFromInheritance(elt.type, executableElt.name, enclosingType); | 19432 FunctionType foundConcreteFT = _inheritanceManager.substituteTypeArgum
entsInMemberFromInheritance(elt.type, executableElt.name, enclosingType); |
| 18391 FunctionType requiredMemberFT = _inheritanceManager.substituteTypeArgu
mentsInMemberFromInheritance(executableElt.type, executableElt.name, enclosingTy
pe); | 19433 FunctionType requiredMemberFT = _inheritanceManager.substituteTypeArgu
mentsInMemberFromInheritance(executableElt.type, executableElt.name, enclosingTy
pe); |
| 18392 if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) { | 19434 if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) { |
| 18393 continue; | 19435 continue; |
| 18394 } | 19436 } |
| 18395 } | 19437 } |
| 18396 } | 19438 } |
| 19439 // The not qualifying concrete executable element was found, add it to the
list. |
| 18397 missingOverrides.add(executableElt); | 19440 missingOverrides.add(executableElt); |
| 18398 } | 19441 } |
| 19442 // Now that we have the set of missing overrides, generate a warning on this
class |
| 18399 int missingOverridesSize = missingOverrides.length; | 19443 int missingOverridesSize = missingOverrides.length; |
| 18400 if (missingOverridesSize == 0) { | 19444 if (missingOverridesSize == 0) { |
| 18401 return false; | 19445 return false; |
| 18402 } | 19446 } |
| 18403 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid
es); | 19447 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid
es); |
| 18404 List<String> stringMembersArrayListSet = new List<String>(); | 19448 List<String> stringMembersArrayListSet = new List<String>(); |
| 18405 for (int i = 0; i < missingOverridesArray.length; i++) { | 19449 for (int i = 0; i < missingOverridesArray.length; i++) { |
| 18406 String newStrMember = "${missingOverridesArray[i].enclosingElement.display
Name}.${missingOverridesArray[i].displayName}"; | 19450 String newStrMember = "${missingOverridesArray[i].enclosingElement.display
Name}.${missingOverridesArray[i].displayName}"; |
| 18407 if (!stringMembersArrayListSet.contains(newStrMember)) { | 19451 if (!stringMembersArrayListSet.contains(newStrMember)) { |
| 18408 stringMembersArrayListSet.add(newStrMember); | 19452 stringMembersArrayListSet.add(newStrMember); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18502 * * has `const modifier` | 19546 * * has `const modifier` |
| 18503 * * has explicit type arguments | 19547 * * has explicit type arguments |
| 18504 * * is not start of the statement | 19548 * * is not start of the statement |
| 18505 * | 19549 * |
| 18506 * | 19550 * |
| 18507 * @param node the map literal to evaluate | 19551 * @param node the map literal to evaluate |
| 18508 * @return `true` if and only if an error code is generated on the passed node | 19552 * @return `true` if and only if an error code is generated on the passed node |
| 18509 * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT | 19553 * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT |
| 18510 */ | 19554 */ |
| 18511 bool checkForNonConstMapAsExpressionStatement(MapLiteral node) { | 19555 bool checkForNonConstMapAsExpressionStatement(MapLiteral node) { |
| 19556 // "const" |
| 18512 if (node.constKeyword != null) { | 19557 if (node.constKeyword != null) { |
| 18513 return false; | 19558 return false; |
| 18514 } | 19559 } |
| 19560 // has type arguments |
| 18515 if (node.typeArguments != null) { | 19561 if (node.typeArguments != null) { |
| 18516 return false; | 19562 return false; |
| 18517 } | 19563 } |
| 19564 // prepare statement |
| 18518 Statement statement = node.getAncestor(ExpressionStatement); | 19565 Statement statement = node.getAncestor(ExpressionStatement); |
| 18519 if (statement == null) { | 19566 if (statement == null) { |
| 18520 return false; | 19567 return false; |
| 18521 } | 19568 } |
| 19569 // OK, statement does not start with map |
| 18522 if (statement.beginToken != node.beginToken) { | 19570 if (statement.beginToken != node.beginToken) { |
| 18523 return false; | 19571 return false; |
| 18524 } | 19572 } |
| 19573 // report problem |
| 18525 _errorReporter.reportError3(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION
_STATEMENT, node, []); | 19574 _errorReporter.reportError3(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION
_STATEMENT, node, []); |
| 18526 return true; | 19575 return true; |
| 18527 } | 19576 } |
| 18528 | 19577 |
| 18529 /** | 19578 /** |
| 18530 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn | 19579 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn |
| 18531 * type. | 19580 * type. |
| 18532 * | 19581 * |
| 18533 * @param node the method declaration to evaluate | 19582 * @param node the method declaration to evaluate |
| 18534 * @return `true` if and only if an error code is generated on the passed node | 19583 * @return `true` if and only if an error code is generated on the passed node |
| 18535 * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR | 19584 * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR |
| 18536 */ | 19585 */ |
| 18537 bool checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { | 19586 bool checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { |
| 19587 // check that []= operator |
| 18538 SimpleIdentifier name = node.name; | 19588 SimpleIdentifier name = node.name; |
| 18539 if (name.name != "[]=") { | 19589 if (name.name != "[]=") { |
| 18540 return false; | 19590 return false; |
| 18541 } | 19591 } |
| 19592 // check return type |
| 18542 TypeName typeName = node.returnType; | 19593 TypeName typeName = node.returnType; |
| 18543 if (typeName != null) { | 19594 if (typeName != null) { |
| 18544 Type2 type = typeName.type; | 19595 Type2 type = typeName.type; |
| 18545 if (type != null && !type.isVoid) { | 19596 if (type != null && !type.isVoid) { |
| 18546 _errorReporter.reportError3(StaticWarningCode.NON_VOID_RETURN_FOR_OPERAT
OR, typeName, []); | 19597 _errorReporter.reportError3(StaticWarningCode.NON_VOID_RETURN_FOR_OPERAT
OR, typeName, []); |
| 18547 } | 19598 } |
| 18548 } | 19599 } |
| 19600 // no warning |
| 18549 return false; | 19601 return false; |
| 18550 } | 19602 } |
| 18551 | 19603 |
| 18552 /** | 19604 /** |
| 18553 * This verifies the passed setter has no return type or the `void` return typ
e. | 19605 * This verifies the passed setter has no return type or the `void` return typ
e. |
| 18554 * | 19606 * |
| 18555 * @param typeName the type name to evaluate | 19607 * @param typeName the type name to evaluate |
| 18556 * @return `true` if and only if an error code is generated on the passed node | 19608 * @return `true` if and only if an error code is generated on the passed node |
| 18557 * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER | 19609 * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER |
| 18558 */ | 19610 */ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18593 } | 19645 } |
| 18594 | 19646 |
| 18595 /** | 19647 /** |
| 18596 * This checks for named optional parameters that begin with '_'. | 19648 * This checks for named optional parameters that begin with '_'. |
| 18597 * | 19649 * |
| 18598 * @param node the default formal parameter to evaluate | 19650 * @param node the default formal parameter to evaluate |
| 18599 * @return `true` if and only if an error code is generated on the passed node | 19651 * @return `true` if and only if an error code is generated on the passed node |
| 18600 * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER | 19652 * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER |
| 18601 */ | 19653 */ |
| 18602 bool checkForPrivateOptionalParameter(FormalParameter node) { | 19654 bool checkForPrivateOptionalParameter(FormalParameter node) { |
| 19655 // should be named parameter |
| 18603 if (node.kind != ParameterKind.NAMED) { | 19656 if (node.kind != ParameterKind.NAMED) { |
| 18604 return false; | 19657 return false; |
| 18605 } | 19658 } |
| 19659 // name should start with '_' |
| 18606 SimpleIdentifier name = node.identifier; | 19660 SimpleIdentifier name = node.identifier; |
| 18607 if (name.isSynthetic || !name.name.startsWith("_")) { | 19661 if (name.isSynthetic || !name.name.startsWith("_")) { |
| 18608 return false; | 19662 return false; |
| 18609 } | 19663 } |
| 19664 // report problem |
| 18610 _errorReporter.reportError3(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER,
node, []); | 19665 _errorReporter.reportError3(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER,
node, []); |
| 18611 return true; | 19666 return true; |
| 18612 } | 19667 } |
| 18613 | 19668 |
| 18614 /** | 19669 /** |
| 18615 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and | 19670 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and |
| 18616 * references itself directly or indirectly. | 19671 * references itself directly or indirectly. |
| 18617 * | 19672 * |
| 18618 * @param node the constructor declaration to evaluate | 19673 * @param node the constructor declaration to evaluate |
| 18619 * @return `true` if and only if an error code is generated on the passed node | 19674 * @return `true` if and only if an error code is generated on the passed node |
| 18620 * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT | 19675 * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT |
| 18621 */ | 19676 */ |
| 18622 bool checkForRecursiveConstructorRedirect(ConstructorDeclaration node) { | 19677 bool checkForRecursiveConstructorRedirect(ConstructorDeclaration node) { |
| 19678 // we check generative constructor here |
| 18623 if (node.factoryKeyword != null) { | 19679 if (node.factoryKeyword != null) { |
| 18624 return false; | 19680 return false; |
| 18625 } | 19681 } |
| 19682 // try to find redirecting constructor invocation and analyzer it for recurs
ion |
| 18626 for (ConstructorInitializer initializer in node.initializers) { | 19683 for (ConstructorInitializer initializer in node.initializers) { |
| 18627 if (initializer is RedirectingConstructorInvocation) { | 19684 if (initializer is RedirectingConstructorInvocation) { |
| 19685 // OK if no cycle |
| 18628 ConstructorElement element = node.element; | 19686 ConstructorElement element = node.element; |
| 18629 if (!hasRedirectingFactoryConstructorCycle(element)) { | 19687 if (!hasRedirectingFactoryConstructorCycle(element)) { |
| 18630 return false; | 19688 return false; |
| 18631 } | 19689 } |
| 19690 // report error |
| 18632 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_R
EDIRECT, initializer, []); | 19691 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_R
EDIRECT, initializer, []); |
| 18633 return true; | 19692 return true; |
| 18634 } | 19693 } |
| 18635 } | 19694 } |
| 19695 // OK, no redirecting constructor invocation |
| 18636 return false; | 19696 return false; |
| 18637 } | 19697 } |
| 18638 | 19698 |
| 18639 /** | 19699 /** |
| 18640 * This checks if the passed constructor declaration has redirected constructo
r and references | 19700 * This checks if the passed constructor declaration has redirected constructo
r and references |
| 18641 * itself directly or indirectly. | 19701 * itself directly or indirectly. |
| 18642 * | 19702 * |
| 18643 * @param node the constructor declaration to evaluate | 19703 * @param node the constructor declaration to evaluate |
| 18644 * @return `true` if and only if an error code is generated on the passed node | 19704 * @return `true` if and only if an error code is generated on the passed node |
| 18645 * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT | 19705 * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT |
| 18646 */ | 19706 */ |
| 18647 bool checkForRecursiveFactoryRedirect(ConstructorDeclaration node) { | 19707 bool checkForRecursiveFactoryRedirect(ConstructorDeclaration node) { |
| 19708 // prepare redirected constructor |
| 18648 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 19709 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
| 18649 if (redirectedConstructorNode == null) { | 19710 if (redirectedConstructorNode == null) { |
| 18650 return false; | 19711 return false; |
| 18651 } | 19712 } |
| 19713 // OK if no cycle |
| 18652 ConstructorElement element = node.element; | 19714 ConstructorElement element = node.element; |
| 18653 if (!hasRedirectingFactoryConstructorCycle(element)) { | 19715 if (!hasRedirectingFactoryConstructorCycle(element)) { |
| 18654 return false; | 19716 return false; |
| 18655 } | 19717 } |
| 19718 // report error |
| 18656 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
redirectedConstructorNode, []); | 19719 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
redirectedConstructorNode, []); |
| 18657 return true; | 19720 return true; |
| 18658 } | 19721 } |
| 18659 | 19722 |
| 18660 /** | 19723 /** |
| 18661 * This checks the class declaration is not a superinterface to itself. | 19724 * This checks the class declaration is not a superinterface to itself. |
| 18662 * | 19725 * |
| 18663 * @param classElt the class element to test | 19726 * @param classElt the class element to test |
| 18664 * @return `true` if and only if an error code is generated on the passed elem
ent | 19727 * @return `true` if and only if an error code is generated on the passed elem
ent |
| 18665 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE | 19728 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE |
| (...skipping 11 matching lines...) Expand all Loading... |
| 18677 * This checks the class declaration is not a superinterface to itself. | 19740 * This checks the class declaration is not a superinterface to itself. |
| 18678 * | 19741 * |
| 18679 * @param classElt the class element to test | 19742 * @param classElt the class element to test |
| 18680 * @param path a list containing the potentially cyclic implements path | 19743 * @param path a list containing the potentially cyclic implements path |
| 18681 * @return `true` if and only if an error code is generated on the passed elem
ent | 19744 * @return `true` if and only if an error code is generated on the passed elem
ent |
| 18682 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE | 19745 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE |
| 18683 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS | 19746 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS |
| 18684 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS | 19747 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS |
| 18685 */ | 19748 */ |
| 18686 bool checkForRecursiveInterfaceInheritance2(ClassElement classElt, List<ClassE
lement> path) { | 19749 bool checkForRecursiveInterfaceInheritance2(ClassElement classElt, List<ClassE
lement> path) { |
| 19750 // Detect error condition. |
| 18687 int size = path.length; | 19751 int size = path.length; |
| 19752 // If this is not the base case (size > 0), and the enclosing class is the p
assed class |
| 19753 // element then an error an error. |
| 18688 if (size > 0 && _enclosingClass == classElt) { | 19754 if (size > 0 && _enclosingClass == classElt) { |
| 18689 String enclosingClassName = _enclosingClass.displayName; | 19755 String enclosingClassName = _enclosingClass.displayName; |
| 18690 if (size > 1) { | 19756 if (size > 1) { |
| 19757 // Construct a string showing the cyclic implements path: "A, B, C, D, A
" |
| 18691 String separator = ", "; | 19758 String separator = ", "; |
| 18692 JavaStringBuilder builder = new JavaStringBuilder(); | 19759 JavaStringBuilder builder = new JavaStringBuilder(); |
| 18693 for (int i = 0; i < size; i++) { | 19760 for (int i = 0; i < size; i++) { |
| 18694 builder.append(path[i].displayName); | 19761 builder.append(path[i].displayName); |
| 18695 builder.append(separator); | 19762 builder.append(separator); |
| 18696 } | 19763 } |
| 18697 builder.append(classElt.displayName); | 19764 builder.append(classElt.displayName); |
| 18698 _errorReporter.reportError5(CompileTimeErrorCode.RECURSIVE_INTERFACE_INH
ERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClass
Name, builder.toString()]); | 19765 _errorReporter.reportError5(CompileTimeErrorCode.RECURSIVE_INTERFACE_INH
ERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClass
Name, builder.toString()]); |
| 18699 return true; | 19766 return true; |
| 18700 } else { | 19767 } else { |
| 19768 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or RECURSIVE_INT
ERFACE_INHERITANCE_BASE_CASE_EXTENDS |
| 18701 InterfaceType supertype = classElt.supertype; | 19769 InterfaceType supertype = classElt.supertype; |
| 18702 ErrorCode errorCode = (supertype != null && _enclosingClass == supertype
.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTEND
S : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS); | 19770 ErrorCode errorCode = (supertype != null && _enclosingClass == supertype
.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTEND
S : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS); |
| 18703 _errorReporter.reportError5(errorCode, _enclosingClass.nameOffset, enclo
singClassName.length, [enclosingClassName]); | 19771 _errorReporter.reportError5(errorCode, _enclosingClass.nameOffset, enclo
singClassName.length, [enclosingClassName]); |
| 18704 return true; | 19772 return true; |
| 18705 } | 19773 } |
| 18706 } | 19774 } |
| 18707 if (path.indexOf(classElt) > 0) { | 19775 if (path.indexOf(classElt) > 0) { |
| 18708 return false; | 19776 return false; |
| 18709 } | 19777 } |
| 18710 path.add(classElt); | 19778 path.add(classElt); |
| 19779 // n-case |
| 18711 InterfaceType supertype = classElt.supertype; | 19780 InterfaceType supertype = classElt.supertype; |
| 18712 if (supertype != null && checkForRecursiveInterfaceInheritance2(supertype.el
ement, path)) { | 19781 if (supertype != null && checkForRecursiveInterfaceInheritance2(supertype.el
ement, path)) { |
| 18713 return true; | 19782 return true; |
| 18714 } | 19783 } |
| 18715 List<InterfaceType> interfaceTypes = classElt.interfaces; | 19784 List<InterfaceType> interfaceTypes = classElt.interfaces; |
| 18716 for (InterfaceType interfaceType in interfaceTypes) { | 19785 for (InterfaceType interfaceType in interfaceTypes) { |
| 18717 if (checkForRecursiveInterfaceInheritance2(interfaceType.element, path)) { | 19786 if (checkForRecursiveInterfaceInheritance2(interfaceType.element, path)) { |
| 18718 return true; | 19787 return true; |
| 18719 } | 19788 } |
| 18720 } | 19789 } |
| 18721 path.removeAt(path.length - 1); | 19790 path.removeAt(path.length - 1); |
| 18722 return false; | 19791 return false; |
| 18723 } | 19792 } |
| 18724 | 19793 |
| 18725 /** | 19794 /** |
| 18726 * This checks the passed constructor declaration has a valid combination of r
edirected | 19795 * This checks the passed constructor declaration has a valid combination of r
edirected |
| 18727 * constructor invocation(s), super constructor invocations and field initiali
zers. | 19796 * constructor invocation(s), super constructor invocations and field initiali
zers. |
| 18728 * | 19797 * |
| 18729 * @param node the constructor declaration to evaluate | 19798 * @param node the constructor declaration to evaluate |
| 18730 * @return `true` if and only if an error code is generated on the passed node | 19799 * @return `true` if and only if an error code is generated on the passed node |
| 18731 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR | 19800 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR |
| 18732 * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR | 19801 * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR |
| 18733 * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS | 19802 * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS |
| 18734 * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR | 19803 * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR |
| 18735 */ | 19804 */ |
| 18736 bool checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { | 19805 bool checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { |
| 18737 bool errorReported = false; | 19806 bool errorReported = false; |
| 19807 // |
| 19808 // Check for default values in the parameters |
| 19809 // |
| 18738 ConstructorName redirectedConstructor = node.redirectedConstructor; | 19810 ConstructorName redirectedConstructor = node.redirectedConstructor; |
| 18739 if (redirectedConstructor != null) { | 19811 if (redirectedConstructor != null) { |
| 18740 for (FormalParameter parameter in node.parameters.parameters) { | 19812 for (FormalParameter parameter in node.parameters.parameters) { |
| 18741 if (parameter is DefaultFormalParameter && parameter.defaultValue != nul
l) { | 19813 if (parameter is DefaultFormalParameter && parameter.defaultValue != nul
l) { |
| 18742 _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_REDI
RECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []); | 19814 _errorReporter.reportError3(CompileTimeErrorCode.DEFAULT_VALUE_IN_REDI
RECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []); |
| 18743 errorReported = true; | 19815 errorReported = true; |
| 18744 } | 19816 } |
| 18745 } | 19817 } |
| 18746 } | 19818 } |
| 19819 // check if there are redirected invocations |
| 18747 int numRedirections = 0; | 19820 int numRedirections = 0; |
| 18748 for (ConstructorInitializer initializer in node.initializers) { | 19821 for (ConstructorInitializer initializer in node.initializers) { |
| 18749 if (initializer is RedirectingConstructorInvocation) { | 19822 if (initializer is RedirectingConstructorInvocation) { |
| 18750 if (numRedirections > 0) { | 19823 if (numRedirections > 0) { |
| 18751 _errorReporter.reportError3(CompileTimeErrorCode.MULTIPLE_REDIRECTING_
CONSTRUCTOR_INVOCATIONS, initializer, []); | 19824 _errorReporter.reportError3(CompileTimeErrorCode.MULTIPLE_REDIRECTING_
CONSTRUCTOR_INVOCATIONS, initializer, []); |
| 18752 errorReported = true; | 19825 errorReported = true; |
| 18753 } | 19826 } |
| 18754 numRedirections++; | 19827 numRedirections++; |
| 18755 } | 19828 } |
| 18756 } | 19829 } |
| 19830 // check for other initializers |
| 18757 if (numRedirections > 0) { | 19831 if (numRedirections > 0) { |
| 18758 for (ConstructorInitializer initializer in node.initializers) { | 19832 for (ConstructorInitializer initializer in node.initializers) { |
| 18759 if (initializer is SuperConstructorInvocation) { | 19833 if (initializer is SuperConstructorInvocation) { |
| 18760 _errorReporter.reportError3(CompileTimeErrorCode.SUPER_IN_REDIRECTING_
CONSTRUCTOR, initializer, []); | 19834 _errorReporter.reportError3(CompileTimeErrorCode.SUPER_IN_REDIRECTING_
CONSTRUCTOR, initializer, []); |
| 18761 errorReported = true; | 19835 errorReported = true; |
| 18762 } | 19836 } |
| 18763 if (initializer is ConstructorFieldInitializer) { | 19837 if (initializer is ConstructorFieldInitializer) { |
| 18764 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_RED
IRECTING_CONSTRUCTOR, initializer, []); | 19838 _errorReporter.reportError3(CompileTimeErrorCode.FIELD_INITIALIZER_RED
IRECTING_CONSTRUCTOR, initializer, []); |
| 18765 errorReported = true; | 19839 errorReported = true; |
| 18766 } | 19840 } |
| 18767 } | 19841 } |
| 18768 } | 19842 } |
| 19843 // done |
| 18769 return errorReported; | 19844 return errorReported; |
| 18770 } | 19845 } |
| 18771 | 19846 |
| 18772 /** | 19847 /** |
| 18773 * This checks if the passed constructor declaration has redirected constructo
r and references | 19848 * This checks if the passed constructor declaration has redirected constructo
r and references |
| 18774 * itself directly or indirectly. | 19849 * itself directly or indirectly. |
| 18775 * | 19850 * |
| 18776 * @param node the constructor declaration to evaluate | 19851 * @param node the constructor declaration to evaluate |
| 18777 * @return `true` if and only if an error code is generated on the passed node | 19852 * @return `true` if and only if an error code is generated on the passed node |
| 18778 * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR | 19853 * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR |
| 18779 */ | 19854 */ |
| 18780 bool checkForRedirectToNonConstConstructor(ConstructorDeclaration node) { | 19855 bool checkForRedirectToNonConstConstructor(ConstructorDeclaration node) { |
| 19856 // prepare redirected constructor |
| 18781 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 19857 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
| 18782 if (redirectedConstructorNode == null) { | 19858 if (redirectedConstructorNode == null) { |
| 18783 return false; | 19859 return false; |
| 18784 } | 19860 } |
| 19861 // prepare element |
| 18785 ConstructorElement element = node.element; | 19862 ConstructorElement element = node.element; |
| 18786 if (element == null) { | 19863 if (element == null) { |
| 18787 return false; | 19864 return false; |
| 18788 } | 19865 } |
| 19866 // OK, it is not 'const' |
| 18789 if (!element.isConst) { | 19867 if (!element.isConst) { |
| 18790 return false; | 19868 return false; |
| 18791 } | 19869 } |
| 19870 // prepare redirected constructor |
| 18792 ConstructorElement redirectedConstructor = element.redirectedConstructor; | 19871 ConstructorElement redirectedConstructor = element.redirectedConstructor; |
| 18793 if (redirectedConstructor == null) { | 19872 if (redirectedConstructor == null) { |
| 18794 return false; | 19873 return false; |
| 18795 } | 19874 } |
| 19875 // OK, it is also 'const' |
| 18796 if (redirectedConstructor.isConst) { | 19876 if (redirectedConstructor.isConst) { |
| 18797 return false; | 19877 return false; |
| 18798 } | 19878 } |
| 19879 // report error |
| 18799 _errorReporter.reportError3(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONST
RUCTOR, redirectedConstructorNode, []); | 19880 _errorReporter.reportError3(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONST
RUCTOR, redirectedConstructorNode, []); |
| 18800 return true; | 19881 return true; |
| 18801 } | 19882 } |
| 18802 | 19883 |
| 18803 /** | 19884 /** |
| 18804 * This checks that the rethrow is inside of a catch clause. | 19885 * This checks that the rethrow is inside of a catch clause. |
| 18805 * | 19886 * |
| 18806 * @param node the rethrow expression to evaluate | 19887 * @param node the rethrow expression to evaluate |
| 18807 * @return `true` if and only if an error code is generated on the passed node | 19888 * @return `true` if and only if an error code is generated on the passed node |
| 18808 * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH | 19889 * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH |
| 18809 */ | 19890 */ |
| 18810 bool checkForRethrowOutsideCatch(RethrowExpression node) { | 19891 bool checkForRethrowOutsideCatch(RethrowExpression node) { |
| 18811 if (!_isInCatchClause) { | 19892 if (!_isInCatchClause) { |
| 18812 _errorReporter.reportError3(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, no
de, []); | 19893 _errorReporter.reportError3(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, no
de, []); |
| 18813 return true; | 19894 return true; |
| 18814 } | 19895 } |
| 18815 return false; | 19896 return false; |
| 18816 } | 19897 } |
| 18817 | 19898 |
| 18818 /** | 19899 /** |
| 18819 * This checks that if the the given constructor declaration is generative, th
en it does not have | 19900 * This checks that if the the given constructor declaration is generative, th
en it does not have |
| 18820 * an expression function body. | 19901 * an expression function body. |
| 18821 * | 19902 * |
| 18822 * @param node the constructor to evaluate | 19903 * @param node the constructor to evaluate |
| 18823 * @return `true` if and only if an error code is generated on the passed node | 19904 * @return `true` if and only if an error code is generated on the passed node |
| 18824 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR | 19905 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 18825 */ | 19906 */ |
| 18826 bool checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { | 19907 bool checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { |
| 19908 // ignore factory |
| 18827 if (node.factoryKeyword != null) { | 19909 if (node.factoryKeyword != null) { |
| 18828 return false; | 19910 return false; |
| 18829 } | 19911 } |
| 19912 // block body (with possible return statement) is checked elsewhere |
| 18830 FunctionBody body = node.body; | 19913 FunctionBody body = node.body; |
| 18831 if (body is! ExpressionFunctionBody) { | 19914 if (body is! ExpressionFunctionBody) { |
| 18832 return false; | 19915 return false; |
| 18833 } | 19916 } |
| 19917 // report error |
| 18834 _errorReporter.reportError3(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTR
UCTOR, body, []); | 19918 _errorReporter.reportError3(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTR
UCTOR, body, []); |
| 18835 return true; | 19919 return true; |
| 18836 } | 19920 } |
| 18837 | 19921 |
| 18838 /** | 19922 /** |
| 18839 * This checks that a type mis-match between the return type and the expressed
return type by the | 19923 * This checks that a type mis-match between the return type and the expressed
return type by the |
| 18840 * enclosing method or function. | 19924 * enclosing method or function. |
| 18841 * | 19925 * |
| 18842 * This method is called both by [checkForAllReturnStatementErrorCodes] | 19926 * This method is called both by [checkForAllReturnStatementErrorCodes] |
| 18843 * and [visitExpressionFunctionBody]. | 19927 * and [visitExpressionFunctionBody]. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18875 * member. | 19959 * member. |
| 18876 * | 19960 * |
| 18877 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 19961 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
| 18878 * or `null`, aka, the class element of 'C' in 'C.x', see | 19962 * or `null`, aka, the class element of 'C' in 'C.x', see |
| 18879 * [getTypeReference] | 19963 * [getTypeReference] |
| 18880 * @param name the accessed name to evaluate | 19964 * @param name the accessed name to evaluate |
| 18881 * @return `true` if and only if an error code is generated on the passed node | 19965 * @return `true` if and only if an error code is generated on the passed node |
| 18882 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER | 19966 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER |
| 18883 */ | 19967 */ |
| 18884 bool checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleId
entifier name) { | 19968 bool checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleId
entifier name) { |
| 19969 // OK, target is not a type |
| 18885 if (typeReference == null) { | 19970 if (typeReference == null) { |
| 18886 return false; | 19971 return false; |
| 18887 } | 19972 } |
| 19973 // prepare member Element |
| 18888 Element element = name.staticElement; | 19974 Element element = name.staticElement; |
| 18889 if (element is! ExecutableElement) { | 19975 if (element is! ExecutableElement) { |
| 18890 return false; | 19976 return false; |
| 18891 } | 19977 } |
| 18892 ExecutableElement memberElement = element as ExecutableElement; | 19978 ExecutableElement memberElement = element as ExecutableElement; |
| 19979 // OK, static |
| 18893 if (memberElement.isStatic) { | 19980 if (memberElement.isStatic) { |
| 18894 return false; | 19981 return false; |
| 18895 } | 19982 } |
| 19983 // report problem |
| 18896 _errorReporter.reportError3(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMB
ER, name, [name.name]); | 19984 _errorReporter.reportError3(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMB
ER, name, [name.name]); |
| 18897 return true; | 19985 return true; |
| 18898 } | 19986 } |
| 18899 | 19987 |
| 18900 /** | 19988 /** |
| 18901 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the | 19989 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the |
| 18902 * 'case' members. | 19990 * 'case' members. |
| 18903 * | 19991 * |
| 18904 * @param node the 'switch' statement to evaluate | 19992 * @param node the 'switch' statement to evaluate |
| 18905 * @return `true` if and only if an error code is generated on the passed node | 19993 * @return `true` if and only if an error code is generated on the passed node |
| 18906 * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE | 19994 * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE |
| 18907 */ | 19995 */ |
| 18908 bool checkForSwitchExpressionNotAssignable(SwitchStatement node) { | 19996 bool checkForSwitchExpressionNotAssignable(SwitchStatement node) { |
| 19997 // prepare 'switch' expression type |
| 18909 Expression expression = node.expression; | 19998 Expression expression = node.expression; |
| 18910 Type2 expressionType = getStaticType(expression); | 19999 Type2 expressionType = getStaticType(expression); |
| 18911 if (expressionType == null) { | 20000 if (expressionType == null) { |
| 18912 return false; | 20001 return false; |
| 18913 } | 20002 } |
| 20003 // compare with type of the first 'case' |
| 18914 NodeList<SwitchMember> members = node.members; | 20004 NodeList<SwitchMember> members = node.members; |
| 18915 for (SwitchMember switchMember in members) { | 20005 for (SwitchMember switchMember in members) { |
| 18916 if (switchMember is! SwitchCase) { | 20006 if (switchMember is! SwitchCase) { |
| 18917 continue; | 20007 continue; |
| 18918 } | 20008 } |
| 18919 SwitchCase switchCase = switchMember as SwitchCase; | 20009 SwitchCase switchCase = switchMember as SwitchCase; |
| 20010 // prepare 'case' type |
| 18920 Expression caseExpression = switchCase.expression; | 20011 Expression caseExpression = switchCase.expression; |
| 18921 Type2 caseType = getStaticType(caseExpression); | 20012 Type2 caseType = getStaticType(caseExpression); |
| 20013 // check types |
| 18922 if (expressionType.isAssignableTo(caseType)) { | 20014 if (expressionType.isAssignableTo(caseType)) { |
| 18923 return false; | 20015 return false; |
| 18924 } | 20016 } |
| 20017 // report problem |
| 18925 _errorReporter.reportError3(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGN
ABLE, expression, [expressionType, caseType]); | 20018 _errorReporter.reportError3(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGN
ABLE, expression, [expressionType, caseType]); |
| 18926 return true; | 20019 return true; |
| 18927 } | 20020 } |
| 18928 return false; | 20021 return false; |
| 18929 } | 20022 } |
| 18930 | 20023 |
| 18931 /** | 20024 /** |
| 18932 * This verifies that the passed function type alias does not reference itself
directly. | 20025 * This verifies that the passed function type alias does not reference itself
directly. |
| 18933 * | 20026 * |
| 18934 * @param node the function type alias to evaluate | 20027 * @param node the function type alias to evaluate |
| (...skipping 28 matching lines...) Expand all Loading... |
| 18963 * This verifies that the type arguments in the passed type name are all withi
n their bounds. | 20056 * This verifies that the type arguments in the passed type name are all withi
n their bounds. |
| 18964 * | 20057 * |
| 18965 * @param node the [TypeName] to evaluate | 20058 * @param node the [TypeName] to evaluate |
| 18966 * @return `true` if and only if an error code is generated on the passed node | 20059 * @return `true` if and only if an error code is generated on the passed node |
| 18967 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS | 20060 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS |
| 18968 */ | 20061 */ |
| 18969 bool checkForTypeArgumentNotMatchingBounds(TypeName node) { | 20062 bool checkForTypeArgumentNotMatchingBounds(TypeName node) { |
| 18970 if (node.typeArguments == null) { | 20063 if (node.typeArguments == null) { |
| 18971 return false; | 20064 return false; |
| 18972 } | 20065 } |
| 20066 // prepare Type |
| 18973 Type2 type = node.type; | 20067 Type2 type = node.type; |
| 18974 if (type == null) { | 20068 if (type == null) { |
| 18975 return false; | 20069 return false; |
| 18976 } | 20070 } |
| 20071 // prepare ClassElement |
| 18977 Element element = type.element; | 20072 Element element = type.element; |
| 18978 if (element is! ClassElement) { | 20073 if (element is! ClassElement) { |
| 18979 return false; | 20074 return false; |
| 18980 } | 20075 } |
| 18981 ClassElement classElement = element as ClassElement; | 20076 ClassElement classElement = element as ClassElement; |
| 20077 // prepare type parameters |
| 18982 List<Type2> typeParameters = classElement.type.typeArguments; | 20078 List<Type2> typeParameters = classElement.type.typeArguments; |
| 18983 List<TypeParameterElement> boundingElts = classElement.typeParameters; | 20079 List<TypeParameterElement> boundingElts = classElement.typeParameters; |
| 20080 // iterate over each bounded type parameter and corresponding argument |
| 18984 NodeList<TypeName> typeNameArgList = node.typeArguments.arguments; | 20081 NodeList<TypeName> typeNameArgList = node.typeArguments.arguments; |
| 18985 List<Type2> typeArguments = (type as InterfaceType).typeArguments; | 20082 List<Type2> typeArguments = (type as InterfaceType).typeArguments; |
| 18986 int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.length)
; | 20083 int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.length)
; |
| 18987 bool foundError = false; | 20084 bool foundError = false; |
| 18988 for (int i = 0; i < loopThroughIndex; i++) { | 20085 for (int i = 0; i < loopThroughIndex; i++) { |
| 18989 TypeName argTypeName = typeNameArgList[i]; | 20086 TypeName argTypeName = typeNameArgList[i]; |
| 18990 Type2 argType = argTypeName.type; | 20087 Type2 argType = argTypeName.type; |
| 18991 Type2 boundType = boundingElts[i].bound; | 20088 Type2 boundType = boundingElts[i].bound; |
| 18992 if (argType != null && boundType != null) { | 20089 if (argType != null && boundType != null) { |
| 18993 boundType = boundType.substitute2(typeArguments, typeParameters); | 20090 boundType = boundType.substitute2(typeArguments, typeParameters); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19027 | 20124 |
| 19028 /** | 20125 /** |
| 19029 * This checks that if the passed type parameter is a supertype of its bound. | 20126 * This checks that if the passed type parameter is a supertype of its bound. |
| 19030 * | 20127 * |
| 19031 * @param node the type parameter to evaluate | 20128 * @param node the type parameter to evaluate |
| 19032 * @return `true` if and only if an error code is generated on the passed node | 20129 * @return `true` if and only if an error code is generated on the passed node |
| 19033 * @see StaticTypeWarningCode#TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND | 20130 * @see StaticTypeWarningCode#TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND |
| 19034 */ | 20131 */ |
| 19035 bool checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { | 20132 bool checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { |
| 19036 TypeParameterElement element = node.element; | 20133 TypeParameterElement element = node.element; |
| 20134 // prepare bound |
| 19037 Type2 bound = element.bound; | 20135 Type2 bound = element.bound; |
| 19038 if (bound == null) { | 20136 if (bound == null) { |
| 19039 return false; | 20137 return false; |
| 19040 } | 20138 } |
| 20139 // OK, type parameter is not supertype of its bound |
| 19041 if (!bound.isMoreSpecificThan(element.type)) { | 20140 if (!bound.isMoreSpecificThan(element.type)) { |
| 19042 return false; | 20141 return false; |
| 19043 } | 20142 } |
| 20143 // report problem |
| 19044 _errorReporter.reportError3(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_O
F_ITS_BOUND, node, [element.displayName]); | 20144 _errorReporter.reportError3(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_O
F_ITS_BOUND, node, [element.displayName]); |
| 19045 return true; | 20145 return true; |
| 19046 } | 20146 } |
| 19047 | 20147 |
| 19048 /** | 20148 /** |
| 19049 * This checks that if the passed generative constructor has neither an explic
it super constructor | 20149 * This checks that if the passed generative constructor has neither an explic
it super constructor |
| 19050 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default | 20150 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default |
| 19051 * generative constructor. | 20151 * generative constructor. |
| 19052 * | 20152 * |
| 19053 * @param node the constructor declaration to evaluate | 20153 * @param node the constructor declaration to evaluate |
| 19054 * @return `true` if and only if an error code is generated on the passed node | 20154 * @return `true` if and only if an error code is generated on the passed node |
| 19055 * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT | 20155 * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT |
| 19056 * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR | 20156 * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR |
| 19057 * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT | 20157 * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT |
| 19058 */ | 20158 */ |
| 19059 bool checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration
node) { | 20159 bool checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration
node) { |
| 20160 // |
| 20161 // Ignore if the constructor is not generative. |
| 20162 // |
| 19060 if (node.factoryKeyword != null) { | 20163 if (node.factoryKeyword != null) { |
| 19061 return false; | 20164 return false; |
| 19062 } | 20165 } |
| 20166 // |
| 20167 // Ignore if the constructor has either an implicit super constructor invoca
tion or a |
| 20168 // redirecting constructor invocation. |
| 20169 // |
| 19063 for (ConstructorInitializer constructorInitializer in node.initializers) { | 20170 for (ConstructorInitializer constructorInitializer in node.initializers) { |
| 19064 if (constructorInitializer is SuperConstructorInvocation || constructorIni
tializer is RedirectingConstructorInvocation) { | 20171 if (constructorInitializer is SuperConstructorInvocation || constructorIni
tializer is RedirectingConstructorInvocation) { |
| 19065 return false; | 20172 return false; |
| 19066 } | 20173 } |
| 19067 } | 20174 } |
| 20175 // |
| 20176 // Check to see whether the superclass has a non-factory unnamed constructor
. |
| 20177 // |
| 19068 if (_enclosingClass == null) { | 20178 if (_enclosingClass == null) { |
| 19069 return false; | 20179 return false; |
| 19070 } | 20180 } |
| 19071 InterfaceType superType = _enclosingClass.supertype; | 20181 InterfaceType superType = _enclosingClass.supertype; |
| 19072 if (superType == null) { | 20182 if (superType == null) { |
| 19073 return false; | 20183 return false; |
| 19074 } | 20184 } |
| 19075 ClassElement superElement = superType.element; | 20185 ClassElement superElement = superType.element; |
| 19076 ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor
; | 20186 ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor
; |
| 19077 if (superUnnamedConstructor != null) { | 20187 if (superUnnamedConstructor != null) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19127 * This verifies the passed operator-method declaration, has correct number of
parameters. | 20237 * This verifies the passed operator-method declaration, has correct number of
parameters. |
| 19128 * | 20238 * |
| 19129 * This method assumes that the method declaration was tested to be an operato
r declaration before | 20239 * This method assumes that the method declaration was tested to be an operato
r declaration before |
| 19130 * being called. | 20240 * being called. |
| 19131 * | 20241 * |
| 19132 * @param node the method declaration to evaluate | 20242 * @param node the method declaration to evaluate |
| 19133 * @return `true` if and only if an error code is generated on the passed node | 20243 * @return `true` if and only if an error code is generated on the passed node |
| 19134 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR | 20244 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR |
| 19135 */ | 20245 */ |
| 19136 bool checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { | 20246 bool checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { |
| 20247 // prepare number of parameters |
| 19137 FormalParameterList parameterList = node.parameters; | 20248 FormalParameterList parameterList = node.parameters; |
| 19138 if (parameterList == null) { | 20249 if (parameterList == null) { |
| 19139 return false; | 20250 return false; |
| 19140 } | 20251 } |
| 19141 int numParameters = parameterList.parameters.length; | 20252 int numParameters = parameterList.parameters.length; |
| 20253 // prepare operator name |
| 19142 SimpleIdentifier nameNode = node.name; | 20254 SimpleIdentifier nameNode = node.name; |
| 19143 if (nameNode == null) { | 20255 if (nameNode == null) { |
| 19144 return false; | 20256 return false; |
| 19145 } | 20257 } |
| 19146 String name = nameNode.name; | 20258 String name = nameNode.name; |
| 20259 // check for exact number of parameters |
| 19147 int expected = -1; | 20260 int expected = -1; |
| 19148 if ("[]=" == name) { | 20261 if ("[]=" == name) { |
| 19149 expected = 2; | 20262 expected = 2; |
| 19150 } else if ("<" == name || ">" == name || "<=" == name || ">=" == name || "==
" == name || "+" == name || "/" == name || "~/" == name || "*" == name || "%" ==
name || "|" == name || "^" == name || "&" == name || "<<" == name || ">>" == na
me || "[]" == name) { | 20263 } else if ("<" == name || ">" == name || "<=" == name || ">=" == name || "==
" == name || "+" == name || "/" == name || "~/" == name || "*" == name || "%" ==
name || "|" == name || "^" == name || "&" == name || "<<" == name || ">>" == na
me || "[]" == name) { |
| 19151 expected = 1; | 20264 expected = 1; |
| 19152 } else if ("~" == name) { | 20265 } else if ("~" == name) { |
| 19153 expected = 0; | 20266 expected = 0; |
| 19154 } | 20267 } |
| 19155 if (expected != -1 && numParameters != expected) { | 20268 if (expected != -1 && numParameters != expected) { |
| 19156 _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER
S_FOR_OPERATOR, nameNode, [name, expected, numParameters]); | 20269 _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER
S_FOR_OPERATOR, nameNode, [name, expected, numParameters]); |
| 19157 return true; | 20270 return true; |
| 19158 } | 20271 } |
| 20272 // check for operator "-" |
| 19159 if ("-" == name && numParameters > 1) { | 20273 if ("-" == name && numParameters > 1) { |
| 19160 _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER
S_FOR_OPERATOR_MINUS, nameNode, [numParameters]); | 20274 _errorReporter.reportError3(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER
S_FOR_OPERATOR_MINUS, nameNode, [numParameters]); |
| 19161 return true; | 20275 return true; |
| 19162 } | 20276 } |
| 20277 // OK |
| 19163 return false; | 20278 return false; |
| 19164 } | 20279 } |
| 19165 | 20280 |
| 19166 /** | 20281 /** |
| 19167 * This verifies if the passed setter parameter list have only one required pa
rameter. | 20282 * This verifies if the passed setter parameter list have only one required pa
rameter. |
| 19168 * | 20283 * |
| 19169 * This method assumes that the method declaration was tested to be a setter b
efore being called. | 20284 * This method assumes that the method declaration was tested to be a setter b
efore being called. |
| 19170 * | 20285 * |
| 19171 * @param setterName the name of the setter to report problems on | 20286 * @param setterName the name of the setter to report problems on |
| 19172 * @param parameterList the parameter list to evaluate | 20287 * @param parameterList the parameter list to evaluate |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19215 } | 20330 } |
| 19216 | 20331 |
| 19217 /** | 20332 /** |
| 19218 * This verifies that the given class declaration does not have the same class
in the 'extends' | 20333 * This verifies that the given class declaration does not have the same class
in the 'extends' |
| 19219 * and 'implements' clauses. | 20334 * and 'implements' clauses. |
| 19220 * | 20335 * |
| 19221 * @return `true` if and only if an error code is generated on the passed node | 20336 * @return `true` if and only if an error code is generated on the passed node |
| 19222 * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS | 20337 * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS |
| 19223 */ | 20338 */ |
| 19224 bool checkImplementsSuperClass(ClassDeclaration node) { | 20339 bool checkImplementsSuperClass(ClassDeclaration node) { |
| 20340 // prepare super type |
| 19225 InterfaceType superType = _enclosingClass.supertype; | 20341 InterfaceType superType = _enclosingClass.supertype; |
| 19226 if (superType == null) { | 20342 if (superType == null) { |
| 19227 return false; | 20343 return false; |
| 19228 } | 20344 } |
| 20345 // prepare interfaces |
| 19229 ImplementsClause implementsClause = node.implementsClause; | 20346 ImplementsClause implementsClause = node.implementsClause; |
| 19230 if (implementsClause == null) { | 20347 if (implementsClause == null) { |
| 19231 return false; | 20348 return false; |
| 19232 } | 20349 } |
| 20350 // check interfaces |
| 19233 bool hasProblem = false; | 20351 bool hasProblem = false; |
| 19234 for (TypeName interfaceNode in implementsClause.interfaces) { | 20352 for (TypeName interfaceNode in implementsClause.interfaces) { |
| 19235 if (interfaceNode.type == superType) { | 20353 if (interfaceNode.type == superType) { |
| 19236 hasProblem = true; | 20354 hasProblem = true; |
| 19237 _errorReporter.reportError3(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
interfaceNode, [superType.displayName]); | 20355 _errorReporter.reportError3(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
interfaceNode, [superType.displayName]); |
| 19238 } | 20356 } |
| 19239 } | 20357 } |
| 20358 // done |
| 19240 return hasProblem; | 20359 return hasProblem; |
| 19241 } | 20360 } |
| 19242 | 20361 |
| 19243 /** | 20362 /** |
| 19244 * Returns the Type (return type) for a given getter. | 20363 * Returns the Type (return type) for a given getter. |
| 19245 * | 20364 * |
| 19246 * @param propertyAccessorElement | 20365 * @param propertyAccessorElement |
| 19247 * @return The type of the given getter. | 20366 * @return The type of the given getter. |
| 19248 */ | 20367 */ |
| 19249 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) { | 20368 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) { |
| 19250 FunctionType functionType = propertyAccessorElement.type; | 20369 FunctionType functionType = propertyAccessorElement.type; |
| 19251 if (functionType != null) { | 20370 if (functionType != null) { |
| 19252 return functionType.returnType; | 20371 return functionType.returnType; |
| 19253 } else { | 20372 } else { |
| 19254 return null; | 20373 return null; |
| 19255 } | 20374 } |
| 19256 } | 20375 } |
| 19257 | 20376 |
| 19258 /** | 20377 /** |
| 19259 * Returns the Type (first and only parameter) for a given setter. | 20378 * Returns the Type (first and only parameter) for a given setter. |
| 19260 * | 20379 * |
| 19261 * @param propertyAccessorElement | 20380 * @param propertyAccessorElement |
| 19262 * @return The type of the given setter. | 20381 * @return The type of the given setter. |
| 19263 */ | 20382 */ |
| 19264 Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) { | 20383 Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) { |
| 20384 // Get the parameters for MethodDeclaration or FunctionDeclaration |
| 19265 List<ParameterElement> setterParameters = propertyAccessorElement.parameters
; | 20385 List<ParameterElement> setterParameters = propertyAccessorElement.parameters
; |
| 20386 // If there are no setter parameters, return no type. |
| 19266 if (setterParameters.length == 0) { | 20387 if (setterParameters.length == 0) { |
| 19267 return null; | 20388 return null; |
| 19268 } | 20389 } |
| 19269 return setterParameters[0].type; | 20390 return setterParameters[0].type; |
| 19270 } | 20391 } |
| 19271 | 20392 |
| 19272 /** | 20393 /** |
| 19273 * Return the static type of the given expression that is to be used for type
analysis. | 20394 * Return the static type of the given expression that is to be used for type
analysis. |
| 19274 * | 20395 * |
| 19275 * @param expression the expression whose type is to be returned | 20396 * @param expression the expression whose type is to be returned |
| 19276 * @return the static type of the given expression | 20397 * @return the static type of the given expression |
| 19277 */ | 20398 */ |
| 19278 Type2 getStaticType(Expression expression) { | 20399 Type2 getStaticType(Expression expression) { |
| 19279 Type2 type = expression.staticType; | 20400 Type2 type = expression.staticType; |
| 19280 if (type == null) { | 20401 if (type == null) { |
| 20402 // TODO(brianwilkerson) This should never happen. |
| 19281 return _dynamicType; | 20403 return _dynamicType; |
| 19282 } | 20404 } |
| 19283 return type; | 20405 return type; |
| 19284 } | 20406 } |
| 19285 | 20407 |
| 19286 /** | 20408 /** |
| 19287 * Return the variable element represented by the given expression, or `null`
if there is no | 20409 * Return the variable element represented by the given expression, or `null`
if there is no |
| 19288 * such element. | 20410 * such element. |
| 19289 * | 20411 * |
| 19290 * @param expression the expression whose element is to be returned | 20412 * @param expression the expression whose element is to be returned |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19323 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself | 20445 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself |
| 19324 * from anywhere except [ClassElement] or type parameter bounds. | 20446 * from anywhere except [ClassElement] or type parameter bounds. |
| 19325 */ | 20447 */ |
| 19326 bool hasTypedefSelfReference(Element target) { | 20448 bool hasTypedefSelfReference(Element target) { |
| 19327 Set<Element> checked = new Set<Element>(); | 20449 Set<Element> checked = new Set<Element>(); |
| 19328 List<Element> toCheck = new List<Element>(); | 20450 List<Element> toCheck = new List<Element>(); |
| 19329 toCheck.add(target); | 20451 toCheck.add(target); |
| 19330 bool firstIteration = true; | 20452 bool firstIteration = true; |
| 19331 while (true) { | 20453 while (true) { |
| 19332 Element current; | 20454 Element current; |
| 20455 // get next element |
| 19333 while (true) { | 20456 while (true) { |
| 20457 // may be no more elements to check |
| 19334 if (toCheck.isEmpty) { | 20458 if (toCheck.isEmpty) { |
| 19335 return false; | 20459 return false; |
| 19336 } | 20460 } |
| 20461 // try to get next element |
| 19337 current = toCheck.removeAt(toCheck.length - 1); | 20462 current = toCheck.removeAt(toCheck.length - 1); |
| 19338 if (target == current) { | 20463 if (target == current) { |
| 19339 if (firstIteration) { | 20464 if (firstIteration) { |
| 19340 firstIteration = false; | 20465 firstIteration = false; |
| 19341 break; | 20466 break; |
| 19342 } else { | 20467 } else { |
| 19343 return true; | 20468 return true; |
| 19344 } | 20469 } |
| 19345 } | 20470 } |
| 19346 if (current != null && !checked.contains(current)) { | 20471 if (current != null && !checked.contains(current)) { |
| 19347 break; | 20472 break; |
| 19348 } | 20473 } |
| 19349 } | 20474 } |
| 20475 // check current element |
| 19350 current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelf
Reference(target, toCheck)); | 20476 current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelf
Reference(target, toCheck)); |
| 19351 checked.add(current); | 20477 checked.add(current); |
| 19352 } | 20478 } |
| 19353 } | 20479 } |
| 19354 | 20480 |
| 19355 /** | 20481 /** |
| 19356 * @return `true` if given [Type] implements operator <i>==</i>, and it is not | 20482 * @return `true` if given [Type] implements operator <i>==</i>, and it is not |
| 19357 * <i>int</i> or <i>String</i>. | 20483 * <i>int</i> or <i>String</i>. |
| 19358 */ | 20484 */ |
| 19359 bool implementsEqualsWhenNotAllowed(Type2 type) { | 20485 bool implementsEqualsWhenNotAllowed(Type2 type) { |
| 20486 // ignore int or String |
| 19360 if (type == null || type == _typeProvider.intType || type == _typeProvider.s
tringType) { | 20487 if (type == null || type == _typeProvider.intType || type == _typeProvider.s
tringType) { |
| 19361 return false; | 20488 return false; |
| 19362 } | 20489 } |
| 20490 // prepare ClassElement |
| 19363 Element element = type.element; | 20491 Element element = type.element; |
| 19364 if (element is! ClassElement) { | 20492 if (element is! ClassElement) { |
| 19365 return false; | 20493 return false; |
| 19366 } | 20494 } |
| 19367 ClassElement classElement = element as ClassElement; | 20495 ClassElement classElement = element as ClassElement; |
| 20496 // lookup for == |
| 19368 MethodElement method = classElement.lookUpMethod("==", _currentLibrary); | 20497 MethodElement method = classElement.lookUpMethod("==", _currentLibrary); |
| 19369 if (method == null || method.enclosingElement.type.isObject) { | 20498 if (method == null || method.enclosingElement.type.isObject) { |
| 19370 return false; | 20499 return false; |
| 19371 } | 20500 } |
| 20501 // there is == that we don't like |
| 19372 return true; | 20502 return true; |
| 19373 } | 20503 } |
| 19374 | 20504 |
| 19375 bool isFunctionType(Type2 type) { | 20505 bool isFunctionType(Type2 type) { |
| 19376 if (type.isDynamic || type.isBottom) { | 20506 if (type.isDynamic || type.isBottom) { |
| 19377 return true; | 20507 return true; |
| 19378 } else if (type is FunctionType || type.isDartCoreFunction) { | 20508 } else if (type is FunctionType || type.isDartCoreFunction) { |
| 19379 return true; | 20509 return true; |
| 19380 } else if (type is InterfaceType) { | 20510 } else if (type is InterfaceType) { |
| 19381 MethodElement callMethod = type.lookUpMethod(ElementResolver.CALL_METHOD_N
AME, _currentLibrary); | 20511 MethodElement callMethod = type.lookUpMethod(ElementResolver.CALL_METHOD_N
AME, _currentLibrary); |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19657 Object visitVariableElement(VariableElement element) { | 20787 Object visitVariableElement(VariableElement element) { |
| 19658 addTypeToCheck(element.type); | 20788 addTypeToCheck(element.type); |
| 19659 return super.visitVariableElement(element); | 20789 return super.visitVariableElement(element); |
| 19660 } | 20790 } |
| 19661 | 20791 |
| 19662 void addTypeToCheck(Type2 type) { | 20792 void addTypeToCheck(Type2 type) { |
| 19663 if (type == null) { | 20793 if (type == null) { |
| 19664 return; | 20794 return; |
| 19665 } | 20795 } |
| 19666 Element element = type.element; | 20796 Element element = type.element; |
| 20797 // it is OK to reference target from class |
| 19667 if (_inClass && target == element) { | 20798 if (_inClass && target == element) { |
| 19668 return; | 20799 return; |
| 19669 } | 20800 } |
| 20801 // schedule for checking |
| 19670 toCheck.add(element); | 20802 toCheck.add(element); |
| 20803 // type arguments |
| 19671 if (type is InterfaceType) { | 20804 if (type is InterfaceType) { |
| 19672 InterfaceType interfaceType = type; | 20805 InterfaceType interfaceType = type; |
| 19673 for (Type2 typeArgument in interfaceType.typeArguments) { | 20806 for (Type2 typeArgument in interfaceType.typeArguments) { |
| 19674 addTypeToCheck(typeArgument); | 20807 addTypeToCheck(typeArgument); |
| 19675 } | 20808 } |
| 19676 } | 20809 } |
| 19677 } | 20810 } |
| 19678 } | 20811 } |
| 19679 | 20812 |
| 19680 /** | 20813 /** |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19729 * @param correction the template used to create the correction to be displaye
d for the error | 20862 * @param correction the template used to create the correction to be displaye
d for the error |
| 19730 */ | 20863 */ |
| 19731 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri
ng correction) : super(name, ordinal) { | 20864 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri
ng correction) : super(name, ordinal) { |
| 19732 this.correction10 = correction; | 20865 this.correction10 = correction; |
| 19733 } | 20866 } |
| 19734 | 20867 |
| 19735 String get correction => correction10; | 20868 String get correction => correction10; |
| 19736 | 20869 |
| 19737 ErrorSeverity get errorSeverity => type.severity; | 20870 ErrorSeverity get errorSeverity => type.severity; |
| 19738 } | 20871 } |
| OLD | NEW |