| OLD | NEW |
| 1 // This code was auto-generated, is not intended to be edited, and is subject to | 1 // This code was auto-generated, is not intended to be edited, and is subject to |
| 2 // significant change. Please see the README file for more information. | 2 // significant change. Please see the README file for more information. |
| 3 | 3 |
| 4 library engine.resolver; | 4 library engine.resolver; |
| 5 | 5 |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'java_core.dart'; | 7 import 'java_core.dart'; |
| 8 import 'java_engine.dart'; | 8 import 'java_engine.dart'; |
| 9 import 'instrumentation.dart'; | 9 import 'instrumentation.dart'; |
| 10 import 'source.dart'; | 10 import 'source.dart'; |
| 11 import 'error.dart'; | 11 import 'error.dart'; |
| 12 import 'scanner.dart' as sc; | 12 import 'scanner.dart' as sc; |
| 13 import 'utilities_dart.dart'; | 13 import 'utilities_dart.dart'; |
| 14 import 'utilities_general.dart'; | 14 import 'utilities_general.dart'; |
| 15 import 'ast.dart'; | 15 import 'ast.dart'; |
| 16 import 'parser.dart' show Parser, ParserErrorCode; | 16 import 'parser.dart' show Parser, ParserErrorCode; |
| 17 import 'sdk.dart' show DartSdk, SdkLibrary; | 17 import 'sdk.dart' show DartSdk, SdkLibrary; |
| 18 import 'element.dart'; | 18 import 'element.dart'; |
| 19 import 'html.dart' as ht; | 19 import 'html.dart' as ht; |
| 20 import 'engine.dart'; | 20 import 'engine.dart'; |
| 21 import 'constant.dart'; | 21 import 'constant.dart'; |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * Instances of the class `AngularCompilationUnitBuilder` build an Angular speci
fic element |
| 25 * model for a single compilation unit. |
| 26 * |
| 27 * @coverage dart.engine.resolver |
| 28 */ |
| 29 class AngularCompilationUnitBuilder { |
| 30 static String _NG_COMPONENT = "NgComponent"; |
| 31 |
| 32 static String _NG_CONTROLLER = "NgController"; |
| 33 |
| 34 static String _NG_FILTER = "NgFilter"; |
| 35 |
| 36 static String _NAME = "name"; |
| 37 |
| 38 static String _SELECTOR = "selector"; |
| 39 |
| 40 static String _PUBLISH_AS = "publishAs"; |
| 41 |
| 42 static String _TEMPLATE_URL = "templateUrl"; |
| 43 |
| 44 static String _CSS_URL = "cssUrl"; |
| 45 |
| 46 static String _PREFIX_ATTR = "@"; |
| 47 |
| 48 static String _PREFIX_CALLBACK = "&"; |
| 49 |
| 50 static String _PREFIX_ONE_WAY = "=>"; |
| 51 |
| 52 static String _PREFIX_ONE_WAY_ONE_TIME = "=>!"; |
| 53 |
| 54 static String _PREFIX_TWO_WAY = "<=>"; |
| 55 |
| 56 static String _NG_ATTR = "NgAttr"; |
| 57 |
| 58 static String _NG_CALLBACK = "NgCallback"; |
| 59 |
| 60 static String _NG_ONE_WAY = "NgOneWay"; |
| 61 |
| 62 static String _NG_ONE_WAY_ONE_TIME = "NgOneWayOneTime"; |
| 63 |
| 64 static String _NG_TWO_WAY = "NgTwoWay"; |
| 65 |
| 66 /** |
| 67 * Checks if given [Type] is an Angular <code>Module</code> or its subclass. |
| 68 */ |
| 69 static bool isModule(Type2 type) { |
| 70 if (type is! InterfaceType) { |
| 71 return false; |
| 72 } |
| 73 InterfaceType interfaceType = type as InterfaceType; |
| 74 Set<Type2> seenTypes = new Set(); |
| 75 while (interfaceType != null) { |
| 76 if (!seenTypes.add(interfaceType)) { |
| 77 return false; |
| 78 } |
| 79 if (interfaceType.element.name == "Module") { |
| 80 return true; |
| 81 } |
| 82 interfaceType = interfaceType.superclass; |
| 83 } |
| 84 return false; |
| 85 } |
| 86 |
| 87 static bool isTagName(String s) { |
| 88 if (s == null || s.length == 0) { |
| 89 return false; |
| 90 } |
| 91 int sz = s.length; |
| 92 for (int i = 0; i < sz; i++) { |
| 93 int c = s.codeUnitAt(i); |
| 94 if (!Character.isLetter(c)) { |
| 95 if (i == 0) { |
| 96 return false; |
| 97 } |
| 98 if (!Character.isDigit(c) && c != 0x2D) { |
| 99 return false; |
| 100 } |
| 101 } |
| 102 } |
| 103 return true; |
| 104 } |
| 105 |
| 106 /** |
| 107 * Parses given selector text and returns [AngularSelector]. May be `null` if
cannot |
| 108 * parse. |
| 109 */ |
| 110 static AngularSelector parseSelector(String text) { |
| 111 if (text.startsWith("[") && text.endsWith("]")) { |
| 112 return new HasAttributeSelector(text.substring(1, text.length - 1)); |
| 113 } |
| 114 if (StringUtilities.isTagName(text)) { |
| 115 return new IsTagSelector(text); |
| 116 } |
| 117 return null; |
| 118 } |
| 119 |
| 120 /** |
| 121 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio
n]. |
| 122 */ |
| 123 static FieldElement getOnlyFieldElement(FieldDeclaration fieldDeclaration) { |
| 124 NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables; |
| 125 return fields[0].element as FieldElement; |
| 126 } |
| 127 |
| 128 /** |
| 129 * If given [Annotation] has one argument and it is [SimpleStringLiteral], ret
urns it, |
| 130 * otherwise returns `null`. |
| 131 */ |
| 132 static SimpleStringLiteral getOnlySimpleStringLiteralArgument(Annotation annot
ation) { |
| 133 SimpleStringLiteral nameLiteral = null; |
| 134 ArgumentList argsNode = annotation.arguments; |
| 135 if (argsNode != null) { |
| 136 NodeList<Expression> args = argsNode.arguments; |
| 137 if (args.length == 1) { |
| 138 Expression arg = args[0]; |
| 139 if (arg is SimpleStringLiteral) { |
| 140 nameLiteral = arg as SimpleStringLiteral; |
| 141 } |
| 142 } |
| 143 } |
| 144 return nameLiteral; |
| 145 } |
| 146 |
| 147 /** |
| 148 * Checks if given [LocalVariableElement] is an Angular <code>Module</code>. |
| 149 */ |
| 150 static bool isModule2(VariableDeclaration node) { |
| 151 Type2 type = node.name.bestType; |
| 152 return isModule(type); |
| 153 } |
| 154 |
| 155 /** |
| 156 * The source containing the unit that will be analyzed. |
| 157 */ |
| 158 Source _source; |
| 159 |
| 160 /** |
| 161 * The listener to which errors will be reported. |
| 162 */ |
| 163 AnalysisErrorListener _errorListener; |
| 164 |
| 165 /** |
| 166 * The [ClassDeclaration] that is currently being analyzed. |
| 167 */ |
| 168 ClassDeclaration _classDeclaration; |
| 169 |
| 170 /** |
| 171 * The [ClassElementImpl] that is currently being analyzed. |
| 172 */ |
| 173 ClassElementImpl _classElement; |
| 174 |
| 175 /** |
| 176 * The [ToolkitObjectElement]s to set for [classElement]. |
| 177 */ |
| 178 List<ToolkitObjectElement> _classToolkitObjects = []; |
| 179 |
| 180 /** |
| 181 * The [Annotation] that is currently being analyzed. |
| 182 */ |
| 183 Annotation _annotation; |
| 184 |
| 185 /** |
| 186 * Initialize a newly created compilation unit element builder. |
| 187 * |
| 188 * @param errorListener the listener to which errors will be reported. |
| 189 * @param source the source containing the unit that will be analyzed |
| 190 */ |
| 191 AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source sour
ce) { |
| 192 this._errorListener = errorListener; |
| 193 this._source = source; |
| 194 } |
| 195 |
| 196 /** |
| 197 * Builds Angular specific element models and adds them to the existing Dart e
lements. |
| 198 * |
| 199 * @param unit the compilation unit with built Dart element models |
| 200 */ |
| 201 void build(CompilationUnit unit) { |
| 202 for (CompilationUnitMember unitMember in unit.declarations) { |
| 203 if (unitMember is ClassDeclaration) { |
| 204 this._classDeclaration = unitMember as ClassDeclaration; |
| 205 this._classElement = _classDeclaration.element as ClassElementImpl; |
| 206 this._classToolkitObjects.clear(); |
| 207 parseModuleClass(); |
| 208 NodeList<Annotation> annotations = _classDeclaration.metadata; |
| 209 for (Annotation annotation in annotations) { |
| 210 this._annotation = annotation; |
| 211 if (isAngularAnnotation2(_NG_FILTER)) { |
| 212 parseNgFilter(); |
| 213 continue; |
| 214 } |
| 215 if (isAngularAnnotation2(_NG_COMPONENT)) { |
| 216 parseNgComponent(); |
| 217 continue; |
| 218 } |
| 219 if (isAngularAnnotation2(_NG_CONTROLLER)) { |
| 220 parseNgController(); |
| 221 continue; |
| 222 } |
| 223 } |
| 224 if (!_classToolkitObjects.isEmpty) { |
| 225 List<ToolkitObjectElement> objects = _classToolkitObjects; |
| 226 _classElement.toolkitObjects = new List.from(objects); |
| 227 } |
| 228 } |
| 229 } |
| 230 parseModuleVariables(unit); |
| 231 } |
| 232 |
| 233 /** |
| 234 * Creates [AngularModuleElementImpl] for given information. |
| 235 */ |
| 236 AngularModuleElementImpl createModuleElement(List<AngularModuleElement> childM
odules, List<ClassElement> keyTypes) { |
| 237 AngularModuleElementImpl module = new AngularModuleElementImpl(); |
| 238 module.childModules = new List.from(childModules); |
| 239 module.keyTypes = new List.from(keyTypes); |
| 240 return module; |
| 241 } |
| 242 |
| 243 /** |
| 244 * @return the argument [Expression] with given name form [annotation], may be |
| 245 * `null` if not found. |
| 246 */ |
| 247 Expression getArgument(String name) { |
| 248 List<Expression> arguments = _annotation.arguments.arguments; |
| 249 for (Expression argument in arguments) { |
| 250 if (argument is NamedExpression) { |
| 251 NamedExpression namedExpression = argument as NamedExpression; |
| 252 String argumentName = namedExpression.name.label.name; |
| 253 if (name == argumentName) { |
| 254 return namedExpression.expression; |
| 255 } |
| 256 } |
| 257 } |
| 258 return null; |
| 259 } |
| 260 |
| 261 /** |
| 262 * @return the [String] value of the named argument. |
| 263 */ |
| 264 String getStringArgument(String name) { |
| 265 Expression argument = getArgument(name); |
| 266 return (argument as SimpleStringLiteral).value; |
| 267 } |
| 268 |
| 269 /** |
| 270 * @return the offset of the value of the named argument. |
| 271 */ |
| 272 int getStringArgumentOffset(String name) { |
| 273 Expression argument = getArgument(name); |
| 274 return (argument as SimpleStringLiteral).valueOffset; |
| 275 } |
| 276 |
| 277 /** |
| 278 * Checks if [namedArguments] has string value for the argument with the given
name. |
| 279 */ |
| 280 bool hasStringArgument(String name) { |
| 281 Expression argument = getArgument(name); |
| 282 return argument is SimpleStringLiteral; |
| 283 } |
| 284 |
| 285 /** |
| 286 * Checks if given [Annotation] is an annotation with required name. |
| 287 */ |
| 288 bool isAngularAnnotation(Annotation annotation, String name) { |
| 289 Element element = annotation.element; |
| 290 if (element is ConstructorElement) { |
| 291 ConstructorElement constructorElement = element as ConstructorElement; |
| 292 return constructorElement.returnType.displayName == name; |
| 293 } |
| 294 return false; |
| 295 } |
| 296 |
| 297 /** |
| 298 * Checks if [annotation] is an annotation with required name. |
| 299 */ |
| 300 bool isAngularAnnotation2(String name) => isAngularAnnotation(_annotation, nam
e); |
| 301 |
| 302 /** |
| 303 * Checks if [classElement] is an Angular <code>Module</code>. |
| 304 */ |
| 305 bool get isModule4 { |
| 306 InterfaceType supertype = _classElement.supertype; |
| 307 return isModule(supertype); |
| 308 } |
| 309 |
| 310 /** |
| 311 * Analyzes [classDeclaration] and if it is a module, creates [AngularModuleEl
ement] |
| 312 * model for it. |
| 313 */ |
| 314 void parseModuleClass() { |
| 315 if (!isModule4) { |
| 316 return; |
| 317 } |
| 318 List<AngularModuleElement> childModules = []; |
| 319 List<ClassElement> keyTypes = []; |
| 320 _classDeclaration.accept(new RecursiveASTVisitor_8(this, childModules, keyTy
pes)); |
| 321 AngularModuleElementImpl module = createModuleElement(childModules, keyTypes
); |
| 322 _classToolkitObjects.add(module); |
| 323 } |
| 324 |
| 325 /** |
| 326 * Checks if given [MethodInvocation] is an interesting <code>Module</code> me
thod |
| 327 * invocation and remembers corresponding elements into lists. |
| 328 */ |
| 329 void parseModuleInvocation(MethodInvocation node, List<AngularModuleElement> c
hildModules, List<ClassElement> keyTypes) { |
| 330 String methodName = node.methodName.name; |
| 331 NodeList<Expression> arguments = node.argumentList.arguments; |
| 332 if (arguments.length == 1 && methodName == "install") { |
| 333 Type2 argType = arguments[0].bestType; |
| 334 if (argType is InterfaceType) { |
| 335 ClassElement argElement = (argType as InterfaceType).element; |
| 336 List<ToolkitObjectElement> toolkitObjects = argElement.toolkitObjects; |
| 337 for (ToolkitObjectElement toolkitObject in toolkitObjects) { |
| 338 if (toolkitObject is AngularModuleElement) { |
| 339 childModules.add(toolkitObject as AngularModuleElement); |
| 340 } |
| 341 } |
| 342 } |
| 343 return; |
| 344 } |
| 345 if (arguments.length >= 1 && (methodName == "type" || methodName == "value")
) { |
| 346 Expression arg = arguments[0]; |
| 347 if (arg is Identifier) { |
| 348 Element argElement = (arg as Identifier).staticElement; |
| 349 if (argElement is ClassElement) { |
| 350 keyTypes.add(argElement as ClassElement); |
| 351 } |
| 352 } |
| 353 return; |
| 354 } |
| 355 } |
| 356 |
| 357 /** |
| 358 * Checks every local variable in the given unit to see if it is a <code>Modul
e</code> and creates |
| 359 * [AngularModuleElement] for it. |
| 360 */ |
| 361 void parseModuleVariables(CompilationUnit unit) { |
| 362 unit.accept(new RecursiveASTVisitor_9(this)); |
| 363 } |
| 364 |
| 365 void parseNgComponent() { |
| 366 bool isValid = true; |
| 367 if (!hasStringArgument(_PUBLISH_AS)) { |
| 368 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); |
| 369 isValid = false; |
| 370 } |
| 371 AngularSelector selector = null; |
| 372 if (!hasStringArgument(_SELECTOR)) { |
| 373 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 374 isValid = false; |
| 375 } else { |
| 376 String selectorText = getStringArgument(_SELECTOR); |
| 377 selector = parseSelector(selectorText); |
| 378 if (selector == null) { |
| 379 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorText]); |
| 380 isValid = false; |
| 381 } |
| 382 } |
| 383 if (!hasStringArgument(_TEMPLATE_URL)) { |
| 384 reportErrorForAnnotation(AngularCode.MISSING_TEMPLATE_URL, []); |
| 385 isValid = false; |
| 386 } |
| 387 if (!hasStringArgument(_CSS_URL)) { |
| 388 reportErrorForAnnotation(AngularCode.MISSING_CSS_URL, []); |
| 389 isValid = false; |
| 390 } |
| 391 if (isValid) { |
| 392 String name = getStringArgument(_PUBLISH_AS); |
| 393 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); |
| 394 String templateUri = getStringArgument(_TEMPLATE_URL); |
| 395 int templateUriOffset = getStringArgumentOffset(_TEMPLATE_URL); |
| 396 String styleUri = getStringArgument(_CSS_URL); |
| 397 int styleUriOffset = getStringArgumentOffset(_CSS_URL); |
| 398 AngularComponentElementImpl element = new AngularComponentElementImpl(name
, nameOffset); |
| 399 element.selector = selector; |
| 400 element.templateUri = templateUri; |
| 401 element.templateUriOffset = templateUriOffset; |
| 402 element.styleUri = styleUri; |
| 403 element.styleUriOffset = styleUriOffset; |
| 404 element.properties = parseNgComponentProperties(); |
| 405 _classToolkitObjects.add(element); |
| 406 } |
| 407 } |
| 408 |
| 409 /** |
| 410 * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration]. |
| 411 */ |
| 412 List<AngularPropertyElement> parseNgComponentProperties() { |
| 413 List<AngularPropertyElement> properties = []; |
| 414 parseNgComponentProperties_fromMap(properties); |
| 415 parseNgComponentProperties_fromFields(properties); |
| 416 return new List.from(properties); |
| 417 } |
| 418 |
| 419 /** |
| 420 * Parses [AngularPropertyElement]s from [annotation]. |
| 421 */ |
| 422 void parseNgComponentProperties_fromFields(List<AngularPropertyElement> proper
ties) { |
| 423 NodeList<ClassMember> members = _classDeclaration.members; |
| 424 for (ClassMember member in members) { |
| 425 if (member is FieldDeclaration) { |
| 426 FieldDeclaration fieldDeclaration = member as FieldDeclaration; |
| 427 for (Annotation annotation in fieldDeclaration.metadata) { |
| 428 AngularPropertyKind kind = null; |
| 429 if (isAngularAnnotation(annotation, _NG_ATTR)) { |
| 430 kind = AngularPropertyKind.ATTR; |
| 431 } else if (isAngularAnnotation(annotation, _NG_CALLBACK)) { |
| 432 kind = AngularPropertyKind.CALLBACK; |
| 433 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY)) { |
| 434 kind = AngularPropertyKind.ONE_WAY; |
| 435 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY_ONE_TIME)) { |
| 436 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; |
| 437 } else if (isAngularAnnotation(annotation, _NG_TWO_WAY)) { |
| 438 kind = AngularPropertyKind.TWO_WAY; |
| 439 } |
| 440 if (kind != null) { |
| 441 SimpleStringLiteral nameLiteral = getOnlySimpleStringLiteralArgument
(annotation); |
| 442 FieldElement field = getOnlyFieldElement(fieldDeclaration); |
| 443 if (nameLiteral != null && field != null) { |
| 444 AngularPropertyElementImpl property = new AngularPropertyElementIm
pl(nameLiteral.value, nameLiteral.valueOffset); |
| 445 property.field = field; |
| 446 property.propertyKind = kind; |
| 447 properties.add(property); |
| 448 } |
| 449 } |
| 450 } |
| 451 } |
| 452 } |
| 453 } |
| 454 |
| 455 /** |
| 456 * Parses [AngularPropertyElement]s from [annotation]. |
| 457 */ |
| 458 void parseNgComponentProperties_fromMap(List<AngularPropertyElement> propertie
s) { |
| 459 Expression mapExpression = getArgument("map"); |
| 460 if (mapExpression == null) { |
| 461 return; |
| 462 } |
| 463 if (mapExpression is! MapLiteral) { |
| 464 reportError(mapExpression, AngularCode.INVALID_PROPERTY_MAP, []); |
| 465 return; |
| 466 } |
| 467 MapLiteral mapLiteral = mapExpression as MapLiteral; |
| 468 for (MapLiteralEntry entry in mapLiteral.entries) { |
| 469 Expression nameExpression = entry.key; |
| 470 if (nameExpression is! SimpleStringLiteral) { |
| 471 reportError(nameExpression, AngularCode.INVALID_PROPERTY_NAME, []); |
| 472 continue; |
| 473 } |
| 474 SimpleStringLiteral nameLiteral = nameExpression as SimpleStringLiteral; |
| 475 String name = nameLiteral.value; |
| 476 int nameOffset = nameLiteral.valueOffset; |
| 477 Expression specExpression = entry.value; |
| 478 if (specExpression is! SimpleStringLiteral) { |
| 479 reportError(specExpression, AngularCode.INVALID_PROPERTY_SPEC, []); |
| 480 continue; |
| 481 } |
| 482 SimpleStringLiteral specLiteral = specExpression as SimpleStringLiteral; |
| 483 String spec = specLiteral.value; |
| 484 AngularPropertyKind kind; |
| 485 int fieldNameOffset; |
| 486 if (spec.startsWith(_PREFIX_ATTR)) { |
| 487 kind = AngularPropertyKind.ATTR; |
| 488 fieldNameOffset = 1; |
| 489 } else if (spec.startsWith(_PREFIX_CALLBACK)) { |
| 490 kind = AngularPropertyKind.CALLBACK; |
| 491 fieldNameOffset = 1; |
| 492 } else if (spec.startsWith(_PREFIX_ONE_WAY_ONE_TIME)) { |
| 493 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; |
| 494 fieldNameOffset = 3; |
| 495 } else if (spec.startsWith(_PREFIX_ONE_WAY)) { |
| 496 kind = AngularPropertyKind.ONE_WAY; |
| 497 fieldNameOffset = 2; |
| 498 } else if (spec.startsWith(_PREFIX_TWO_WAY)) { |
| 499 kind = AngularPropertyKind.TWO_WAY; |
| 500 fieldNameOffset = 3; |
| 501 } else { |
| 502 reportError(specLiteral, AngularCode.INVALID_PROPERTY_KIND, [spec]); |
| 503 continue; |
| 504 } |
| 505 String fieldName = spec.substring(fieldNameOffset); |
| 506 fieldNameOffset += specLiteral.valueOffset; |
| 507 FieldElement field = _classElement.getField(fieldName); |
| 508 if (field == null) { |
| 509 reportError(specLiteral, AngularCode.INVALID_PROPERTY_FIELD, [fieldName]
); |
| 510 continue; |
| 511 } |
| 512 AngularPropertyElementImpl property = new AngularPropertyElementImpl(name,
nameOffset); |
| 513 property.field = field; |
| 514 property.propertyKind = kind; |
| 515 property.fieldNameOffset = fieldNameOffset; |
| 516 properties.add(property); |
| 517 } |
| 518 } |
| 519 |
| 520 void parseNgController() { |
| 521 bool isValid = true; |
| 522 if (!hasStringArgument(_PUBLISH_AS)) { |
| 523 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); |
| 524 isValid = false; |
| 525 } |
| 526 AngularSelector selector = null; |
| 527 if (!hasStringArgument(_SELECTOR)) { |
| 528 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 529 isValid = false; |
| 530 } else { |
| 531 String selectorText = getStringArgument(_SELECTOR); |
| 532 selector = parseSelector(selectorText); |
| 533 if (selector == null) { |
| 534 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorText]); |
| 535 isValid = false; |
| 536 } |
| 537 } |
| 538 if (isValid) { |
| 539 String name = getStringArgument(_PUBLISH_AS); |
| 540 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); |
| 541 AngularControllerElementImpl element = new AngularControllerElementImpl(na
me, nameOffset); |
| 542 element.selector = selector; |
| 543 _classToolkitObjects.add(element); |
| 544 } |
| 545 } |
| 546 |
| 547 void parseNgFilter() { |
| 548 bool isValid = true; |
| 549 if (!hasStringArgument(_NAME)) { |
| 550 reportErrorForAnnotation(AngularCode.MISSING_NAME, []); |
| 551 isValid = false; |
| 552 } |
| 553 if (isValid) { |
| 554 String name = getStringArgument(_NAME); |
| 555 int nameOffset = getStringArgumentOffset(_NAME); |
| 556 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset)); |
| 557 } |
| 558 } |
| 559 |
| 560 void reportError(ASTNode node, ErrorCode errorCode, List<Object> arguments) { |
| 561 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len
gth, errorCode, arguments)); |
| 562 } |
| 563 |
| 564 void reportErrorForAnnotation(ErrorCode errorCode, List<Object> arguments) { |
| 565 reportError(_annotation, errorCode, arguments); |
| 566 } |
| 567 |
| 568 void reportErrorForArgument(String argumentName, ErrorCode errorCode, List<Obj
ect> arguments) { |
| 569 Expression argument = getArgument(argumentName); |
| 570 reportError(argument, errorCode, arguments); |
| 571 } |
| 572 } |
| 573 |
| 574 class RecursiveASTVisitor_8 extends RecursiveASTVisitor<Object> { |
| 575 final AngularCompilationUnitBuilder AngularCompilationUnitBuilder_this; |
| 576 |
| 577 List<AngularModuleElement> childModules; |
| 578 |
| 579 List<ClassElement> keyTypes; |
| 580 |
| 581 RecursiveASTVisitor_8(this.AngularCompilationUnitBuilder_this, this.childModul
es, this.keyTypes) : super(); |
| 582 |
| 583 Object visitMethodInvocation(MethodInvocation node) { |
| 584 if (node.target == null) { |
| 585 AngularCompilationUnitBuilder_this.parseModuleInvocation(node, childModule
s, keyTypes); |
| 586 } |
| 587 return null; |
| 588 } |
| 589 } |
| 590 |
| 591 class RecursiveASTVisitor_9 extends RecursiveASTVisitor<Object> { |
| 592 final AngularCompilationUnitBuilder AngularCompilationUnitBuilder_this; |
| 593 |
| 594 RecursiveASTVisitor_9(this.AngularCompilationUnitBuilder_this) : super(); |
| 595 |
| 596 LocalVariableElementImpl _variable = null; |
| 597 |
| 598 Expression _variableInit = null; |
| 599 |
| 600 List<AngularModuleElement> _childModules = []; |
| 601 |
| 602 List<ClassElement> _keyTypes = []; |
| 603 |
| 604 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 605 _childModules.clear(); |
| 606 _keyTypes.clear(); |
| 607 super.visitFunctionDeclaration(node); |
| 608 if (_variable != null) { |
| 609 AngularModuleElementImpl module = AngularCompilationUnitBuilder_this.creat
eModuleElement(_childModules, _keyTypes); |
| 610 _variable.toolkitObjects = <ToolkitObjectElement> [module]; |
| 611 } |
| 612 return null; |
| 613 } |
| 614 |
| 615 Object visitMethodInvocation(MethodInvocation node) { |
| 616 if (_variable != null) { |
| 617 if (isVariableInvocation(node)) { |
| 618 AngularCompilationUnitBuilder_this.parseModuleInvocation(node, _childMod
ules, _keyTypes); |
| 619 } |
| 620 } |
| 621 return null; |
| 622 } |
| 623 |
| 624 Object visitVariableDeclaration(VariableDeclaration node) { |
| 625 VariableElement element = node.element; |
| 626 if (element is LocalVariableElementImpl && AngularCompilationUnitBuilder.isM
odule2(node)) { |
| 627 _variable = element as LocalVariableElementImpl; |
| 628 _variableInit = node.initializer; |
| 629 } |
| 630 return super.visitVariableDeclaration(node); |
| 631 } |
| 632 |
| 633 bool isVariableInvocation(MethodInvocation node) { |
| 634 Expression target = node.realTarget; |
| 635 if (_variableInit is CascadeExpression && target != null && identical(target
.parent, _variableInit)) { |
| 636 return true; |
| 637 } |
| 638 if (target is Identifier) { |
| 639 Element targetElement = (target as Identifier).staticElement; |
| 640 return identical(targetElement, _variable); |
| 641 } |
| 642 return false; |
| 643 } |
| 644 } |
| 645 |
| 646 /** |
| 24 * Instances of the class `CompilationUnitBuilder` build an element model for a
single | 647 * Instances of the class `CompilationUnitBuilder` build an element model for a
single |
| 25 * compilation unit. | 648 * compilation unit. |
| 26 * | 649 * |
| 27 * @coverage dart.engine.resolver | 650 * @coverage dart.engine.resolver |
| 28 */ | 651 */ |
| 29 class CompilationUnitBuilder { | 652 class CompilationUnitBuilder { |
| 30 /** | 653 /** |
| 31 * Build the compilation unit element for the given source. | 654 * Build the compilation unit element for the given source. |
| 32 * | 655 * |
| 33 * @param source the source describing the compilation unit | 656 * @param source the source describing the compilation unit |
| (...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 } | 1913 } |
| 1291 | 1914 |
| 1292 /** | 1915 /** |
| 1293 * Return the first source attribute for the given tag node, or `null` if it d
oes not exist. | 1916 * Return the first source attribute for the given tag node, or `null` if it d
oes not exist. |
| 1294 * | 1917 * |
| 1295 * @param node the node containing attributes | 1918 * @param node the node containing attributes |
| 1296 * @return the source attribute contained in the given tag | 1919 * @return the source attribute contained in the given tag |
| 1297 */ | 1920 */ |
| 1298 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) { | 1921 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) { |
| 1299 for (ht.XmlAttributeNode attribute in node.attributes) { | 1922 for (ht.XmlAttributeNode attribute in node.attributes) { |
| 1300 if (attribute.name.lexeme == _SRC) { | 1923 if (attribute.name == _SRC) { |
| 1301 return attribute; | 1924 return attribute; |
| 1302 } | 1925 } |
| 1303 } | 1926 } |
| 1304 return null; | 1927 return null; |
| 1305 } | 1928 } |
| 1306 | 1929 |
| 1307 Object reportCircularity(ht.XmlTagNode node) { | 1930 Object reportCircularity(ht.XmlTagNode node) { |
| 1308 JavaStringBuilder builder = new JavaStringBuilder(); | 1931 JavaStringBuilder builder = new JavaStringBuilder(); |
| 1309 builder.append("Found circularity in XML nodes: "); | 1932 builder.append("Found circularity in XML nodes: "); |
| 1310 bool first = true; | 1933 bool first = true; |
| 1311 for (ht.XmlTagNode pathNode in _parentNodes) { | 1934 for (ht.XmlTagNode pathNode in _parentNodes) { |
| 1312 if (first) { | 1935 if (first) { |
| 1313 first = false; | 1936 first = false; |
| 1314 } else { | 1937 } else { |
| 1315 builder.append(", "); | 1938 builder.append(", "); |
| 1316 } | 1939 } |
| 1317 String tagName = pathNode.tag.lexeme; | 1940 String tagName = pathNode.tag; |
| 1318 if (identical(pathNode, node)) { | 1941 if (identical(pathNode, node)) { |
| 1319 builder.append("*"); | 1942 builder.append("*"); |
| 1320 builder.append(tagName); | 1943 builder.append(tagName); |
| 1321 builder.append("*"); | 1944 builder.append("*"); |
| 1322 } else { | 1945 } else { |
| 1323 builder.append(tagName); | 1946 builder.append(tagName); |
| 1324 } | 1947 } |
| 1325 } | 1948 } |
| 1326 AnalysisEngine.instance.logger.logError(builder.toString()); | 1949 AnalysisEngine.instance.logger.logError(builder.toString()); |
| 1327 return null; | 1950 return null; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1343 /** | 1966 /** |
| 1344 * Report an error with the given error code at the location of the value of t
he given attribute. | 1967 * Report an error with the given error code at the location of the value of t
he given attribute. |
| 1345 * Use the given arguments to compose the error message. | 1968 * Use the given arguments to compose the error message. |
| 1346 * | 1969 * |
| 1347 * @param errorCode the error code of the error to be reported | 1970 * @param errorCode the error code of the error to be reported |
| 1348 * @param offset the offset of the first character to be highlighted | 1971 * @param offset the offset of the first character to be highlighted |
| 1349 * @param length the number of characters to be highlighted | 1972 * @param length the number of characters to be highlighted |
| 1350 * @param arguments the arguments used to compose the error message | 1973 * @param arguments the arguments used to compose the error message |
| 1351 */ | 1974 */ |
| 1352 void reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, List
<Object> arguments) { | 1975 void reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, List
<Object> arguments) { |
| 1353 int offset = attribute.value.offset + 1; | 1976 int offset = attribute.valueToken.offset + 1; |
| 1354 int length = attribute.value.length - 2; | 1977 int length = attribute.valueToken.length - 2; |
| 1355 reportError(errorCode, offset, length, arguments); | 1978 reportError(errorCode, offset, length, arguments); |
| 1356 } | 1979 } |
| 1357 | 1980 |
| 1358 void resolveExpression(Expression expression) { | 1981 void resolveExpression(Expression expression) { |
| 1359 } | 1982 } |
| 1360 } | 1983 } |
| 1361 | 1984 |
| 1362 /** | 1985 /** |
| 1363 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for | 1986 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for |
| 1364 * violations of Dart best practices. | 1987 * violations of Dart best practices. |
| (...skipping 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3214 if (prefixElement != null && prefix.name == prefixElement.displayName)
{ | 3837 if (prefixElement != null && prefix.name == prefixElement.displayName)
{ |
| 3215 return element; | 3838 return element; |
| 3216 } | 3839 } |
| 3217 } | 3840 } |
| 3218 } | 3841 } |
| 3219 } | 3842 } |
| 3220 return null; | 3843 return null; |
| 3221 } | 3844 } |
| 3222 | 3845 |
| 3223 void gatherElements(Element element) { | 3846 void gatherElements(Element element) { |
| 3224 element.accept(new GeneralizingElementVisitor_8(this)); | 3847 element.accept(new GeneralizingElementVisitor_10(this)); |
| 3225 } | 3848 } |
| 3226 | 3849 |
| 3227 /** | 3850 /** |
| 3228 * Search the most closely enclosing list of parameters for a parameter with t
he given name. | 3851 * Search the most closely enclosing list of parameters for a parameter with t
he given name. |
| 3229 * | 3852 * |
| 3230 * @param node the node defining the parameter with the given name | 3853 * @param node the node defining the parameter with the given name |
| 3231 * @param parameterName the name of the parameter being searched for | 3854 * @param parameterName the name of the parameter being searched for |
| 3232 * @return the element representing the parameter with that name | 3855 * @return the element representing the parameter with that name |
| 3233 */ | 3856 */ |
| 3234 ParameterElement getElementForParameter(FormalParameter node, SimpleIdentifier
parameterName) { | 3857 ParameterElement getElementForParameter(FormalParameter node, SimpleIdentifier
parameterName) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3276 } | 3899 } |
| 3277 | 3900 |
| 3278 /** | 3901 /** |
| 3279 * Instances of the class `DeclarationMismatchException` represent an exception
that is | 3902 * Instances of the class `DeclarationMismatchException` represent an exception
that is |
| 3280 * thrown when the element model defined by a given AST structure does not match
an existing | 3903 * thrown when the element model defined by a given AST structure does not match
an existing |
| 3281 * element model. | 3904 * element model. |
| 3282 */ | 3905 */ |
| 3283 class DeclarationMatcher_DeclarationMismatchException extends RuntimeException { | 3906 class DeclarationMatcher_DeclarationMismatchException extends RuntimeException { |
| 3284 } | 3907 } |
| 3285 | 3908 |
| 3286 class GeneralizingElementVisitor_8 extends GeneralizingElementVisitor<Object> { | 3909 class GeneralizingElementVisitor_10 extends GeneralizingElementVisitor<Object> { |
| 3287 final DeclarationMatcher DeclarationMatcher_this; | 3910 final DeclarationMatcher DeclarationMatcher_this; |
| 3288 | 3911 |
| 3289 GeneralizingElementVisitor_8(this.DeclarationMatcher_this) : super(); | 3912 GeneralizingElementVisitor_10(this.DeclarationMatcher_this) : super(); |
| 3290 | 3913 |
| 3291 Object visitElement(Element element) { | 3914 Object visitElement(Element element) { |
| 3292 DeclarationMatcher_this._allElements.add(element); | 3915 DeclarationMatcher_this._allElements.add(element); |
| 3293 DeclarationMatcher_this._unmatchedElements.add(element); | 3916 DeclarationMatcher_this._unmatchedElements.add(element); |
| 3294 return super.visitElement(element); | 3917 return super.visitElement(element); |
| 3295 } | 3918 } |
| 3296 } | 3919 } |
| 3297 | 3920 |
| 3298 /** | 3921 /** |
| 3299 * Instances of the class `DeclarationResolver` are used to resolve declarations
in an AST | 3922 * Instances of the class `DeclarationResolver` are used to resolve declarations
in an AST |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4167 } | 4790 } |
| 4168 } | 4791 } |
| 4169 setMetadata(constructorElement, node); | 4792 setMetadata(constructorElement, node); |
| 4170 } | 4793 } |
| 4171 return null; | 4794 return null; |
| 4172 } | 4795 } |
| 4173 | 4796 |
| 4174 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 4797 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 4175 SimpleIdentifier fieldName = node.fieldName; | 4798 SimpleIdentifier fieldName = node.fieldName; |
| 4176 ClassElement enclosingClass = _resolver.enclosingClass; | 4799 ClassElement enclosingClass = _resolver.enclosingClass; |
| 4177 FieldElement fieldElement = (enclosingClass as ClassElementImpl).getField(fi
eldName.name); | 4800 FieldElement fieldElement = enclosingClass.getField(fieldName.name); |
| 4178 fieldName.staticElement = fieldElement; | 4801 fieldName.staticElement = fieldElement; |
| 4179 if (fieldElement == null || fieldElement.isSynthetic) { | 4802 if (fieldElement == null || fieldElement.isSynthetic) { |
| 4180 _resolver.reportError6(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_F
IELD, node, [fieldName]); | 4803 _resolver.reportError6(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_F
IELD, node, [fieldName]); |
| 4181 } else if (fieldElement.isStatic) { | 4804 } else if (fieldElement.isStatic) { |
| 4182 _resolver.reportError6(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
node, [fieldName]); | 4805 _resolver.reportError6(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
node, [fieldName]); |
| 4183 } | 4806 } |
| 4184 return null; | 4807 return null; |
| 4185 } | 4808 } |
| 4186 | 4809 |
| 4187 Object visitConstructorName(ConstructorName node) { | 4810 Object visitConstructorName(ConstructorName node) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4231 resolveCombinators((element as ExportElement).exportedLibrary, node.combin
ators); | 4854 resolveCombinators((element as ExportElement).exportedLibrary, node.combin
ators); |
| 4232 setMetadata(element, node); | 4855 setMetadata(element, node); |
| 4233 } | 4856 } |
| 4234 return null; | 4857 return null; |
| 4235 } | 4858 } |
| 4236 | 4859 |
| 4237 Object visitFieldFormalParameter(FieldFormalParameter node) { | 4860 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 4238 String fieldName = node.identifier.name; | 4861 String fieldName = node.identifier.name; |
| 4239 ClassElement classElement = _resolver.enclosingClass; | 4862 ClassElement classElement = _resolver.enclosingClass; |
| 4240 if (classElement != null) { | 4863 if (classElement != null) { |
| 4241 FieldElement fieldElement = (classElement as ClassElementImpl).getField(fi
eldName); | 4864 FieldElement fieldElement = classElement.getField(fieldName); |
| 4242 if (fieldElement == null) { | 4865 if (fieldElement == null) { |
| 4243 _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_
EXISTANT_FIELD, node, [fieldName]); | 4866 _resolver.reportError6(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_
EXISTANT_FIELD, node, [fieldName]); |
| 4244 } else { | 4867 } else { |
| 4245 ParameterElement parameterElement = node.element; | 4868 ParameterElement parameterElement = node.element; |
| 4246 if (parameterElement is FieldFormalParameterElementImpl) { | 4869 if (parameterElement is FieldFormalParameterElementImpl) { |
| 4247 FieldFormalParameterElementImpl fieldFormal = parameterElement as Fiel
dFormalParameterElementImpl; | 4870 FieldFormalParameterElementImpl fieldFormal = parameterElement as Fiel
dFormalParameterElementImpl; |
| 4248 fieldFormal.field = fieldElement; | 4871 fieldFormal.field = fieldElement; |
| 4249 Type2 declaredType = fieldFormal.type; | 4872 Type2 declaredType = fieldFormal.type; |
| 4250 Type2 fieldType = fieldElement.type; | 4873 Type2 fieldType = fieldElement.type; |
| 4251 if (node.type == null) { | 4874 if (node.type == null) { |
| (...skipping 3495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7747 ast.accept(visitor); | 8370 ast.accept(visitor); |
| 7748 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondi
tionalAnalysisErrors) { | 8371 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondi
tionalAnalysisErrors) { |
| 7749 if (conditionalCode.shouldIncludeErrorCode()) { | 8372 if (conditionalCode.shouldIncludeErrorCode()) { |
| 7750 visitor.reportError(conditionalCode.analysisError); | 8373 visitor.reportError(conditionalCode.analysisError); |
| 7751 } | 8374 } |
| 7752 } | 8375 } |
| 7753 } | 8376 } |
| 7754 } finally { | 8377 } finally { |
| 7755 timeCounter.stop(); | 8378 timeCounter.stop(); |
| 7756 } | 8379 } |
| 8380 timeCounter = PerformanceStatistics.angular.start(); |
| 8381 try { |
| 8382 for (Source source in library.compilationUnitSources) { |
| 8383 CompilationUnit ast = library.getAST(source); |
| 8384 new AngularCompilationUnitBuilder(_errorListener, source).build(ast); |
| 8385 } |
| 8386 } finally { |
| 8387 timeCounter.stop(); |
| 8388 } |
| 7757 } | 8389 } |
| 7758 | 8390 |
| 7759 /** | 8391 /** |
| 7760 * Return the result of resolving the URI of the given URI-based directive aga
inst the URI of the | 8392 * Return the result of resolving the URI of the given URI-based directive aga
inst the URI of the |
| 7761 * given library, or `null` if the URI is not valid. | 8393 * given library, or `null` if the URI is not valid. |
| 7762 * | 8394 * |
| 7763 * @param librarySource the source representing the library containing the dir
ective | 8395 * @param librarySource the source representing the library containing the dir
ective |
| 7764 * @param directive the directive which URI should be resolved | 8396 * @param directive the directive which URI should be resolved |
| 7765 * @return the result of resolving the URI against the URI of the library | 8397 * @return the result of resolving the URI against the URI of the library |
| 7766 */ | 8398 */ |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8179 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass.
type; | 8811 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass.
type; |
| 8180 super.visitClassDeclaration(node); | 8812 super.visitClassDeclaration(node); |
| 8181 } finally { | 8813 } finally { |
| 8182 _typeAnalyzer.thisType = outerType == null ? null : outerType.type; | 8814 _typeAnalyzer.thisType = outerType == null ? null : outerType.type; |
| 8183 _enclosingClass = outerType; | 8815 _enclosingClass = outerType; |
| 8184 } | 8816 } |
| 8185 return null; | 8817 return null; |
| 8186 } | 8818 } |
| 8187 | 8819 |
| 8188 Object visitComment(Comment node) { | 8820 Object visitComment(Comment node) { |
| 8189 if (node.parent is FunctionDeclaration || node.parent is MethodDeclaration)
{ | 8821 if (node.parent is FunctionDeclaration || node.parent is ConstructorDeclarat
ion || node.parent is MethodDeclaration) { |
| 8190 if (node != _commentBeforeFunction) { | 8822 if (node != _commentBeforeFunction) { |
| 8191 _commentBeforeFunction = node; | 8823 _commentBeforeFunction = node; |
| 8192 return null; | 8824 return null; |
| 8193 } | 8825 } |
| 8194 } | 8826 } |
| 8195 super.visitComment(node); | 8827 super.visitComment(node); |
| 8196 _commentBeforeFunction = null; | 8828 _commentBeforeFunction = null; |
| 8197 return null; | 8829 return null; |
| 8198 } | 8830 } |
| 8199 | 8831 |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8943 * Return `true` if the given variable is accessed within a closure in the giv
en | 9575 * Return `true` if the given variable is accessed within a closure in the giv
en |
| 8944 * [ASTNode] and also mutated somewhere in variable scope. This information is
only | 9576 * [ASTNode] and also mutated somewhere in variable scope. This information is
only |
| 8945 * available for local variables (including parameters). | 9577 * available for local variables (including parameters). |
| 8946 * | 9578 * |
| 8947 * @param variable the variable to check | 9579 * @param variable the variable to check |
| 8948 * @param target the [ASTNode] to check within | 9580 * @param target the [ASTNode] to check within |
| 8949 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode | 9581 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode |
| 8950 */ | 9582 */ |
| 8951 bool isVariableAccessedInClosure(Element variable, ASTNode target) { | 9583 bool isVariableAccessedInClosure(Element variable, ASTNode target) { |
| 8952 List<bool> result = [false]; | 9584 List<bool> result = [false]; |
| 8953 target.accept(new RecursiveASTVisitor_9(result, variable)); | 9585 target.accept(new RecursiveASTVisitor_11(result, variable)); |
| 8954 return result[0]; | 9586 return result[0]; |
| 8955 } | 9587 } |
| 8956 | 9588 |
| 8957 /** | 9589 /** |
| 8958 * Return `true` if the given variable is potentially mutated somewhere in the
given | 9590 * Return `true` if the given variable is potentially mutated somewhere in the
given |
| 8959 * [ASTNode]. This information is only available for local variables (includin
g parameters). | 9591 * [ASTNode]. This information is only available for local variables (includin
g parameters). |
| 8960 * | 9592 * |
| 8961 * @param variable the variable to check | 9593 * @param variable the variable to check |
| 8962 * @param target the [ASTNode] to check within | 9594 * @param target the [ASTNode] to check within |
| 8963 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode | 9595 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode |
| 8964 */ | 9596 */ |
| 8965 bool isVariablePotentiallyMutatedIn(Element variable, ASTNode target) { | 9597 bool isVariablePotentiallyMutatedIn(Element variable, ASTNode target) { |
| 8966 List<bool> result = [false]; | 9598 List<bool> result = [false]; |
| 8967 target.accept(new RecursiveASTVisitor_10(result, variable)); | 9599 target.accept(new RecursiveASTVisitor_12(result, variable)); |
| 8968 return result[0]; | 9600 return result[0]; |
| 8969 } | 9601 } |
| 8970 | 9602 |
| 8971 /** | 9603 /** |
| 8972 * If it is appropriate to do so, promotes the current type of the static elem
ent associated with | 9604 * If it is appropriate to do so, promotes the current type of the static elem
ent associated with |
| 8973 * the given expression with the given type. Generally speaking, it is appropr
iate if the given | 9605 * the given expression with the given type. Generally speaking, it is appropr
iate if the given |
| 8974 * type is more specific than the current type. | 9606 * type is more specific than the current type. |
| 8975 * | 9607 * |
| 8976 * @param expression the expression used to access the static element whose ty
pes might be | 9608 * @param expression the expression used to access the static element whose ty
pes might be |
| 8977 * promoted | 9609 * promoted |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9114 | 9746 |
| 9115 get typeAnalyzer_J2DAccessor => _typeAnalyzer; | 9747 get typeAnalyzer_J2DAccessor => _typeAnalyzer; |
| 9116 | 9748 |
| 9117 set typeAnalyzer_J2DAccessor(__v) => _typeAnalyzer = __v; | 9749 set typeAnalyzer_J2DAccessor(__v) => _typeAnalyzer = __v; |
| 9118 | 9750 |
| 9119 get enclosingClass_J2DAccessor => _enclosingClass; | 9751 get enclosingClass_J2DAccessor => _enclosingClass; |
| 9120 | 9752 |
| 9121 set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v; | 9753 set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v; |
| 9122 } | 9754 } |
| 9123 | 9755 |
| 9124 class RecursiveASTVisitor_9 extends RecursiveASTVisitor<Object> { | 9756 class RecursiveASTVisitor_11 extends RecursiveASTVisitor<Object> { |
| 9125 List<bool> result; | 9757 List<bool> result; |
| 9126 | 9758 |
| 9127 Element variable; | 9759 Element variable; |
| 9128 | 9760 |
| 9129 RecursiveASTVisitor_9(this.result, this.variable) : super(); | 9761 RecursiveASTVisitor_11(this.result, this.variable) : super(); |
| 9130 | 9762 |
| 9131 bool _inClosure = false; | 9763 bool _inClosure = false; |
| 9132 | 9764 |
| 9133 Object visitFunctionExpression(FunctionExpression node) { | 9765 Object visitFunctionExpression(FunctionExpression node) { |
| 9134 bool inClosure = this._inClosure; | 9766 bool inClosure = this._inClosure; |
| 9135 try { | 9767 try { |
| 9136 this._inClosure = true; | 9768 this._inClosure = true; |
| 9137 return super.visitFunctionExpression(node); | 9769 return super.visitFunctionExpression(node); |
| 9138 } finally { | 9770 } finally { |
| 9139 this._inClosure = inClosure; | 9771 this._inClosure = inClosure; |
| 9140 } | 9772 } |
| 9141 } | 9773 } |
| 9142 | 9774 |
| 9143 Object visitSimpleIdentifier(SimpleIdentifier node) { | 9775 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 9144 if (result[0]) { | 9776 if (result[0]) { |
| 9145 return null; | 9777 return null; |
| 9146 } | 9778 } |
| 9147 if (_inClosure && identical(node.staticElement, variable)) { | 9779 if (_inClosure && identical(node.staticElement, variable)) { |
| 9148 result[0] = javaBooleanOr(result[0], true); | 9780 result[0] = javaBooleanOr(result[0], true); |
| 9149 } | 9781 } |
| 9150 return null; | 9782 return null; |
| 9151 } | 9783 } |
| 9152 } | 9784 } |
| 9153 | 9785 |
| 9154 class RecursiveASTVisitor_10 extends RecursiveASTVisitor<Object> { | 9786 class RecursiveASTVisitor_12 extends RecursiveASTVisitor<Object> { |
| 9155 List<bool> result; | 9787 List<bool> result; |
| 9156 | 9788 |
| 9157 Element variable; | 9789 Element variable; |
| 9158 | 9790 |
| 9159 RecursiveASTVisitor_10(this.result, this.variable) : super(); | 9791 RecursiveASTVisitor_12(this.result, this.variable) : super(); |
| 9160 | 9792 |
| 9161 Object visitSimpleIdentifier(SimpleIdentifier node) { | 9793 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 9162 if (result[0]) { | 9794 if (result[0]) { |
| 9163 return null; | 9795 return null; |
| 9164 } | 9796 } |
| 9165 if (identical(node.staticElement, variable)) { | 9797 if (identical(node.staticElement, variable)) { |
| 9166 if (node.inSetterContext()) { | 9798 if (node.inSetterContext()) { |
| 9167 result[0] = javaBooleanOr(result[0], true); | 9799 result[0] = javaBooleanOr(result[0], true); |
| 9168 } | 9800 } |
| 9169 } | 9801 } |
| (...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10924 * @param body the boy of the function whose propagated return type is to be c
omputed | 11556 * @param body the boy of the function whose propagated return type is to be c
omputed |
| 10925 * @return the propagated return type that was computed | 11557 * @return the propagated return type that was computed |
| 10926 */ | 11558 */ |
| 10927 Type2 computePropagatedReturnType2(FunctionBody body) { | 11559 Type2 computePropagatedReturnType2(FunctionBody body) { |
| 10928 if (body is ExpressionFunctionBody) { | 11560 if (body is ExpressionFunctionBody) { |
| 10929 ExpressionFunctionBody expressionBody = body as ExpressionFunctionBody; | 11561 ExpressionFunctionBody expressionBody = body as ExpressionFunctionBody; |
| 10930 return expressionBody.expression.bestType; | 11562 return expressionBody.expression.bestType; |
| 10931 } | 11563 } |
| 10932 if (body is BlockFunctionBody) { | 11564 if (body is BlockFunctionBody) { |
| 10933 List<Type2> result = [null]; | 11565 List<Type2> result = [null]; |
| 10934 body.accept(new GeneralizingASTVisitor_11(result)); | 11566 body.accept(new GeneralizingASTVisitor_13(result)); |
| 10935 return result[0]; | 11567 return result[0]; |
| 10936 } | 11568 } |
| 10937 return null; | 11569 return null; |
| 10938 } | 11570 } |
| 10939 | 11571 |
| 10940 /** | 11572 /** |
| 10941 * Compute the static return type of the method or function represented by the
given element. | 11573 * Compute the static return type of the method or function represented by the
given element. |
| 10942 * | 11574 * |
| 10943 * @param element the element representing the method or function invoked by t
he given node | 11575 * @param element the element representing the method or function invoked by t
he given node |
| 10944 * @return the static return type that was computed | 11576 * @return the static return type that was computed |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11287 } | 11919 } |
| 11288 } | 11920 } |
| 11289 return staticType; | 11921 return staticType; |
| 11290 } | 11922 } |
| 11291 | 11923 |
| 11292 get thisType_J2DAccessor => _thisType; | 11924 get thisType_J2DAccessor => _thisType; |
| 11293 | 11925 |
| 11294 set thisType_J2DAccessor(__v) => _thisType = __v; | 11926 set thisType_J2DAccessor(__v) => _thisType = __v; |
| 11295 } | 11927 } |
| 11296 | 11928 |
| 11297 class GeneralizingASTVisitor_11 extends GeneralizingASTVisitor<Object> { | 11929 class GeneralizingASTVisitor_13 extends GeneralizingASTVisitor<Object> { |
| 11298 List<Type2> result; | 11930 List<Type2> result; |
| 11299 | 11931 |
| 11300 GeneralizingASTVisitor_11(this.result) : super(); | 11932 GeneralizingASTVisitor_13(this.result) : super(); |
| 11301 | 11933 |
| 11302 Object visitExpression(Expression node) => null; | 11934 Object visitExpression(Expression node) => null; |
| 11303 | 11935 |
| 11304 Object visitReturnStatement(ReturnStatement node) { | 11936 Object visitReturnStatement(ReturnStatement node) { |
| 11305 Type2 type; | 11937 Type2 type; |
| 11306 Expression expression = node.expression; | 11938 Expression expression = node.expression; |
| 11307 if (expression != null) { | 11939 if (expression != null) { |
| 11308 type = expression.bestType; | 11940 type = expression.bestType; |
| 11309 } else { | 11941 } else { |
| 11310 type = BottomTypeImpl.instance; | 11942 type = BottomTypeImpl.instance; |
| (...skipping 3120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14431 } | 15063 } |
| 14432 | 15064 |
| 14433 /** | 15065 /** |
| 14434 * Validates that the given expression is a compile time constant. | 15066 * Validates that the given expression is a compile time constant. |
| 14435 * | 15067 * |
| 14436 * @param parameterElements the elements of parameters of constant constructor
, they are | 15068 * @param parameterElements the elements of parameters of constant constructor
, they are |
| 14437 * considered as a valid potentially constant expressions | 15069 * considered as a valid potentially constant expressions |
| 14438 * @param expression the expression to validate | 15070 * @param expression the expression to validate |
| 14439 */ | 15071 */ |
| 14440 void validateInitializerExpression(List<ParameterElement> parameterElements, E
xpression expression) { | 15072 void validateInitializerExpression(List<ParameterElement> parameterElements, E
xpression expression) { |
| 14441 EvaluationResultImpl result = expression.accept(new ConstantVisitor_14(_type
Provider, this, parameterElements)); | 15073 EvaluationResultImpl result = expression.accept(new ConstantVisitor_16(_type
Provider, this, parameterElements)); |
| 14442 reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER)
; | 15074 reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER)
; |
| 14443 } | 15075 } |
| 14444 | 15076 |
| 14445 /** | 15077 /** |
| 14446 * Validates that all of the arguments of a constructor initializer are compil
e time constants. | 15078 * Validates that all of the arguments of a constructor initializer are compil
e time constants. |
| 14447 * | 15079 * |
| 14448 * @param parameterElements the elements of parameters of constant constructor
, they are | 15080 * @param parameterElements the elements of parameters of constant constructor
, they are |
| 14449 * considered as a valid potentially constant expressions | 15081 * considered as a valid potentially constant expressions |
| 14450 * @param argumentList the argument list to validate | 15082 * @param argumentList the argument list to validate |
| 14451 */ | 15083 */ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 14477 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); | 15109 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); |
| 14478 } | 15110 } |
| 14479 if (initializer is SuperConstructorInvocation) { | 15111 if (initializer is SuperConstructorInvocation) { |
| 14480 SuperConstructorInvocation invocation = initializer as SuperConstructorI
nvocation; | 15112 SuperConstructorInvocation invocation = initializer as SuperConstructorI
nvocation; |
| 14481 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); | 15113 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); |
| 14482 } | 15114 } |
| 14483 } | 15115 } |
| 14484 } | 15116 } |
| 14485 } | 15117 } |
| 14486 | 15118 |
| 14487 class ConstantVisitor_14 extends ConstantVisitor { | 15119 class ConstantVisitor_16 extends ConstantVisitor { |
| 14488 final ConstantVerifier ConstantVerifier_this; | 15120 final ConstantVerifier ConstantVerifier_this; |
| 14489 | 15121 |
| 14490 List<ParameterElement> parameterElements; | 15122 List<ParameterElement> parameterElements; |
| 14491 | 15123 |
| 14492 ConstantVisitor_14(TypeProvider arg0, this.ConstantVerifier_this, this.paramet
erElements) : super(arg0); | 15124 ConstantVisitor_16(TypeProvider arg0, this.ConstantVerifier_this, this.paramet
erElements) : super(arg0); |
| 14493 | 15125 |
| 14494 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) { | 15126 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) { |
| 14495 Element element = node.staticElement; | 15127 Element element = node.staticElement; |
| 14496 for (ParameterElement parameterElement in parameterElements) { | 15128 for (ParameterElement parameterElement in parameterElements) { |
| 14497 if (identical(parameterElement, element) && parameterElement != null) { | 15129 if (identical(parameterElement, element) && parameterElement != null) { |
| 14498 Type2 type = parameterElement.type; | 15130 Type2 type = parameterElement.type; |
| 14499 if (type != null) { | 15131 if (type != null) { |
| 14500 if (type.isDynamic) { | 15132 if (type.isDynamic) { |
| 14501 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.objectType, DynamicState.DYNAMIC_STATE); | 15133 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.objectType, DynamicState.DYNAMIC_STATE); |
| 14502 } else if (type.isSubtypeOf(ConstantVerifier_this._boolType)) { | 15134 } else if (type.isSubtypeOf(ConstantVerifier_this._boolType)) { |
| (...skipping 1610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16113 if (name == otherConstructor.name) { | 16745 if (name == otherConstructor.name) { |
| 16114 if (name == null || name.length == 0) { | 16746 if (name == null || name.length == 0) { |
| 16115 _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_DEFAULT, node, []); | 16747 _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_DEFAULT, node, []); |
| 16116 } else { | 16748 } else { |
| 16117 _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_NAME, node, [name]); | 16749 _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR
_NAME, node, [name]); |
| 16118 } | 16750 } |
| 16119 return true; | 16751 return true; |
| 16120 } | 16752 } |
| 16121 } | 16753 } |
| 16122 if (constructorName != null && constructorElement != null && !constructorNam
e.isSynthetic) { | 16754 if (constructorName != null && constructorElement != null && !constructorNam
e.isSynthetic) { |
| 16123 List<FieldElement> fields = classElement.fields; | 16755 FieldElement field = classElement.getField(name); |
| 16124 for (FieldElement field in fields) { | 16756 if (field != null) { |
| 16125 if (field.name == name) { | 16757 _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR
_NAME_AND_FIELD, node, [name]); |
| 16126 _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCT
OR_NAME_AND_FIELD, node, [name]); | 16758 return true; |
| 16127 return true; | |
| 16128 } | |
| 16129 } | 16759 } |
| 16130 List<MethodElement> methods = classElement.methods; | 16760 MethodElement method = classElement.getMethod(name); |
| 16131 for (MethodElement method in methods) { | 16761 if (method != null) { |
| 16132 if (method.name == name) { | 16762 _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR
_NAME_AND_METHOD, node, [name]); |
| 16133 _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCT
OR_NAME_AND_METHOD, node, [name]); | 16763 return true; |
| 16134 return true; | |
| 16135 } | |
| 16136 } | 16764 } |
| 16137 } | 16765 } |
| 16138 return false; | 16766 return false; |
| 16139 } | 16767 } |
| 16140 | 16768 |
| 16141 /** | 16769 /** |
| 16142 * This verifies that the [enclosingClass] does not have method and getter wit
h the same | 16770 * This verifies that the [enclosingClass] does not have method and getter wit
h the same |
| 16143 * names. | 16771 * names. |
| 16144 * | 16772 * |
| 16145 * @return `true` if and only if an error code is generated on the passed node | 16773 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 2487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18633 firstIteration = false; | 19261 firstIteration = false; |
| 18634 break; | 19262 break; |
| 18635 } else { | 19263 } else { |
| 18636 return true; | 19264 return true; |
| 18637 } | 19265 } |
| 18638 } | 19266 } |
| 18639 if (current != null && !checked.contains(current)) { | 19267 if (current != null && !checked.contains(current)) { |
| 18640 break; | 19268 break; |
| 18641 } | 19269 } |
| 18642 } | 19270 } |
| 18643 current.accept(new GeneralizingElementVisitor_15(target, toCheck)); | 19271 current.accept(new GeneralizingElementVisitor_17(target, toCheck)); |
| 18644 checked.add(current); | 19272 checked.add(current); |
| 18645 } | 19273 } |
| 18646 } | 19274 } |
| 18647 | 19275 |
| 18648 /** | 19276 /** |
| 18649 * @return `true` if given [Type] implements operator <i>==</i>, and it is not | 19277 * @return `true` if given [Type] implements operator <i>==</i>, and it is not |
| 18650 * <i>int</i> or <i>String</i>. | 19278 * <i>int</i> or <i>String</i>. |
| 18651 */ | 19279 */ |
| 18652 bool implementsEqualsWhenNotAllowed(Type2 type) { | 19280 bool implementsEqualsWhenNotAllowed(Type2 type) { |
| 18653 if (type == null || type == _typeProvider.intType || type == _typeProvider.s
tringType) { | 19281 if (type == null || type == _typeProvider.intType || type == _typeProvider.s
tringType) { |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18895 | 19523 |
| 18896 static final List<INIT_STATE> values = [ | 19524 static final List<INIT_STATE> values = [ |
| 18897 NOT_INIT, | 19525 NOT_INIT, |
| 18898 INIT_IN_DECLARATION, | 19526 INIT_IN_DECLARATION, |
| 18899 INIT_IN_FIELD_FORMAL, | 19527 INIT_IN_FIELD_FORMAL, |
| 18900 INIT_IN_INITIALIZERS]; | 19528 INIT_IN_INITIALIZERS]; |
| 18901 | 19529 |
| 18902 INIT_STATE(String name, int ordinal) : super(name, ordinal); | 19530 INIT_STATE(String name, int ordinal) : super(name, ordinal); |
| 18903 } | 19531 } |
| 18904 | 19532 |
| 18905 class GeneralizingElementVisitor_15 extends GeneralizingElementVisitor<Object> { | 19533 class GeneralizingElementVisitor_17 extends GeneralizingElementVisitor<Object> { |
| 18906 Element target; | 19534 Element target; |
| 18907 | 19535 |
| 18908 List<Element> toCheck; | 19536 List<Element> toCheck; |
| 18909 | 19537 |
| 18910 GeneralizingElementVisitor_15(this.target, this.toCheck) : super(); | 19538 GeneralizingElementVisitor_17(this.target, this.toCheck) : super(); |
| 18911 | 19539 |
| 18912 bool _inClass = false; | 19540 bool _inClass = false; |
| 18913 | 19541 |
| 18914 Object visitClassElement(ClassElement element) { | 19542 Object visitClassElement(ClassElement element) { |
| 18915 addTypeToCheck(element.supertype); | 19543 addTypeToCheck(element.supertype); |
| 18916 for (InterfaceType mixin in element.mixins) { | 19544 for (InterfaceType mixin in element.mixins) { |
| 18917 addTypeToCheck(mixin); | 19545 addTypeToCheck(mixin); |
| 18918 } | 19546 } |
| 18919 _inClass = !element.isTypedef; | 19547 _inClass = !element.isTypedef; |
| 18920 try { | 19548 try { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18997 | 19625 |
| 18998 /** | 19626 /** |
| 18999 * The template used to create the message to be displayed for this error. | 19627 * The template used to create the message to be displayed for this error. |
| 19000 */ | 19628 */ |
| 19001 final String message; | 19629 final String message; |
| 19002 | 19630 |
| 19003 /** | 19631 /** |
| 19004 * The template used to create the correction to be displayed for this error,
or `null` if | 19632 * The template used to create the correction to be displayed for this error,
or `null` if |
| 19005 * there is no correction information for this error. | 19633 * there is no correction information for this error. |
| 19006 */ | 19634 */ |
| 19007 String correction9; | 19635 String correction10; |
| 19008 | 19636 |
| 19009 /** | 19637 /** |
| 19010 * Initialize a newly created error code to have the given type and message. | 19638 * Initialize a newly created error code to have the given type and message. |
| 19011 * | 19639 * |
| 19012 * @param type the type of this error | 19640 * @param type the type of this error |
| 19013 * @param message the message template used to create the message to be displa
yed for the error | 19641 * @param message the message template used to create the message to be displa
yed for the error |
| 19014 */ | 19642 */ |
| 19015 ResolverErrorCode.con1(String name, int ordinal, this.type, this.message) : su
per(name, ordinal); | 19643 ResolverErrorCode.con1(String name, int ordinal, this.type, this.message) : su
per(name, ordinal); |
| 19016 | 19644 |
| 19017 /** | 19645 /** |
| 19018 * Initialize a newly created error code to have the given type, message and c
orrection. | 19646 * Initialize a newly created error code to have the given type, message and c
orrection. |
| 19019 * | 19647 * |
| 19020 * @param type the type of this error | 19648 * @param type the type of this error |
| 19021 * @param message the template used to create the message to be displayed for
the error | 19649 * @param message the template used to create the message to be displayed for
the error |
| 19022 * @param correction the template used to create the correction to be displaye
d for the error | 19650 * @param correction the template used to create the correction to be displaye
d for the error |
| 19023 */ | 19651 */ |
| 19024 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri
ng correction) : super(name, ordinal) { | 19652 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri
ng correction) : super(name, ordinal) { |
| 19025 this.correction9 = correction; | 19653 this.correction10 = correction; |
| 19026 } | 19654 } |
| 19027 | 19655 |
| 19028 String get correction => correction9; | 19656 String get correction => correction10; |
| 19029 | 19657 |
| 19030 ErrorSeverity get errorSeverity => type.severity; | 19658 ErrorSeverity get errorSeverity => type.severity; |
| 19031 } | 19659 } |
| OLD | NEW |