| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 // prepare ClassElement | 78 // prepare ClassElement |
| 79 ClassElement classElement = classDeclaration.element; | 79 ClassElement classElement = classDeclaration.element; |
| 80 if (classElement == null) { | 80 if (classElement == null) { |
| 81 return null; | 81 return null; |
| 82 } | 82 } |
| 83 // check toolkit objects | 83 // check toolkit objects |
| 84 for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) { | 84 for (ToolkitObjectElement toolkitObject in classElement.toolkitObjects) { |
| 85 List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARR
AY; | 85 List<AngularPropertyElement> properties = AngularPropertyElement.EMPTY_ARR
AY; |
| 86 // maybe name | 86 // maybe name |
| 87 if (toolkitObject is AngularElement) { | 87 if (toolkitObject is AngularElement) { |
| 88 if (isNameCoveredByLiteral(toolkitObject, node)) { | 88 if (_isNameCoveredByLiteral(toolkitObject, node)) { |
| 89 return toolkitObject; | 89 return toolkitObject; |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 // try selector | 92 // try selector |
| 93 if (toolkitObject is AngularHasSelectorElement) { | 93 if (toolkitObject is AngularHasSelectorElement) { |
| 94 AngularHasSelectorElement hasSelector = toolkitObject; | 94 AngularHasSelectorElement hasSelector = toolkitObject; |
| 95 AngularSelectorElement selector = hasSelector.selector; | 95 AngularSelectorElement selector = hasSelector.selector; |
| 96 if (isNameCoveredByLiteral(selector, node)) { | 96 if (_isNameCoveredByLiteral(selector, node)) { |
| 97 return selector; | 97 return selector; |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 // try properties of AngularComponentElement | 100 // try properties of AngularComponentElement |
| 101 if (toolkitObject is AngularComponentElement) { | 101 if (toolkitObject is AngularComponentElement) { |
| 102 AngularComponentElement component = toolkitObject; | 102 AngularComponentElement component = toolkitObject; |
| 103 properties = component.properties; | 103 properties = component.properties; |
| 104 } | 104 } |
| 105 // try properties of AngularDirectiveElement | 105 // try properties of AngularDirectiveElement |
| 106 if (toolkitObject is AngularDirectiveElement) { | 106 if (toolkitObject is AngularDirectiveElement) { |
| 107 AngularDirectiveElement directive = toolkitObject; | 107 AngularDirectiveElement directive = toolkitObject; |
| 108 properties = directive.properties; | 108 properties = directive.properties; |
| 109 } | 109 } |
| 110 // check properties | 110 // check properties |
| 111 for (AngularPropertyElement property in properties) { | 111 for (AngularPropertyElement property in properties) { |
| 112 // property name (use complete node range) | 112 // property name (use complete node range) |
| 113 if (isNameCoveredByLiteral(property, node)) { | 113 if (_isNameCoveredByLiteral(property, node)) { |
| 114 return property; | 114 return property; |
| 115 } | 115 } |
| 116 // field name (use complete node range, including @, => and <=>) | 116 // field name (use complete node range, including @, => and <=>) |
| 117 FieldElement field = property.field; | 117 FieldElement field = property.field; |
| 118 if (field != null) { | 118 if (field != null) { |
| 119 int fieldOffset = property.fieldNameOffset; | 119 int fieldOffset = property.fieldNameOffset; |
| 120 int fieldEnd = fieldOffset + field.name.length; | 120 int fieldEnd = fieldOffset + field.name.length; |
| 121 if (node.offset <= fieldOffset && fieldEnd < node.end) { | 121 if (node.offset <= fieldOffset && fieldEnd < node.end) { |
| 122 return field; | 122 return field; |
| 123 } | 123 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 // tag | 160 // tag |
| 161 if (StringUtilities.isTagName(text)) { | 161 if (StringUtilities.isTagName(text)) { |
| 162 return new AngularTagSelectorElementImpl(text, offset); | 162 return new AngularTagSelectorElementImpl(text, offset); |
| 163 } | 163 } |
| 164 return null; | 164 return null; |
| 165 } | 165 } |
| 166 | 166 |
| 167 /** | 167 /** |
| 168 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio
n]. | 168 * Returns the [FieldElement] of the first field in the given [FieldDeclaratio
n]. |
| 169 */ | 169 */ |
| 170 static FieldElement getOnlyFieldElement(FieldDeclaration fieldDeclaration) { | 170 static FieldElement _getOnlyFieldElement(FieldDeclaration fieldDeclaration) { |
| 171 NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables; | 171 NodeList<VariableDeclaration> fields = fieldDeclaration.fields.variables; |
| 172 return fields[0].element as FieldElement; | 172 return fields[0].element as FieldElement; |
| 173 } | 173 } |
| 174 | 174 |
| 175 /** | 175 /** |
| 176 * If given [Annotation] has one argument and it is [SimpleStringLiteral], ret
urns it, | 176 * If given [Annotation] has one argument and it is [SimpleStringLiteral], ret
urns it, |
| 177 * otherwise returns `null`. | 177 * otherwise returns `null`. |
| 178 */ | 178 */ |
| 179 static SimpleStringLiteral getOnlySimpleStringLiteralArgument(Annotation annot
ation) { | 179 static SimpleStringLiteral _getOnlySimpleStringLiteralArgument(Annotation anno
tation) { |
| 180 SimpleStringLiteral nameLiteral = null; | 180 SimpleStringLiteral nameLiteral = null; |
| 181 ArgumentList argsNode = annotation.arguments; | 181 ArgumentList argsNode = annotation.arguments; |
| 182 if (argsNode != null) { | 182 if (argsNode != null) { |
| 183 NodeList<Expression> args = argsNode.arguments; | 183 NodeList<Expression> args = argsNode.arguments; |
| 184 if (args.length == 1) { | 184 if (args.length == 1) { |
| 185 Expression arg = args[0]; | 185 Expression arg = args[0]; |
| 186 if (arg is SimpleStringLiteral) { | 186 if (arg is SimpleStringLiteral) { |
| 187 nameLiteral = arg; | 187 nameLiteral = arg; |
| 188 } | 188 } |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 return nameLiteral; | 191 return nameLiteral; |
| 192 } | 192 } |
| 193 | 193 |
| 194 /** | 194 /** |
| 195 * Checks if the name range of the given [Element] is completely covered by th
e given | 195 * Checks if the name range of the given [Element] is completely covered by th
e given |
| 196 * [SimpleStringLiteral]. | 196 * [SimpleStringLiteral]. |
| 197 */ | 197 */ |
| 198 static bool isNameCoveredByLiteral(Element element, AstNode node) { | 198 static bool _isNameCoveredByLiteral(Element element, AstNode node) { |
| 199 if (element != null) { | 199 if (element != null) { |
| 200 String name = element.name; | 200 String name = element.name; |
| 201 if (name != null) { | 201 if (name != null) { |
| 202 int nameOffset = element.nameOffset; | 202 int nameOffset = element.nameOffset; |
| 203 int nameEnd = nameOffset + name.length; | 203 int nameEnd = nameOffset + name.length; |
| 204 return node.offset <= nameOffset && nameEnd < node.end; | 204 return node.offset <= nameOffset && nameEnd < node.end; |
| 205 } | 205 } |
| 206 } | 206 } |
| 207 return false; | 207 return false; |
| 208 } | 208 } |
| 209 | 209 |
| 210 /** | 210 /** |
| 211 * Parses given [SimpleStringLiteral] using [parseSelector]. | 211 * Parses given [SimpleStringLiteral] using [parseSelector]. |
| 212 */ | 212 */ |
| 213 static AngularSelectorElement parseSelectorFromString(SimpleStringLiteral lite
ral) { | 213 static AngularSelectorElement _parseSelectorFromString(SimpleStringLiteral lit
eral) { |
| 214 int offset = literal.valueOffset; | 214 int offset = literal.valueOffset; |
| 215 String text = literal.stringValue; | 215 String text = literal.stringValue; |
| 216 return parseSelector(offset, text); | 216 return parseSelector(offset, text); |
| 217 } | 217 } |
| 218 | 218 |
| 219 /** | 219 /** |
| 220 * The listener to which errors will be reported. | 220 * The listener to which errors will be reported. |
| 221 */ | 221 */ |
| 222 AnalysisErrorListener _errorListener; | 222 AnalysisErrorListener _errorListener; |
| 223 | 223 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source sour
ce, CompilationUnit unit) { | 261 AngularCompilationUnitBuilder(AnalysisErrorListener errorListener, Source sour
ce, CompilationUnit unit) { |
| 262 this._errorListener = errorListener; | 262 this._errorListener = errorListener; |
| 263 this._source = source; | 263 this._source = source; |
| 264 this._unit = unit; | 264 this._unit = unit; |
| 265 } | 265 } |
| 266 | 266 |
| 267 /** | 267 /** |
| 268 * Builds Angular specific element models and adds them to the existing Dart e
lements. | 268 * Builds Angular specific element models and adds them to the existing Dart e
lements. |
| 269 */ | 269 */ |
| 270 void build() { | 270 void build() { |
| 271 parseViews(); | 271 _parseViews(); |
| 272 // process classes | 272 // process classes |
| 273 for (CompilationUnitMember unitMember in _unit.declarations) { | 273 for (CompilationUnitMember unitMember in _unit.declarations) { |
| 274 if (unitMember is ClassDeclaration) { | 274 if (unitMember is ClassDeclaration) { |
| 275 this._classDeclaration = unitMember; | 275 this._classDeclaration = unitMember; |
| 276 this._classElement = _classDeclaration.element as ClassElementImpl; | 276 this._classElement = _classDeclaration.element as ClassElementImpl; |
| 277 this._classToolkitObjects.clear(); | 277 this._classToolkitObjects.clear(); |
| 278 // process annotations | 278 // process annotations |
| 279 NodeList<Annotation> annotations = _classDeclaration.metadata; | 279 NodeList<Annotation> annotations = _classDeclaration.metadata; |
| 280 for (Annotation annotation in annotations) { | 280 for (Annotation annotation in annotations) { |
| 281 // verify annotation | 281 // verify annotation |
| 282 if (annotation.arguments == null) { | 282 if (annotation.arguments == null) { |
| 283 continue; | 283 continue; |
| 284 } | 284 } |
| 285 this._annotation = annotation; | 285 this._annotation = annotation; |
| 286 // @NgFilter | 286 // @NgFilter |
| 287 if (isAngularAnnotation(annotation, _NG_FILTER)) { | 287 if (_isAngularAnnotation(annotation, _NG_FILTER)) { |
| 288 parseNgFilter(); | 288 _parseNgFilter(); |
| 289 continue; | 289 continue; |
| 290 } | 290 } |
| 291 // @NgComponent | 291 // @NgComponent |
| 292 if (isAngularAnnotation(annotation, _NG_COMPONENT)) { | 292 if (_isAngularAnnotation(annotation, _NG_COMPONENT)) { |
| 293 parseNgComponent(); | 293 _parseNgComponent(); |
| 294 continue; | 294 continue; |
| 295 } | 295 } |
| 296 // @NgController | 296 // @NgController |
| 297 if (isAngularAnnotation(annotation, _NG_CONTROLLER)) { | 297 if (_isAngularAnnotation(annotation, _NG_CONTROLLER)) { |
| 298 parseNgController(); | 298 _parseNgController(); |
| 299 continue; | 299 continue; |
| 300 } | 300 } |
| 301 // @NgDirective | 301 // @NgDirective |
| 302 if (isAngularAnnotation(annotation, _NG_DIRECTIVE)) { | 302 if (_isAngularAnnotation(annotation, _NG_DIRECTIVE)) { |
| 303 parseNgDirective(); | 303 _parseNgDirective(); |
| 304 continue; | 304 continue; |
| 305 } | 305 } |
| 306 } | 306 } |
| 307 // set toolkit objects | 307 // set toolkit objects |
| 308 if (!_classToolkitObjects.isEmpty) { | 308 if (!_classToolkitObjects.isEmpty) { |
| 309 List<ToolkitObjectElement> objects = _classToolkitObjects; | 309 List<ToolkitObjectElement> objects = _classToolkitObjects; |
| 310 _classElement.toolkitObjects = new List.from(objects); | 310 _classElement.toolkitObjects = new List.from(objects); |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 } | 313 } |
| 314 } | 314 } |
| 315 | 315 |
| 316 /** | 316 /** |
| 317 * @return the argument [Expression] with given name form [annotation], may be | 317 * @return the argument [Expression] with given name form [annotation], may be |
| 318 * `null` if not found. | 318 * `null` if not found. |
| 319 */ | 319 */ |
| 320 Expression getArgument(String name) { | 320 Expression _getArgument(String name) { |
| 321 List<Expression> arguments = _annotation.arguments.arguments; | 321 List<Expression> arguments = _annotation.arguments.arguments; |
| 322 for (Expression argument in arguments) { | 322 for (Expression argument in arguments) { |
| 323 if (argument is NamedExpression) { | 323 if (argument is NamedExpression) { |
| 324 NamedExpression namedExpression = argument; | 324 NamedExpression namedExpression = argument; |
| 325 String argumentName = namedExpression.name.label.name; | 325 String argumentName = namedExpression.name.label.name; |
| 326 if (name == argumentName) { | 326 if (name == argumentName) { |
| 327 return namedExpression.expression; | 327 return namedExpression.expression; |
| 328 } | 328 } |
| 329 } | 329 } |
| 330 } | 330 } |
| 331 return null; | 331 return null; |
| 332 } | 332 } |
| 333 | 333 |
| 334 /** | 334 /** |
| 335 * @return the [String] value of the named argument. | 335 * @return the [String] value of the named argument. |
| 336 */ | 336 */ |
| 337 String getStringArgument(String name) => getStringLiteral(name).value; | 337 String _getStringArgument(String name) => _getStringLiteral(name).value; |
| 338 | 338 |
| 339 /** | 339 /** |
| 340 * @return the offset of the value of the named argument. | 340 * @return the offset of the value of the named argument. |
| 341 */ | 341 */ |
| 342 int getStringArgumentOffset(String name) { | 342 int _getStringArgumentOffset(String name) { |
| 343 Expression argument = getArgument(name); | 343 Expression argument = _getArgument(name); |
| 344 return (argument as SimpleStringLiteral).valueOffset; | 344 return (argument as SimpleStringLiteral).valueOffset; |
| 345 } | 345 } |
| 346 | 346 |
| 347 /** | 347 /** |
| 348 * @return the [SimpleStringLiteral] of the named argument. | 348 * @return the [SimpleStringLiteral] of the named argument. |
| 349 */ | 349 */ |
| 350 SimpleStringLiteral getStringLiteral(String name) { | 350 SimpleStringLiteral _getStringLiteral(String name) { |
| 351 Expression argument = getArgument(name); | 351 Expression argument = _getArgument(name); |
| 352 return argument as SimpleStringLiteral; | 352 return argument as SimpleStringLiteral; |
| 353 } | 353 } |
| 354 | 354 |
| 355 /** | 355 /** |
| 356 * Checks if [namedArguments] has string value for the argument with the given
name. | 356 * Checks if [namedArguments] has string value for the argument with the given
name. |
| 357 */ | 357 */ |
| 358 bool hasStringArgument(String name) { | 358 bool _hasStringArgument(String name) { |
| 359 Expression argument = getArgument(name); | 359 Expression argument = _getArgument(name); |
| 360 return argument is SimpleStringLiteral; | 360 return argument is SimpleStringLiteral; |
| 361 } | 361 } |
| 362 | 362 |
| 363 /** | 363 /** |
| 364 * Checks if given [Annotation] is an annotation with required name. | 364 * Checks if given [Annotation] is an annotation with required name. |
| 365 */ | 365 */ |
| 366 bool isAngularAnnotation(Annotation annotation, String name) { | 366 bool _isAngularAnnotation(Annotation annotation, String name) { |
| 367 Element element = annotation.element; | 367 Element element = annotation.element; |
| 368 if (element is ConstructorElement) { | 368 if (element is ConstructorElement) { |
| 369 ConstructorElement constructorElement = element; | 369 ConstructorElement constructorElement = element; |
| 370 return constructorElement.returnType.displayName == name; | 370 return constructorElement.returnType.displayName == name; |
| 371 } | 371 } |
| 372 return false; | 372 return false; |
| 373 } | 373 } |
| 374 | 374 |
| 375 void parseNgComponent() { | 375 void _parseNgComponent() { |
| 376 bool isValid = true; | 376 bool isValid = true; |
| 377 // publishAs | 377 // publishAs |
| 378 String name = null; | 378 String name = null; |
| 379 int nameOffset = -1; | 379 int nameOffset = -1; |
| 380 if (hasStringArgument(_PUBLISH_AS)) { | 380 if (_hasStringArgument(_PUBLISH_AS)) { |
| 381 name = getStringArgument(_PUBLISH_AS); | 381 name = _getStringArgument(_PUBLISH_AS); |
| 382 nameOffset = getStringArgumentOffset(_PUBLISH_AS); | 382 nameOffset = _getStringArgumentOffset(_PUBLISH_AS); |
| 383 } | 383 } |
| 384 // selector | 384 // selector |
| 385 AngularSelectorElement selector = null; | 385 AngularSelectorElement selector = null; |
| 386 if (!hasStringArgument(_SELECTOR)) { | 386 if (!_hasStringArgument(_SELECTOR)) { |
| 387 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); | 387 _reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 388 isValid = false; | 388 isValid = false; |
| 389 } else { | 389 } else { |
| 390 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); | 390 SimpleStringLiteral selectorLiteral = _getStringLiteral(_SELECTOR); |
| 391 selector = parseSelectorFromString(selectorLiteral); | 391 selector = _parseSelectorFromString(selectorLiteral); |
| 392 if (selector == null) { | 392 if (selector == null) { |
| 393 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); | 393 _reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [s
electorLiteral]); |
| 394 isValid = false; | 394 isValid = false; |
| 395 } | 395 } |
| 396 } | 396 } |
| 397 // templateUrl | 397 // templateUrl |
| 398 String templateUri = null; | 398 String templateUri = null; |
| 399 int templateUriOffset = -1; | 399 int templateUriOffset = -1; |
| 400 if (hasStringArgument(_TEMPLATE_URL)) { | 400 if (_hasStringArgument(_TEMPLATE_URL)) { |
| 401 templateUri = getStringArgument(_TEMPLATE_URL); | 401 templateUri = _getStringArgument(_TEMPLATE_URL); |
| 402 templateUriOffset = getStringArgumentOffset(_TEMPLATE_URL); | 402 templateUriOffset = _getStringArgumentOffset(_TEMPLATE_URL); |
| 403 } | 403 } |
| 404 // cssUrl | 404 // cssUrl |
| 405 String styleUri = null; | 405 String styleUri = null; |
| 406 int styleUriOffset = -1; | 406 int styleUriOffset = -1; |
| 407 if (hasStringArgument(_CSS_URL)) { | 407 if (_hasStringArgument(_CSS_URL)) { |
| 408 styleUri = getStringArgument(_CSS_URL); | 408 styleUri = _getStringArgument(_CSS_URL); |
| 409 styleUriOffset = getStringArgumentOffset(_CSS_URL); | 409 styleUriOffset = _getStringArgumentOffset(_CSS_URL); |
| 410 } | 410 } |
| 411 // create | 411 // create |
| 412 if (isValid) { | 412 if (isValid) { |
| 413 AngularComponentElementImpl element = new AngularComponentElementImpl(name
, nameOffset, _annotation.offset); | 413 AngularComponentElementImpl element = new AngularComponentElementImpl(name
, nameOffset, _annotation.offset); |
| 414 element.selector = selector; | 414 element.selector = selector; |
| 415 element.templateUri = templateUri; | 415 element.templateUri = templateUri; |
| 416 element.templateUriOffset = templateUriOffset; | 416 element.templateUriOffset = templateUriOffset; |
| 417 element.styleUri = styleUri; | 417 element.styleUri = styleUri; |
| 418 element.styleUriOffset = styleUriOffset; | 418 element.styleUriOffset = styleUriOffset; |
| 419 element.properties = parseNgComponentProperties(); | 419 element.properties = _parseNgComponentProperties(); |
| 420 element.scopeProperties = parseScopeProperties(); | 420 element.scopeProperties = _parseScopeProperties(); |
| 421 _classToolkitObjects.add(element); | 421 _classToolkitObjects.add(element); |
| 422 } | 422 } |
| 423 } | 423 } |
| 424 | 424 |
| 425 /** | 425 /** |
| 426 * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration]. | 426 * Parses [AngularPropertyElement]s from [annotation] and [classDeclaration]. |
| 427 */ | 427 */ |
| 428 List<AngularPropertyElement> parseNgComponentProperties() { | 428 List<AngularPropertyElement> _parseNgComponentProperties() { |
| 429 List<AngularPropertyElement> properties = []; | 429 List<AngularPropertyElement> properties = []; |
| 430 parseNgComponentProperties_fromMap(properties); | 430 _parseNgComponentProperties_fromMap(properties); |
| 431 parseNgComponentProperties_fromFields(properties); | 431 _parseNgComponentProperties_fromFields(properties); |
| 432 return new List.from(properties); | 432 return new List.from(properties); |
| 433 } | 433 } |
| 434 | 434 |
| 435 /** | 435 /** |
| 436 * Parses [AngularPropertyElement]s from [annotation]. | 436 * Parses [AngularPropertyElement]s from [annotation]. |
| 437 */ | 437 */ |
| 438 void parseNgComponentProperties_fromFields(List<AngularPropertyElement> proper
ties) { | 438 void _parseNgComponentProperties_fromFields(List<AngularPropertyElement> prope
rties) { |
| 439 NodeList<ClassMember> members = _classDeclaration.members; | 439 NodeList<ClassMember> members = _classDeclaration.members; |
| 440 for (ClassMember member in members) { | 440 for (ClassMember member in members) { |
| 441 if (member is FieldDeclaration) { | 441 if (member is FieldDeclaration) { |
| 442 FieldDeclaration fieldDeclaration = member; | 442 FieldDeclaration fieldDeclaration = member; |
| 443 for (Annotation annotation in fieldDeclaration.metadata) { | 443 for (Annotation annotation in fieldDeclaration.metadata) { |
| 444 // prepare property kind (if property annotation at all) | 444 // prepare property kind (if property annotation at all) |
| 445 AngularPropertyKind kind = null; | 445 AngularPropertyKind kind = null; |
| 446 if (isAngularAnnotation(annotation, _NG_ATTR)) { | 446 if (_isAngularAnnotation(annotation, _NG_ATTR)) { |
| 447 kind = AngularPropertyKind.ATTR; | 447 kind = AngularPropertyKind.ATTR; |
| 448 } else if (isAngularAnnotation(annotation, _NG_CALLBACK)) { | 448 } else if (_isAngularAnnotation(annotation, _NG_CALLBACK)) { |
| 449 kind = AngularPropertyKind.CALLBACK; | 449 kind = AngularPropertyKind.CALLBACK; |
| 450 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY)) { | 450 } else if (_isAngularAnnotation(annotation, _NG_ONE_WAY)) { |
| 451 kind = AngularPropertyKind.ONE_WAY; | 451 kind = AngularPropertyKind.ONE_WAY; |
| 452 } else if (isAngularAnnotation(annotation, _NG_ONE_WAY_ONE_TIME)) { | 452 } else if (_isAngularAnnotation(annotation, _NG_ONE_WAY_ONE_TIME)) { |
| 453 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; | 453 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; |
| 454 } else if (isAngularAnnotation(annotation, _NG_TWO_WAY)) { | 454 } else if (_isAngularAnnotation(annotation, _NG_TWO_WAY)) { |
| 455 kind = AngularPropertyKind.TWO_WAY; | 455 kind = AngularPropertyKind.TWO_WAY; |
| 456 } | 456 } |
| 457 // add property | 457 // add property |
| 458 if (kind != null) { | 458 if (kind != null) { |
| 459 SimpleStringLiteral nameLiteral = getOnlySimpleStringLiteralArgument
(annotation); | 459 SimpleStringLiteral nameLiteral = _getOnlySimpleStringLiteralArgumen
t(annotation); |
| 460 FieldElement field = getOnlyFieldElement(fieldDeclaration); | 460 FieldElement field = _getOnlyFieldElement(fieldDeclaration); |
| 461 if (nameLiteral != null && field != null) { | 461 if (nameLiteral != null && field != null) { |
| 462 AngularPropertyElementImpl property = new AngularPropertyElementIm
pl(nameLiteral.value, nameLiteral.valueOffset); | 462 AngularPropertyElementImpl property = new AngularPropertyElementIm
pl(nameLiteral.value, nameLiteral.valueOffset); |
| 463 property.field = field; | 463 property.field = field; |
| 464 property.propertyKind = kind; | 464 property.propertyKind = kind; |
| 465 properties.add(property); | 465 properties.add(property); |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 } | 468 } |
| 469 } | 469 } |
| 470 } | 470 } |
| 471 } | 471 } |
| 472 | 472 |
| 473 /** | 473 /** |
| 474 * Parses [AngularPropertyElement]s from [annotation]. | 474 * Parses [AngularPropertyElement]s from [annotation]. |
| 475 */ | 475 */ |
| 476 void parseNgComponentProperties_fromMap(List<AngularPropertyElement> propertie
s) { | 476 void _parseNgComponentProperties_fromMap(List<AngularPropertyElement> properti
es) { |
| 477 Expression mapExpression = getArgument("map"); | 477 Expression mapExpression = _getArgument("map"); |
| 478 // may be not properties | 478 // may be not properties |
| 479 if (mapExpression == null) { | 479 if (mapExpression == null) { |
| 480 return; | 480 return; |
| 481 } | 481 } |
| 482 // prepare map literal | 482 // prepare map literal |
| 483 if (mapExpression is! MapLiteral) { | 483 if (mapExpression is! MapLiteral) { |
| 484 reportErrorForNode(AngularCode.INVALID_PROPERTY_MAP, mapExpression, []); | 484 _reportErrorForNode(AngularCode.INVALID_PROPERTY_MAP, mapExpression, []); |
| 485 return; | 485 return; |
| 486 } | 486 } |
| 487 MapLiteral mapLiteral = mapExpression as MapLiteral; | 487 MapLiteral mapLiteral = mapExpression as MapLiteral; |
| 488 // analyze map entries | 488 // analyze map entries |
| 489 for (MapLiteralEntry entry in mapLiteral.entries) { | 489 for (MapLiteralEntry entry in mapLiteral.entries) { |
| 490 // prepare property name | 490 // prepare property name |
| 491 Expression nameExpression = entry.key; | 491 Expression nameExpression = entry.key; |
| 492 if (nameExpression is! SimpleStringLiteral) { | 492 if (nameExpression is! SimpleStringLiteral) { |
| 493 reportErrorForNode(AngularCode.INVALID_PROPERTY_NAME, nameExpression, []
); | 493 _reportErrorForNode(AngularCode.INVALID_PROPERTY_NAME, nameExpression, [
]); |
| 494 continue; | 494 continue; |
| 495 } | 495 } |
| 496 SimpleStringLiteral nameLiteral = nameExpression as SimpleStringLiteral; | 496 SimpleStringLiteral nameLiteral = nameExpression as SimpleStringLiteral; |
| 497 String name = nameLiteral.value; | 497 String name = nameLiteral.value; |
| 498 int nameOffset = nameLiteral.valueOffset; | 498 int nameOffset = nameLiteral.valueOffset; |
| 499 // prepare field specification | 499 // prepare field specification |
| 500 Expression specExpression = entry.value; | 500 Expression specExpression = entry.value; |
| 501 if (specExpression is! SimpleStringLiteral) { | 501 if (specExpression is! SimpleStringLiteral) { |
| 502 reportErrorForNode(AngularCode.INVALID_PROPERTY_SPEC, specExpression, []
); | 502 _reportErrorForNode(AngularCode.INVALID_PROPERTY_SPEC, specExpression, [
]); |
| 503 continue; | 503 continue; |
| 504 } | 504 } |
| 505 SimpleStringLiteral specLiteral = specExpression as SimpleStringLiteral; | 505 SimpleStringLiteral specLiteral = specExpression as SimpleStringLiteral; |
| 506 String spec = specLiteral.value; | 506 String spec = specLiteral.value; |
| 507 // parse binding kind and field name | 507 // parse binding kind and field name |
| 508 AngularPropertyKind kind; | 508 AngularPropertyKind kind; |
| 509 int fieldNameOffset; | 509 int fieldNameOffset; |
| 510 if (StringUtilities.startsWithChar(spec, 0x40)) { | 510 if (StringUtilities.startsWithChar(spec, 0x40)) { |
| 511 kind = AngularPropertyKind.ATTR; | 511 kind = AngularPropertyKind.ATTR; |
| 512 fieldNameOffset = 1; | 512 fieldNameOffset = 1; |
| 513 } else if (StringUtilities.startsWithChar(spec, 0x26)) { | 513 } else if (StringUtilities.startsWithChar(spec, 0x26)) { |
| 514 kind = AngularPropertyKind.CALLBACK; | 514 kind = AngularPropertyKind.CALLBACK; |
| 515 fieldNameOffset = 1; | 515 fieldNameOffset = 1; |
| 516 } else if (StringUtilities.startsWith3(spec, 0, 0x3D, 0x3E, 0x21)) { | 516 } else if (StringUtilities.startsWith3(spec, 0, 0x3D, 0x3E, 0x21)) { |
| 517 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; | 517 kind = AngularPropertyKind.ONE_WAY_ONE_TIME; |
| 518 fieldNameOffset = 3; | 518 fieldNameOffset = 3; |
| 519 } else if (StringUtilities.startsWith2(spec, 0, 0x3D, 0x3E)) { | 519 } else if (StringUtilities.startsWith2(spec, 0, 0x3D, 0x3E)) { |
| 520 kind = AngularPropertyKind.ONE_WAY; | 520 kind = AngularPropertyKind.ONE_WAY; |
| 521 fieldNameOffset = 2; | 521 fieldNameOffset = 2; |
| 522 } else if (StringUtilities.startsWith3(spec, 0, 0x3C, 0x3D, 0x3E)) { | 522 } else if (StringUtilities.startsWith3(spec, 0, 0x3C, 0x3D, 0x3E)) { |
| 523 kind = AngularPropertyKind.TWO_WAY; | 523 kind = AngularPropertyKind.TWO_WAY; |
| 524 fieldNameOffset = 3; | 524 fieldNameOffset = 3; |
| 525 } else { | 525 } else { |
| 526 reportErrorForNode(AngularCode.INVALID_PROPERTY_KIND, specLiteral, [spec
]); | 526 _reportErrorForNode(AngularCode.INVALID_PROPERTY_KIND, specLiteral, [spe
c]); |
| 527 continue; | 527 continue; |
| 528 } | 528 } |
| 529 String fieldName = spec.substring(fieldNameOffset); | 529 String fieldName = spec.substring(fieldNameOffset); |
| 530 fieldNameOffset += specLiteral.valueOffset; | 530 fieldNameOffset += specLiteral.valueOffset; |
| 531 // prepare field | 531 // prepare field |
| 532 PropertyAccessorElement setter = _classElement.type.lookUpSetter(fieldName
, _classElement.library); | 532 PropertyAccessorElement setter = _classElement.type.lookUpSetter(fieldName
, _classElement.library); |
| 533 if (setter == null) { | 533 if (setter == null) { |
| 534 reportErrorForOffset(AngularCode.INVALID_PROPERTY_FIELD, fieldNameOffset
, fieldName.length, [fieldName]); | 534 _reportErrorForOffset(AngularCode.INVALID_PROPERTY_FIELD, fieldNameOffse
t, fieldName.length, [fieldName]); |
| 535 continue; | 535 continue; |
| 536 } | 536 } |
| 537 FieldElement field = setter.variable as FieldElement; | 537 FieldElement field = setter.variable as FieldElement; |
| 538 // add property | 538 // add property |
| 539 AngularPropertyElementImpl property = new AngularPropertyElementImpl(name,
nameOffset); | 539 AngularPropertyElementImpl property = new AngularPropertyElementImpl(name,
nameOffset); |
| 540 property.field = field; | 540 property.field = field; |
| 541 property.propertyKind = kind; | 541 property.propertyKind = kind; |
| 542 property.fieldNameOffset = fieldNameOffset; | 542 property.fieldNameOffset = fieldNameOffset; |
| 543 properties.add(property); | 543 properties.add(property); |
| 544 } | 544 } |
| 545 } | 545 } |
| 546 | 546 |
| 547 void parseNgController() { | 547 void _parseNgController() { |
| 548 bool isValid = true; | 548 bool isValid = true; |
| 549 // publishAs | 549 // publishAs |
| 550 if (!hasStringArgument(_PUBLISH_AS)) { | 550 if (!_hasStringArgument(_PUBLISH_AS)) { |
| 551 reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); | 551 _reportErrorForAnnotation(AngularCode.MISSING_PUBLISH_AS, []); |
| 552 isValid = false; | 552 isValid = false; |
| 553 } | 553 } |
| 554 // selector | 554 // selector |
| 555 AngularSelectorElement selector = null; | 555 AngularSelectorElement selector = null; |
| 556 if (!hasStringArgument(_SELECTOR)) { | 556 if (!_hasStringArgument(_SELECTOR)) { |
| 557 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); | 557 _reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 558 isValid = false; | 558 isValid = false; |
| 559 } else { | 559 } else { |
| 560 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); | 560 SimpleStringLiteral selectorLiteral = _getStringLiteral(_SELECTOR); |
| 561 selector = parseSelectorFromString(selectorLiteral); | 561 selector = _parseSelectorFromString(selectorLiteral); |
| 562 if (selector == null) { | 562 if (selector == null) { |
| 563 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); | 563 _reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [s
electorLiteral]); |
| 564 isValid = false; | 564 isValid = false; |
| 565 } | 565 } |
| 566 } | 566 } |
| 567 // create | 567 // create |
| 568 if (isValid) { | 568 if (isValid) { |
| 569 String name = getStringArgument(_PUBLISH_AS); | 569 String name = _getStringArgument(_PUBLISH_AS); |
| 570 int nameOffset = getStringArgumentOffset(_PUBLISH_AS); | 570 int nameOffset = _getStringArgumentOffset(_PUBLISH_AS); |
| 571 AngularControllerElementImpl element = new AngularControllerElementImpl(na
me, nameOffset); | 571 AngularControllerElementImpl element = new AngularControllerElementImpl(na
me, nameOffset); |
| 572 element.selector = selector; | 572 element.selector = selector; |
| 573 _classToolkitObjects.add(element); | 573 _classToolkitObjects.add(element); |
| 574 } | 574 } |
| 575 } | 575 } |
| 576 | 576 |
| 577 void parseNgDirective() { | 577 void _parseNgDirective() { |
| 578 bool isValid = true; | 578 bool isValid = true; |
| 579 // selector | 579 // selector |
| 580 AngularSelectorElement selector = null; | 580 AngularSelectorElement selector = null; |
| 581 if (!hasStringArgument(_SELECTOR)) { | 581 if (!_hasStringArgument(_SELECTOR)) { |
| 582 reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); | 582 _reportErrorForAnnotation(AngularCode.MISSING_SELECTOR, []); |
| 583 isValid = false; | 583 isValid = false; |
| 584 } else { | 584 } else { |
| 585 SimpleStringLiteral selectorLiteral = getStringLiteral(_SELECTOR); | 585 SimpleStringLiteral selectorLiteral = _getStringLiteral(_SELECTOR); |
| 586 selector = parseSelectorFromString(selectorLiteral); | 586 selector = _parseSelectorFromString(selectorLiteral); |
| 587 if (selector == null) { | 587 if (selector == null) { |
| 588 reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [se
lectorLiteral]); | 588 _reportErrorForArgument(_SELECTOR, AngularCode.CANNOT_PARSE_SELECTOR, [s
electorLiteral]); |
| 589 isValid = false; | 589 isValid = false; |
| 590 } | 590 } |
| 591 } | 591 } |
| 592 // create | 592 // create |
| 593 if (isValid) { | 593 if (isValid) { |
| 594 int offset = _annotation.offset; | 594 int offset = _annotation.offset; |
| 595 AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offs
et); | 595 AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offs
et); |
| 596 element.selector = selector; | 596 element.selector = selector; |
| 597 element.properties = parseNgComponentProperties(); | 597 element.properties = _parseNgComponentProperties(); |
| 598 _classToolkitObjects.add(element); | 598 _classToolkitObjects.add(element); |
| 599 } | 599 } |
| 600 } | 600 } |
| 601 | 601 |
| 602 void parseNgFilter() { | 602 void _parseNgFilter() { |
| 603 bool isValid = true; | 603 bool isValid = true; |
| 604 // name | 604 // name |
| 605 if (!hasStringArgument(_NAME)) { | 605 if (!_hasStringArgument(_NAME)) { |
| 606 reportErrorForAnnotation(AngularCode.MISSING_NAME, []); | 606 _reportErrorForAnnotation(AngularCode.MISSING_NAME, []); |
| 607 isValid = false; | 607 isValid = false; |
| 608 } | 608 } |
| 609 // create | 609 // create |
| 610 if (isValid) { | 610 if (isValid) { |
| 611 String name = getStringArgument(_NAME); | 611 String name = _getStringArgument(_NAME); |
| 612 int nameOffset = getStringArgumentOffset(_NAME); | 612 int nameOffset = _getStringArgumentOffset(_NAME); |
| 613 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset)); | 613 _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset)); |
| 614 } | 614 } |
| 615 } | 615 } |
| 616 | 616 |
| 617 List<AngularScopePropertyElement> parseScopeProperties() { | 617 List<AngularScopePropertyElement> _parseScopeProperties() { |
| 618 List<AngularScopePropertyElement> properties = []; | 618 List<AngularScopePropertyElement> properties = []; |
| 619 _classDeclaration.accept(new RecursiveAstVisitor_AngularCompilationUnitBuild
er_parseScopeProperties(properties)); | 619 _classDeclaration.accept(new RecursiveAstVisitor_AngularCompilationUnitBuild
er_parseScopeProperties(properties)); |
| 620 return new List.from(properties); | 620 return new List.from(properties); |
| 621 } | 621 } |
| 622 | 622 |
| 623 /** | 623 /** |
| 624 * Create [AngularViewElement] for each valid <code>view('template.html')</cod
e> invocation, | 624 * Create [AngularViewElement] for each valid <code>view('template.html')</cod
e> invocation, |
| 625 * where <code>view</code> is <code>ViewFactory</code>. | 625 * where <code>view</code> is <code>ViewFactory</code>. |
| 626 */ | 626 */ |
| 627 void parseViews() { | 627 void _parseViews() { |
| 628 List<AngularViewElement> views = []; | 628 List<AngularViewElement> views = []; |
| 629 _unit.accept(new RecursiveAstVisitor_AngularCompilationUnitBuilder_parseView
s(views)); | 629 _unit.accept(new RecursiveAstVisitor_AngularCompilationUnitBuilder_parseView
s(views)); |
| 630 if (!views.isEmpty) { | 630 if (!views.isEmpty) { |
| 631 List<AngularViewElement> viewArray = new List.from(views); | 631 List<AngularViewElement> viewArray = new List.from(views); |
| 632 (_unit.element as CompilationUnitElementImpl).angularViews = viewArray; | 632 (_unit.element as CompilationUnitElementImpl).angularViews = viewArray; |
| 633 } | 633 } |
| 634 } | 634 } |
| 635 | 635 |
| 636 void reportErrorForAnnotation(ErrorCode errorCode, List<Object> arguments) { | 636 void _reportErrorForAnnotation(ErrorCode errorCode, List<Object> arguments) { |
| 637 reportErrorForNode(errorCode, _annotation, arguments); | 637 _reportErrorForNode(errorCode, _annotation, arguments); |
| 638 } | 638 } |
| 639 | 639 |
| 640 void reportErrorForArgument(String argumentName, ErrorCode errorCode, List<Obj
ect> arguments) { | 640 void _reportErrorForArgument(String argumentName, ErrorCode errorCode, List<Ob
ject> arguments) { |
| 641 Expression argument = getArgument(argumentName); | 641 Expression argument = _getArgument(argumentName); |
| 642 reportErrorForNode(errorCode, argument, arguments); | 642 _reportErrorForNode(errorCode, argument, arguments); |
| 643 } | 643 } |
| 644 | 644 |
| 645 void reportErrorForNode(ErrorCode errorCode, AstNode node, List<Object> argume
nts) { | 645 void _reportErrorForNode(ErrorCode errorCode, AstNode node, List<Object> argum
ents) { |
| 646 int offset = node.offset; | 646 int offset = node.offset; |
| 647 int length = node.length; | 647 int length = node.length; |
| 648 reportErrorForOffset(errorCode, offset, length, arguments); | 648 _reportErrorForOffset(errorCode, offset, length, arguments); |
| 649 } | 649 } |
| 650 | 650 |
| 651 void reportErrorForOffset(ErrorCode errorCode, int offset, int length, List<Ob
ject> arguments) { | 651 void _reportErrorForOffset(ErrorCode errorCode, int offset, int length, List<O
bject> arguments) { |
| 652 _errorListener.onError(new AnalysisError.con2(_source, offset, length, error
Code, arguments)); | 652 _errorListener.onError(new AnalysisError.con2(_source, offset, length, error
Code, arguments)); |
| 653 } | 653 } |
| 654 } | 654 } |
| 655 | 655 |
| 656 class RecursiveAstVisitor_AngularCompilationUnitBuilder_parseScopeProperties ext
ends RecursiveAstVisitor<Object> { | 656 class RecursiveAstVisitor_AngularCompilationUnitBuilder_parseScopeProperties ext
ends RecursiveAstVisitor<Object> { |
| 657 List<AngularScopePropertyElement> properties; | 657 List<AngularScopePropertyElement> properties; |
| 658 | 658 |
| 659 RecursiveAstVisitor_AngularCompilationUnitBuilder_parseScopeProperties(this.pr
operties) : super(); | 659 RecursiveAstVisitor_AngularCompilationUnitBuilder_parseScopeProperties(this.pr
operties) : super(); |
| 660 | 660 |
| 661 Object visitAssignmentExpression(AssignmentExpression node) { | 661 Object visitAssignmentExpression(AssignmentExpression node) { |
| 662 addProperty(node); | 662 _addProperty(node); |
| 663 return super.visitAssignmentExpression(node); | 663 return super.visitAssignmentExpression(node); |
| 664 } | 664 } |
| 665 | 665 |
| 666 void addProperty(AssignmentExpression node) { | 666 void _addProperty(AssignmentExpression node) { |
| 667 // try to find "name" in scope[name] | 667 // try to find "name" in scope[name] |
| 668 SimpleStringLiteral nameNode = getNameNode(node.leftHandSide); | 668 SimpleStringLiteral nameNode = _getNameNode(node.leftHandSide); |
| 669 if (nameNode == null) { | 669 if (nameNode == null) { |
| 670 return; | 670 return; |
| 671 } | 671 } |
| 672 // prepare unique | 672 // prepare unique |
| 673 String name = nameNode.stringValue; | 673 String name = nameNode.stringValue; |
| 674 if (hasPropertyWithName(name)) { | 674 if (_hasPropertyWithName(name)) { |
| 675 return; | 675 return; |
| 676 } | 676 } |
| 677 // do add property | 677 // do add property |
| 678 int nameOffset = nameNode.valueOffset; | 678 int nameOffset = nameNode.valueOffset; |
| 679 AngularScopePropertyElement property = new AngularScopePropertyElementImpl(n
ame, nameOffset, node.rightHandSide.bestType); | 679 AngularScopePropertyElement property = new AngularScopePropertyElementImpl(n
ame, nameOffset, node.rightHandSide.bestType); |
| 680 nameNode.toolkitElement = property; | 680 nameNode.toolkitElement = property; |
| 681 properties.add(property); | 681 properties.add(property); |
| 682 } | 682 } |
| 683 | 683 |
| 684 SimpleStringLiteral getNameNode(Expression node) { | 684 SimpleStringLiteral _getNameNode(Expression node) { |
| 685 if (node is IndexExpression) { | 685 if (node is IndexExpression) { |
| 686 IndexExpression indexExpression = node; | 686 IndexExpression indexExpression = node; |
| 687 Expression target = indexExpression.target; | 687 Expression target = indexExpression.target; |
| 688 Expression index = indexExpression.index; | 688 Expression index = indexExpression.index; |
| 689 if (index is SimpleStringLiteral && isContext(target)) { | 689 if (index is SimpleStringLiteral && _isContext(target)) { |
| 690 return index; | 690 return index; |
| 691 } | 691 } |
| 692 } | 692 } |
| 693 return null; | 693 return null; |
| 694 } | 694 } |
| 695 | 695 |
| 696 bool hasPropertyWithName(String name) { | 696 bool _hasPropertyWithName(String name) { |
| 697 for (AngularScopePropertyElement property in properties) { | 697 for (AngularScopePropertyElement property in properties) { |
| 698 if (property.name == name) { | 698 if (property.name == name) { |
| 699 return true; | 699 return true; |
| 700 } | 700 } |
| 701 } | 701 } |
| 702 return false; | 702 return false; |
| 703 } | 703 } |
| 704 | 704 |
| 705 bool isContext(Expression target) { | 705 bool _isContext(Expression target) { |
| 706 if (target is PrefixedIdentifier) { | 706 if (target is PrefixedIdentifier) { |
| 707 PrefixedIdentifier prefixed = target; | 707 PrefixedIdentifier prefixed = target; |
| 708 SimpleIdentifier prefix = prefixed.prefix; | 708 SimpleIdentifier prefix = prefixed.prefix; |
| 709 SimpleIdentifier identifier = prefixed.identifier; | 709 SimpleIdentifier identifier = prefixed.identifier; |
| 710 return (identifier.name == "context") && isScope(prefix); | 710 return (identifier.name == "context") && _isScope(prefix); |
| 711 } | 711 } |
| 712 return false; | 712 return false; |
| 713 } | 713 } |
| 714 | 714 |
| 715 bool isScope(Expression target) { | 715 bool _isScope(Expression target) { |
| 716 if (target != null) { | 716 if (target != null) { |
| 717 Type2 type = target.bestType; | 717 Type2 type = target.bestType; |
| 718 if (type is InterfaceType) { | 718 if (type is InterfaceType) { |
| 719 InterfaceType interfaceType = type; | 719 InterfaceType interfaceType = type; |
| 720 return interfaceType.name == "Scope"; | 720 return interfaceType.name == "Scope"; |
| 721 } | 721 } |
| 722 } | 722 } |
| 723 return false; | 723 return false; |
| 724 } | 724 } |
| 725 } | 725 } |
| 726 | 726 |
| 727 class RecursiveAstVisitor_AngularCompilationUnitBuilder_parseViews extends Recur
siveAstVisitor<Object> { | 727 class RecursiveAstVisitor_AngularCompilationUnitBuilder_parseViews extends Recur
siveAstVisitor<Object> { |
| 728 List<AngularViewElement> views; | 728 List<AngularViewElement> views; |
| 729 | 729 |
| 730 RecursiveAstVisitor_AngularCompilationUnitBuilder_parseViews(this.views) : sup
er(); | 730 RecursiveAstVisitor_AngularCompilationUnitBuilder_parseViews(this.views) : sup
er(); |
| 731 | 731 |
| 732 Object visitMethodInvocation(MethodInvocation node) { | 732 Object visitMethodInvocation(MethodInvocation node) { |
| 733 addView(node); | 733 _addView(node); |
| 734 return super.visitMethodInvocation(node); | 734 return super.visitMethodInvocation(node); |
| 735 } | 735 } |
| 736 | 736 |
| 737 void addView(MethodInvocation node) { | 737 void _addView(MethodInvocation node) { |
| 738 // only one argument | 738 // only one argument |
| 739 List<Expression> arguments = node.argumentList.arguments; | 739 List<Expression> arguments = node.argumentList.arguments; |
| 740 if (arguments.length != 1) { | 740 if (arguments.length != 1) { |
| 741 return; | 741 return; |
| 742 } | 742 } |
| 743 // String literal | 743 // String literal |
| 744 Expression argument = arguments[0]; | 744 Expression argument = arguments[0]; |
| 745 if (argument is! SimpleStringLiteral) { | 745 if (argument is! SimpleStringLiteral) { |
| 746 return; | 746 return; |
| 747 } | 747 } |
| 748 SimpleStringLiteral literal = argument as SimpleStringLiteral; | 748 SimpleStringLiteral literal = argument as SimpleStringLiteral; |
| 749 // just view('template') | 749 // just view('template') |
| 750 if (node.realTarget != null) { | 750 if (node.realTarget != null) { |
| 751 return; | 751 return; |
| 752 } | 752 } |
| 753 // should be ViewFactory | 753 // should be ViewFactory |
| 754 if (!isViewFactory(node.methodName)) { | 754 if (!_isViewFactory(node.methodName)) { |
| 755 return; | 755 return; |
| 756 } | 756 } |
| 757 // add AngularViewElement | 757 // add AngularViewElement |
| 758 String templateUri = literal.stringValue; | 758 String templateUri = literal.stringValue; |
| 759 int templateUriOffset = literal.valueOffset; | 759 int templateUriOffset = literal.valueOffset; |
| 760 views.add(new AngularViewElementImpl(templateUri, templateUriOffset)); | 760 views.add(new AngularViewElementImpl(templateUri, templateUriOffset)); |
| 761 } | 761 } |
| 762 | 762 |
| 763 bool isViewFactory(Expression target) { | 763 bool _isViewFactory(Expression target) { |
| 764 if (target is SimpleIdentifier) { | 764 if (target is SimpleIdentifier) { |
| 765 SimpleIdentifier identifier = target; | 765 SimpleIdentifier identifier = target; |
| 766 Element element = identifier.staticElement; | 766 Element element = identifier.staticElement; |
| 767 if (element is VariableElement) { | 767 if (element is VariableElement) { |
| 768 VariableElement variable = element; | 768 VariableElement variable = element; |
| 769 Type2 type = variable.type; | 769 Type2 type = variable.type; |
| 770 if (type is InterfaceType) { | 770 if (type is InterfaceType) { |
| 771 InterfaceType interfaceType = type; | 771 InterfaceType interfaceType = type; |
| 772 return interfaceType.name == "ViewFactory"; | 772 return interfaceType.name == "ViewFactory"; |
| 773 } | 773 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 _functionTypesToFix = new List<FunctionTypeImpl>(); | 894 _functionTypesToFix = new List<FunctionTypeImpl>(); |
| 895 // | 895 // |
| 896 // Process field declarations before constructors and methods so that field
formal parameters | 896 // Process field declarations before constructors and methods so that field
formal parameters |
| 897 // can be correctly resolved to their fields. | 897 // can be correctly resolved to their fields. |
| 898 // | 898 // |
| 899 ElementHolder previousHolder = _currentHolder; | 899 ElementHolder previousHolder = _currentHolder; |
| 900 _currentHolder = holder; | 900 _currentHolder = holder; |
| 901 try { | 901 try { |
| 902 List<ClassMember> nonFields = new List<ClassMember>(); | 902 List<ClassMember> nonFields = new List<ClassMember>(); |
| 903 node.visitChildren(new UnifyingAstVisitor_ElementBuilder_visitClassDeclara
tion(this, nonFields)); | 903 node.visitChildren(new UnifyingAstVisitor_ElementBuilder_visitClassDeclara
tion(this, nonFields)); |
| 904 buildFieldMap(holder.fieldsWithoutFlushing); | 904 _buildFieldMap(holder.fieldsWithoutFlushing); |
| 905 int count = nonFields.length; | 905 int count = nonFields.length; |
| 906 for (int i = 0; i < count; i++) { | 906 for (int i = 0; i < count; i++) { |
| 907 nonFields[i].accept(this); | 907 nonFields[i].accept(this); |
| 908 } | 908 } |
| 909 } finally { | 909 } finally { |
| 910 _currentHolder = previousHolder; | 910 _currentHolder = previousHolder; |
| 911 } | 911 } |
| 912 SimpleIdentifier className = node.name; | 912 SimpleIdentifier className = node.name; |
| 913 ClassElementImpl element = new ClassElementImpl(className); | 913 ClassElementImpl element = new ClassElementImpl(className); |
| 914 List<TypeParameterElement> typeParameters = holder.typeParameters; | 914 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 915 List<Type2> typeArguments = createTypeParameterTypes(typeParameters); | 915 List<Type2> typeArguments = _createTypeParameterTypes(typeParameters); |
| 916 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); | 916 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); |
| 917 interfaceType.typeArguments = typeArguments; | 917 interfaceType.typeArguments = typeArguments; |
| 918 element.type = interfaceType; | 918 element.type = interfaceType; |
| 919 List<ConstructorElement> constructors = holder.constructors; | 919 List<ConstructorElement> constructors = holder.constructors; |
| 920 if (constructors.length == 0) { | 920 if (constructors.length == 0) { |
| 921 // | 921 // |
| 922 // Create the default constructor. | 922 // Create the default constructor. |
| 923 // | 923 // |
| 924 constructors = createDefaultConstructors(interfaceType); | 924 constructors = _createDefaultConstructors(interfaceType); |
| 925 } | 925 } |
| 926 element.abstract = node.abstractKeyword != null; | 926 element.abstract = node.abstractKeyword != null; |
| 927 element.accessors = holder.accessors; | 927 element.accessors = holder.accessors; |
| 928 element.constructors = constructors; | 928 element.constructors = constructors; |
| 929 element.fields = holder.fields; | 929 element.fields = holder.fields; |
| 930 element.methods = holder.methods; | 930 element.methods = holder.methods; |
| 931 element.typeParameters = typeParameters; | 931 element.typeParameters = typeParameters; |
| 932 element.validMixin = _isValidMixin; | 932 element.validMixin = _isValidMixin; |
| 933 int functionTypeCount = _functionTypesToFix.length; | 933 int functionTypeCount = _functionTypesToFix.length; |
| 934 for (int i = 0; i < functionTypeCount; i++) { | 934 for (int i = 0; i < functionTypeCount; i++) { |
| 935 _functionTypesToFix[i].typeArguments = typeArguments; | 935 _functionTypesToFix[i].typeArguments = typeArguments; |
| 936 } | 936 } |
| 937 _functionTypesToFix = null; | 937 _functionTypesToFix = null; |
| 938 _currentHolder.addType(element); | 938 _currentHolder.addType(element); |
| 939 className.staticElement = element; | 939 className.staticElement = element; |
| 940 _fieldMap = null; | 940 _fieldMap = null; |
| 941 holder.validate(); | 941 holder.validate(); |
| 942 return null; | 942 return null; |
| 943 } | 943 } |
| 944 | 944 |
| 945 Object visitClassTypeAlias(ClassTypeAlias node) { | 945 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 946 ElementHolder holder = new ElementHolder(); | 946 ElementHolder holder = new ElementHolder(); |
| 947 _functionTypesToFix = new List<FunctionTypeImpl>(); | 947 _functionTypesToFix = new List<FunctionTypeImpl>(); |
| 948 visitChildren(holder, node); | 948 _visitChildren(holder, node); |
| 949 SimpleIdentifier className = node.name; | 949 SimpleIdentifier className = node.name; |
| 950 ClassElementImpl element = new ClassElementImpl(className); | 950 ClassElementImpl element = new ClassElementImpl(className); |
| 951 element.abstract = node.abstractKeyword != null; | 951 element.abstract = node.abstractKeyword != null; |
| 952 element.typedef = true; | 952 element.typedef = true; |
| 953 List<TypeParameterElement> typeParameters = holder.typeParameters; | 953 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 954 element.typeParameters = typeParameters; | 954 element.typeParameters = typeParameters; |
| 955 List<Type2> typeArguments = createTypeParameterTypes(typeParameters); | 955 List<Type2> typeArguments = _createTypeParameterTypes(typeParameters); |
| 956 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); | 956 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); |
| 957 interfaceType.typeArguments = typeArguments; | 957 interfaceType.typeArguments = typeArguments; |
| 958 element.type = interfaceType; | 958 element.type = interfaceType; |
| 959 // set default constructor | 959 // set default constructor |
| 960 element.constructors = createDefaultConstructors(interfaceType); | 960 element.constructors = _createDefaultConstructors(interfaceType); |
| 961 for (FunctionTypeImpl functionType in _functionTypesToFix) { | 961 for (FunctionTypeImpl functionType in _functionTypesToFix) { |
| 962 functionType.typeArguments = typeArguments; | 962 functionType.typeArguments = typeArguments; |
| 963 } | 963 } |
| 964 _functionTypesToFix = null; | 964 _functionTypesToFix = null; |
| 965 _currentHolder.addType(element); | 965 _currentHolder.addType(element); |
| 966 className.staticElement = element; | 966 className.staticElement = element; |
| 967 holder.validate(); | 967 holder.validate(); |
| 968 return null; | 968 return null; |
| 969 } | 969 } |
| 970 | 970 |
| 971 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 971 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 972 _isValidMixin = false; | 972 _isValidMixin = false; |
| 973 ElementHolder holder = new ElementHolder(); | 973 ElementHolder holder = new ElementHolder(); |
| 974 bool wasInFunction = _inFunction; | 974 bool wasInFunction = _inFunction; |
| 975 _inFunction = true; | 975 _inFunction = true; |
| 976 try { | 976 try { |
| 977 visitChildren(holder, node); | 977 _visitChildren(holder, node); |
| 978 } finally { | 978 } finally { |
| 979 _inFunction = wasInFunction; | 979 _inFunction = wasInFunction; |
| 980 } | 980 } |
| 981 SimpleIdentifier constructorName = node.name; | 981 SimpleIdentifier constructorName = node.name; |
| 982 ConstructorElementImpl element = new ConstructorElementImpl.con1(constructor
Name); | 982 ConstructorElementImpl element = new ConstructorElementImpl.con1(constructor
Name); |
| 983 if (node.factoryKeyword != null) { | 983 if (node.factoryKeyword != null) { |
| 984 element.factory = true; | 984 element.factory = true; |
| 985 } | 985 } |
| 986 element.functions = holder.functions; | 986 element.functions = holder.functions; |
| 987 element.labels = holder.labels; | 987 element.labels = holder.labels; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1003 } | 1003 } |
| 1004 | 1004 |
| 1005 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 1005 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 1006 SimpleIdentifier variableName = node.identifier; | 1006 SimpleIdentifier variableName = node.identifier; |
| 1007 sc.Token keyword = node.keyword; | 1007 sc.Token keyword = node.keyword; |
| 1008 LocalVariableElementImpl element = new LocalVariableElementImpl(variableName
); | 1008 LocalVariableElementImpl element = new LocalVariableElementImpl(variableName
); |
| 1009 ForEachStatement statement = node.parent as ForEachStatement; | 1009 ForEachStatement statement = node.parent as ForEachStatement; |
| 1010 int declarationEnd = node.offset + node.length; | 1010 int declarationEnd = node.offset + node.length; |
| 1011 int statementEnd = statement.offset + statement.length; | 1011 int statementEnd = statement.offset + statement.length; |
| 1012 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); | 1012 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); |
| 1013 element.const3 = matches(keyword, sc.Keyword.CONST); | 1013 element.const3 = _matches(keyword, sc.Keyword.CONST); |
| 1014 element.final2 = matches(keyword, sc.Keyword.FINAL); | 1014 element.final2 = _matches(keyword, sc.Keyword.FINAL); |
| 1015 _currentHolder.addLocalVariable(element); | 1015 _currentHolder.addLocalVariable(element); |
| 1016 variableName.staticElement = element; | 1016 variableName.staticElement = element; |
| 1017 return super.visitDeclaredIdentifier(node); | 1017 return super.visitDeclaredIdentifier(node); |
| 1018 } | 1018 } |
| 1019 | 1019 |
| 1020 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 1020 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 1021 ElementHolder holder = new ElementHolder(); | 1021 ElementHolder holder = new ElementHolder(); |
| 1022 NormalFormalParameter normalParameter = node.parameter; | 1022 NormalFormalParameter normalParameter = node.parameter; |
| 1023 SimpleIdentifier parameterName = normalParameter.identifier; | 1023 SimpleIdentifier parameterName = normalParameter.identifier; |
| 1024 ParameterElementImpl parameter; | 1024 ParameterElementImpl parameter; |
| 1025 if (normalParameter is FieldFormalParameter) { | 1025 if (normalParameter is FieldFormalParameter) { |
| 1026 parameter = new DefaultFieldFormalParameterElementImpl(parameterName); | 1026 parameter = new DefaultFieldFormalParameterElementImpl(parameterName); |
| 1027 FieldElement field = _fieldMap == null ? null : _fieldMap[parameterName.na
me]; | 1027 FieldElement field = _fieldMap == null ? null : _fieldMap[parameterName.na
me]; |
| 1028 if (field != null) { | 1028 if (field != null) { |
| 1029 (parameter as DefaultFieldFormalParameterElementImpl).field = field; | 1029 (parameter as DefaultFieldFormalParameterElementImpl).field = field; |
| 1030 } | 1030 } |
| 1031 } else { | 1031 } else { |
| 1032 parameter = new DefaultParameterElementImpl(parameterName); | 1032 parameter = new DefaultParameterElementImpl(parameterName); |
| 1033 } | 1033 } |
| 1034 parameter.const3 = node.isConst; | 1034 parameter.const3 = node.isConst; |
| 1035 parameter.final2 = node.isFinal; | 1035 parameter.final2 = node.isFinal; |
| 1036 parameter.parameterKind = node.kind; | 1036 parameter.parameterKind = node.kind; |
| 1037 // set initializer, default value range | 1037 // set initializer, default value range |
| 1038 Expression defaultValue = node.defaultValue; | 1038 Expression defaultValue = node.defaultValue; |
| 1039 if (defaultValue != null) { | 1039 if (defaultValue != null) { |
| 1040 visit(holder, defaultValue); | 1040 _visit(holder, defaultValue); |
| 1041 FunctionElementImpl initializer = new FunctionElementImpl.con2(defaultValu
e.beginToken.offset); | 1041 FunctionElementImpl initializer = new FunctionElementImpl.con2(defaultValu
e.beginToken.offset); |
| 1042 initializer.functions = holder.functions; | 1042 initializer.functions = holder.functions; |
| 1043 initializer.labels = holder.labels; | 1043 initializer.labels = holder.labels; |
| 1044 initializer.localVariables = holder.localVariables; | 1044 initializer.localVariables = holder.localVariables; |
| 1045 initializer.parameters = holder.parameters; | 1045 initializer.parameters = holder.parameters; |
| 1046 initializer.synthetic = true; | 1046 initializer.synthetic = true; |
| 1047 parameter.initializer = initializer; | 1047 parameter.initializer = initializer; |
| 1048 parameter.setDefaultValueRange(defaultValue.offset, defaultValue.length); | 1048 parameter.setDefaultValueRange(defaultValue.offset, defaultValue.length); |
| 1049 } | 1049 } |
| 1050 // visible range | 1050 // visible range |
| 1051 setParameterVisibleRange(node, parameter); | 1051 _setParameterVisibleRange(node, parameter); |
| 1052 _currentHolder.addParameter(parameter); | 1052 _currentHolder.addParameter(parameter); |
| 1053 parameterName.staticElement = parameter; | 1053 parameterName.staticElement = parameter; |
| 1054 normalParameter.accept(this); | 1054 normalParameter.accept(this); |
| 1055 holder.validate(); | 1055 holder.validate(); |
| 1056 return null; | 1056 return null; |
| 1057 } | 1057 } |
| 1058 | 1058 |
| 1059 Object visitFieldDeclaration(FieldDeclaration node) { | 1059 Object visitFieldDeclaration(FieldDeclaration node) { |
| 1060 bool wasInField = _inFieldContext; | 1060 bool wasInField = _inFieldContext; |
| 1061 _inFieldContext = true; | 1061 _inFieldContext = true; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1078 if (field != null) { | 1078 if (field != null) { |
| 1079 parameter.field = field; | 1079 parameter.field = field; |
| 1080 } | 1080 } |
| 1081 _currentHolder.addParameter(parameter); | 1081 _currentHolder.addParameter(parameter); |
| 1082 parameterName.staticElement = parameter; | 1082 parameterName.staticElement = parameter; |
| 1083 } | 1083 } |
| 1084 // | 1084 // |
| 1085 // The children of this parameter include any parameters defined on the type
of this parameter. | 1085 // The children of this parameter include any parameters defined on the type
of this parameter. |
| 1086 // | 1086 // |
| 1087 ElementHolder holder = new ElementHolder(); | 1087 ElementHolder holder = new ElementHolder(); |
| 1088 visitChildren(holder, node); | 1088 _visitChildren(holder, node); |
| 1089 (node.element as ParameterElementImpl).parameters = holder.parameters; | 1089 (node.element as ParameterElementImpl).parameters = holder.parameters; |
| 1090 holder.validate(); | 1090 holder.validate(); |
| 1091 return null; | 1091 return null; |
| 1092 } | 1092 } |
| 1093 | 1093 |
| 1094 Object visitFunctionDeclaration(FunctionDeclaration node) { | 1094 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 1095 FunctionExpression expression = node.functionExpression; | 1095 FunctionExpression expression = node.functionExpression; |
| 1096 if (expression != null) { | 1096 if (expression != null) { |
| 1097 ElementHolder holder = new ElementHolder(); | 1097 ElementHolder holder = new ElementHolder(); |
| 1098 bool wasInFunction = _inFunction; | 1098 bool wasInFunction = _inFunction; |
| 1099 _inFunction = true; | 1099 _inFunction = true; |
| 1100 try { | 1100 try { |
| 1101 visitChildren(holder, expression); | 1101 _visitChildren(holder, expression); |
| 1102 } finally { | 1102 } finally { |
| 1103 _inFunction = wasInFunction; | 1103 _inFunction = wasInFunction; |
| 1104 } | 1104 } |
| 1105 sc.Token property = node.propertyKeyword; | 1105 sc.Token property = node.propertyKeyword; |
| 1106 if (property == null) { | 1106 if (property == null) { |
| 1107 SimpleIdentifier functionName = node.name; | 1107 SimpleIdentifier functionName = node.name; |
| 1108 FunctionElementImpl element = new FunctionElementImpl.con1(functionName)
; | 1108 FunctionElementImpl element = new FunctionElementImpl.con1(functionName)
; |
| 1109 element.functions = holder.functions; | 1109 element.functions = holder.functions; |
| 1110 element.labels = holder.labels; | 1110 element.labels = holder.labels; |
| 1111 element.localVariables = holder.localVariables; | 1111 element.localVariables = holder.localVariables; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1128 return null; | 1128 return null; |
| 1129 } | 1129 } |
| 1130 String propertyName = propertyNameNode.name; | 1130 String propertyName = propertyNameNode.name; |
| 1131 TopLevelVariableElementImpl variable = _currentHolder.getTopLevelVariabl
e(propertyName) as TopLevelVariableElementImpl; | 1131 TopLevelVariableElementImpl variable = _currentHolder.getTopLevelVariabl
e(propertyName) as TopLevelVariableElementImpl; |
| 1132 if (variable == null) { | 1132 if (variable == null) { |
| 1133 variable = new TopLevelVariableElementImpl.con2(node.name.name); | 1133 variable = new TopLevelVariableElementImpl.con2(node.name.name); |
| 1134 variable.final2 = true; | 1134 variable.final2 = true; |
| 1135 variable.synthetic = true; | 1135 variable.synthetic = true; |
| 1136 _currentHolder.addTopLevelVariable(variable); | 1136 _currentHolder.addTopLevelVariable(variable); |
| 1137 } | 1137 } |
| 1138 if (matches(property, sc.Keyword.GET)) { | 1138 if (_matches(property, sc.Keyword.GET)) { |
| 1139 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.c
on1(propertyNameNode); | 1139 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.c
on1(propertyNameNode); |
| 1140 getter.functions = holder.functions; | 1140 getter.functions = holder.functions; |
| 1141 getter.labels = holder.labels; | 1141 getter.labels = holder.labels; |
| 1142 getter.localVariables = holder.localVariables; | 1142 getter.localVariables = holder.localVariables; |
| 1143 getter.variable = variable; | 1143 getter.variable = variable; |
| 1144 getter.getter = true; | 1144 getter.getter = true; |
| 1145 getter.static = true; | 1145 getter.static = true; |
| 1146 variable.getter = getter; | 1146 variable.getter = getter; |
| 1147 _currentHolder.addAccessor(getter); | 1147 _currentHolder.addAccessor(getter); |
| 1148 expression.element = getter; | 1148 expression.element = getter; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1166 holder.validate(); | 1166 holder.validate(); |
| 1167 } | 1167 } |
| 1168 return null; | 1168 return null; |
| 1169 } | 1169 } |
| 1170 | 1170 |
| 1171 Object visitFunctionExpression(FunctionExpression node) { | 1171 Object visitFunctionExpression(FunctionExpression node) { |
| 1172 ElementHolder holder = new ElementHolder(); | 1172 ElementHolder holder = new ElementHolder(); |
| 1173 bool wasInFunction = _inFunction; | 1173 bool wasInFunction = _inFunction; |
| 1174 _inFunction = true; | 1174 _inFunction = true; |
| 1175 try { | 1175 try { |
| 1176 visitChildren(holder, node); | 1176 _visitChildren(holder, node); |
| 1177 } finally { | 1177 } finally { |
| 1178 _inFunction = wasInFunction; | 1178 _inFunction = wasInFunction; |
| 1179 } | 1179 } |
| 1180 FunctionElementImpl element = new FunctionElementImpl.con2(node.beginToken.o
ffset); | 1180 FunctionElementImpl element = new FunctionElementImpl.con2(node.beginToken.o
ffset); |
| 1181 element.functions = holder.functions; | 1181 element.functions = holder.functions; |
| 1182 element.labels = holder.labels; | 1182 element.labels = holder.labels; |
| 1183 element.localVariables = holder.localVariables; | 1183 element.localVariables = holder.localVariables; |
| 1184 element.parameters = holder.parameters; | 1184 element.parameters = holder.parameters; |
| 1185 if (_inFunction) { | 1185 if (_inFunction) { |
| 1186 Block enclosingBlock = node.getAncestor((node) => node is Block); | 1186 Block enclosingBlock = node.getAncestor((node) => node is Block); |
| 1187 if (enclosingBlock != null) { | 1187 if (enclosingBlock != null) { |
| 1188 int functionEnd = node.offset + node.length; | 1188 int functionEnd = node.offset + node.length; |
| 1189 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 1189 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
| 1190 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 1190 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
| 1191 } | 1191 } |
| 1192 } | 1192 } |
| 1193 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); | 1193 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); |
| 1194 if (_functionTypesToFix != null) { | 1194 if (_functionTypesToFix != null) { |
| 1195 _functionTypesToFix.add(type); | 1195 _functionTypesToFix.add(type); |
| 1196 } | 1196 } |
| 1197 element.type = type; | 1197 element.type = type; |
| 1198 _currentHolder.addFunction(element); | 1198 _currentHolder.addFunction(element); |
| 1199 node.element = element; | 1199 node.element = element; |
| 1200 holder.validate(); | 1200 holder.validate(); |
| 1201 return null; | 1201 return null; |
| 1202 } | 1202 } |
| 1203 | 1203 |
| 1204 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 1204 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 1205 ElementHolder holder = new ElementHolder(); | 1205 ElementHolder holder = new ElementHolder(); |
| 1206 visitChildren(holder, node); | 1206 _visitChildren(holder, node); |
| 1207 SimpleIdentifier aliasName = node.name; | 1207 SimpleIdentifier aliasName = node.name; |
| 1208 List<ParameterElement> parameters = holder.parameters; | 1208 List<ParameterElement> parameters = holder.parameters; |
| 1209 List<TypeParameterElement> typeParameters = holder.typeParameters; | 1209 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 1210 FunctionTypeAliasElementImpl element = new FunctionTypeAliasElementImpl(alia
sName); | 1210 FunctionTypeAliasElementImpl element = new FunctionTypeAliasElementImpl(alia
sName); |
| 1211 element.parameters = parameters; | 1211 element.parameters = parameters; |
| 1212 element.typeParameters = typeParameters; | 1212 element.typeParameters = typeParameters; |
| 1213 FunctionTypeImpl type = new FunctionTypeImpl.con2(element); | 1213 FunctionTypeImpl type = new FunctionTypeImpl.con2(element); |
| 1214 type.typeArguments = createTypeParameterTypes(typeParameters); | 1214 type.typeArguments = _createTypeParameterTypes(typeParameters); |
| 1215 element.type = type; | 1215 element.type = type; |
| 1216 _currentHolder.addTypeAlias(element); | 1216 _currentHolder.addTypeAlias(element); |
| 1217 aliasName.staticElement = element; | 1217 aliasName.staticElement = element; |
| 1218 holder.validate(); | 1218 holder.validate(); |
| 1219 return null; | 1219 return null; |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 1222 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 1223 if (node.parent is! DefaultFormalParameter) { | 1223 if (node.parent is! DefaultFormalParameter) { |
| 1224 SimpleIdentifier parameterName = node.identifier; | 1224 SimpleIdentifier parameterName = node.identifier; |
| 1225 ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterNa
me); | 1225 ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterNa
me); |
| 1226 parameter.parameterKind = node.kind; | 1226 parameter.parameterKind = node.kind; |
| 1227 setParameterVisibleRange(node, parameter); | 1227 _setParameterVisibleRange(node, parameter); |
| 1228 _currentHolder.addParameter(parameter); | 1228 _currentHolder.addParameter(parameter); |
| 1229 parameterName.staticElement = parameter; | 1229 parameterName.staticElement = parameter; |
| 1230 } | 1230 } |
| 1231 // | 1231 // |
| 1232 // The children of this parameter include any parameters defined on the type
of this parameter. | 1232 // The children of this parameter include any parameters defined on the type
of this parameter. |
| 1233 // | 1233 // |
| 1234 ElementHolder holder = new ElementHolder(); | 1234 ElementHolder holder = new ElementHolder(); |
| 1235 visitChildren(holder, node); | 1235 _visitChildren(holder, node); |
| 1236 (node.element as ParameterElementImpl).parameters = holder.parameters; | 1236 (node.element as ParameterElementImpl).parameters = holder.parameters; |
| 1237 holder.validate(); | 1237 holder.validate(); |
| 1238 return null; | 1238 return null; |
| 1239 } | 1239 } |
| 1240 | 1240 |
| 1241 Object visitLabeledStatement(LabeledStatement node) { | 1241 Object visitLabeledStatement(LabeledStatement node) { |
| 1242 bool onSwitchStatement = node.statement is SwitchStatement; | 1242 bool onSwitchStatement = node.statement is SwitchStatement; |
| 1243 for (Label label in node.labels) { | 1243 for (Label label in node.labels) { |
| 1244 SimpleIdentifier labelName = label.label; | 1244 SimpleIdentifier labelName = label.label; |
| 1245 LabelElementImpl element = new LabelElementImpl(labelName, onSwitchStateme
nt, false); | 1245 LabelElementImpl element = new LabelElementImpl(labelName, onSwitchStateme
nt, false); |
| 1246 _currentHolder.addLabel(element); | 1246 _currentHolder.addLabel(element); |
| 1247 labelName.staticElement = element; | 1247 labelName.staticElement = element; |
| 1248 } | 1248 } |
| 1249 return super.visitLabeledStatement(node); | 1249 return super.visitLabeledStatement(node); |
| 1250 } | 1250 } |
| 1251 | 1251 |
| 1252 Object visitMethodDeclaration(MethodDeclaration node) { | 1252 Object visitMethodDeclaration(MethodDeclaration node) { |
| 1253 ElementHolder holder = new ElementHolder(); | 1253 ElementHolder holder = new ElementHolder(); |
| 1254 bool wasInFunction = _inFunction; | 1254 bool wasInFunction = _inFunction; |
| 1255 _inFunction = true; | 1255 _inFunction = true; |
| 1256 try { | 1256 try { |
| 1257 visitChildren(holder, node); | 1257 _visitChildren(holder, node); |
| 1258 } finally { | 1258 } finally { |
| 1259 _inFunction = wasInFunction; | 1259 _inFunction = wasInFunction; |
| 1260 } | 1260 } |
| 1261 bool isStatic = node.isStatic; | 1261 bool isStatic = node.isStatic; |
| 1262 sc.Token property = node.propertyKeyword; | 1262 sc.Token property = node.propertyKeyword; |
| 1263 if (property == null) { | 1263 if (property == null) { |
| 1264 SimpleIdentifier methodName = node.name; | 1264 SimpleIdentifier methodName = node.name; |
| 1265 String nameOfMethod = methodName.name; | 1265 String nameOfMethod = methodName.name; |
| 1266 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter
s.length == 0) { | 1266 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter
s.length == 0) { |
| 1267 nameOfMethod = "unary-"; | 1267 nameOfMethod = "unary-"; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1279 SimpleIdentifier propertyNameNode = node.name; | 1279 SimpleIdentifier propertyNameNode = node.name; |
| 1280 String propertyName = propertyNameNode.name; | 1280 String propertyName = propertyNameNode.name; |
| 1281 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldEle
mentImpl; | 1281 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldEle
mentImpl; |
| 1282 if (field == null) { | 1282 if (field == null) { |
| 1283 field = new FieldElementImpl.con2(node.name.name); | 1283 field = new FieldElementImpl.con2(node.name.name); |
| 1284 field.final2 = true; | 1284 field.final2 = true; |
| 1285 field.static = isStatic; | 1285 field.static = isStatic; |
| 1286 field.synthetic = true; | 1286 field.synthetic = true; |
| 1287 _currentHolder.addField(field); | 1287 _currentHolder.addField(field); |
| 1288 } | 1288 } |
| 1289 if (matches(property, sc.Keyword.GET)) { | 1289 if (_matches(property, sc.Keyword.GET)) { |
| 1290 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con
1(propertyNameNode); | 1290 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con
1(propertyNameNode); |
| 1291 getter.functions = holder.functions; | 1291 getter.functions = holder.functions; |
| 1292 getter.labels = holder.labels; | 1292 getter.labels = holder.labels; |
| 1293 getter.localVariables = holder.localVariables; | 1293 getter.localVariables = holder.localVariables; |
| 1294 getter.variable = field; | 1294 getter.variable = field; |
| 1295 getter.abstract = node.body is EmptyFunctionBody && node.externalKeyword
== null; | 1295 getter.abstract = node.body is EmptyFunctionBody && node.externalKeyword
== null; |
| 1296 getter.getter = true; | 1296 getter.getter = true; |
| 1297 getter.static = isStatic; | 1297 getter.static = isStatic; |
| 1298 field.getter = getter; | 1298 field.getter = getter; |
| 1299 _currentHolder.addAccessor(getter); | 1299 _currentHolder.addAccessor(getter); |
| 1300 propertyNameNode.staticElement = getter; | 1300 propertyNameNode.staticElement = getter; |
| 1301 } else { | 1301 } else { |
| 1302 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con
1(propertyNameNode); | 1302 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con
1(propertyNameNode); |
| 1303 setter.functions = holder.functions; | 1303 setter.functions = holder.functions; |
| 1304 setter.labels = holder.labels; | 1304 setter.labels = holder.labels; |
| 1305 setter.localVariables = holder.localVariables; | 1305 setter.localVariables = holder.localVariables; |
| 1306 setter.parameters = holder.parameters; | 1306 setter.parameters = holder.parameters; |
| 1307 setter.variable = field; | 1307 setter.variable = field; |
| 1308 setter.abstract = node.body is EmptyFunctionBody && !matches(node.extern
alKeyword, sc.Keyword.EXTERNAL); | 1308 setter.abstract = node.body is EmptyFunctionBody && !_matches(node.exter
nalKeyword, sc.Keyword.EXTERNAL); |
| 1309 setter.setter = true; | 1309 setter.setter = true; |
| 1310 setter.static = isStatic; | 1310 setter.static = isStatic; |
| 1311 field.setter = setter; | 1311 field.setter = setter; |
| 1312 field.final2 = false; | 1312 field.final2 = false; |
| 1313 _currentHolder.addAccessor(setter); | 1313 _currentHolder.addAccessor(setter); |
| 1314 propertyNameNode.staticElement = setter; | 1314 propertyNameNode.staticElement = setter; |
| 1315 } | 1315 } |
| 1316 } | 1316 } |
| 1317 holder.validate(); | 1317 holder.validate(); |
| 1318 return null; | 1318 return null; |
| 1319 } | 1319 } |
| 1320 | 1320 |
| 1321 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 1321 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 1322 if (node.parent is! DefaultFormalParameter) { | 1322 if (node.parent is! DefaultFormalParameter) { |
| 1323 SimpleIdentifier parameterName = node.identifier; | 1323 SimpleIdentifier parameterName = node.identifier; |
| 1324 ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterNa
me); | 1324 ParameterElementImpl parameter = new ParameterElementImpl.con1(parameterNa
me); |
| 1325 parameter.const3 = node.isConst; | 1325 parameter.const3 = node.isConst; |
| 1326 parameter.final2 = node.isFinal; | 1326 parameter.final2 = node.isFinal; |
| 1327 parameter.parameterKind = node.kind; | 1327 parameter.parameterKind = node.kind; |
| 1328 setParameterVisibleRange(node, parameter); | 1328 _setParameterVisibleRange(node, parameter); |
| 1329 _currentHolder.addParameter(parameter); | 1329 _currentHolder.addParameter(parameter); |
| 1330 parameterName.staticElement = parameter; | 1330 parameterName.staticElement = parameter; |
| 1331 } | 1331 } |
| 1332 return super.visitSimpleFormalParameter(node); | 1332 return super.visitSimpleFormalParameter(node); |
| 1333 } | 1333 } |
| 1334 | 1334 |
| 1335 Object visitSuperExpression(SuperExpression node) { | 1335 Object visitSuperExpression(SuperExpression node) { |
| 1336 _isValidMixin = false; | 1336 _isValidMixin = false; |
| 1337 return super.visitSuperExpression(node); | 1337 return super.visitSuperExpression(node); |
| 1338 } | 1338 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1362 TypeParameterElementImpl typeParameter = new TypeParameterElementImpl(parame
terName); | 1362 TypeParameterElementImpl typeParameter = new TypeParameterElementImpl(parame
terName); |
| 1363 TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typePara
meter); | 1363 TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typePara
meter); |
| 1364 typeParameter.type = typeParameterType; | 1364 typeParameter.type = typeParameterType; |
| 1365 _currentHolder.addTypeParameter(typeParameter); | 1365 _currentHolder.addTypeParameter(typeParameter); |
| 1366 parameterName.staticElement = typeParameter; | 1366 parameterName.staticElement = typeParameter; |
| 1367 return super.visitTypeParameter(node); | 1367 return super.visitTypeParameter(node); |
| 1368 } | 1368 } |
| 1369 | 1369 |
| 1370 Object visitVariableDeclaration(VariableDeclaration node) { | 1370 Object visitVariableDeclaration(VariableDeclaration node) { |
| 1371 sc.Token keyword = (node.parent as VariableDeclarationList).keyword; | 1371 sc.Token keyword = (node.parent as VariableDeclarationList).keyword; |
| 1372 bool isConst = matches(keyword, sc.Keyword.CONST); | 1372 bool isConst = _matches(keyword, sc.Keyword.CONST); |
| 1373 bool isFinal = matches(keyword, sc.Keyword.FINAL); | 1373 bool isFinal = _matches(keyword, sc.Keyword.FINAL); |
| 1374 bool hasInitializer = node.initializer != null; | 1374 bool hasInitializer = node.initializer != null; |
| 1375 VariableElementImpl element; | 1375 VariableElementImpl element; |
| 1376 if (_inFieldContext) { | 1376 if (_inFieldContext) { |
| 1377 SimpleIdentifier fieldName = node.name; | 1377 SimpleIdentifier fieldName = node.name; |
| 1378 FieldElementImpl field; | 1378 FieldElementImpl field; |
| 1379 if (isConst && hasInitializer) { | 1379 if (isConst && hasInitializer) { |
| 1380 field = new ConstFieldElementImpl(fieldName); | 1380 field = new ConstFieldElementImpl(fieldName); |
| 1381 } else { | 1381 } else { |
| 1382 field = new FieldElementImpl.con1(fieldName); | 1382 field = new FieldElementImpl.con1(fieldName); |
| 1383 } | 1383 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1412 _currentHolder.addTopLevelVariable(variable); | 1412 _currentHolder.addTopLevelVariable(variable); |
| 1413 variableName.staticElement = element; | 1413 variableName.staticElement = element; |
| 1414 } | 1414 } |
| 1415 element.const3 = isConst; | 1415 element.const3 = isConst; |
| 1416 element.final2 = isFinal; | 1416 element.final2 = isFinal; |
| 1417 if (hasInitializer) { | 1417 if (hasInitializer) { |
| 1418 ElementHolder holder = new ElementHolder(); | 1418 ElementHolder holder = new ElementHolder(); |
| 1419 bool wasInFieldContext = _inFieldContext; | 1419 bool wasInFieldContext = _inFieldContext; |
| 1420 _inFieldContext = false; | 1420 _inFieldContext = false; |
| 1421 try { | 1421 try { |
| 1422 visit(holder, node.initializer); | 1422 _visit(holder, node.initializer); |
| 1423 } finally { | 1423 } finally { |
| 1424 _inFieldContext = wasInFieldContext; | 1424 _inFieldContext = wasInFieldContext; |
| 1425 } | 1425 } |
| 1426 FunctionElementImpl initializer = new FunctionElementImpl.con2(node.initia
lizer.beginToken.offset); | 1426 FunctionElementImpl initializer = new FunctionElementImpl.con2(node.initia
lizer.beginToken.offset); |
| 1427 initializer.functions = holder.functions; | 1427 initializer.functions = holder.functions; |
| 1428 initializer.labels = holder.labels; | 1428 initializer.labels = holder.labels; |
| 1429 initializer.localVariables = holder.localVariables; | 1429 initializer.localVariables = holder.localVariables; |
| 1430 initializer.synthetic = true; | 1430 initializer.synthetic = true; |
| 1431 element.initializer = initializer; | 1431 element.initializer = initializer; |
| 1432 holder.validate(); | 1432 holder.validate(); |
| 1433 } | 1433 } |
| 1434 if (element is PropertyInducingElementImpl) { | 1434 if (element is PropertyInducingElementImpl) { |
| 1435 PropertyInducingElementImpl variable = element as PropertyInducingElementI
mpl; | 1435 PropertyInducingElementImpl variable = element as PropertyInducingElementI
mpl; |
| 1436 if (_inFieldContext) { | 1436 if (_inFieldContext) { |
| 1437 (variable as FieldElementImpl).static = matches((node.parent.parent as F
ieldDeclaration).staticKeyword, sc.Keyword.STATIC); | 1437 (variable as FieldElementImpl).static = _matches((node.parent.parent as
FieldDeclaration).staticKeyword, sc.Keyword.STATIC); |
| 1438 } | 1438 } |
| 1439 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(
variable); | 1439 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2(
variable); |
| 1440 getter.getter = true; | 1440 getter.getter = true; |
| 1441 getter.static = variable.isStatic; | 1441 getter.static = variable.isStatic; |
| 1442 _currentHolder.addAccessor(getter); | 1442 _currentHolder.addAccessor(getter); |
| 1443 variable.getter = getter; | 1443 variable.getter = getter; |
| 1444 if (!isFinal) { | 1444 if (!isFinal) { |
| 1445 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con
2(variable); | 1445 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con
2(variable); |
| 1446 setter.setter = true; | 1446 setter.setter = true; |
| 1447 setter.static = variable.isStatic; | 1447 setter.static = variable.isStatic; |
| 1448 ParameterElementImpl parameter = new ParameterElementImpl.con2("_${varia
ble.name}", variable.nameOffset); | 1448 ParameterElementImpl parameter = new ParameterElementImpl.con2("_${varia
ble.name}", variable.nameOffset); |
| 1449 parameter.synthetic = true; | 1449 parameter.synthetic = true; |
| 1450 parameter.parameterKind = ParameterKind.REQUIRED; | 1450 parameter.parameterKind = ParameterKind.REQUIRED; |
| 1451 setter.parameters = <ParameterElement> [parameter]; | 1451 setter.parameters = <ParameterElement> [parameter]; |
| 1452 _currentHolder.addAccessor(setter); | 1452 _currentHolder.addAccessor(setter); |
| 1453 variable.setter = setter; | 1453 variable.setter = setter; |
| 1454 } | 1454 } |
| 1455 } | 1455 } |
| 1456 return null; | 1456 return null; |
| 1457 } | 1457 } |
| 1458 | 1458 |
| 1459 /** | 1459 /** |
| 1460 * Build the table mapping field names to field elements for the fields define
d in the current | 1460 * Build the table mapping field names to field elements for the fields define
d in the current |
| 1461 * class. | 1461 * class. |
| 1462 * | 1462 * |
| 1463 * @param fields the field elements defined in the current class | 1463 * @param fields the field elements defined in the current class |
| 1464 */ | 1464 */ |
| 1465 void buildFieldMap(List<FieldElement> fields) { | 1465 void _buildFieldMap(List<FieldElement> fields) { |
| 1466 _fieldMap = new Map<String, FieldElement>(); | 1466 _fieldMap = new Map<String, FieldElement>(); |
| 1467 int count = fields.length; | 1467 int count = fields.length; |
| 1468 for (int i = 0; i < count; i++) { | 1468 for (int i = 0; i < count; i++) { |
| 1469 FieldElement field = fields[i]; | 1469 FieldElement field = fields[i]; |
| 1470 _fieldMap[field.name] = field; | 1470 _fieldMap[field.name] = field; |
| 1471 } | 1471 } |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 /** | 1474 /** |
| 1475 * Creates the [ConstructorElement]s array with the single default constructor
element. | 1475 * Creates the [ConstructorElement]s array with the single default constructor
element. |
| 1476 * | 1476 * |
| 1477 * @param interfaceType the interface type for which to create a default const
ructor | 1477 * @param interfaceType the interface type for which to create a default const
ructor |
| 1478 * @return the [ConstructorElement]s array with the single default constructor
element | 1478 * @return the [ConstructorElement]s array with the single default constructor
element |
| 1479 */ | 1479 */ |
| 1480 List<ConstructorElement> createDefaultConstructors(InterfaceTypeImpl interface
Type) { | 1480 List<ConstructorElement> _createDefaultConstructors(InterfaceTypeImpl interfac
eType) { |
| 1481 ConstructorElementImpl constructor = new ConstructorElementImpl.con1(null); | 1481 ConstructorElementImpl constructor = new ConstructorElementImpl.con1(null); |
| 1482 constructor.synthetic = true; | 1482 constructor.synthetic = true; |
| 1483 constructor.returnType = interfaceType; | 1483 constructor.returnType = interfaceType; |
| 1484 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor); | 1484 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor); |
| 1485 _functionTypesToFix.add(type); | 1485 _functionTypesToFix.add(type); |
| 1486 constructor.type = type; | 1486 constructor.type = type; |
| 1487 return <ConstructorElement> [constructor]; | 1487 return <ConstructorElement> [constructor]; |
| 1488 } | 1488 } |
| 1489 | 1489 |
| 1490 /** | 1490 /** |
| 1491 * Create the types associated with the given type parameters, setting the typ
e of each type | 1491 * Create the types associated with the given type parameters, setting the typ
e of each type |
| 1492 * parameter, and return an array of types corresponding to the given paramete
rs. | 1492 * parameter, and return an array of types corresponding to the given paramete
rs. |
| 1493 * | 1493 * |
| 1494 * @param typeParameters the type parameters for which types are to be created | 1494 * @param typeParameters the type parameters for which types are to be created |
| 1495 * @return an array of types corresponding to the given parameters | 1495 * @return an array of types corresponding to the given parameters |
| 1496 */ | 1496 */ |
| 1497 List<Type2> createTypeParameterTypes(List<TypeParameterElement> typeParameters
) { | 1497 List<Type2> _createTypeParameterTypes(List<TypeParameterElement> typeParameter
s) { |
| 1498 int typeParameterCount = typeParameters.length; | 1498 int typeParameterCount = typeParameters.length; |
| 1499 List<Type2> typeArguments = new List<Type2>(typeParameterCount); | 1499 List<Type2> typeArguments = new List<Type2>(typeParameterCount); |
| 1500 for (int i = 0; i < typeParameterCount; i++) { | 1500 for (int i = 0; i < typeParameterCount; i++) { |
| 1501 TypeParameterElementImpl typeParameter = typeParameters[i] as TypeParamete
rElementImpl; | 1501 TypeParameterElementImpl typeParameter = typeParameters[i] as TypeParamete
rElementImpl; |
| 1502 TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typePa
rameter); | 1502 TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typePa
rameter); |
| 1503 typeParameter.type = typeParameterType; | 1503 typeParameter.type = typeParameterType; |
| 1504 typeArguments[i] = typeParameterType; | 1504 typeArguments[i] = typeParameterType; |
| 1505 } | 1505 } |
| 1506 return typeArguments; | 1506 return typeArguments; |
| 1507 } | 1507 } |
| 1508 | 1508 |
| 1509 /** | 1509 /** |
| 1510 * Return the body of the function that contains the given parameter, or `null
` if no | 1510 * Return the body of the function that contains the given parameter, or `null
` if no |
| 1511 * function body could be found. | 1511 * function body could be found. |
| 1512 * | 1512 * |
| 1513 * @param node the parameter contained in the function whose body is to be ret
urned | 1513 * @param node the parameter contained in the function whose body is to be ret
urned |
| 1514 * @return the body of the function that contains the given parameter | 1514 * @return the body of the function that contains the given parameter |
| 1515 */ | 1515 */ |
| 1516 FunctionBody getFunctionBody(FormalParameter node) { | 1516 FunctionBody _getFunctionBody(FormalParameter node) { |
| 1517 AstNode parent = node.parent; | 1517 AstNode parent = node.parent; |
| 1518 while (parent != null) { | 1518 while (parent != null) { |
| 1519 if (parent is ConstructorDeclaration) { | 1519 if (parent is ConstructorDeclaration) { |
| 1520 return (parent as ConstructorDeclaration).body; | 1520 return (parent as ConstructorDeclaration).body; |
| 1521 } else if (parent is FunctionExpression) { | 1521 } else if (parent is FunctionExpression) { |
| 1522 return (parent as FunctionExpression).body; | 1522 return (parent as FunctionExpression).body; |
| 1523 } else if (parent is MethodDeclaration) { | 1523 } else if (parent is MethodDeclaration) { |
| 1524 return (parent as MethodDeclaration).body; | 1524 return (parent as MethodDeclaration).body; |
| 1525 } | 1525 } |
| 1526 parent = parent.parent; | 1526 parent = parent.parent; |
| 1527 } | 1527 } |
| 1528 return null; | 1528 return null; |
| 1529 } | 1529 } |
| 1530 | 1530 |
| 1531 /** | 1531 /** |
| 1532 * Return `true` if the given token is a token for the given keyword. | 1532 * Return `true` if the given token is a token for the given keyword. |
| 1533 * | 1533 * |
| 1534 * @param token the token being tested | 1534 * @param token the token being tested |
| 1535 * @param keyword the keyword being tested for | 1535 * @param keyword the keyword being tested for |
| 1536 * @return `true` if the given token is a token for the given keyword | 1536 * @return `true` if the given token is a token for the given keyword |
| 1537 */ | 1537 */ |
| 1538 bool matches(sc.Token token, sc.Keyword keyword) => token != null && identical
(token.type, sc.TokenType.KEYWORD) && identical((token as sc.KeywordToken).keywo
rd, keyword); | 1538 bool _matches(sc.Token token, sc.Keyword keyword) => token != null && identica
l(token.type, sc.TokenType.KEYWORD) && identical((token as sc.KeywordToken).keyw
ord, keyword); |
| 1539 | 1539 |
| 1540 /** | 1540 /** |
| 1541 * Sets the visible source range for formal parameter. | 1541 * Sets the visible source range for formal parameter. |
| 1542 */ | 1542 */ |
| 1543 void setParameterVisibleRange(FormalParameter node, ParameterElementImpl eleme
nt) { | 1543 void _setParameterVisibleRange(FormalParameter node, ParameterElementImpl elem
ent) { |
| 1544 FunctionBody body = getFunctionBody(node); | 1544 FunctionBody body = _getFunctionBody(node); |
| 1545 if (body != null) { | 1545 if (body != null) { |
| 1546 element.setVisibleRange(body.offset, body.length); | 1546 element.setVisibleRange(body.offset, body.length); |
| 1547 } | 1547 } |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 /** | 1550 /** |
| 1551 * Make the given holder be the current holder while visiting the given node. | 1551 * Make the given holder be the current holder while visiting the given node. |
| 1552 * | 1552 * |
| 1553 * @param holder the holder that will gather elements that are built while vis
iting the children | 1553 * @param holder the holder that will gather elements that are built while vis
iting the children |
| 1554 * @param node the node to be visited | 1554 * @param node the node to be visited |
| 1555 */ | 1555 */ |
| 1556 void visit(ElementHolder holder, AstNode node) { | 1556 void _visit(ElementHolder holder, AstNode node) { |
| 1557 if (node != null) { | 1557 if (node != null) { |
| 1558 ElementHolder previousHolder = _currentHolder; | 1558 ElementHolder previousHolder = _currentHolder; |
| 1559 _currentHolder = holder; | 1559 _currentHolder = holder; |
| 1560 try { | 1560 try { |
| 1561 node.accept(this); | 1561 node.accept(this); |
| 1562 } finally { | 1562 } finally { |
| 1563 _currentHolder = previousHolder; | 1563 _currentHolder = previousHolder; |
| 1564 } | 1564 } |
| 1565 } | 1565 } |
| 1566 } | 1566 } |
| 1567 | 1567 |
| 1568 /** | 1568 /** |
| 1569 * Make the given holder be the current holder while visiting the children of
the given node. | 1569 * Make the given holder be the current holder while visiting the children of
the given node. |
| 1570 * | 1570 * |
| 1571 * @param holder the holder that will gather elements that are built while vis
iting the children | 1571 * @param holder the holder that will gather elements that are built while vis
iting the children |
| 1572 * @param node the node whose children are to be visited | 1572 * @param node the node whose children are to be visited |
| 1573 */ | 1573 */ |
| 1574 void visitChildren(ElementHolder holder, AstNode node) { | 1574 void _visitChildren(ElementHolder holder, AstNode node) { |
| 1575 if (node != null) { | 1575 if (node != null) { |
| 1576 ElementHolder previousHolder = _currentHolder; | 1576 ElementHolder previousHolder = _currentHolder; |
| 1577 _currentHolder = holder; | 1577 _currentHolder = holder; |
| 1578 try { | 1578 try { |
| 1579 node.visitChildren(this); | 1579 node.visitChildren(this); |
| 1580 } finally { | 1580 } finally { |
| 1581 _currentHolder = previousHolder; | 1581 _currentHolder = previousHolder; |
| 1582 } | 1582 } |
| 1583 } | 1583 } |
| 1584 } | 1584 } |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 | 2026 |
| 2027 /** | 2027 /** |
| 2028 * Return an array containing information about all of the libraries that were
resolved. | 2028 * Return an array containing information about all of the libraries that were
resolved. |
| 2029 * | 2029 * |
| 2030 * @return an array containing the libraries that were resolved | 2030 * @return an array containing the libraries that were resolved |
| 2031 */ | 2031 */ |
| 2032 Set<Library> get resolvedLibraries => _resolvedLibraries; | 2032 Set<Library> get resolvedLibraries => _resolvedLibraries; |
| 2033 | 2033 |
| 2034 Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) { | 2034 Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) { |
| 2035 if (_parentNodes.contains(node)) { | 2035 if (_parentNodes.contains(node)) { |
| 2036 return reportCircularity(node); | 2036 return _reportCircularity(node); |
| 2037 } | 2037 } |
| 2038 _parentNodes.add(node); | 2038 _parentNodes.add(node); |
| 2039 try { | 2039 try { |
| 2040 Source htmlSource = _htmlElement.source; | 2040 Source htmlSource = _htmlElement.source; |
| 2041 ht.XmlAttributeNode scriptAttribute = getScriptSourcePath(node); | 2041 ht.XmlAttributeNode scriptAttribute = _getScriptSourcePath(node); |
| 2042 String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute
.text; | 2042 String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute
.text; |
| 2043 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath
== null) { | 2043 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath
== null) { |
| 2044 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl
(node); | 2044 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl
(node); |
| 2045 try { | 2045 try { |
| 2046 LibraryResolver resolver = new LibraryResolver(_context); | 2046 LibraryResolver resolver = new LibraryResolver(_context); |
| 2047 LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSourc
e, _modificationStamp, node.script, true) as LibraryElementImpl; | 2047 LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSourc
e, _modificationStamp, node.script, true) as LibraryElementImpl; |
| 2048 script.scriptLibrary = library; | 2048 script.scriptLibrary = library; |
| 2049 _resolvedLibraries.addAll(resolver.resolvedLibraries); | 2049 _resolvedLibraries.addAll(resolver.resolvedLibraries); |
| 2050 _errorListener.addAll(resolver.errorListener); | 2050 _errorListener.addAll(resolver.errorListener); |
| 2051 } on AnalysisException catch (exception) { | 2051 } on AnalysisException catch (exception) { |
| 2052 //TODO (danrubel): Handle or forward the exception | 2052 //TODO (danrubel): Handle or forward the exception |
| 2053 AnalysisEngine.instance.logger.logError2("Could not resolve script tag
", exception); | 2053 AnalysisEngine.instance.logger.logError2("Could not resolve script tag
", exception); |
| 2054 } | 2054 } |
| 2055 node.scriptElement = script; | 2055 node.scriptElement = script; |
| 2056 _scripts.add(script); | 2056 _scripts.add(script); |
| 2057 } else { | 2057 } else { |
| 2058 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl
(node); | 2058 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl
(node); |
| 2059 if (scriptSourcePath != null) { | 2059 if (scriptSourcePath != null) { |
| 2060 try { | 2060 try { |
| 2061 scriptSourcePath = Uri.encodeFull(scriptSourcePath); | 2061 scriptSourcePath = Uri.encodeFull(scriptSourcePath); |
| 2062 // Force an exception to be thrown if the URI is invalid so that we
can report the | 2062 // Force an exception to be thrown if the URI is invalid so that we
can report the |
| 2063 // problem. | 2063 // problem. |
| 2064 parseUriWithException(scriptSourcePath); | 2064 parseUriWithException(scriptSourcePath); |
| 2065 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource,
scriptSourcePath); | 2065 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource,
scriptSourcePath); |
| 2066 script.scriptSource = scriptSource; | 2066 script.scriptSource = scriptSource; |
| 2067 if (!_context.exists(scriptSource)) { | 2067 if (!_context.exists(scriptSource)) { |
| 2068 reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribu
te, [scriptSourcePath]); | 2068 _reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttrib
ute, [scriptSourcePath]); |
| 2069 } | 2069 } |
| 2070 } on URISyntaxException catch (exception) { | 2070 } on URISyntaxException catch (exception) { |
| 2071 reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scri
ptSourcePath]); | 2071 _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [scr
iptSourcePath]); |
| 2072 } | 2072 } |
| 2073 } | 2073 } |
| 2074 node.scriptElement = script; | 2074 node.scriptElement = script; |
| 2075 _scripts.add(script); | 2075 _scripts.add(script); |
| 2076 } | 2076 } |
| 2077 } finally { | 2077 } finally { |
| 2078 _parentNodes.remove(node); | 2078 _parentNodes.remove(node); |
| 2079 } | 2079 } |
| 2080 return null; | 2080 return null; |
| 2081 } | 2081 } |
| 2082 | 2082 |
| 2083 Object visitHtmlUnit(ht.HtmlUnit node) { | 2083 Object visitHtmlUnit(ht.HtmlUnit node) { |
| 2084 _parentNodes = new List<ht.XmlTagNode>(); | 2084 _parentNodes = new List<ht.XmlTagNode>(); |
| 2085 _scripts = new List<HtmlScriptElement>(); | 2085 _scripts = new List<HtmlScriptElement>(); |
| 2086 try { | 2086 try { |
| 2087 node.visitChildren(this); | 2087 node.visitChildren(this); |
| 2088 _htmlElement.scripts = new List.from(_scripts); | 2088 _htmlElement.scripts = new List.from(_scripts); |
| 2089 } finally { | 2089 } finally { |
| 2090 _scripts = null; | 2090 _scripts = null; |
| 2091 _parentNodes = null; | 2091 _parentNodes = null; |
| 2092 } | 2092 } |
| 2093 return null; | 2093 return null; |
| 2094 } | 2094 } |
| 2095 | 2095 |
| 2096 Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null; | 2096 Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null; |
| 2097 | 2097 |
| 2098 Object visitXmlTagNode(ht.XmlTagNode node) { | 2098 Object visitXmlTagNode(ht.XmlTagNode node) { |
| 2099 if (_parentNodes.contains(node)) { | 2099 if (_parentNodes.contains(node)) { |
| 2100 return reportCircularity(node); | 2100 return _reportCircularity(node); |
| 2101 } | 2101 } |
| 2102 _parentNodes.add(node); | 2102 _parentNodes.add(node); |
| 2103 try { | 2103 try { |
| 2104 node.visitChildren(this); | 2104 node.visitChildren(this); |
| 2105 } finally { | 2105 } finally { |
| 2106 _parentNodes.remove(node); | 2106 _parentNodes.remove(node); |
| 2107 } | 2107 } |
| 2108 return null; | 2108 return null; |
| 2109 } | 2109 } |
| 2110 | 2110 |
| 2111 /** | 2111 /** |
| 2112 * Return the first source attribute for the given tag node, or `null` if it d
oes not exist. | 2112 * Return the first source attribute for the given tag node, or `null` if it d
oes not exist. |
| 2113 * | 2113 * |
| 2114 * @param node the node containing attributes | 2114 * @param node the node containing attributes |
| 2115 * @return the source attribute contained in the given tag | 2115 * @return the source attribute contained in the given tag |
| 2116 */ | 2116 */ |
| 2117 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) { | 2117 ht.XmlAttributeNode _getScriptSourcePath(ht.XmlTagNode node) { |
| 2118 for (ht.XmlAttributeNode attribute in node.attributes) { | 2118 for (ht.XmlAttributeNode attribute in node.attributes) { |
| 2119 if (attribute.name == _SRC) { | 2119 if (attribute.name == _SRC) { |
| 2120 return attribute; | 2120 return attribute; |
| 2121 } | 2121 } |
| 2122 } | 2122 } |
| 2123 return null; | 2123 return null; |
| 2124 } | 2124 } |
| 2125 | 2125 |
| 2126 Object reportCircularity(ht.XmlTagNode node) { | 2126 Object _reportCircularity(ht.XmlTagNode node) { |
| 2127 // | 2127 // |
| 2128 // This should not be possible, but we have an error report that suggests th
at it happened at | 2128 // This should not be possible, but we have an error report that suggests th
at it happened at |
| 2129 // least once. This code will guard against infinite recursion and might hel
p us identify the | 2129 // least once. This code will guard against infinite recursion and might hel
p us identify the |
| 2130 // cause of the issue. | 2130 // cause of the issue. |
| 2131 // | 2131 // |
| 2132 JavaStringBuilder builder = new JavaStringBuilder(); | 2132 JavaStringBuilder builder = new JavaStringBuilder(); |
| 2133 builder.append("Found circularity in XML nodes: "); | 2133 builder.append("Found circularity in XML nodes: "); |
| 2134 bool first = true; | 2134 bool first = true; |
| 2135 for (ht.XmlTagNode pathNode in _parentNodes) { | 2135 for (ht.XmlTagNode pathNode in _parentNodes) { |
| 2136 if (first) { | 2136 if (first) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2153 | 2153 |
| 2154 /** | 2154 /** |
| 2155 * Report an error with the given error code at the given location. Use the gi
ven arguments to | 2155 * Report an error with the given error code at the given location. Use the gi
ven arguments to |
| 2156 * compose the error message. | 2156 * compose the error message. |
| 2157 * | 2157 * |
| 2158 * @param errorCode the error code of the error to be reported | 2158 * @param errorCode the error code of the error to be reported |
| 2159 * @param offset the offset of the first character to be highlighted | 2159 * @param offset the offset of the first character to be highlighted |
| 2160 * @param length the number of characters to be highlighted | 2160 * @param length the number of characters to be highlighted |
| 2161 * @param arguments the arguments used to compose the error message | 2161 * @param arguments the arguments used to compose the error message |
| 2162 */ | 2162 */ |
| 2163 void reportErrorForOffset(ErrorCode errorCode, int offset, int length, List<Ob
ject> arguments) { | 2163 void _reportErrorForOffset(ErrorCode errorCode, int offset, int length, List<O
bject> arguments) { |
| 2164 _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, l
ength, errorCode, arguments)); | 2164 _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, l
ength, errorCode, arguments)); |
| 2165 } | 2165 } |
| 2166 | 2166 |
| 2167 /** | 2167 /** |
| 2168 * Report an error with the given error code at the location of the value of t
he given attribute. | 2168 * Report an error with the given error code at the location of the value of t
he given attribute. |
| 2169 * Use the given arguments to compose the error message. | 2169 * Use the given arguments to compose the error message. |
| 2170 * | 2170 * |
| 2171 * @param errorCode the error code of the error to be reported | 2171 * @param errorCode the error code of the error to be reported |
| 2172 * @param offset the offset of the first character to be highlighted | 2172 * @param offset the offset of the first character to be highlighted |
| 2173 * @param length the number of characters to be highlighted | 2173 * @param length the number of characters to be highlighted |
| 2174 * @param arguments the arguments used to compose the error message | 2174 * @param arguments the arguments used to compose the error message |
| 2175 */ | 2175 */ |
| 2176 void reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, List
<Object> arguments) { | 2176 void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute, Lis
t<Object> arguments) { |
| 2177 int offset = attribute.valueToken.offset + 1; | 2177 int offset = attribute.valueToken.offset + 1; |
| 2178 int length = attribute.valueToken.length - 2; | 2178 int length = attribute.valueToken.length - 2; |
| 2179 reportErrorForOffset(errorCode, offset, length, arguments); | 2179 _reportErrorForOffset(errorCode, offset, length, arguments); |
| 2180 } | 2180 } |
| 2181 } | 2181 } |
| 2182 | 2182 |
| 2183 /** | 2183 /** |
| 2184 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for | 2184 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for |
| 2185 * violations of Dart best practices. | 2185 * violations of Dart best practices. |
| 2186 */ | 2186 */ |
| 2187 class BestPracticesVerifier extends RecursiveAstVisitor<Object> { | 2187 class BestPracticesVerifier extends RecursiveAstVisitor<Object> { |
| 2188 static String _GETTER = "getter"; | 2188 static String _GETTER = "getter"; |
| 2189 | 2189 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2201 * Given a parenthesized expression, this returns the parent (or recursively g
rand-parent) of the | 2201 * Given a parenthesized expression, this returns the parent (or recursively g
rand-parent) of the |
| 2202 * expression that is a parenthesized expression, but whose parent is not a pa
renthesized | 2202 * expression that is a parenthesized expression, but whose parent is not a pa
renthesized |
| 2203 * expression. | 2203 * expression. |
| 2204 * | 2204 * |
| 2205 * For example given the code `(((e)))`: `(e) -> (((e)))`. | 2205 * For example given the code `(((e)))`: `(e) -> (((e)))`. |
| 2206 * | 2206 * |
| 2207 * @param parenthesizedExpression some expression whose parent is a parenthesi
zed expression | 2207 * @param parenthesizedExpression some expression whose parent is a parenthesi
zed expression |
| 2208 * @return the first parent or grand-parent that is a parenthesized expression
, that does not have | 2208 * @return the first parent or grand-parent that is a parenthesized expression
, that does not have |
| 2209 * a parenthesized expression parent | 2209 * a parenthesized expression parent |
| 2210 */ | 2210 */ |
| 2211 static ParenthesizedExpression wrapParenthesizedExpression(ParenthesizedExpres
sion parenthesizedExpression) { | 2211 static ParenthesizedExpression _wrapParenthesizedExpression(ParenthesizedExpre
ssion parenthesizedExpression) { |
| 2212 if (parenthesizedExpression.parent is ParenthesizedExpression) { | 2212 if (parenthesizedExpression.parent is ParenthesizedExpression) { |
| 2213 return wrapParenthesizedExpression(parenthesizedExpression.parent as Paren
thesizedExpression); | 2213 return _wrapParenthesizedExpression(parenthesizedExpression.parent as Pare
nthesizedExpression); |
| 2214 } | 2214 } |
| 2215 return parenthesizedExpression; | 2215 return parenthesizedExpression; |
| 2216 } | 2216 } |
| 2217 | 2217 |
| 2218 /** | 2218 /** |
| 2219 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of | 2219 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of |
| 2220 * a class. | 2220 * a class. |
| 2221 */ | 2221 */ |
| 2222 ClassElement _enclosingClass; | 2222 ClassElement _enclosingClass; |
| 2223 | 2223 |
| 2224 /** | 2224 /** |
| 2225 * The error reporter by which errors will be reported. | 2225 * The error reporter by which errors will be reported. |
| 2226 */ | 2226 */ |
| 2227 ErrorReporter _errorReporter; | 2227 ErrorReporter _errorReporter; |
| 2228 | 2228 |
| 2229 /** | 2229 /** |
| 2230 * Create a new instance of the [BestPracticesVerifier]. | 2230 * Create a new instance of the [BestPracticesVerifier]. |
| 2231 * | 2231 * |
| 2232 * @param errorReporter the error reporter | 2232 * @param errorReporter the error reporter |
| 2233 */ | 2233 */ |
| 2234 BestPracticesVerifier(ErrorReporter errorReporter) { | 2234 BestPracticesVerifier(ErrorReporter errorReporter) { |
| 2235 this._errorReporter = errorReporter; | 2235 this._errorReporter = errorReporter; |
| 2236 } | 2236 } |
| 2237 | 2237 |
| 2238 Object visitAsExpression(AsExpression node) { | 2238 Object visitAsExpression(AsExpression node) { |
| 2239 checkForUnnecessaryCast(node); | 2239 _checkForUnnecessaryCast(node); |
| 2240 return super.visitAsExpression(node); | 2240 return super.visitAsExpression(node); |
| 2241 } | 2241 } |
| 2242 | 2242 |
| 2243 Object visitAssignmentExpression(AssignmentExpression node) { | 2243 Object visitAssignmentExpression(AssignmentExpression node) { |
| 2244 sc.TokenType operatorType = node.operator.type; | 2244 sc.TokenType operatorType = node.operator.type; |
| 2245 if (operatorType != sc.TokenType.EQ) { | 2245 if (operatorType != sc.TokenType.EQ) { |
| 2246 checkForDeprecatedMemberUse(node.bestElement, node); | 2246 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 2247 } else { | 2247 } else { |
| 2248 checkForUseOfVoidResult(node.rightHandSide); | 2248 _checkForUseOfVoidResult(node.rightHandSide); |
| 2249 } | 2249 } |
| 2250 return super.visitAssignmentExpression(node); | 2250 return super.visitAssignmentExpression(node); |
| 2251 } | 2251 } |
| 2252 | 2252 |
| 2253 Object visitBinaryExpression(BinaryExpression node) { | 2253 Object visitBinaryExpression(BinaryExpression node) { |
| 2254 checkForDivisionOptimizationHint(node); | 2254 _checkForDivisionOptimizationHint(node); |
| 2255 checkForDeprecatedMemberUse(node.bestElement, node); | 2255 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 2256 return super.visitBinaryExpression(node); | 2256 return super.visitBinaryExpression(node); |
| 2257 } | 2257 } |
| 2258 | 2258 |
| 2259 Object visitClassDeclaration(ClassDeclaration node) { | 2259 Object visitClassDeclaration(ClassDeclaration node) { |
| 2260 ClassElement outerClass = _enclosingClass; | 2260 ClassElement outerClass = _enclosingClass; |
| 2261 try { | 2261 try { |
| 2262 _enclosingClass = node.element; | 2262 _enclosingClass = node.element; |
| 2263 // Commented out until we decide that we want this hint in the analyzer | 2263 // Commented out until we decide that we want this hint in the analyzer |
| 2264 // checkForOverrideEqualsButNotHashCode(node); | 2264 // checkForOverrideEqualsButNotHashCode(node); |
| 2265 return super.visitClassDeclaration(node); | 2265 return super.visitClassDeclaration(node); |
| 2266 } finally { | 2266 } finally { |
| 2267 _enclosingClass = outerClass; | 2267 _enclosingClass = outerClass; |
| 2268 } | 2268 } |
| 2269 } | 2269 } |
| 2270 | 2270 |
| 2271 Object visitExportDirective(ExportDirective node) { | 2271 Object visitExportDirective(ExportDirective node) { |
| 2272 checkForDeprecatedMemberUse(node.uriElement, node); | 2272 _checkForDeprecatedMemberUse(node.uriElement, node); |
| 2273 return super.visitExportDirective(node); | 2273 return super.visitExportDirective(node); |
| 2274 } | 2274 } |
| 2275 | 2275 |
| 2276 Object visitFunctionDeclaration(FunctionDeclaration node) { | 2276 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 2277 checkForMissingReturn(node.returnType, node.functionExpression.body); | 2277 _checkForMissingReturn(node.returnType, node.functionExpression.body); |
| 2278 return super.visitFunctionDeclaration(node); | 2278 return super.visitFunctionDeclaration(node); |
| 2279 } | 2279 } |
| 2280 | 2280 |
| 2281 Object visitImportDirective(ImportDirective node) { | 2281 Object visitImportDirective(ImportDirective node) { |
| 2282 checkForDeprecatedMemberUse(node.uriElement, node); | 2282 _checkForDeprecatedMemberUse(node.uriElement, node); |
| 2283 return super.visitImportDirective(node); | 2283 return super.visitImportDirective(node); |
| 2284 } | 2284 } |
| 2285 | 2285 |
| 2286 Object visitIndexExpression(IndexExpression node) { | 2286 Object visitIndexExpression(IndexExpression node) { |
| 2287 checkForDeprecatedMemberUse(node.bestElement, node); | 2287 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 2288 return super.visitIndexExpression(node); | 2288 return super.visitIndexExpression(node); |
| 2289 } | 2289 } |
| 2290 | 2290 |
| 2291 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 2291 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 2292 checkForDeprecatedMemberUse(node.staticElement, node); | 2292 _checkForDeprecatedMemberUse(node.staticElement, node); |
| 2293 return super.visitInstanceCreationExpression(node); | 2293 return super.visitInstanceCreationExpression(node); |
| 2294 } | 2294 } |
| 2295 | 2295 |
| 2296 Object visitIsExpression(IsExpression node) { | 2296 Object visitIsExpression(IsExpression node) { |
| 2297 checkAllTypeChecks(node); | 2297 _checkAllTypeChecks(node); |
| 2298 return super.visitIsExpression(node); | 2298 return super.visitIsExpression(node); |
| 2299 } | 2299 } |
| 2300 | 2300 |
| 2301 Object visitMethodDeclaration(MethodDeclaration node) { | 2301 Object visitMethodDeclaration(MethodDeclaration node) { |
| 2302 // This was determined to not be a good hint, see: dartbug.com/16029 | 2302 // This was determined to not be a good hint, see: dartbug.com/16029 |
| 2303 //checkForOverridingPrivateMember(node); | 2303 //checkForOverridingPrivateMember(node); |
| 2304 checkForMissingReturn(node.returnType, node.body); | 2304 _checkForMissingReturn(node.returnType, node.body); |
| 2305 return super.visitMethodDeclaration(node); | 2305 return super.visitMethodDeclaration(node); |
| 2306 } | 2306 } |
| 2307 | 2307 |
| 2308 Object visitPostfixExpression(PostfixExpression node) { | 2308 Object visitPostfixExpression(PostfixExpression node) { |
| 2309 checkForDeprecatedMemberUse(node.bestElement, node); | 2309 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 2310 return super.visitPostfixExpression(node); | 2310 return super.visitPostfixExpression(node); |
| 2311 } | 2311 } |
| 2312 | 2312 |
| 2313 Object visitPrefixExpression(PrefixExpression node) { | 2313 Object visitPrefixExpression(PrefixExpression node) { |
| 2314 checkForDeprecatedMemberUse(node.bestElement, node); | 2314 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 2315 return super.visitPrefixExpression(node); | 2315 return super.visitPrefixExpression(node); |
| 2316 } | 2316 } |
| 2317 | 2317 |
| 2318 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { | 2318 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { |
| 2319 checkForDeprecatedMemberUse(node.staticElement, node); | 2319 _checkForDeprecatedMemberUse(node.staticElement, node); |
| 2320 return super.visitRedirectingConstructorInvocation(node); | 2320 return super.visitRedirectingConstructorInvocation(node); |
| 2321 } | 2321 } |
| 2322 | 2322 |
| 2323 Object visitSimpleIdentifier(SimpleIdentifier node) { | 2323 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 2324 checkForDeprecatedMemberUseAtIdentifier(node); | 2324 _checkForDeprecatedMemberUseAtIdentifier(node); |
| 2325 return super.visitSimpleIdentifier(node); | 2325 return super.visitSimpleIdentifier(node); |
| 2326 } | 2326 } |
| 2327 | 2327 |
| 2328 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 2328 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 2329 checkForDeprecatedMemberUse(node.staticElement, node); | 2329 _checkForDeprecatedMemberUse(node.staticElement, node); |
| 2330 return super.visitSuperConstructorInvocation(node); | 2330 return super.visitSuperConstructorInvocation(node); |
| 2331 } | 2331 } |
| 2332 | 2332 |
| 2333 Object visitVariableDeclaration(VariableDeclaration node) { | 2333 Object visitVariableDeclaration(VariableDeclaration node) { |
| 2334 checkForUseOfVoidResult(node.initializer); | 2334 _checkForUseOfVoidResult(node.initializer); |
| 2335 return super.visitVariableDeclaration(node); | 2335 return super.visitVariableDeclaration(node); |
| 2336 } | 2336 } |
| 2337 | 2337 |
| 2338 /** | 2338 /** |
| 2339 * Check for the passed is expression for the unnecessary type check hint code
s as well as null | 2339 * Check for the passed is expression for the unnecessary type check hint code
s as well as null |
| 2340 * checks expressed using an is expression. | 2340 * checks expressed using an is expression. |
| 2341 * | 2341 * |
| 2342 * @param node the is expression to check | 2342 * @param node the is expression to check |
| 2343 * @return `true` if and only if a hint code is generated on the passed node | 2343 * @return `true` if and only if a hint code is generated on the passed node |
| 2344 * @see HintCode#TYPE_CHECK_IS_NOT_NULL | 2344 * @see HintCode#TYPE_CHECK_IS_NOT_NULL |
| 2345 * @see HintCode#TYPE_CHECK_IS_NULL | 2345 * @see HintCode#TYPE_CHECK_IS_NULL |
| 2346 * @see HintCode#UNNECESSARY_TYPE_CHECK_TRUE | 2346 * @see HintCode#UNNECESSARY_TYPE_CHECK_TRUE |
| 2347 * @see HintCode#UNNECESSARY_TYPE_CHECK_FALSE | 2347 * @see HintCode#UNNECESSARY_TYPE_CHECK_FALSE |
| 2348 */ | 2348 */ |
| 2349 bool checkAllTypeChecks(IsExpression node) { | 2349 bool _checkAllTypeChecks(IsExpression node) { |
| 2350 Expression expression = node.expression; | 2350 Expression expression = node.expression; |
| 2351 TypeName typeName = node.type; | 2351 TypeName typeName = node.type; |
| 2352 Type2 lhsType = expression.staticType; | 2352 Type2 lhsType = expression.staticType; |
| 2353 Type2 rhsType = typeName.type; | 2353 Type2 rhsType = typeName.type; |
| 2354 if (lhsType == null || rhsType == null) { | 2354 if (lhsType == null || rhsType == null) { |
| 2355 return false; | 2355 return false; |
| 2356 } | 2356 } |
| 2357 String rhsNameStr = typeName.name.name; | 2357 String rhsNameStr = typeName.name.name; |
| 2358 // if x is dynamic | 2358 // if x is dynamic |
| 2359 if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) { | 2359 if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2395 | 2395 |
| 2396 /** | 2396 /** |
| 2397 * Given some [Element], look at the associated metadata and report the use of
the member if | 2397 * Given some [Element], look at the associated metadata and report the use of
the member if |
| 2398 * it is declared as deprecated. | 2398 * it is declared as deprecated. |
| 2399 * | 2399 * |
| 2400 * @param element some element to check for deprecated use of | 2400 * @param element some element to check for deprecated use of |
| 2401 * @param node the node use for the location of the error | 2401 * @param node the node use for the location of the error |
| 2402 * @return `true` if and only if a hint code is generated on the passed node | 2402 * @return `true` if and only if a hint code is generated on the passed node |
| 2403 * @see HintCode#DEPRECATED_MEMBER_USE | 2403 * @see HintCode#DEPRECATED_MEMBER_USE |
| 2404 */ | 2404 */ |
| 2405 bool checkForDeprecatedMemberUse(Element element, AstNode node) { | 2405 bool _checkForDeprecatedMemberUse(Element element, AstNode node) { |
| 2406 if (element != null && element.isDeprecated) { | 2406 if (element != null && element.isDeprecated) { |
| 2407 String displayName = element.displayName; | 2407 String displayName = element.displayName; |
| 2408 if (element is ConstructorElement) { | 2408 if (element is ConstructorElement) { |
| 2409 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), or
have the logic | 2409 // TODO(jwren) We should modify ConstructorElement.getDisplayName(), or
have the logic |
| 2410 // centralized elsewhere, instead of doing this logic here. | 2410 // centralized elsewhere, instead of doing this logic here. |
| 2411 ConstructorElement constructorElement = element; | 2411 ConstructorElement constructorElement = element; |
| 2412 displayName = constructorElement.enclosingElement.displayName; | 2412 displayName = constructorElement.enclosingElement.displayName; |
| 2413 if (!constructorElement.displayName.isEmpty) { | 2413 if (!constructorElement.displayName.isEmpty) { |
| 2414 displayName = "${displayName}.${constructorElement.displayName}"; | 2414 displayName = "${displayName}.${constructorElement.displayName}"; |
| 2415 } | 2415 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2427 * Also, if the identifier is a constructor name in a constructor invocation,
then calls to the | 2427 * Also, if the identifier is a constructor name in a constructor invocation,
then calls to the |
| 2428 * deprecated constructor will be caught by | 2428 * deprecated constructor will be caught by |
| 2429 * [visitInstanceCreationExpression] and | 2429 * [visitInstanceCreationExpression] and |
| 2430 * [visitSuperConstructorInvocation], and can be ignored by | 2430 * [visitSuperConstructorInvocation], and can be ignored by |
| 2431 * this visit method. | 2431 * this visit method. |
| 2432 * | 2432 * |
| 2433 * @param identifier some simple identifier to check for deprecated use of | 2433 * @param identifier some simple identifier to check for deprecated use of |
| 2434 * @return `true` if and only if a hint code is generated on the passed node | 2434 * @return `true` if and only if a hint code is generated on the passed node |
| 2435 * @see HintCode#DEPRECATED_MEMBER_USE | 2435 * @see HintCode#DEPRECATED_MEMBER_USE |
| 2436 */ | 2436 */ |
| 2437 bool checkForDeprecatedMemberUseAtIdentifier(SimpleIdentifier identifier) { | 2437 bool _checkForDeprecatedMemberUseAtIdentifier(SimpleIdentifier identifier) { |
| 2438 if (identifier.inDeclarationContext()) { | 2438 if (identifier.inDeclarationContext()) { |
| 2439 return false; | 2439 return false; |
| 2440 } | 2440 } |
| 2441 AstNode parent = identifier.parent; | 2441 AstNode parent = identifier.parent; |
| 2442 if ((parent is ConstructorName && identical(identifier, parent.name)) || (pa
rent is SuperConstructorInvocation && identical(identifier, parent.constructorNa
me)) || parent is HideCombinator) { | 2442 if ((parent is ConstructorName && identical(identifier, parent.name)) || (pa
rent is SuperConstructorInvocation && identical(identifier, parent.constructorNa
me)) || parent is HideCombinator) { |
| 2443 return false; | 2443 return false; |
| 2444 } | 2444 } |
| 2445 return checkForDeprecatedMemberUse(identifier.bestElement, identifier); | 2445 return _checkForDeprecatedMemberUse(identifier.bestElement, identifier); |
| 2446 } | 2446 } |
| 2447 | 2447 |
| 2448 /** | 2448 /** |
| 2449 * Check for the passed binary expression for the [HintCode#DIVISION_OPTIMIZAT
ION]. | 2449 * Check for the passed binary expression for the [HintCode#DIVISION_OPTIMIZAT
ION]. |
| 2450 * | 2450 * |
| 2451 * @param node the binary expression to check | 2451 * @param node the binary expression to check |
| 2452 * @return `true` if and only if a hint code is generated on the passed node | 2452 * @return `true` if and only if a hint code is generated on the passed node |
| 2453 * @see HintCode#DIVISION_OPTIMIZATION | 2453 * @see HintCode#DIVISION_OPTIMIZATION |
| 2454 */ | 2454 */ |
| 2455 bool checkForDivisionOptimizationHint(BinaryExpression node) { | 2455 bool _checkForDivisionOptimizationHint(BinaryExpression node) { |
| 2456 // Return if the operator is not '/' | 2456 // Return if the operator is not '/' |
| 2457 if (node.operator.type != sc.TokenType.SLASH) { | 2457 if (node.operator.type != sc.TokenType.SLASH) { |
| 2458 return false; | 2458 return false; |
| 2459 } | 2459 } |
| 2460 // Return if the '/' operator is not defined in core, or if we don't know it
s static or propagated type | 2460 // Return if the '/' operator is not defined in core, or if we don't know it
s static or propagated type |
| 2461 MethodElement methodElement = node.bestElement; | 2461 MethodElement methodElement = node.bestElement; |
| 2462 if (methodElement == null) { | 2462 if (methodElement == null) { |
| 2463 return false; | 2463 return false; |
| 2464 } | 2464 } |
| 2465 LibraryElement libraryElement = methodElement.library; | 2465 LibraryElement libraryElement = methodElement.library; |
| 2466 if (libraryElement != null && !libraryElement.isDartCore) { | 2466 if (libraryElement != null && !libraryElement.isDartCore) { |
| 2467 return false; | 2467 return false; |
| 2468 } | 2468 } |
| 2469 // Report error if the (x/y) has toInt() invoked on it | 2469 // Report error if the (x/y) has toInt() invoked on it |
| 2470 if (node.parent is ParenthesizedExpression) { | 2470 if (node.parent is ParenthesizedExpression) { |
| 2471 ParenthesizedExpression parenthesizedExpression = wrapParenthesizedExpress
ion(node.parent as ParenthesizedExpression); | 2471 ParenthesizedExpression parenthesizedExpression = _wrapParenthesizedExpres
sion(node.parent as ParenthesizedExpression); |
| 2472 if (parenthesizedExpression.parent is MethodInvocation) { | 2472 if (parenthesizedExpression.parent is MethodInvocation) { |
| 2473 MethodInvocation methodInvocation = parenthesizedExpression.parent as Me
thodInvocation; | 2473 MethodInvocation methodInvocation = parenthesizedExpression.parent as Me
thodInvocation; |
| 2474 if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && methodInv
ocation.argumentList.arguments.isEmpty) { | 2474 if (_TO_INT_METHOD_NAME == methodInvocation.methodName.name && methodInv
ocation.argumentList.arguments.isEmpty) { |
| 2475 _errorReporter.reportErrorForNode(HintCode.DIVISION_OPTIMIZATION, meth
odInvocation, []); | 2475 _errorReporter.reportErrorForNode(HintCode.DIVISION_OPTIMIZATION, meth
odInvocation, []); |
| 2476 return true; | 2476 return true; |
| 2477 } | 2477 } |
| 2478 } | 2478 } |
| 2479 } | 2479 } |
| 2480 return false; | 2480 return false; |
| 2481 } | 2481 } |
| 2482 | 2482 |
| 2483 /** | 2483 /** |
| 2484 * Generate a hint for functions or methods that have a return type, but do no
t have a return | 2484 * Generate a hint for functions or methods that have a return type, but do no
t have a return |
| 2485 * statement on all branches. At the end of blocks with no return, Dart implic
itly returns | 2485 * statement on all branches. At the end of blocks with no return, Dart implic
itly returns |
| 2486 * `null`, avoiding these implicit returns is considered a best practice. | 2486 * `null`, avoiding these implicit returns is considered a best practice. |
| 2487 * | 2487 * |
| 2488 * @param node the binary expression to check | 2488 * @param node the binary expression to check |
| 2489 * @param body the function body | 2489 * @param body the function body |
| 2490 * @return `true` if and only if a hint code is generated on the passed node | 2490 * @return `true` if and only if a hint code is generated on the passed node |
| 2491 * @see HintCode#MISSING_RETURN | 2491 * @see HintCode#MISSING_RETURN |
| 2492 */ | 2492 */ |
| 2493 bool checkForMissingReturn(TypeName returnType, FunctionBody body) { | 2493 bool _checkForMissingReturn(TypeName returnType, FunctionBody body) { |
| 2494 // Check that the method or function has a return type, and a function body | 2494 // Check that the method or function has a return type, and a function body |
| 2495 if (returnType == null || body == null) { | 2495 if (returnType == null || body == null) { |
| 2496 return false; | 2496 return false; |
| 2497 } | 2497 } |
| 2498 // Check that the body is a BlockFunctionBody | 2498 // Check that the body is a BlockFunctionBody |
| 2499 if (body is! BlockFunctionBody) { | 2499 if (body is! BlockFunctionBody) { |
| 2500 return false; | 2500 return false; |
| 2501 } | 2501 } |
| 2502 // Check that the type is resolvable, and is not "void" | 2502 // Check that the type is resolvable, and is not "void" |
| 2503 Type2 returnTypeType = returnType.type; | 2503 Type2 returnTypeType = returnType.type; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2514 } | 2514 } |
| 2515 | 2515 |
| 2516 /** | 2516 /** |
| 2517 * Check for the passed class declaration for the | 2517 * Check for the passed class declaration for the |
| 2518 * [HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code. | 2518 * [HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code. |
| 2519 * | 2519 * |
| 2520 * @param node the class declaration to check | 2520 * @param node the class declaration to check |
| 2521 * @return `true` if and only if a hint code is generated on the passed node | 2521 * @return `true` if and only if a hint code is generated on the passed node |
| 2522 * @see HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE | 2522 * @see HintCode#OVERRIDE_EQUALS_BUT_NOT_HASH_CODE |
| 2523 */ | 2523 */ |
| 2524 bool checkForOverrideEqualsButNotHashCode(ClassDeclaration node) { | 2524 bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) { |
| 2525 ClassElement classElement = node.element; | 2525 ClassElement classElement = node.element; |
| 2526 if (classElement == null) { | 2526 if (classElement == null) { |
| 2527 return false; | 2527 return false; |
| 2528 } | 2528 } |
| 2529 MethodElement equalsOperatorMethodElement = classElement.getMethod(sc.TokenT
ype.EQ_EQ.lexeme); | 2529 MethodElement equalsOperatorMethodElement = classElement.getMethod(sc.TokenT
ype.EQ_EQ.lexeme); |
| 2530 if (equalsOperatorMethodElement != null) { | 2530 if (equalsOperatorMethodElement != null) { |
| 2531 PropertyAccessorElement hashCodeElement = classElement.getGetter(_HASHCODE
_GETTER_NAME); | 2531 PropertyAccessorElement hashCodeElement = classElement.getGetter(_HASHCODE
_GETTER_NAME); |
| 2532 if (hashCodeElement == null) { | 2532 if (hashCodeElement == null) { |
| 2533 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_
CODE, node.name, [classElement.displayName]); | 2533 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_
CODE, node.name, [classElement.displayName]); |
| 2534 return true; | 2534 return true; |
| 2535 } | 2535 } |
| 2536 } | 2536 } |
| 2537 return false; | 2537 return false; |
| 2538 } | 2538 } |
| 2539 | 2539 |
| 2540 /** | 2540 /** |
| 2541 * Checks that if the passed method declaration is private, it does not overri
de a private member | 2541 * Checks that if the passed method declaration is private, it does not overri
de a private member |
| 2542 * in a superclass. | 2542 * in a superclass. |
| 2543 * | 2543 * |
| 2544 * @param node the method declaration to check | 2544 * @param node the method declaration to check |
| 2545 * @return `true` if and only if a hint code is generated on the passed node | 2545 * @return `true` if and only if a hint code is generated on the passed node |
| 2546 * @see HintCode#OVERRIDDING_PRIVATE_MEMBER | 2546 * @see HintCode#OVERRIDDING_PRIVATE_MEMBER |
| 2547 */ | 2547 */ |
| 2548 bool checkForOverridingPrivateMember(MethodDeclaration node) { | 2548 bool _checkForOverridingPrivateMember(MethodDeclaration node) { |
| 2549 // If not in an enclosing class, return false | 2549 // If not in an enclosing class, return false |
| 2550 if (_enclosingClass == null) { | 2550 if (_enclosingClass == null) { |
| 2551 return false; | 2551 return false; |
| 2552 } | 2552 } |
| 2553 // If the member is not private, return false | 2553 // If the member is not private, return false |
| 2554 if (!Identifier.isPrivateName(node.name.name)) { | 2554 if (!Identifier.isPrivateName(node.name.name)) { |
| 2555 return false; | 2555 return false; |
| 2556 } | 2556 } |
| 2557 // Get the element of the member, if null, return false | 2557 // Get the element of the member, if null, return false |
| 2558 ExecutableElement executableElement = node.element; | 2558 ExecutableElement executableElement = node.element; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 return false; | 2606 return false; |
| 2607 } | 2607 } |
| 2608 | 2608 |
| 2609 /** | 2609 /** |
| 2610 * Check for the passed as expression for the [HintCode#UNNECESSARY_CAST] hint
code. | 2610 * Check for the passed as expression for the [HintCode#UNNECESSARY_CAST] hint
code. |
| 2611 * | 2611 * |
| 2612 * @param node the as expression to check | 2612 * @param node the as expression to check |
| 2613 * @return `true` if and only if a hint code is generated on the passed node | 2613 * @return `true` if and only if a hint code is generated on the passed node |
| 2614 * @see HintCode#UNNECESSARY_CAST | 2614 * @see HintCode#UNNECESSARY_CAST |
| 2615 */ | 2615 */ |
| 2616 bool checkForUnnecessaryCast(AsExpression node) { | 2616 bool _checkForUnnecessaryCast(AsExpression node) { |
| 2617 Expression expression = node.expression; | 2617 Expression expression = node.expression; |
| 2618 TypeName typeName = node.type; | 2618 TypeName typeName = node.type; |
| 2619 Type2 lhsType = expression.staticType; | 2619 Type2 lhsType = expression.staticType; |
| 2620 Type2 rhsType = typeName.type; | 2620 Type2 rhsType = typeName.type; |
| 2621 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to r
emove the | 2621 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to r
emove the |
| 2622 // !(x instanceof TypeParameterType) checks. | 2622 // !(x instanceof TypeParameterType) checks. |
| 2623 if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isD
ynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsT
ype.isSubtypeOf(rhsType)) { | 2623 if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isD
ynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsT
ype.isSubtypeOf(rhsType)) { |
| 2624 _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node, []); | 2624 _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node, []); |
| 2625 return true; | 2625 return true; |
| 2626 } | 2626 } |
| 2627 return false; | 2627 return false; |
| 2628 } | 2628 } |
| 2629 | 2629 |
| 2630 /** | 2630 /** |
| 2631 * Check for situations where the result of a method or function is used, when
it returns 'void'. | 2631 * Check for situations where the result of a method or function is used, when
it returns 'void'. |
| 2632 * | 2632 * |
| 2633 * TODO(jwren) Many other situations of use could be covered. We currently cov
er the cases var x = | 2633 * TODO(jwren) Many other situations of use could be covered. We currently cov
er the cases var x = |
| 2634 * m() and x = m(), but we could also cover cases such as m().x, m()[k], a + m
(), f(m()), return | 2634 * m() and x = m(), but we could also cover cases such as m().x, m()[k], a + m
(), f(m()), return |
| 2635 * m(). | 2635 * m(). |
| 2636 * | 2636 * |
| 2637 * @param node expression on the RHS of some assignment | 2637 * @param node expression on the RHS of some assignment |
| 2638 * @return `true` if and only if a hint code is generated on the passed node | 2638 * @return `true` if and only if a hint code is generated on the passed node |
| 2639 * @see HintCode#USE_OF_VOID_RESULT | 2639 * @see HintCode#USE_OF_VOID_RESULT |
| 2640 */ | 2640 */ |
| 2641 bool checkForUseOfVoidResult(Expression expression) { | 2641 bool _checkForUseOfVoidResult(Expression expression) { |
| 2642 if (expression == null || expression is! MethodInvocation) { | 2642 if (expression == null || expression is! MethodInvocation) { |
| 2643 return false; | 2643 return false; |
| 2644 } | 2644 } |
| 2645 MethodInvocation methodInvocation = expression as MethodInvocation; | 2645 MethodInvocation methodInvocation = expression as MethodInvocation; |
| 2646 if (identical(methodInvocation.staticType, VoidTypeImpl.instance)) { | 2646 if (identical(methodInvocation.staticType, VoidTypeImpl.instance)) { |
| 2647 SimpleIdentifier methodName = methodInvocation.methodName; | 2647 SimpleIdentifier methodName = methodInvocation.methodName; |
| 2648 _errorReporter.reportErrorForNode(HintCode.USE_OF_VOID_RESULT, methodName,
[methodName.name]); | 2648 _errorReporter.reportErrorForNode(HintCode.USE_OF_VOID_RESULT, methodName,
[methodName.name]); |
| 2649 return true; | 2649 return true; |
| 2650 } | 2650 } |
| 2651 return false; | 2651 return false; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2670 /** | 2670 /** |
| 2671 * Create a new instance of the [Dart2JSVerifier]. | 2671 * Create a new instance of the [Dart2JSVerifier]. |
| 2672 * | 2672 * |
| 2673 * @param errorReporter the error reporter | 2673 * @param errorReporter the error reporter |
| 2674 */ | 2674 */ |
| 2675 Dart2JSVerifier(ErrorReporter errorReporter) { | 2675 Dart2JSVerifier(ErrorReporter errorReporter) { |
| 2676 this._errorReporter = errorReporter; | 2676 this._errorReporter = errorReporter; |
| 2677 } | 2677 } |
| 2678 | 2678 |
| 2679 Object visitIsExpression(IsExpression node) { | 2679 Object visitIsExpression(IsExpression node) { |
| 2680 checkForIsDoubleHints(node); | 2680 _checkForIsDoubleHints(node); |
| 2681 return super.visitIsExpression(node); | 2681 return super.visitIsExpression(node); |
| 2682 } | 2682 } |
| 2683 | 2683 |
| 2684 /** | 2684 /** |
| 2685 * Check for instances of `x is double`, `x is int`, `x is! double` and | 2685 * Check for instances of `x is double`, `x is int`, `x is! double` and |
| 2686 * `x is! int`. | 2686 * `x is! int`. |
| 2687 * | 2687 * |
| 2688 * @param node the is expression to check | 2688 * @param node the is expression to check |
| 2689 * @return `true` if and only if a hint code is generated on the passed node | 2689 * @return `true` if and only if a hint code is generated on the passed node |
| 2690 * @see HintCode#IS_DOUBLE | 2690 * @see HintCode#IS_DOUBLE |
| 2691 * @see HintCode#IS_INT | 2691 * @see HintCode#IS_INT |
| 2692 * @see HintCode#IS_NOT_DOUBLE | 2692 * @see HintCode#IS_NOT_DOUBLE |
| 2693 * @see HintCode#IS_NOT_INT | 2693 * @see HintCode#IS_NOT_INT |
| 2694 */ | 2694 */ |
| 2695 bool checkForIsDoubleHints(IsExpression node) { | 2695 bool _checkForIsDoubleHints(IsExpression node) { |
| 2696 TypeName typeName = node.type; | 2696 TypeName typeName = node.type; |
| 2697 Type2 type = typeName.type; | 2697 Type2 type = typeName.type; |
| 2698 if (type != null && type.element != null) { | 2698 if (type != null && type.element != null) { |
| 2699 Element element = type.element; | 2699 Element element = type.element; |
| 2700 String typeNameStr = element.name; | 2700 String typeNameStr = element.name; |
| 2701 LibraryElement libraryElement = element.library; | 2701 LibraryElement libraryElement = element.library; |
| 2702 // if (typeNameStr.equals(INT_TYPE_NAME) && libraryElement != null | 2702 // if (typeNameStr.equals(INT_TYPE_NAME) && libraryElement != null |
| 2703 // && libraryElement.isDartCore()) { | 2703 // && libraryElement.isDartCore()) { |
| 2704 // if (node.getNotOperator() == null) { | 2704 // if (node.getNotOperator() == null) { |
| 2705 // errorReporter.reportError(HintCode.IS_INT, node); | 2705 // errorReporter.reportError(HintCode.IS_INT, node); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2739 DeadCodeVerifier(ErrorReporter errorReporter) { | 2739 DeadCodeVerifier(ErrorReporter errorReporter) { |
| 2740 this._errorReporter = errorReporter; | 2740 this._errorReporter = errorReporter; |
| 2741 } | 2741 } |
| 2742 | 2742 |
| 2743 Object visitBinaryExpression(BinaryExpression node) { | 2743 Object visitBinaryExpression(BinaryExpression node) { |
| 2744 sc.Token operator = node.operator; | 2744 sc.Token operator = node.operator; |
| 2745 bool isAmpAmp = identical(operator.type, sc.TokenType.AMPERSAND_AMPERSAND); | 2745 bool isAmpAmp = identical(operator.type, sc.TokenType.AMPERSAND_AMPERSAND); |
| 2746 bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR); | 2746 bool isBarBar = identical(operator.type, sc.TokenType.BAR_BAR); |
| 2747 if (isAmpAmp || isBarBar) { | 2747 if (isAmpAmp || isBarBar) { |
| 2748 Expression lhsCondition = node.leftOperand; | 2748 Expression lhsCondition = node.leftOperand; |
| 2749 if (!isDebugConstant(lhsCondition)) { | 2749 if (!_isDebugConstant(lhsCondition)) { |
| 2750 ValidResult lhsResult = getConstantBooleanValue(lhsCondition); | 2750 ValidResult lhsResult = _getConstantBooleanValue(lhsCondition); |
| 2751 if (lhsResult != null) { | 2751 if (lhsResult != null) { |
| 2752 if (lhsResult.isTrue && isBarBar) { | 2752 if (lhsResult.isTrue && isBarBar) { |
| 2753 // report error on else block: true || !e! | 2753 // report error on else block: true || !e! |
| 2754 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.rightOper
and, []); | 2754 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.rightOper
and, []); |
| 2755 // only visit the LHS: | 2755 // only visit the LHS: |
| 2756 safelyVisit(lhsCondition); | 2756 _safelyVisit(lhsCondition); |
| 2757 return null; | 2757 return null; |
| 2758 } else if (lhsResult.isFalse && isAmpAmp) { | 2758 } else if (lhsResult.isFalse && isAmpAmp) { |
| 2759 // report error on if block: false && !e! | 2759 // report error on if block: false && !e! |
| 2760 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.rightOper
and, []); | 2760 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.rightOper
and, []); |
| 2761 // only visit the LHS: | 2761 // only visit the LHS: |
| 2762 safelyVisit(lhsCondition); | 2762 _safelyVisit(lhsCondition); |
| 2763 return null; | 2763 return null; |
| 2764 } | 2764 } |
| 2765 } | 2765 } |
| 2766 } | 2766 } |
| 2767 } | 2767 } |
| 2768 return super.visitBinaryExpression(node); | 2768 return super.visitBinaryExpression(node); |
| 2769 } | 2769 } |
| 2770 | 2770 |
| 2771 /** | 2771 /** |
| 2772 * For each [Block], this method reports and error on all statements between t
he end of the | 2772 * For each [Block], this method reports and error on all statements between t
he end of the |
| 2773 * block and the first return statement (assuming there it is not at the end o
f the block.) | 2773 * block and the first return statement (assuming there it is not at the end o
f the block.) |
| 2774 * | 2774 * |
| 2775 * @param node the block to evaluate | 2775 * @param node the block to evaluate |
| 2776 */ | 2776 */ |
| 2777 Object visitBlock(Block node) { | 2777 Object visitBlock(Block node) { |
| 2778 NodeList<Statement> statements = node.statements; | 2778 NodeList<Statement> statements = node.statements; |
| 2779 int size = statements.length; | 2779 int size = statements.length; |
| 2780 for (int i = 0; i < size; i++) { | 2780 for (int i = 0; i < size; i++) { |
| 2781 Statement currentStatement = statements[i]; | 2781 Statement currentStatement = statements[i]; |
| 2782 safelyVisit(currentStatement); | 2782 _safelyVisit(currentStatement); |
| 2783 if (currentStatement is ReturnStatement && i != size - 1) { | 2783 if (currentStatement is ReturnStatement && i != size - 1) { |
| 2784 Statement nextStatement = statements[i + 1]; | 2784 Statement nextStatement = statements[i + 1]; |
| 2785 Statement lastStatement = statements[size - 1]; | 2785 Statement lastStatement = statements[size - 1]; |
| 2786 int offset = nextStatement.offset; | 2786 int offset = nextStatement.offset; |
| 2787 int length = lastStatement.end - offset; | 2787 int length = lastStatement.end - offset; |
| 2788 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE, offset, length,
[]); | 2788 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE, offset, length,
[]); |
| 2789 return null; | 2789 return null; |
| 2790 } | 2790 } |
| 2791 } | 2791 } |
| 2792 return null; | 2792 return null; |
| 2793 } | 2793 } |
| 2794 | 2794 |
| 2795 Object visitConditionalExpression(ConditionalExpression node) { | 2795 Object visitConditionalExpression(ConditionalExpression node) { |
| 2796 Expression conditionExpression = node.condition; | 2796 Expression conditionExpression = node.condition; |
| 2797 safelyVisit(conditionExpression); | 2797 _safelyVisit(conditionExpression); |
| 2798 if (!isDebugConstant(conditionExpression)) { | 2798 if (!_isDebugConstant(conditionExpression)) { |
| 2799 ValidResult result = getConstantBooleanValue(conditionExpression); | 2799 ValidResult result = _getConstantBooleanValue(conditionExpression); |
| 2800 if (result != null) { | 2800 if (result != null) { |
| 2801 if (result.isTrue) { | 2801 if (result.isTrue) { |
| 2802 // report error on else block: true ? 1 : !2! | 2802 // report error on else block: true ? 1 : !2! |
| 2803 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.elseExpress
ion, []); | 2803 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.elseExpress
ion, []); |
| 2804 safelyVisit(node.thenExpression); | 2804 _safelyVisit(node.thenExpression); |
| 2805 return null; | 2805 return null; |
| 2806 } else { | 2806 } else { |
| 2807 // report error on if block: false ? !1! : 2 | 2807 // report error on if block: false ? !1! : 2 |
| 2808 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.thenExpress
ion, []); | 2808 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.thenExpress
ion, []); |
| 2809 safelyVisit(node.elseExpression); | 2809 _safelyVisit(node.elseExpression); |
| 2810 return null; | 2810 return null; |
| 2811 } | 2811 } |
| 2812 } | 2812 } |
| 2813 } | 2813 } |
| 2814 return super.visitConditionalExpression(node); | 2814 return super.visitConditionalExpression(node); |
| 2815 } | 2815 } |
| 2816 | 2816 |
| 2817 Object visitIfStatement(IfStatement node) { | 2817 Object visitIfStatement(IfStatement node) { |
| 2818 Expression conditionExpression = node.condition; | 2818 Expression conditionExpression = node.condition; |
| 2819 safelyVisit(conditionExpression); | 2819 _safelyVisit(conditionExpression); |
| 2820 if (!isDebugConstant(conditionExpression)) { | 2820 if (!_isDebugConstant(conditionExpression)) { |
| 2821 ValidResult result = getConstantBooleanValue(conditionExpression); | 2821 ValidResult result = _getConstantBooleanValue(conditionExpression); |
| 2822 if (result != null) { | 2822 if (result != null) { |
| 2823 if (result.isTrue) { | 2823 if (result.isTrue) { |
| 2824 // report error on else block: if(true) {} else {!} | 2824 // report error on else block: if(true) {} else {!} |
| 2825 Statement elseStatement = node.elseStatement; | 2825 Statement elseStatement = node.elseStatement; |
| 2826 if (elseStatement != null) { | 2826 if (elseStatement != null) { |
| 2827 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, elseStatement,
[]); | 2827 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, elseStatement,
[]); |
| 2828 safelyVisit(node.thenStatement); | 2828 _safelyVisit(node.thenStatement); |
| 2829 return null; | 2829 return null; |
| 2830 } | 2830 } |
| 2831 } else { | 2831 } else { |
| 2832 // report error on if block: if (false) {!} else {} | 2832 // report error on if block: if (false) {!} else {} |
| 2833 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.thenStateme
nt, []); | 2833 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.thenStateme
nt, []); |
| 2834 safelyVisit(node.elseStatement); | 2834 _safelyVisit(node.elseStatement); |
| 2835 return null; | 2835 return null; |
| 2836 } | 2836 } |
| 2837 } | 2837 } |
| 2838 } | 2838 } |
| 2839 return super.visitIfStatement(node); | 2839 return super.visitIfStatement(node); |
| 2840 } | 2840 } |
| 2841 | 2841 |
| 2842 Object visitTryStatement(TryStatement node) { | 2842 Object visitTryStatement(TryStatement node) { |
| 2843 safelyVisit(node.body); | 2843 _safelyVisit(node.body); |
| 2844 safelyVisit(node.finallyBlock); | 2844 _safelyVisit(node.finallyBlock); |
| 2845 NodeList<CatchClause> catchClauses = node.catchClauses; | 2845 NodeList<CatchClause> catchClauses = node.catchClauses; |
| 2846 int numOfCatchClauses = catchClauses.length; | 2846 int numOfCatchClauses = catchClauses.length; |
| 2847 List<Type2> visitedTypes = new List<Type2>(); | 2847 List<Type2> visitedTypes = new List<Type2>(); |
| 2848 for (int i = 0; i < numOfCatchClauses; i++) { | 2848 for (int i = 0; i < numOfCatchClauses; i++) { |
| 2849 CatchClause catchClause = catchClauses[i]; | 2849 CatchClause catchClause = catchClauses[i]; |
| 2850 if (catchClause.onKeyword != null) { | 2850 if (catchClause.onKeyword != null) { |
| 2851 // on-catch clause found, verify that the exception type is not a subtyp
e of a previous | 2851 // on-catch clause found, verify that the exception type is not a subtyp
e of a previous |
| 2852 // on-catch exception type | 2852 // on-catch exception type |
| 2853 TypeName typeName = catchClause.exceptionType; | 2853 TypeName typeName = catchClause.exceptionType; |
| 2854 if (typeName != null && typeName.type != null) { | 2854 if (typeName != null && typeName.type != null) { |
| 2855 Type2 currentType = typeName.type; | 2855 Type2 currentType = typeName.type; |
| 2856 if (currentType.isObject) { | 2856 if (currentType.isObject) { |
| 2857 // Found catch clause clause that has Object as an exception type, t
his is equivalent to | 2857 // Found catch clause clause that has Object as an exception type, t
his is equivalent to |
| 2858 // having a catch clause that doesn't have an exception type, visit
the block, but | 2858 // having a catch clause that doesn't have an exception type, visit
the block, but |
| 2859 // generate an error on any following catch clauses (and don't visi
t them). | 2859 // generate an error on any following catch clauses (and don't visi
t them). |
| 2860 safelyVisit(catchClause); | 2860 _safelyVisit(catchClause); |
| 2861 if (i + 1 != numOfCatchClauses) { | 2861 if (i + 1 != numOfCatchClauses) { |
| 2862 // this catch clause is not the last in the try statement | 2862 // this catch clause is not the last in the try statement |
| 2863 CatchClause nextCatchClause = catchClauses[i + 1]; | 2863 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 2864 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2864 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2865 int offset = nextCatchClause.offset; | 2865 int offset = nextCatchClause.offset; |
| 2866 int length = lastCatchClause.end - offset; | 2866 int length = lastCatchClause.end - offset; |
| 2867 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE_CATCH_FOLLO
WING_CATCH, offset, length, []); | 2867 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE_CATCH_FOLLO
WING_CATCH, offset, length, []); |
| 2868 return null; | 2868 return null; |
| 2869 } | 2869 } |
| 2870 } | 2870 } |
| 2871 for (Type2 type in visitedTypes) { | 2871 for (Type2 type in visitedTypes) { |
| 2872 if (currentType.isSubtypeOf(type)) { | 2872 if (currentType.isSubtypeOf(type)) { |
| 2873 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2873 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2874 int offset = catchClause.offset; | 2874 int offset = catchClause.offset; |
| 2875 int length = lastCatchClause.end - offset; | 2875 int length = lastCatchClause.end - offset; |
| 2876 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE_ON_CATCH_SU
BTYPE, offset, length, [currentType.displayName, type.displayName]); | 2876 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE_ON_CATCH_SU
BTYPE, offset, length, [currentType.displayName, type.displayName]); |
| 2877 return null; | 2877 return null; |
| 2878 } | 2878 } |
| 2879 } | 2879 } |
| 2880 visitedTypes.add(currentType); | 2880 visitedTypes.add(currentType); |
| 2881 } | 2881 } |
| 2882 safelyVisit(catchClause); | 2882 _safelyVisit(catchClause); |
| 2883 } else { | 2883 } else { |
| 2884 // Found catch clause clause that doesn't have an exception type, visit
the block, but | 2884 // Found catch clause clause that doesn't have an exception type, visit
the block, but |
| 2885 // generate an error on any following catch clauses (and don't visit the
m). | 2885 // generate an error on any following catch clauses (and don't visit the
m). |
| 2886 safelyVisit(catchClause); | 2886 _safelyVisit(catchClause); |
| 2887 if (i + 1 != numOfCatchClauses) { | 2887 if (i + 1 != numOfCatchClauses) { |
| 2888 // this catch clause is not the last in the try statement | 2888 // this catch clause is not the last in the try statement |
| 2889 CatchClause nextCatchClause = catchClauses[i + 1]; | 2889 CatchClause nextCatchClause = catchClauses[i + 1]; |
| 2890 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 2890 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
| 2891 int offset = nextCatchClause.offset; | 2891 int offset = nextCatchClause.offset; |
| 2892 int length = lastCatchClause.end - offset; | 2892 int length = lastCatchClause.end - offset; |
| 2893 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE_CATCH_FOLLOWING
_CATCH, offset, length, []); | 2893 _errorReporter.reportErrorForOffset(HintCode.DEAD_CODE_CATCH_FOLLOWING
_CATCH, offset, length, []); |
| 2894 return null; | 2894 return null; |
| 2895 } | 2895 } |
| 2896 } | 2896 } |
| 2897 } | 2897 } |
| 2898 return null; | 2898 return null; |
| 2899 } | 2899 } |
| 2900 | 2900 |
| 2901 Object visitWhileStatement(WhileStatement node) { | 2901 Object visitWhileStatement(WhileStatement node) { |
| 2902 Expression conditionExpression = node.condition; | 2902 Expression conditionExpression = node.condition; |
| 2903 safelyVisit(conditionExpression); | 2903 _safelyVisit(conditionExpression); |
| 2904 if (!isDebugConstant(conditionExpression)) { | 2904 if (!_isDebugConstant(conditionExpression)) { |
| 2905 ValidResult result = getConstantBooleanValue(conditionExpression); | 2905 ValidResult result = _getConstantBooleanValue(conditionExpression); |
| 2906 if (result != null) { | 2906 if (result != null) { |
| 2907 if (result.isFalse) { | 2907 if (result.isFalse) { |
| 2908 // report error on if block: while (false) {!} | 2908 // report error on if block: while (false) {!} |
| 2909 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.body, []); | 2909 _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.body, []); |
| 2910 return null; | 2910 return null; |
| 2911 } | 2911 } |
| 2912 } | 2912 } |
| 2913 } | 2913 } |
| 2914 safelyVisit(node.body); | 2914 _safelyVisit(node.body); |
| 2915 return null; | 2915 return null; |
| 2916 } | 2916 } |
| 2917 | 2917 |
| 2918 /** | 2918 /** |
| 2919 * Given some [Expression], this method returns [ValidResult#RESULT_TRUE] if i
t is | 2919 * Given some [Expression], this method returns [ValidResult#RESULT_TRUE] if i
t is |
| 2920 * `true`, [ValidResult#RESULT_FALSE] if it is `false`, or `null` if the | 2920 * `true`, [ValidResult#RESULT_FALSE] if it is `false`, or `null` if the |
| 2921 * expression is not a constant boolean value. | 2921 * expression is not a constant boolean value. |
| 2922 * | 2922 * |
| 2923 * @param expression the expression to evaluate | 2923 * @param expression the expression to evaluate |
| 2924 * @return [ValidResult#RESULT_TRUE] if it is `true`, [ValidResult#RESULT_FALS
E] | 2924 * @return [ValidResult#RESULT_TRUE] if it is `true`, [ValidResult#RESULT_FALS
E] |
| 2925 * if it is `false`, or `null` if the expression is not a constant boo
lean | 2925 * if it is `false`, or `null` if the expression is not a constant boo
lean |
| 2926 * value | 2926 * value |
| 2927 */ | 2927 */ |
| 2928 ValidResult getConstantBooleanValue(Expression expression) { | 2928 ValidResult _getConstantBooleanValue(Expression expression) { |
| 2929 if (expression is BooleanLiteral) { | 2929 if (expression is BooleanLiteral) { |
| 2930 if (expression.value) { | 2930 if (expression.value) { |
| 2931 return new ValidResult(new DartObjectImpl(null, BoolState.from(true))); | 2931 return new ValidResult(new DartObjectImpl(null, BoolState.from(true))); |
| 2932 } else { | 2932 } else { |
| 2933 return new ValidResult(new DartObjectImpl(null, BoolState.from(false))); | 2933 return new ValidResult(new DartObjectImpl(null, BoolState.from(false))); |
| 2934 } | 2934 } |
| 2935 } | 2935 } |
| 2936 // Don't consider situations where we could evaluate to a constant boolean e
xpression with the | 2936 // Don't consider situations where we could evaluate to a constant boolean e
xpression with the |
| 2937 // ConstantVisitor | 2937 // ConstantVisitor |
| 2938 // | 2938 // |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2955 // } | 2955 // } |
| 2956 return null; | 2956 return null; |
| 2957 } | 2957 } |
| 2958 | 2958 |
| 2959 /** | 2959 /** |
| 2960 * Return `true` if and only if the passed expression is resolved to a constan
t variable. | 2960 * Return `true` if and only if the passed expression is resolved to a constan
t variable. |
| 2961 * | 2961 * |
| 2962 * @param expression some conditional expression | 2962 * @param expression some conditional expression |
| 2963 * @return `true` if and only if the passed expression is resolved to a consta
nt variable | 2963 * @return `true` if and only if the passed expression is resolved to a consta
nt variable |
| 2964 */ | 2964 */ |
| 2965 bool isDebugConstant(Expression expression) { | 2965 bool _isDebugConstant(Expression expression) { |
| 2966 Element element = null; | 2966 Element element = null; |
| 2967 if (expression is Identifier) { | 2967 if (expression is Identifier) { |
| 2968 Identifier identifier = expression; | 2968 Identifier identifier = expression; |
| 2969 element = identifier.staticElement; | 2969 element = identifier.staticElement; |
| 2970 } else if (expression is PropertyAccess) { | 2970 } else if (expression is PropertyAccess) { |
| 2971 PropertyAccess propertyAccess = expression; | 2971 PropertyAccess propertyAccess = expression; |
| 2972 element = propertyAccess.propertyName.staticElement; | 2972 element = propertyAccess.propertyName.staticElement; |
| 2973 } | 2973 } |
| 2974 if (element is PropertyAccessorElement) { | 2974 if (element is PropertyAccessorElement) { |
| 2975 PropertyAccessorElement pae = element as PropertyAccessorElement; | 2975 PropertyAccessorElement pae = element as PropertyAccessorElement; |
| 2976 PropertyInducingElement variable = pae.variable; | 2976 PropertyInducingElement variable = pae.variable; |
| 2977 return variable != null && variable.isConst; | 2977 return variable != null && variable.isConst; |
| 2978 } | 2978 } |
| 2979 return false; | 2979 return false; |
| 2980 } | 2980 } |
| 2981 | 2981 |
| 2982 /** | 2982 /** |
| 2983 * If the given node is not `null`, visit this instance of the dead code verif
ier. | 2983 * If the given node is not `null`, visit this instance of the dead code verif
ier. |
| 2984 * | 2984 * |
| 2985 * @param node the node to be visited | 2985 * @param node the node to be visited |
| 2986 */ | 2986 */ |
| 2987 void safelyVisit(AstNode node) { | 2987 void _safelyVisit(AstNode node) { |
| 2988 if (node != null) { | 2988 if (node != null) { |
| 2989 node.accept(this); | 2989 node.accept(this); |
| 2990 } | 2990 } |
| 2991 } | 2991 } |
| 2992 } | 2992 } |
| 2993 | 2993 |
| 2994 /** | 2994 /** |
| 2995 * Instances of the class `ExitDetector` determine whether the visited AST node
is guaranteed | 2995 * Instances of the class `ExitDetector` determine whether the visited AST node
is guaranteed |
| 2996 * to terminate by executing a `return` statement, `throw` expression, `rethrow` | 2996 * to terminate by executing a `return` statement, `throw` expression, `rethrow` |
| 2997 * expression, or simple infinite loop such as `while(true)`. | 2997 * expression, or simple infinite loop such as `while(true)`. |
| 2998 */ | 2998 */ |
| 2999 class ExitDetector extends GeneralizingAstVisitor<bool> { | 2999 class ExitDetector extends GeneralizingAstVisitor<bool> { |
| 3000 /** | 3000 /** |
| 3001 * Set to `true` when a `break` is encountered, and reset to `false` when a | 3001 * Set to `true` when a `break` is encountered, and reset to `false` when a |
| 3002 * `do`, `while`, `for` or `switch` block is entered. | 3002 * `do`, `while`, `for` or `switch` block is entered. |
| 3003 */ | 3003 */ |
| 3004 bool _enclosingBlockContainsBreak = false; | 3004 bool _enclosingBlockContainsBreak = false; |
| 3005 | 3005 |
| 3006 bool visitArgumentList(ArgumentList node) => visitExpressions(node.arguments); | 3006 bool visitArgumentList(ArgumentList node) => _visitExpressions(node.arguments)
; |
| 3007 | 3007 |
| 3008 bool visitAsExpression(AsExpression node) => node.expression.accept(this); | 3008 bool visitAsExpression(AsExpression node) => node.expression.accept(this); |
| 3009 | 3009 |
| 3010 bool visitAssertStatement(AssertStatement node) => node.condition.accept(this)
; | 3010 bool visitAssertStatement(AssertStatement node) => node.condition.accept(this)
; |
| 3011 | 3011 |
| 3012 bool visitAssignmentExpression(AssignmentExpression node) => node.leftHandSide
.accept(this) || node.rightHandSide.accept(this); | 3012 bool visitAssignmentExpression(AssignmentExpression node) => node.leftHandSide
.accept(this) || node.rightHandSide.accept(this); |
| 3013 | 3013 |
| 3014 bool visitBinaryExpression(BinaryExpression node) { | 3014 bool visitBinaryExpression(BinaryExpression node) { |
| 3015 Expression lhsExpression = node.leftOperand; | 3015 Expression lhsExpression = node.leftOperand; |
| 3016 sc.TokenType operatorType = node.operator.type; | 3016 sc.TokenType operatorType = node.operator.type; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3032 if (lhsExpression is BooleanLiteral) { | 3032 if (lhsExpression is BooleanLiteral) { |
| 3033 BooleanLiteral booleanLiteral = lhsExpression; | 3033 BooleanLiteral booleanLiteral = lhsExpression; |
| 3034 if (booleanLiteral.value) { | 3034 if (booleanLiteral.value) { |
| 3035 return false; | 3035 return false; |
| 3036 } | 3036 } |
| 3037 } | 3037 } |
| 3038 } | 3038 } |
| 3039 return lhsExpression.accept(this) || node.rightOperand.accept(this); | 3039 return lhsExpression.accept(this) || node.rightOperand.accept(this); |
| 3040 } | 3040 } |
| 3041 | 3041 |
| 3042 bool visitBlock(Block node) => visitStatements(node.statements); | 3042 bool visitBlock(Block node) => _visitStatements(node.statements); |
| 3043 | 3043 |
| 3044 bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this)
; | 3044 bool visitBlockFunctionBody(BlockFunctionBody node) => node.block.accept(this)
; |
| 3045 | 3045 |
| 3046 bool visitBreakStatement(BreakStatement node) { | 3046 bool visitBreakStatement(BreakStatement node) { |
| 3047 _enclosingBlockContainsBreak = true; | 3047 _enclosingBlockContainsBreak = true; |
| 3048 return false; | 3048 return false; |
| 3049 } | 3049 } |
| 3050 | 3050 |
| 3051 bool visitCascadeExpression(CascadeExpression node) { | 3051 bool visitCascadeExpression(CascadeExpression node) { |
| 3052 Expression target = node.target; | 3052 Expression target = node.target; |
| 3053 if (target.accept(this)) { | 3053 if (target.accept(this)) { |
| 3054 return true; | 3054 return true; |
| 3055 } | 3055 } |
| 3056 return visitExpressions(node.cascadeSections); | 3056 return _visitExpressions(node.cascadeSections); |
| 3057 } | 3057 } |
| 3058 | 3058 |
| 3059 bool visitConditionalExpression(ConditionalExpression node) { | 3059 bool visitConditionalExpression(ConditionalExpression node) { |
| 3060 Expression conditionExpression = node.condition; | 3060 Expression conditionExpression = node.condition; |
| 3061 Expression thenStatement = node.thenExpression; | 3061 Expression thenStatement = node.thenExpression; |
| 3062 Expression elseStatement = node.elseExpression; | 3062 Expression elseStatement = node.elseExpression; |
| 3063 // TODO(jwren) Do we want to take constant expressions into account, evaluat
e if(false) {} | 3063 // TODO(jwren) Do we want to take constant expressions into account, evaluat
e if(false) {} |
| 3064 // differently than if(<condition>), when <condition> evaluates to a constan
t false value? | 3064 // differently than if(<condition>), when <condition> evaluates to a constan
t false value? |
| 3065 if (conditionExpression.accept(this)) { | 3065 if (conditionExpression.accept(this)) { |
| 3066 return true; | 3066 return true; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3108 return node.iterator.accept(this); | 3108 return node.iterator.accept(this); |
| 3109 } finally { | 3109 } finally { |
| 3110 _enclosingBlockContainsBreak = outerBreakValue; | 3110 _enclosingBlockContainsBreak = outerBreakValue; |
| 3111 } | 3111 } |
| 3112 } | 3112 } |
| 3113 | 3113 |
| 3114 bool visitForStatement(ForStatement node) { | 3114 bool visitForStatement(ForStatement node) { |
| 3115 bool outerBreakValue = _enclosingBlockContainsBreak; | 3115 bool outerBreakValue = _enclosingBlockContainsBreak; |
| 3116 _enclosingBlockContainsBreak = false; | 3116 _enclosingBlockContainsBreak = false; |
| 3117 try { | 3117 try { |
| 3118 if (node.variables != null && visitVariableDeclarations(node.variables.var
iables)) { | 3118 if (node.variables != null && _visitVariableDeclarations(node.variables.va
riables)) { |
| 3119 return true; | 3119 return true; |
| 3120 } | 3120 } |
| 3121 if (node.initialization != null && node.initialization.accept(this)) { | 3121 if (node.initialization != null && node.initialization.accept(this)) { |
| 3122 return true; | 3122 return true; |
| 3123 } | 3123 } |
| 3124 Expression conditionExpression = node.condition; | 3124 Expression conditionExpression = node.condition; |
| 3125 if (conditionExpression != null && conditionExpression.accept(this)) { | 3125 if (conditionExpression != null && conditionExpression.accept(this)) { |
| 3126 return true; | 3126 return true; |
| 3127 } | 3127 } |
| 3128 if (visitExpressions(node.updaters)) { | 3128 if (_visitExpressions(node.updaters)) { |
| 3129 return true; | 3129 return true; |
| 3130 } | 3130 } |
| 3131 // TODO(jwren) Do we want to take all constant expressions into account? | 3131 // TODO(jwren) Do we want to take all constant expressions into account? |
| 3132 // If for(; true; ) (or for(;;)), and the body doesn't return or the body
doesn't have a | 3132 // If for(; true; ) (or for(;;)), and the body doesn't return or the body
doesn't have a |
| 3133 // break, then return true. | 3133 // break, then return true. |
| 3134 bool implicitOrExplictTrue = conditionExpression == null || (conditionExpr
ession is BooleanLiteral && conditionExpression.value); | 3134 bool implicitOrExplictTrue = conditionExpression == null || (conditionExpr
ession is BooleanLiteral && conditionExpression.value); |
| 3135 if (implicitOrExplictTrue) { | 3135 if (implicitOrExplictTrue) { |
| 3136 bool blockReturns = node.body.accept(this); | 3136 bool blockReturns = node.body.accept(this); |
| 3137 if (blockReturns || !_enclosingBlockContainsBreak) { | 3137 if (blockReturns || !_enclosingBlockContainsBreak) { |
| 3138 return true; | 3138 return true; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3225 } | 3225 } |
| 3226 return false; | 3226 return false; |
| 3227 } | 3227 } |
| 3228 | 3228 |
| 3229 bool visitRethrowExpression(RethrowExpression node) => true; | 3229 bool visitRethrowExpression(RethrowExpression node) => true; |
| 3230 | 3230 |
| 3231 bool visitReturnStatement(ReturnStatement node) => true; | 3231 bool visitReturnStatement(ReturnStatement node) => true; |
| 3232 | 3232 |
| 3233 bool visitSuperExpression(SuperExpression node) => false; | 3233 bool visitSuperExpression(SuperExpression node) => false; |
| 3234 | 3234 |
| 3235 bool visitSwitchCase(SwitchCase node) => visitStatements(node.statements); | 3235 bool visitSwitchCase(SwitchCase node) => _visitStatements(node.statements); |
| 3236 | 3236 |
| 3237 bool visitSwitchDefault(SwitchDefault node) => visitStatements(node.statements
); | 3237 bool visitSwitchDefault(SwitchDefault node) => _visitStatements(node.statement
s); |
| 3238 | 3238 |
| 3239 bool visitSwitchStatement(SwitchStatement node) { | 3239 bool visitSwitchStatement(SwitchStatement node) { |
| 3240 bool outerBreakValue = _enclosingBlockContainsBreak; | 3240 bool outerBreakValue = _enclosingBlockContainsBreak; |
| 3241 _enclosingBlockContainsBreak = false; | 3241 _enclosingBlockContainsBreak = false; |
| 3242 try { | 3242 try { |
| 3243 bool hasDefault = false; | 3243 bool hasDefault = false; |
| 3244 NodeList<SwitchMember> memberList = node.members; | 3244 NodeList<SwitchMember> memberList = node.members; |
| 3245 List<SwitchMember> members = new List.from(memberList); | 3245 List<SwitchMember> members = new List.from(memberList); |
| 3246 for (int i = 0; i < members.length; i++) { | 3246 for (int i = 0; i < members.length; i++) { |
| 3247 SwitchMember switchMember = members[i]; | 3247 SwitchMember switchMember = members[i]; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3282 bool visitTypeName(TypeName node) => false; | 3282 bool visitTypeName(TypeName node) => false; |
| 3283 | 3283 |
| 3284 bool visitVariableDeclaration(VariableDeclaration node) { | 3284 bool visitVariableDeclaration(VariableDeclaration node) { |
| 3285 Expression initializer = node.initializer; | 3285 Expression initializer = node.initializer; |
| 3286 if (initializer != null) { | 3286 if (initializer != null) { |
| 3287 return initializer.accept(this); | 3287 return initializer.accept(this); |
| 3288 } | 3288 } |
| 3289 return false; | 3289 return false; |
| 3290 } | 3290 } |
| 3291 | 3291 |
| 3292 bool visitVariableDeclarationList(VariableDeclarationList node) => visitVariab
leDeclarations(node.variables); | 3292 bool visitVariableDeclarationList(VariableDeclarationList node) => _visitVaria
bleDeclarations(node.variables); |
| 3293 | 3293 |
| 3294 bool visitVariableDeclarationStatement(VariableDeclarationStatement node) { | 3294 bool visitVariableDeclarationStatement(VariableDeclarationStatement node) { |
| 3295 NodeList<VariableDeclaration> variables = node.variables.variables; | 3295 NodeList<VariableDeclaration> variables = node.variables.variables; |
| 3296 for (int i = 0; i < variables.length; i++) { | 3296 for (int i = 0; i < variables.length; i++) { |
| 3297 if (variables[i].accept(this)) { | 3297 if (variables[i].accept(this)) { |
| 3298 return true; | 3298 return true; |
| 3299 } | 3299 } |
| 3300 } | 3300 } |
| 3301 return false; | 3301 return false; |
| 3302 } | 3302 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3318 if (booleanLiteral.value && (blockReturns || !_enclosingBlockContainsBre
ak)) { | 3318 if (booleanLiteral.value && (blockReturns || !_enclosingBlockContainsBre
ak)) { |
| 3319 return true; | 3319 return true; |
| 3320 } | 3320 } |
| 3321 } | 3321 } |
| 3322 return false; | 3322 return false; |
| 3323 } finally { | 3323 } finally { |
| 3324 _enclosingBlockContainsBreak = outerBreakValue; | 3324 _enclosingBlockContainsBreak = outerBreakValue; |
| 3325 } | 3325 } |
| 3326 } | 3326 } |
| 3327 | 3327 |
| 3328 bool visitExpressions(NodeList<Expression> expressions) { | 3328 bool _visitExpressions(NodeList<Expression> expressions) { |
| 3329 for (int i = expressions.length - 1; i >= 0; i--) { | 3329 for (int i = expressions.length - 1; i >= 0; i--) { |
| 3330 if (expressions[i].accept(this)) { | 3330 if (expressions[i].accept(this)) { |
| 3331 return true; | 3331 return true; |
| 3332 } | 3332 } |
| 3333 } | 3333 } |
| 3334 return false; | 3334 return false; |
| 3335 } | 3335 } |
| 3336 | 3336 |
| 3337 bool visitStatements(NodeList<Statement> statements) { | 3337 bool _visitStatements(NodeList<Statement> statements) { |
| 3338 for (int i = statements.length - 1; i >= 0; i--) { | 3338 for (int i = statements.length - 1; i >= 0; i--) { |
| 3339 if (statements[i].accept(this)) { | 3339 if (statements[i].accept(this)) { |
| 3340 return true; | 3340 return true; |
| 3341 } | 3341 } |
| 3342 } | 3342 } |
| 3343 return false; | 3343 return false; |
| 3344 } | 3344 } |
| 3345 | 3345 |
| 3346 bool visitVariableDeclarations(NodeList<VariableDeclaration> variableDeclarati
ons) { | 3346 bool _visitVariableDeclarations(NodeList<VariableDeclaration> variableDeclarat
ions) { |
| 3347 for (int i = variableDeclarations.length - 1; i >= 0; i--) { | 3347 for (int i = variableDeclarations.length - 1; i >= 0; i--) { |
| 3348 if (variableDeclarations[i].accept(this)) { | 3348 if (variableDeclarations[i].accept(this)) { |
| 3349 return true; | 3349 return true; |
| 3350 } | 3350 } |
| 3351 } | 3351 } |
| 3352 return false; | 3352 return false; |
| 3353 } | 3353 } |
| 3354 } | 3354 } |
| 3355 | 3355 |
| 3356 /** | 3356 /** |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3386 } | 3386 } |
| 3387 | 3387 |
| 3388 void generateForLibrary() { | 3388 void generateForLibrary() { |
| 3389 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.hints.star
t(); | 3389 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.hints.star
t(); |
| 3390 try { | 3390 try { |
| 3391 for (int i = 0; i < _compilationUnits.length; i++) { | 3391 for (int i = 0; i < _compilationUnits.length; i++) { |
| 3392 CompilationUnitElement element = _compilationUnits[i].element; | 3392 CompilationUnitElement element = _compilationUnits[i].element; |
| 3393 if (element != null) { | 3393 if (element != null) { |
| 3394 if (i == 0) { | 3394 if (i == 0) { |
| 3395 _importsVerifier.inDefiningCompilationUnit = true; | 3395 _importsVerifier.inDefiningCompilationUnit = true; |
| 3396 generateForCompilationUnit(_compilationUnits[i], element.source); | 3396 _generateForCompilationUnit(_compilationUnits[i], element.source); |
| 3397 _importsVerifier.inDefiningCompilationUnit = false; | 3397 _importsVerifier.inDefiningCompilationUnit = false; |
| 3398 } else { | 3398 } else { |
| 3399 generateForCompilationUnit(_compilationUnits[i], element.source); | 3399 _generateForCompilationUnit(_compilationUnits[i], element.source); |
| 3400 } | 3400 } |
| 3401 } | 3401 } |
| 3402 } | 3402 } |
| 3403 ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter(_er
rorListener, _compilationUnits[0].element.source); | 3403 ErrorReporter definingCompilationUnitErrorReporter = new ErrorReporter(_er
rorListener, _compilationUnits[0].element.source); |
| 3404 _importsVerifier.generateDuplicateImportHints(definingCompilationUnitError
Reporter); | 3404 _importsVerifier.generateDuplicateImportHints(definingCompilationUnitError
Reporter); |
| 3405 _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorRep
orter); | 3405 _importsVerifier.generateUnusedImportHints(definingCompilationUnitErrorRep
orter); |
| 3406 } finally { | 3406 } finally { |
| 3407 timeCounter.stop(); | 3407 timeCounter.stop(); |
| 3408 } | 3408 } |
| 3409 } | 3409 } |
| 3410 | 3410 |
| 3411 void generateForCompilationUnit(CompilationUnit unit, Source source) { | 3411 void _generateForCompilationUnit(CompilationUnit unit, Source source) { |
| 3412 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); | 3412 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); |
| 3413 unit.accept(_importsVerifier); | 3413 unit.accept(_importsVerifier); |
| 3414 // dead code analysis | 3414 // dead code analysis |
| 3415 unit.accept(new DeadCodeVerifier(errorReporter)); | 3415 unit.accept(new DeadCodeVerifier(errorReporter)); |
| 3416 // dart2js analysis | 3416 // dart2js analysis |
| 3417 if (_enableDart2JSHints) { | 3417 if (_enableDart2JSHints) { |
| 3418 unit.accept(new Dart2JSVerifier(errorReporter)); | 3418 unit.accept(new Dart2JSVerifier(errorReporter)); |
| 3419 } | 3419 } |
| 3420 // Dart best practices | 3420 // Dart best practices |
| 3421 unit.accept(new BestPracticesVerifier(errorReporter)); | 3421 unit.accept(new BestPracticesVerifier(errorReporter)); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3560 Element element = prefixIdentifier.staticElement; | 3560 Element element = prefixIdentifier.staticElement; |
| 3561 if (element is PrefixElement) { | 3561 if (element is PrefixElement) { |
| 3562 PrefixElement prefixElementKey = element; | 3562 PrefixElement prefixElementKey = element; |
| 3563 _prefixElementMap[prefixElementKey] = importDirective; | 3563 _prefixElementMap[prefixElementKey] = importDirective; |
| 3564 } | 3564 } |
| 3565 } | 3565 } |
| 3566 } | 3566 } |
| 3567 // | 3567 // |
| 3568 // Initialize libraryMap: libraryElement -> importDirective | 3568 // Initialize libraryMap: libraryElement -> importDirective |
| 3569 // | 3569 // |
| 3570 putIntoLibraryMap(libraryElement, importDirective); | 3570 _putIntoLibraryMap(libraryElement, importDirective); |
| 3571 // | 3571 // |
| 3572 // For this new addition to the libraryMap, also recursively add any
exports from the | 3572 // For this new addition to the libraryMap, also recursively add any
exports from the |
| 3573 // libraryElement | 3573 // libraryElement |
| 3574 // | 3574 // |
| 3575 addAdditionalLibrariesForExports(libraryElement, importDirective, ne
w List<LibraryElement>()); | 3575 _addAdditionalLibrariesForExports(libraryElement, importDirective, n
ew List<LibraryElement>()); |
| 3576 } | 3576 } |
| 3577 } | 3577 } |
| 3578 } | 3578 } |
| 3579 } | 3579 } |
| 3580 // If there are no imports in this library, don't visit the identifiers in t
he library- there | 3580 // If there are no imports in this library, don't visit the identifiers in t
he library- there |
| 3581 // can be no unused imports. | 3581 // can be no unused imports. |
| 3582 if (_unusedImports.isEmpty) { | 3582 if (_unusedImports.isEmpty) { |
| 3583 return null; | 3583 return null; |
| 3584 } | 3584 } |
| 3585 if (_unusedImports.length > 1) { | 3585 if (_unusedImports.length > 1) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3598 _duplicateImports.add(currentDirective); | 3598 _duplicateImports.add(currentDirective); |
| 3599 } | 3599 } |
| 3600 } | 3600 } |
| 3601 currentDirective = nextDirective; | 3601 currentDirective = nextDirective; |
| 3602 } | 3602 } |
| 3603 } | 3603 } |
| 3604 return super.visitCompilationUnit(node); | 3604 return super.visitCompilationUnit(node); |
| 3605 } | 3605 } |
| 3606 | 3606 |
| 3607 Object visitExportDirective(ExportDirective node) { | 3607 Object visitExportDirective(ExportDirective node) { |
| 3608 visitMetadata(node.metadata); | 3608 _visitMetadata(node.metadata); |
| 3609 return null; | 3609 return null; |
| 3610 } | 3610 } |
| 3611 | 3611 |
| 3612 Object visitImportDirective(ImportDirective node) { | 3612 Object visitImportDirective(ImportDirective node) { |
| 3613 visitMetadata(node.metadata); | 3613 _visitMetadata(node.metadata); |
| 3614 return null; | 3614 return null; |
| 3615 } | 3615 } |
| 3616 | 3616 |
| 3617 Object visitLibraryDirective(LibraryDirective node) { | 3617 Object visitLibraryDirective(LibraryDirective node) { |
| 3618 visitMetadata(node.metadata); | 3618 _visitMetadata(node.metadata); |
| 3619 return null; | 3619 return null; |
| 3620 } | 3620 } |
| 3621 | 3621 |
| 3622 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 3622 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 3623 if (_unusedImports.isEmpty) { | 3623 if (_unusedImports.isEmpty) { |
| 3624 return null; | 3624 return null; |
| 3625 } | 3625 } |
| 3626 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can | 3626 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can |
| 3627 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the | 3627 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the |
| 3628 // unusedImports list. | 3628 // unusedImports list. |
| 3629 SimpleIdentifier prefixIdentifier = node.prefix; | 3629 SimpleIdentifier prefixIdentifier = node.prefix; |
| 3630 Element element = prefixIdentifier.staticElement; | 3630 Element element = prefixIdentifier.staticElement; |
| 3631 if (element is PrefixElement) { | 3631 if (element is PrefixElement) { |
| 3632 _unusedImports.remove(_prefixElementMap[element]); | 3632 _unusedImports.remove(_prefixElementMap[element]); |
| 3633 return null; | 3633 return null; |
| 3634 } | 3634 } |
| 3635 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. | 3635 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. |
| 3636 return visitIdentifier(element, prefixIdentifier.name); | 3636 return _visitIdentifier(element, prefixIdentifier.name); |
| 3637 } | 3637 } |
| 3638 | 3638 |
| 3639 Object visitSimpleIdentifier(SimpleIdentifier node) { | 3639 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 3640 if (_unusedImports.isEmpty) { | 3640 if (_unusedImports.isEmpty) { |
| 3641 return null; | 3641 return null; |
| 3642 } | 3642 } |
| 3643 return visitIdentifier(node.staticElement, node.name); | 3643 return _visitIdentifier(node.staticElement, node.name); |
| 3644 } | 3644 } |
| 3645 | 3645 |
| 3646 void set inDefiningCompilationUnit(bool inDefiningCompilationUnit) { | 3646 void set inDefiningCompilationUnit(bool inDefiningCompilationUnit) { |
| 3647 this._inDefiningCompilationUnit = inDefiningCompilationUnit; | 3647 this._inDefiningCompilationUnit = inDefiningCompilationUnit; |
| 3648 } | 3648 } |
| 3649 | 3649 |
| 3650 /** | 3650 /** |
| 3651 * Recursively add any exported library elements into the [libraryMap]. | 3651 * Recursively add any exported library elements into the [libraryMap]. |
| 3652 */ | 3652 */ |
| 3653 void addAdditionalLibrariesForExports(LibraryElement library, ImportDirective
importDirective, List<LibraryElement> exportPath) { | 3653 void _addAdditionalLibrariesForExports(LibraryElement library, ImportDirective
importDirective, List<LibraryElement> exportPath) { |
| 3654 if (exportPath.contains(library)) { | 3654 if (exportPath.contains(library)) { |
| 3655 return; | 3655 return; |
| 3656 } | 3656 } |
| 3657 exportPath.add(library); | 3657 exportPath.add(library); |
| 3658 for (LibraryElement exportedLibraryElt in library.exportedLibraries) { | 3658 for (LibraryElement exportedLibraryElt in library.exportedLibraries) { |
| 3659 putIntoLibraryMap(exportedLibraryElt, importDirective); | 3659 _putIntoLibraryMap(exportedLibraryElt, importDirective); |
| 3660 addAdditionalLibrariesForExports(exportedLibraryElt, importDirective, expo
rtPath); | 3660 _addAdditionalLibrariesForExports(exportedLibraryElt, importDirective, exp
ortPath); |
| 3661 } | 3661 } |
| 3662 } | 3662 } |
| 3663 | 3663 |
| 3664 /** | 3664 /** |
| 3665 * Lookup and return the [Namespace] from the [namespaceMap], if the map does
not | 3665 * Lookup and return the [Namespace] from the [namespaceMap], if the map does
not |
| 3666 * have the computed namespace, compute it and cache it in the map. If the imp
ort directive is not | 3666 * have the computed namespace, compute it and cache it in the map. If the imp
ort directive is not |
| 3667 * resolved or is not resolvable, `null` is returned. | 3667 * resolved or is not resolvable, `null` is returned. |
| 3668 * | 3668 * |
| 3669 * @param importDirective the import directive used to compute the returned na
mespace | 3669 * @param importDirective the import directive used to compute the returned na
mespace |
| 3670 * @return the computed or looked up [Namespace] | 3670 * @return the computed or looked up [Namespace] |
| 3671 */ | 3671 */ |
| 3672 Namespace computeNamespace(ImportDirective importDirective) { | 3672 Namespace _computeNamespace(ImportDirective importDirective) { |
| 3673 Namespace namespace = _namespaceMap[importDirective]; | 3673 Namespace namespace = _namespaceMap[importDirective]; |
| 3674 if (namespace == null) { | 3674 if (namespace == null) { |
| 3675 // If the namespace isn't in the namespaceMap, then compute and put it in
the map | 3675 // If the namespace isn't in the namespaceMap, then compute and put it in
the map |
| 3676 ImportElement importElement = importDirective.element; | 3676 ImportElement importElement = importDirective.element; |
| 3677 if (importElement != null) { | 3677 if (importElement != null) { |
| 3678 NamespaceBuilder builder = new NamespaceBuilder(); | 3678 NamespaceBuilder builder = new NamespaceBuilder(); |
| 3679 namespace = builder.createImportNamespaceForDirective(importElement); | 3679 namespace = builder.createImportNamespaceForDirective(importElement); |
| 3680 _namespaceMap[importDirective] = namespace; | 3680 _namespaceMap[importDirective] = namespace; |
| 3681 } | 3681 } |
| 3682 } | 3682 } |
| 3683 return namespace; | 3683 return namespace; |
| 3684 } | 3684 } |
| 3685 | 3685 |
| 3686 /** | 3686 /** |
| 3687 * The [libraryMap] is a mapping between a library elements and a list of impo
rt | 3687 * The [libraryMap] is a mapping between a library elements and a list of impo
rt |
| 3688 * directives, but when adding these mappings into the [libraryMap], this meth
od can be | 3688 * directives, but when adding these mappings into the [libraryMap], this meth
od can be |
| 3689 * used to simply add the mapping between the library element an an import dir
ective without | 3689 * used to simply add the mapping between the library element an an import dir
ective without |
| 3690 * needing to check to see if a list needs to be created. | 3690 * needing to check to see if a list needs to be created. |
| 3691 */ | 3691 */ |
| 3692 void putIntoLibraryMap(LibraryElement libraryElement, ImportDirective importDi
rective) { | 3692 void _putIntoLibraryMap(LibraryElement libraryElement, ImportDirective importD
irective) { |
| 3693 List<ImportDirective> importList = _libraryMap[libraryElement]; | 3693 List<ImportDirective> importList = _libraryMap[libraryElement]; |
| 3694 if (importList == null) { | 3694 if (importList == null) { |
| 3695 importList = new List<ImportDirective>(); | 3695 importList = new List<ImportDirective>(); |
| 3696 _libraryMap[libraryElement] = importList; | 3696 _libraryMap[libraryElement] = importList; |
| 3697 } | 3697 } |
| 3698 importList.add(importDirective); | 3698 importList.add(importDirective); |
| 3699 } | 3699 } |
| 3700 | 3700 |
| 3701 Object visitIdentifier(Element element, String name) { | 3701 Object _visitIdentifier(Element element, String name) { |
| 3702 if (element == null) { | 3702 if (element == null) { |
| 3703 return null; | 3703 return null; |
| 3704 } | 3704 } |
| 3705 // If the element is multiply defined then call this method recursively for
each of the conflicting elements. | 3705 // If the element is multiply defined then call this method recursively for
each of the conflicting elements. |
| 3706 if (element is MultiplyDefinedElement) { | 3706 if (element is MultiplyDefinedElement) { |
| 3707 MultiplyDefinedElement multiplyDefinedElement = element; | 3707 MultiplyDefinedElement multiplyDefinedElement = element; |
| 3708 for (Element elt in multiplyDefinedElement.conflictingElements) { | 3708 for (Element elt in multiplyDefinedElement.conflictingElements) { |
| 3709 visitIdentifier(elt, name); | 3709 _visitIdentifier(elt, name); |
| 3710 } | 3710 } |
| 3711 return null; | 3711 return null; |
| 3712 } else if (element is PrefixElement) { | 3712 } else if (element is PrefixElement) { |
| 3713 _unusedImports.remove(_prefixElementMap[element]); | 3713 _unusedImports.remove(_prefixElementMap[element]); |
| 3714 return null; | 3714 return null; |
| 3715 } else if (element.enclosingElement is! CompilationUnitElement) { | 3715 } else if (element.enclosingElement is! CompilationUnitElement) { |
| 3716 // Identifiers that aren't a prefix element and whose enclosing element is
n't a | 3716 // Identifiers that aren't a prefix element and whose enclosing element is
n't a |
| 3717 // CompilationUnit are ignored- this covers the case the identifier is a r
elative-reference, | 3717 // CompilationUnit are ignored- this covers the case the identifier is a r
elative-reference, |
| 3718 // a reference to an identifier not imported by this library. | 3718 // a reference to an identifier not imported by this library. |
| 3719 return null; | 3719 return null; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3732 } | 3732 } |
| 3733 if (importsFromSameLibrary.length == 1) { | 3733 if (importsFromSameLibrary.length == 1) { |
| 3734 // If there is only one import directive for this library, then it must be
the directive that | 3734 // If there is only one import directive for this library, then it must be
the directive that |
| 3735 // this element is imported with, remove it from the unusedImports list. | 3735 // this element is imported with, remove it from the unusedImports list. |
| 3736 ImportDirective usedImportDirective = importsFromSameLibrary[0]; | 3736 ImportDirective usedImportDirective = importsFromSameLibrary[0]; |
| 3737 _unusedImports.remove(usedImportDirective); | 3737 _unusedImports.remove(usedImportDirective); |
| 3738 } else { | 3738 } else { |
| 3739 // Otherwise, for each of the imported directives, use the namespaceMap to | 3739 // Otherwise, for each of the imported directives, use the namespaceMap to |
| 3740 for (ImportDirective importDirective in importsFromSameLibrary) { | 3740 for (ImportDirective importDirective in importsFromSameLibrary) { |
| 3741 // Get the namespace for this import | 3741 // Get the namespace for this import |
| 3742 Namespace namespace = computeNamespace(importDirective); | 3742 Namespace namespace = _computeNamespace(importDirective); |
| 3743 if (namespace != null && namespace.get(name) != null) { | 3743 if (namespace != null && namespace.get(name) != null) { |
| 3744 _unusedImports.remove(importDirective); | 3744 _unusedImports.remove(importDirective); |
| 3745 } | 3745 } |
| 3746 } | 3746 } |
| 3747 } | 3747 } |
| 3748 return null; | 3748 return null; |
| 3749 } | 3749 } |
| 3750 | 3750 |
| 3751 /** | 3751 /** |
| 3752 * Given some [NodeList] of [Annotation]s, ensure that the identifiers are vis
ited by | 3752 * Given some [NodeList] of [Annotation]s, ensure that the identifiers are vis
ited by |
| 3753 * this visitor. Specifically, this covers the cases where AST nodes don't hav
e their identifiers | 3753 * this visitor. Specifically, this covers the cases where AST nodes don't hav
e their identifiers |
| 3754 * visited by this visitor, but still need their annotations visited. | 3754 * visited by this visitor, but still need their annotations visited. |
| 3755 * | 3755 * |
| 3756 * @param annotations the list of annotations to visit | 3756 * @param annotations the list of annotations to visit |
| 3757 */ | 3757 */ |
| 3758 void visitMetadata(NodeList<Annotation> annotations) { | 3758 void _visitMetadata(NodeList<Annotation> annotations) { |
| 3759 for (Annotation annotation in annotations) { | 3759 for (Annotation annotation in annotations) { |
| 3760 Identifier name = annotation.name; | 3760 Identifier name = annotation.name; |
| 3761 visitIdentifier(name.staticElement, name.name); | 3761 _visitIdentifier(name.staticElement, name.name); |
| 3762 } | 3762 } |
| 3763 } | 3763 } |
| 3764 } | 3764 } |
| 3765 | 3765 |
| 3766 /** | 3766 /** |
| 3767 * Instances of the class `OverrideVerifier` visit all of the declarations in a
compilation | 3767 * Instances of the class `OverrideVerifier` visit all of the declarations in a
compilation |
| 3768 * unit to verify that if they have an override annotation it is being used corr
ectly. | 3768 * unit to verify that if they have an override annotation it is being used corr
ectly. |
| 3769 */ | 3769 */ |
| 3770 class OverrideVerifier extends RecursiveAstVisitor<Object> { | 3770 class OverrideVerifier extends RecursiveAstVisitor<Object> { |
| 3771 /** | 3771 /** |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3784 * @param manager the inheritance manager used to find overridden methods | 3784 * @param manager the inheritance manager used to find overridden methods |
| 3785 * @param errorReporter the error reporter used to report errors | 3785 * @param errorReporter the error reporter used to report errors |
| 3786 */ | 3786 */ |
| 3787 OverrideVerifier(InheritanceManager manager, ErrorReporter errorReporter) { | 3787 OverrideVerifier(InheritanceManager manager, ErrorReporter errorReporter) { |
| 3788 this._manager = manager; | 3788 this._manager = manager; |
| 3789 this._errorReporter = errorReporter; | 3789 this._errorReporter = errorReporter; |
| 3790 } | 3790 } |
| 3791 | 3791 |
| 3792 Object visitMethodDeclaration(MethodDeclaration node) { | 3792 Object visitMethodDeclaration(MethodDeclaration node) { |
| 3793 ExecutableElement element = node.element; | 3793 ExecutableElement element = node.element; |
| 3794 if (isOverride(element)) { | 3794 if (_isOverride(element)) { |
| 3795 if (getOverriddenMember(element) == null) { | 3795 if (_getOverriddenMember(element) == null) { |
| 3796 if (element is MethodElement) { | 3796 if (element is MethodElement) { |
| 3797 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_ON_NON_OVERRIDING_
METHOD, node.name, []); | 3797 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_ON_NON_OVERRIDING_
METHOD, node.name, []); |
| 3798 } else if (element is PropertyAccessorElement) { | 3798 } else if (element is PropertyAccessorElement) { |
| 3799 if (element.isGetter) { | 3799 if (element.isGetter) { |
| 3800 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_ON_NON_OVERRIDIN
G_GETTER, node.name, []); | 3800 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_ON_NON_OVERRIDIN
G_GETTER, node.name, []); |
| 3801 } else { | 3801 } else { |
| 3802 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_ON_NON_OVERRIDIN
G_SETTER, node.name, []); | 3802 _errorReporter.reportErrorForNode(HintCode.OVERRIDE_ON_NON_OVERRIDIN
G_SETTER, node.name, []); |
| 3803 } | 3803 } |
| 3804 } | 3804 } |
| 3805 } | 3805 } |
| 3806 } | 3806 } |
| 3807 return super.visitMethodDeclaration(node); | 3807 return super.visitMethodDeclaration(node); |
| 3808 } | 3808 } |
| 3809 | 3809 |
| 3810 /** | 3810 /** |
| 3811 * Return the member that overrides the given member. | 3811 * Return the member that overrides the given member. |
| 3812 * | 3812 * |
| 3813 * @param member the member that overrides the returned member | 3813 * @param member the member that overrides the returned member |
| 3814 * @return the member that overrides the given member | 3814 * @return the member that overrides the given member |
| 3815 */ | 3815 */ |
| 3816 ExecutableElement getOverriddenMember(ExecutableElement member) { | 3816 ExecutableElement _getOverriddenMember(ExecutableElement member) { |
| 3817 LibraryElement library = member.library; | 3817 LibraryElement library = member.library; |
| 3818 if (library == null) { | 3818 if (library == null) { |
| 3819 return null; | 3819 return null; |
| 3820 } | 3820 } |
| 3821 ClassElement classElement = member.getAncestor((element) => element is Class
Element); | 3821 ClassElement classElement = member.getAncestor((element) => element is Class
Element); |
| 3822 if (classElement == null) { | 3822 if (classElement == null) { |
| 3823 return null; | 3823 return null; |
| 3824 } | 3824 } |
| 3825 return _manager.lookupInheritance(classElement, member.name); | 3825 return _manager.lookupInheritance(classElement, member.name); |
| 3826 } | 3826 } |
| 3827 | 3827 |
| 3828 /** | 3828 /** |
| 3829 * Return `true` if the given element has an override annotation associated wi
th it. | 3829 * Return `true` if the given element has an override annotation associated wi
th it. |
| 3830 * | 3830 * |
| 3831 * @param element the element being tested | 3831 * @param element the element being tested |
| 3832 * @return `true` if the element has an override annotation associated with it | 3832 * @return `true` if the element has an override annotation associated with it |
| 3833 */ | 3833 */ |
| 3834 bool isOverride(Element element) => element != null && element.isOverride; | 3834 bool _isOverride(Element element) => element != null && element.isOverride; |
| 3835 } | 3835 } |
| 3836 | 3836 |
| 3837 /** | 3837 /** |
| 3838 * Instances of the class `PubVerifier` traverse an AST structure looking for de
viations from | 3838 * Instances of the class `PubVerifier` traverse an AST structure looking for de
viations from |
| 3839 * pub best practices. | 3839 * pub best practices. |
| 3840 */ | 3840 */ |
| 3841 class PubVerifier extends RecursiveAstVisitor<Object> { | 3841 class PubVerifier extends RecursiveAstVisitor<Object> { |
| 3842 static String _PUBSPEC_YAML = "pubspec.yaml"; | 3842 static String _PUBSPEC_YAML = "pubspec.yaml"; |
| 3843 | 3843 |
| 3844 /** | 3844 /** |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3863 /** | 3863 /** |
| 3864 * This verifies that the passed file import directive is not contained in a s
ource inside a | 3864 * This verifies that the passed file import directive is not contained in a s
ource inside a |
| 3865 * package "lib" directory hierarchy referencing a source outside that package
"lib" directory | 3865 * package "lib" directory hierarchy referencing a source outside that package
"lib" directory |
| 3866 * hierarchy. | 3866 * hierarchy. |
| 3867 * | 3867 * |
| 3868 * @param uriLiteral the import URL (not `null`) | 3868 * @param uriLiteral the import URL (not `null`) |
| 3869 * @param path the file path being verified (not `null`) | 3869 * @param path the file path being verified (not `null`) |
| 3870 * @return `true` if and only if an error code is generated on the passed node | 3870 * @return `true` if and only if an error code is generated on the passed node |
| 3871 * @see PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE | 3871 * @see PubSuggestionCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE |
| 3872 */ | 3872 */ |
| 3873 bool checkForFileImportInsideLibReferencesFileOutside(StringLiteral uriLiteral
, String path) { | 3873 bool _checkForFileImportInsideLibReferencesFileOutside(StringLiteral uriLitera
l, String path) { |
| 3874 Source source = getSource(uriLiteral); | 3874 Source source = _getSource(uriLiteral); |
| 3875 String fullName = getSourceFullName(source); | 3875 String fullName = _getSourceFullName(source); |
| 3876 if (fullName != null) { | 3876 if (fullName != null) { |
| 3877 int pathIndex = 0; | 3877 int pathIndex = 0; |
| 3878 int fullNameIndex = fullName.length; | 3878 int fullNameIndex = fullName.length; |
| 3879 while (pathIndex < path.length && StringUtilities.startsWith3(path, pathIn
dex, 0x2E, 0x2E, 0x2F)) { | 3879 while (pathIndex < path.length && StringUtilities.startsWith3(path, pathIn
dex, 0x2E, 0x2E, 0x2F)) { |
| 3880 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); | 3880 fullNameIndex = JavaString.lastIndexOf(fullName, '/', fullNameIndex); |
| 3881 if (fullNameIndex < 4) { | 3881 if (fullNameIndex < 4) { |
| 3882 return false; | 3882 return false; |
| 3883 } | 3883 } |
| 3884 // Check for "/lib" at a specified place in the fullName | 3884 // Check for "/lib" at a specified place in the fullName |
| 3885 if (StringUtilities.startsWith4(fullName, fullNameIndex - 4, 0x2F, 0x6C,
0x69, 0x62)) { | 3885 if (StringUtilities.startsWith4(fullName, fullNameIndex - 4, 0x2F, 0x6C,
0x69, 0x62)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3900 /** | 3900 /** |
| 3901 * This verifies that the passed file import directive is not contained in a s
ource outside a | 3901 * This verifies that the passed file import directive is not contained in a s
ource outside a |
| 3902 * package "lib" directory hierarchy referencing a source inside that package
"lib" directory | 3902 * package "lib" directory hierarchy referencing a source inside that package
"lib" directory |
| 3903 * hierarchy. | 3903 * hierarchy. |
| 3904 * | 3904 * |
| 3905 * @param uriLiteral the import URL (not `null`) | 3905 * @param uriLiteral the import URL (not `null`) |
| 3906 * @param path the file path being verified (not `null`) | 3906 * @param path the file path being verified (not `null`) |
| 3907 * @return `true` if and only if an error code is generated on the passed node | 3907 * @return `true` if and only if an error code is generated on the passed node |
| 3908 * @see PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE | 3908 * @see PubSuggestionCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE |
| 3909 */ | 3909 */ |
| 3910 bool checkForFileImportOutsideLibReferencesFileInside(StringLiteral uriLiteral
, String path) { | 3910 bool _checkForFileImportOutsideLibReferencesFileInside(StringLiteral uriLitera
l, String path) { |
| 3911 if (StringUtilities.startsWith4(path, 0, 0x6C, 0x69, 0x62, 0x2F)) { | 3911 if (StringUtilities.startsWith4(path, 0, 0x6C, 0x69, 0x62, 0x2F)) { |
| 3912 if (checkForFileImportOutsideLibReferencesFileInsideAtIndex(uriLiteral, pa
th, 0)) { | 3912 if (_checkForFileImportOutsideLibReferencesFileInsideAtIndex(uriLiteral, p
ath, 0)) { |
| 3913 return true; | 3913 return true; |
| 3914 } | 3914 } |
| 3915 } | 3915 } |
| 3916 int pathIndex = StringUtilities.indexOf5(path, 0, 0x2F, 0x6C, 0x69, 0x62, 0x
2F); | 3916 int pathIndex = StringUtilities.indexOf5(path, 0, 0x2F, 0x6C, 0x69, 0x62, 0x
2F); |
| 3917 while (pathIndex != -1) { | 3917 while (pathIndex != -1) { |
| 3918 if (checkForFileImportOutsideLibReferencesFileInsideAtIndex(uriLiteral, pa
th, pathIndex + 1)) { | 3918 if (_checkForFileImportOutsideLibReferencesFileInsideAtIndex(uriLiteral, p
ath, pathIndex + 1)) { |
| 3919 return true; | 3919 return true; |
| 3920 } | 3920 } |
| 3921 pathIndex = StringUtilities.indexOf5(path, pathIndex + 4, 0x2F, 0x6C, 0x69
, 0x62, 0x2F); | 3921 pathIndex = StringUtilities.indexOf5(path, pathIndex + 4, 0x2F, 0x6C, 0x69
, 0x62, 0x2F); |
| 3922 } | 3922 } |
| 3923 return false; | 3923 return false; |
| 3924 } | 3924 } |
| 3925 | 3925 |
| 3926 bool checkForFileImportOutsideLibReferencesFileInsideAtIndex(StringLiteral uri
Literal, String path, int pathIndex) { | 3926 bool _checkForFileImportOutsideLibReferencesFileInsideAtIndex(StringLiteral ur
iLiteral, String path, int pathIndex) { |
| 3927 Source source = getSource(uriLiteral); | 3927 Source source = _getSource(uriLiteral); |
| 3928 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; | 3928 String relativePubspecPath = path.substring(0, pathIndex) + _PUBSPEC_YAML; |
| 3929 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub
specPath); | 3929 Source pubspecSource = _context.sourceFactory.resolveUri(source, relativePub
specPath); |
| 3930 if (!_context.exists(pubspecSource)) { | 3930 if (!_context.exists(pubspecSource)) { |
| 3931 return false; | 3931 return false; |
| 3932 } | 3932 } |
| 3933 String fullName = getSourceFullName(source); | 3933 String fullName = _getSourceFullName(source); |
| 3934 if (fullName != null) { | 3934 if (fullName != null) { |
| 3935 if (StringUtilities.indexOf5(fullName, 0, 0x2F, 0x6C, 0x69, 0x62, 0x2F) <
0) { | 3935 if (StringUtilities.indexOf5(fullName, 0, 0x2F, 0x6C, 0x69, 0x62, 0x2F) <
0) { |
| 3936 // Files outside the lib directory hierarchy should not reference files
inside | 3936 // Files outside the lib directory hierarchy should not reference files
inside |
| 3937 // ... use package: url instead | 3937 // ... use package: url instead |
| 3938 _errorReporter.reportErrorForNode(PubSuggestionCode.FILE_IMPORT_OUTSIDE_
LIB_REFERENCES_FILE_INSIDE, uriLiteral, []); | 3938 _errorReporter.reportErrorForNode(PubSuggestionCode.FILE_IMPORT_OUTSIDE_
LIB_REFERENCES_FILE_INSIDE, uriLiteral, []); |
| 3939 return true; | 3939 return true; |
| 3940 } | 3940 } |
| 3941 } | 3941 } |
| 3942 return false; | 3942 return false; |
| 3943 } | 3943 } |
| 3944 | 3944 |
| 3945 /** | 3945 /** |
| 3946 * This verifies that the passed package import directive does not contain "..
" | 3946 * This verifies that the passed package import directive does not contain "..
" |
| 3947 * | 3947 * |
| 3948 * @param uriLiteral the import URL (not `null`) | 3948 * @param uriLiteral the import URL (not `null`) |
| 3949 * @param path the path to be validated (not `null`) | 3949 * @param path the path to be validated (not `null`) |
| 3950 * @return `true` if and only if an error code is generated on the passed node | 3950 * @return `true` if and only if an error code is generated on the passed node |
| 3951 * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT | 3951 * @see PubSuggestionCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT |
| 3952 */ | 3952 */ |
| 3953 bool checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String path
) { | 3953 bool _checkForPackageImportContainsDotDot(StringLiteral uriLiteral, String pat
h) { |
| 3954 if (StringUtilities.startsWith3(path, 0, 0x2E, 0x2E, 0x2F) || StringUtilitie
s.indexOf4(path, 0, 0x2F, 0x2E, 0x2E, 0x2F) >= 0) { | 3954 if (StringUtilities.startsWith3(path, 0, 0x2E, 0x2E, 0x2F) || StringUtilitie
s.indexOf4(path, 0, 0x2F, 0x2E, 0x2E, 0x2F) >= 0) { |
| 3955 // Package import should not to contain ".." | 3955 // Package import should not to contain ".." |
| 3956 _errorReporter.reportErrorForNode(PubSuggestionCode.PACKAGE_IMPORT_CONTAIN
S_DOT_DOT, uriLiteral, []); | 3956 _errorReporter.reportErrorForNode(PubSuggestionCode.PACKAGE_IMPORT_CONTAIN
S_DOT_DOT, uriLiteral, []); |
| 3957 return true; | 3957 return true; |
| 3958 } | 3958 } |
| 3959 return false; | 3959 return false; |
| 3960 } | 3960 } |
| 3961 | 3961 |
| 3962 /** | 3962 /** |
| 3963 * Answer the source associated with the compilation unit containing the given
AST node. | 3963 * Answer the source associated with the compilation unit containing the given
AST node. |
| 3964 * | 3964 * |
| 3965 * @param node the node (not `null`) | 3965 * @param node the node (not `null`) |
| 3966 * @return the source or `null` if it could not be determined | 3966 * @return the source or `null` if it could not be determined |
| 3967 */ | 3967 */ |
| 3968 Source getSource(AstNode node) { | 3968 Source _getSource(AstNode node) { |
| 3969 Source source = null; | 3969 Source source = null; |
| 3970 CompilationUnit unit = node.getAncestor((node) => node is CompilationUnit); | 3970 CompilationUnit unit = node.getAncestor((node) => node is CompilationUnit); |
| 3971 if (unit != null) { | 3971 if (unit != null) { |
| 3972 CompilationUnitElement element = unit.element; | 3972 CompilationUnitElement element = unit.element; |
| 3973 if (element != null) { | 3973 if (element != null) { |
| 3974 source = element.source; | 3974 source = element.source; |
| 3975 } | 3975 } |
| 3976 } | 3976 } |
| 3977 return source; | 3977 return source; |
| 3978 } | 3978 } |
| 3979 | 3979 |
| 3980 /** | 3980 /** |
| 3981 * Answer the full name of the given source. The returned value will have all | 3981 * Answer the full name of the given source. The returned value will have all |
| 3982 * [File#separatorChar] replace by '/'. | 3982 * [File#separatorChar] replace by '/'. |
| 3983 * | 3983 * |
| 3984 * @param source the source | 3984 * @param source the source |
| 3985 * @return the full name or `null` if it could not be determined | 3985 * @return the full name or `null` if it could not be determined |
| 3986 */ | 3986 */ |
| 3987 String getSourceFullName(Source source) { | 3987 String _getSourceFullName(Source source) { |
| 3988 if (source != null) { | 3988 if (source != null) { |
| 3989 String fullName = source.fullName; | 3989 String fullName = source.fullName; |
| 3990 if (fullName != null) { | 3990 if (fullName != null) { |
| 3991 return fullName.replaceAll(r'\', '/'); | 3991 return fullName.replaceAll(r'\', '/'); |
| 3992 } | 3992 } |
| 3993 } | 3993 } |
| 3994 return null; | 3994 return null; |
| 3995 } | 3995 } |
| 3996 } | 3996 } |
| 3997 | 3997 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4013 this._errorReporter = errorReporter; | 4013 this._errorReporter = errorReporter; |
| 4014 } | 4014 } |
| 4015 | 4015 |
| 4016 /** | 4016 /** |
| 4017 * Search the comments in the given compilation unit for to-do comments and re
port an error for | 4017 * Search the comments in the given compilation unit for to-do comments and re
port an error for |
| 4018 * each. | 4018 * each. |
| 4019 * | 4019 * |
| 4020 * @param unit the compilation unit containing the to-do comments | 4020 * @param unit the compilation unit containing the to-do comments |
| 4021 */ | 4021 */ |
| 4022 void findIn(CompilationUnit unit) { | 4022 void findIn(CompilationUnit unit) { |
| 4023 gatherTodoComments(unit.beginToken); | 4023 _gatherTodoComments(unit.beginToken); |
| 4024 } | 4024 } |
| 4025 | 4025 |
| 4026 /** | 4026 /** |
| 4027 * Search the comment tokens reachable from the given token and create errors
for each to-do | 4027 * Search the comment tokens reachable from the given token and create errors
for each to-do |
| 4028 * comment. | 4028 * comment. |
| 4029 * | 4029 * |
| 4030 * @param token the head of the list of tokens being searched | 4030 * @param token the head of the list of tokens being searched |
| 4031 */ | 4031 */ |
| 4032 void gatherTodoComments(sc.Token token) { | 4032 void _gatherTodoComments(sc.Token token) { |
| 4033 while (token != null && token.type != sc.TokenType.EOF) { | 4033 while (token != null && token.type != sc.TokenType.EOF) { |
| 4034 sc.Token commentToken = token.precedingComments; | 4034 sc.Token commentToken = token.precedingComments; |
| 4035 while (commentToken != null) { | 4035 while (commentToken != null) { |
| 4036 if (identical(commentToken.type, sc.TokenType.SINGLE_LINE_COMMENT) || id
entical(commentToken.type, sc.TokenType.MULTI_LINE_COMMENT)) { | 4036 if (identical(commentToken.type, sc.TokenType.SINGLE_LINE_COMMENT) || id
entical(commentToken.type, sc.TokenType.MULTI_LINE_COMMENT)) { |
| 4037 scrapeTodoComment(commentToken); | 4037 _scrapeTodoComment(commentToken); |
| 4038 } | 4038 } |
| 4039 commentToken = commentToken.next; | 4039 commentToken = commentToken.next; |
| 4040 } | 4040 } |
| 4041 token = token.next; | 4041 token = token.next; |
| 4042 } | 4042 } |
| 4043 } | 4043 } |
| 4044 | 4044 |
| 4045 /** | 4045 /** |
| 4046 * Look for user defined tasks in comments and convert them into info level an
alysis issues. | 4046 * Look for user defined tasks in comments and convert them into info level an
alysis issues. |
| 4047 * | 4047 * |
| 4048 * @param commentToken the comment token to analyze | 4048 * @param commentToken the comment token to analyze |
| 4049 */ | 4049 */ |
| 4050 void scrapeTodoComment(sc.Token commentToken) { | 4050 void _scrapeTodoComment(sc.Token commentToken) { |
| 4051 JavaPatternMatcher matcher = new JavaPatternMatcher(TodoCode.TODO_REGEX, com
mentToken.lexeme); | 4051 JavaPatternMatcher matcher = new JavaPatternMatcher(TodoCode.TODO_REGEX, com
mentToken.lexeme); |
| 4052 if (matcher.find()) { | 4052 if (matcher.find()) { |
| 4053 int offset = commentToken.offset + matcher.start() + matcher.group(1).leng
th; | 4053 int offset = commentToken.offset + matcher.start() + matcher.group(1).leng
th; |
| 4054 int length = matcher.group(2).length; | 4054 int length = matcher.group(2).length; |
| 4055 _errorReporter.reportErrorForOffset(TodoCode.TODO, offset, length, [matche
r.group(2)]); | 4055 _errorReporter.reportErrorForOffset(TodoCode.TODO, offset, length, [matche
r.group(2)]); |
| 4056 } | 4056 } |
| 4057 } | 4057 } |
| 4058 } | 4058 } |
| 4059 | 4059 |
| 4060 /** | 4060 /** |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4107 /** | 4107 /** |
| 4108 * Return `true` if the declarations within the given AST structure define an
element model | 4108 * Return `true` if the declarations within the given AST structure define an
element model |
| 4109 * that is equivalent to the corresponding elements rooted at the given elemen
t. | 4109 * that is equivalent to the corresponding elements rooted at the given elemen
t. |
| 4110 * | 4110 * |
| 4111 * @param node the AST structure being compared to the element model | 4111 * @param node the AST structure being compared to the element model |
| 4112 * @param element the root of the element model being compared to the AST stru
cture | 4112 * @param element the root of the element model being compared to the AST stru
cture |
| 4113 * @return `true` if the AST structure defines the same elements as those in t
he given | 4113 * @return `true` if the AST structure defines the same elements as those in t
he given |
| 4114 * element model | 4114 * element model |
| 4115 */ | 4115 */ |
| 4116 bool matches(AstNode node, Element element) { | 4116 bool matches(AstNode node, Element element) { |
| 4117 captureEnclosingElements(element); | 4117 _captureEnclosingElements(element); |
| 4118 gatherElements(element); | 4118 _gatherElements(element); |
| 4119 try { | 4119 try { |
| 4120 node.accept(this); | 4120 node.accept(this); |
| 4121 } on DeclarationMatcher_DeclarationMismatchException catch (exception) { | 4121 } on DeclarationMatcher_DeclarationMismatchException catch (exception) { |
| 4122 return false; | 4122 return false; |
| 4123 } | 4123 } |
| 4124 return _unmatchedElements.isEmpty; | 4124 return _unmatchedElements.isEmpty; |
| 4125 } | 4125 } |
| 4126 | 4126 |
| 4127 Object visitCatchClause(CatchClause node) { | 4127 Object visitCatchClause(CatchClause node) { |
| 4128 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 4128 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
| 4129 if (exceptionParameter != null) { | 4129 if (exceptionParameter != null) { |
| 4130 List<LocalVariableElement> localVariables = _enclosingExecutable.localVari
ables; | 4130 List<LocalVariableElement> localVariables = _enclosingExecutable.localVari
ables; |
| 4131 LocalVariableElement exceptionElement = findIdentifier(localVariables, exc
eptionParameter); | 4131 LocalVariableElement exceptionElement = _findIdentifier(localVariables, ex
ceptionParameter); |
| 4132 processElement(exceptionElement); | 4132 processElement(exceptionElement); |
| 4133 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | 4133 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
| 4134 if (stackTraceParameter != null) { | 4134 if (stackTraceParameter != null) { |
| 4135 LocalVariableElement stackTraceElement = findIdentifier(localVariables,
stackTraceParameter); | 4135 LocalVariableElement stackTraceElement = _findIdentifier(localVariables,
stackTraceParameter); |
| 4136 processElement(stackTraceElement); | 4136 processElement(stackTraceElement); |
| 4137 } | 4137 } |
| 4138 } | 4138 } |
| 4139 return super.visitCatchClause(node); | 4139 return super.visitCatchClause(node); |
| 4140 } | 4140 } |
| 4141 | 4141 |
| 4142 Object visitClassDeclaration(ClassDeclaration node) { | 4142 Object visitClassDeclaration(ClassDeclaration node) { |
| 4143 ClassElement outerClass = _enclosingClass; | 4143 ClassElement outerClass = _enclosingClass; |
| 4144 try { | 4144 try { |
| 4145 SimpleIdentifier className = node.name; | 4145 SimpleIdentifier className = node.name; |
| 4146 _enclosingClass = findIdentifier(_enclosingUnit.types, className); | 4146 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 4147 processElement(_enclosingClass); | 4147 processElement(_enclosingClass); |
| 4148 if (!hasConstructor(node)) { | 4148 if (!_hasConstructor(node)) { |
| 4149 ConstructorElement constructor = _enclosingClass.unnamedConstructor; | 4149 ConstructorElement constructor = _enclosingClass.unnamedConstructor; |
| 4150 if (constructor.isSynthetic) { | 4150 if (constructor.isSynthetic) { |
| 4151 processElement(constructor); | 4151 processElement(constructor); |
| 4152 } | 4152 } |
| 4153 } | 4153 } |
| 4154 return super.visitClassDeclaration(node); | 4154 return super.visitClassDeclaration(node); |
| 4155 } finally { | 4155 } finally { |
| 4156 _enclosingClass = outerClass; | 4156 _enclosingClass = outerClass; |
| 4157 } | 4157 } |
| 4158 } | 4158 } |
| 4159 | 4159 |
| 4160 Object visitClassTypeAlias(ClassTypeAlias node) { | 4160 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 4161 ClassElement outerClass = _enclosingClass; | 4161 ClassElement outerClass = _enclosingClass; |
| 4162 try { | 4162 try { |
| 4163 SimpleIdentifier className = node.name; | 4163 SimpleIdentifier className = node.name; |
| 4164 _enclosingClass = findIdentifier(_enclosingUnit.types, className); | 4164 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 4165 processElement(_enclosingClass); | 4165 processElement(_enclosingClass); |
| 4166 return super.visitClassTypeAlias(node); | 4166 return super.visitClassTypeAlias(node); |
| 4167 } finally { | 4167 } finally { |
| 4168 _enclosingClass = outerClass; | 4168 _enclosingClass = outerClass; |
| 4169 } | 4169 } |
| 4170 } | 4170 } |
| 4171 | 4171 |
| 4172 Object visitCompilationUnit(CompilationUnit node) { | 4172 Object visitCompilationUnit(CompilationUnit node) { |
| 4173 processElement(_enclosingUnit); | 4173 processElement(_enclosingUnit); |
| 4174 return super.visitCompilationUnit(node); | 4174 return super.visitCompilationUnit(node); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4185 } | 4185 } |
| 4186 processElement(_enclosingExecutable); | 4186 processElement(_enclosingExecutable); |
| 4187 return super.visitConstructorDeclaration(node); | 4187 return super.visitConstructorDeclaration(node); |
| 4188 } finally { | 4188 } finally { |
| 4189 _enclosingExecutable = outerExecutable; | 4189 _enclosingExecutable = outerExecutable; |
| 4190 } | 4190 } |
| 4191 } | 4191 } |
| 4192 | 4192 |
| 4193 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 4193 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 4194 SimpleIdentifier variableName = node.identifier; | 4194 SimpleIdentifier variableName = node.identifier; |
| 4195 LocalVariableElement element = findIdentifier(_enclosingExecutable.localVari
ables, variableName); | 4195 LocalVariableElement element = _findIdentifier(_enclosingExecutable.localVar
iables, variableName); |
| 4196 processElement(element); | 4196 processElement(element); |
| 4197 return super.visitDeclaredIdentifier(node); | 4197 return super.visitDeclaredIdentifier(node); |
| 4198 } | 4198 } |
| 4199 | 4199 |
| 4200 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 4200 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 4201 SimpleIdentifier parameterName = node.parameter.identifier; | 4201 SimpleIdentifier parameterName = node.parameter.identifier; |
| 4202 ParameterElement element = getElementForParameter(node, parameterName); | 4202 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4203 Expression defaultValue = node.defaultValue; | 4203 Expression defaultValue = node.defaultValue; |
| 4204 if (defaultValue != null) { | 4204 if (defaultValue != null) { |
| 4205 ExecutableElement outerExecutable = _enclosingExecutable; | 4205 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4206 try { | 4206 try { |
| 4207 if (element == null) { | 4207 if (element == null) { |
| 4208 } else { | 4208 } else { |
| 4209 _enclosingExecutable = element.initializer; | 4209 _enclosingExecutable = element.initializer; |
| 4210 } | 4210 } |
| 4211 defaultValue.accept(this); | 4211 defaultValue.accept(this); |
| 4212 } finally { | 4212 } finally { |
| 4213 _enclosingExecutable = outerExecutable; | 4213 _enclosingExecutable = outerExecutable; |
| 4214 } | 4214 } |
| 4215 processElement(_enclosingExecutable); | 4215 processElement(_enclosingExecutable); |
| 4216 } | 4216 } |
| 4217 ParameterElement outerParameter = _enclosingParameter; | 4217 ParameterElement outerParameter = _enclosingParameter; |
| 4218 try { | 4218 try { |
| 4219 _enclosingParameter = element; | 4219 _enclosingParameter = element; |
| 4220 processElement(_enclosingParameter); | 4220 processElement(_enclosingParameter); |
| 4221 return super.visitDefaultFormalParameter(node); | 4221 return super.visitDefaultFormalParameter(node); |
| 4222 } finally { | 4222 } finally { |
| 4223 _enclosingParameter = outerParameter; | 4223 _enclosingParameter = outerParameter; |
| 4224 } | 4224 } |
| 4225 } | 4225 } |
| 4226 | 4226 |
| 4227 Object visitExportDirective(ExportDirective node) { | 4227 Object visitExportDirective(ExportDirective node) { |
| 4228 String uri = getStringValue(node.uri); | 4228 String uri = _getStringValue(node.uri); |
| 4229 if (uri != null) { | 4229 if (uri != null) { |
| 4230 LibraryElement library = _enclosingUnit.library; | 4230 LibraryElement library = _enclosingUnit.library; |
| 4231 ExportElement exportElement = findExport(library.exports, _enclosingUnit.c
ontext.sourceFactory.resolveUri(_enclosingUnit.source, uri)); | 4231 ExportElement exportElement = _findExport(library.exports, _enclosingUnit.
context.sourceFactory.resolveUri(_enclosingUnit.source, uri)); |
| 4232 processElement(exportElement); | 4232 processElement(exportElement); |
| 4233 } | 4233 } |
| 4234 return super.visitExportDirective(node); | 4234 return super.visitExportDirective(node); |
| 4235 } | 4235 } |
| 4236 | 4236 |
| 4237 Object visitFieldFormalParameter(FieldFormalParameter node) { | 4237 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 4238 if (node.parent is! DefaultFormalParameter) { | 4238 if (node.parent is! DefaultFormalParameter) { |
| 4239 SimpleIdentifier parameterName = node.identifier; | 4239 SimpleIdentifier parameterName = node.identifier; |
| 4240 ParameterElement element = getElementForParameter(node, parameterName); | 4240 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4241 ParameterElement outerParameter = _enclosingParameter; | 4241 ParameterElement outerParameter = _enclosingParameter; |
| 4242 try { | 4242 try { |
| 4243 _enclosingParameter = element; | 4243 _enclosingParameter = element; |
| 4244 processElement(_enclosingParameter); | 4244 processElement(_enclosingParameter); |
| 4245 return super.visitFieldFormalParameter(node); | 4245 return super.visitFieldFormalParameter(node); |
| 4246 } finally { | 4246 } finally { |
| 4247 _enclosingParameter = outerParameter; | 4247 _enclosingParameter = outerParameter; |
| 4248 } | 4248 } |
| 4249 } else { | 4249 } else { |
| 4250 return super.visitFieldFormalParameter(node); | 4250 return super.visitFieldFormalParameter(node); |
| 4251 } | 4251 } |
| 4252 } | 4252 } |
| 4253 | 4253 |
| 4254 Object visitFunctionDeclaration(FunctionDeclaration node) { | 4254 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 4255 ExecutableElement outerExecutable = _enclosingExecutable; | 4255 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4256 try { | 4256 try { |
| 4257 SimpleIdentifier functionName = node.name; | 4257 SimpleIdentifier functionName = node.name; |
| 4258 sc.Token property = node.propertyKeyword; | 4258 sc.Token property = node.propertyKeyword; |
| 4259 if (property == null) { | 4259 if (property == null) { |
| 4260 if (_enclosingExecutable != null) { | 4260 if (_enclosingExecutable != null) { |
| 4261 _enclosingExecutable = findIdentifier(_enclosingExecutable.functions,
functionName); | 4261 _enclosingExecutable = _findIdentifier(_enclosingExecutable.functions,
functionName); |
| 4262 } else { | 4262 } else { |
| 4263 _enclosingExecutable = findIdentifier(_enclosingUnit.functions, functi
onName); | 4263 _enclosingExecutable = _findIdentifier(_enclosingUnit.functions, funct
ionName); |
| 4264 } | 4264 } |
| 4265 } else { | 4265 } else { |
| 4266 PropertyAccessorElement accessor = findIdentifier(_enclosingUnit.accesso
rs, functionName); | 4266 PropertyAccessorElement accessor = _findIdentifier(_enclosingUnit.access
ors, functionName); |
| 4267 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { | 4267 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { |
| 4268 accessor = accessor.variable.setter; | 4268 accessor = accessor.variable.setter; |
| 4269 } | 4269 } |
| 4270 _enclosingExecutable = accessor; | 4270 _enclosingExecutable = accessor; |
| 4271 } | 4271 } |
| 4272 processElement(_enclosingExecutable); | 4272 processElement(_enclosingExecutable); |
| 4273 return super.visitFunctionDeclaration(node); | 4273 return super.visitFunctionDeclaration(node); |
| 4274 } finally { | 4274 } finally { |
| 4275 _enclosingExecutable = outerExecutable; | 4275 _enclosingExecutable = outerExecutable; |
| 4276 } | 4276 } |
| 4277 } | 4277 } |
| 4278 | 4278 |
| 4279 Object visitFunctionExpression(FunctionExpression node) { | 4279 Object visitFunctionExpression(FunctionExpression node) { |
| 4280 if (node.parent is! FunctionDeclaration) { | 4280 if (node.parent is! FunctionDeclaration) { |
| 4281 FunctionElement element = findAtOffset(_enclosingExecutable.functions, nod
e.beginToken.offset); | 4281 FunctionElement element = _findAtOffset(_enclosingExecutable.functions, no
de.beginToken.offset); |
| 4282 processElement(element); | 4282 processElement(element); |
| 4283 } | 4283 } |
| 4284 ExecutableElement outerExecutable = _enclosingExecutable; | 4284 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4285 try { | 4285 try { |
| 4286 _enclosingExecutable = node.element; | 4286 _enclosingExecutable = node.element; |
| 4287 processElement(_enclosingExecutable); | 4287 processElement(_enclosingExecutable); |
| 4288 return super.visitFunctionExpression(node); | 4288 return super.visitFunctionExpression(node); |
| 4289 } finally { | 4289 } finally { |
| 4290 _enclosingExecutable = outerExecutable; | 4290 _enclosingExecutable = outerExecutable; |
| 4291 } | 4291 } |
| 4292 } | 4292 } |
| 4293 | 4293 |
| 4294 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 4294 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 4295 FunctionTypeAliasElement outerAlias = _enclosingAlias; | 4295 FunctionTypeAliasElement outerAlias = _enclosingAlias; |
| 4296 try { | 4296 try { |
| 4297 SimpleIdentifier aliasName = node.name; | 4297 SimpleIdentifier aliasName = node.name; |
| 4298 _enclosingAlias = findIdentifier(_enclosingUnit.functionTypeAliases, alias
Name); | 4298 _enclosingAlias = _findIdentifier(_enclosingUnit.functionTypeAliases, alia
sName); |
| 4299 processElement(_enclosingAlias); | 4299 processElement(_enclosingAlias); |
| 4300 return super.visitFunctionTypeAlias(node); | 4300 return super.visitFunctionTypeAlias(node); |
| 4301 } finally { | 4301 } finally { |
| 4302 _enclosingAlias = outerAlias; | 4302 _enclosingAlias = outerAlias; |
| 4303 } | 4303 } |
| 4304 } | 4304 } |
| 4305 | 4305 |
| 4306 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 4306 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 4307 if (node.parent is! DefaultFormalParameter) { | 4307 if (node.parent is! DefaultFormalParameter) { |
| 4308 SimpleIdentifier parameterName = node.identifier; | 4308 SimpleIdentifier parameterName = node.identifier; |
| 4309 ParameterElement element = getElementForParameter(node, parameterName); | 4309 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4310 ParameterElement outerParameter = _enclosingParameter; | 4310 ParameterElement outerParameter = _enclosingParameter; |
| 4311 try { | 4311 try { |
| 4312 _enclosingParameter = element; | 4312 _enclosingParameter = element; |
| 4313 processElement(_enclosingParameter); | 4313 processElement(_enclosingParameter); |
| 4314 return super.visitFunctionTypedFormalParameter(node); | 4314 return super.visitFunctionTypedFormalParameter(node); |
| 4315 } finally { | 4315 } finally { |
| 4316 _enclosingParameter = outerParameter; | 4316 _enclosingParameter = outerParameter; |
| 4317 } | 4317 } |
| 4318 } else { | 4318 } else { |
| 4319 return super.visitFunctionTypedFormalParameter(node); | 4319 return super.visitFunctionTypedFormalParameter(node); |
| 4320 } | 4320 } |
| 4321 } | 4321 } |
| 4322 | 4322 |
| 4323 Object visitImportDirective(ImportDirective node) { | 4323 Object visitImportDirective(ImportDirective node) { |
| 4324 String uri = getStringValue(node.uri); | 4324 String uri = _getStringValue(node.uri); |
| 4325 if (uri != null) { | 4325 if (uri != null) { |
| 4326 LibraryElement library = _enclosingUnit.library; | 4326 LibraryElement library = _enclosingUnit.library; |
| 4327 ImportElement importElement = findImport(library.imports, _enclosingUnit.c
ontext.sourceFactory.resolveUri(_enclosingUnit.source, uri), node.prefix); | 4327 ImportElement importElement = _findImport(library.imports, _enclosingUnit.
context.sourceFactory.resolveUri(_enclosingUnit.source, uri), node.prefix); |
| 4328 processElement(importElement); | 4328 processElement(importElement); |
| 4329 } | 4329 } |
| 4330 return super.visitImportDirective(node); | 4330 return super.visitImportDirective(node); |
| 4331 } | 4331 } |
| 4332 | 4332 |
| 4333 Object visitLabeledStatement(LabeledStatement node) { | 4333 Object visitLabeledStatement(LabeledStatement node) { |
| 4334 for (Label label in node.labels) { | 4334 for (Label label in node.labels) { |
| 4335 SimpleIdentifier labelName = label.label; | 4335 SimpleIdentifier labelName = label.label; |
| 4336 LabelElement element = findIdentifier(_enclosingExecutable.labels, labelNa
me); | 4336 LabelElement element = _findIdentifier(_enclosingExecutable.labels, labelN
ame); |
| 4337 processElement(element); | 4337 processElement(element); |
| 4338 } | 4338 } |
| 4339 return super.visitLabeledStatement(node); | 4339 return super.visitLabeledStatement(node); |
| 4340 } | 4340 } |
| 4341 | 4341 |
| 4342 Object visitMethodDeclaration(MethodDeclaration node) { | 4342 Object visitMethodDeclaration(MethodDeclaration node) { |
| 4343 ExecutableElement outerExecutable = _enclosingExecutable; | 4343 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4344 try { | 4344 try { |
| 4345 sc.Token property = node.propertyKeyword; | 4345 sc.Token property = node.propertyKeyword; |
| 4346 SimpleIdentifier methodName = node.name; | 4346 SimpleIdentifier methodName = node.name; |
| 4347 String nameOfMethod = methodName.name; | 4347 String nameOfMethod = methodName.name; |
| 4348 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter
s.length == 0) { | 4348 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter
s.length == 0) { |
| 4349 nameOfMethod = "unary-"; | 4349 nameOfMethod = "unary-"; |
| 4350 } | 4350 } |
| 4351 if (property == null) { | 4351 if (property == null) { |
| 4352 _enclosingExecutable = findWithNameAndOffset(_enclosingClass.methods, na
meOfMethod, methodName.offset); | 4352 _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods, n
ameOfMethod, methodName.offset); |
| 4353 methodName.staticElement = _enclosingExecutable; | 4353 methodName.staticElement = _enclosingExecutable; |
| 4354 } else { | 4354 } else { |
| 4355 PropertyAccessorElement accessor = findIdentifier(_enclosingClass.access
ors, methodName); | 4355 PropertyAccessorElement accessor = _findIdentifier(_enclosingClass.acces
sors, methodName); |
| 4356 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { | 4356 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { |
| 4357 accessor = accessor.variable.setter; | 4357 accessor = accessor.variable.setter; |
| 4358 methodName.staticElement = accessor; | 4358 methodName.staticElement = accessor; |
| 4359 } | 4359 } |
| 4360 _enclosingExecutable = accessor; | 4360 _enclosingExecutable = accessor; |
| 4361 } | 4361 } |
| 4362 processElement(_enclosingExecutable); | 4362 processElement(_enclosingExecutable); |
| 4363 return super.visitMethodDeclaration(node); | 4363 return super.visitMethodDeclaration(node); |
| 4364 } finally { | 4364 } finally { |
| 4365 _enclosingExecutable = outerExecutable; | 4365 _enclosingExecutable = outerExecutable; |
| 4366 } | 4366 } |
| 4367 } | 4367 } |
| 4368 | 4368 |
| 4369 Object visitPartDirective(PartDirective node) { | 4369 Object visitPartDirective(PartDirective node) { |
| 4370 String uri = getStringValue(node.uri); | 4370 String uri = _getStringValue(node.uri); |
| 4371 if (uri != null) { | 4371 if (uri != null) { |
| 4372 Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(_enclo
singUnit.source, uri); | 4372 Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(_enclo
singUnit.source, uri); |
| 4373 CompilationUnitElement element = findPart(_enclosingUnit.library.parts, pa
rtSource); | 4373 CompilationUnitElement element = _findPart(_enclosingUnit.library.parts, p
artSource); |
| 4374 processElement(element); | 4374 processElement(element); |
| 4375 } | 4375 } |
| 4376 return super.visitPartDirective(node); | 4376 return super.visitPartDirective(node); |
| 4377 } | 4377 } |
| 4378 | 4378 |
| 4379 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 4379 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 4380 if (node.parent is! DefaultFormalParameter) { | 4380 if (node.parent is! DefaultFormalParameter) { |
| 4381 SimpleIdentifier parameterName = node.identifier; | 4381 SimpleIdentifier parameterName = node.identifier; |
| 4382 ParameterElement element = getElementForParameter(node, parameterName); | 4382 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4383 ParameterElement outerParameter = _enclosingParameter; | 4383 ParameterElement outerParameter = _enclosingParameter; |
| 4384 try { | 4384 try { |
| 4385 _enclosingParameter = element; | 4385 _enclosingParameter = element; |
| 4386 processElement(_enclosingParameter); | 4386 processElement(_enclosingParameter); |
| 4387 return super.visitSimpleFormalParameter(node); | 4387 return super.visitSimpleFormalParameter(node); |
| 4388 } finally { | 4388 } finally { |
| 4389 _enclosingParameter = outerParameter; | 4389 _enclosingParameter = outerParameter; |
| 4390 } | 4390 } |
| 4391 } else { | 4391 } else { |
| 4392 } | 4392 } |
| 4393 return super.visitSimpleFormalParameter(node); | 4393 return super.visitSimpleFormalParameter(node); |
| 4394 } | 4394 } |
| 4395 | 4395 |
| 4396 Object visitSwitchCase(SwitchCase node) { | 4396 Object visitSwitchCase(SwitchCase node) { |
| 4397 for (Label label in node.labels) { | 4397 for (Label label in node.labels) { |
| 4398 SimpleIdentifier labelName = label.label; | 4398 SimpleIdentifier labelName = label.label; |
| 4399 LabelElement element = findIdentifier(_enclosingExecutable.labels, labelNa
me); | 4399 LabelElement element = _findIdentifier(_enclosingExecutable.labels, labelN
ame); |
| 4400 processElement(element); | 4400 processElement(element); |
| 4401 } | 4401 } |
| 4402 return super.visitSwitchCase(node); | 4402 return super.visitSwitchCase(node); |
| 4403 } | 4403 } |
| 4404 | 4404 |
| 4405 Object visitSwitchDefault(SwitchDefault node) { | 4405 Object visitSwitchDefault(SwitchDefault node) { |
| 4406 for (Label label in node.labels) { | 4406 for (Label label in node.labels) { |
| 4407 SimpleIdentifier labelName = label.label; | 4407 SimpleIdentifier labelName = label.label; |
| 4408 LabelElement element = findIdentifier(_enclosingExecutable.labels, labelNa
me); | 4408 LabelElement element = _findIdentifier(_enclosingExecutable.labels, labelN
ame); |
| 4409 processElement(element); | 4409 processElement(element); |
| 4410 } | 4410 } |
| 4411 return super.visitSwitchDefault(node); | 4411 return super.visitSwitchDefault(node); |
| 4412 } | 4412 } |
| 4413 | 4413 |
| 4414 Object visitTypeParameter(TypeParameter node) { | 4414 Object visitTypeParameter(TypeParameter node) { |
| 4415 SimpleIdentifier parameterName = node.name; | 4415 SimpleIdentifier parameterName = node.name; |
| 4416 TypeParameterElement element = null; | 4416 TypeParameterElement element = null; |
| 4417 if (_enclosingClass != null) { | 4417 if (_enclosingClass != null) { |
| 4418 element = findIdentifier(_enclosingClass.typeParameters, parameterName); | 4418 element = _findIdentifier(_enclosingClass.typeParameters, parameterName); |
| 4419 } else if (_enclosingAlias != null) { | 4419 } else if (_enclosingAlias != null) { |
| 4420 element = findIdentifier(_enclosingAlias.typeParameters, parameterName); | 4420 element = _findIdentifier(_enclosingAlias.typeParameters, parameterName); |
| 4421 } | 4421 } |
| 4422 processElement(element); | 4422 processElement(element); |
| 4423 return super.visitTypeParameter(node); | 4423 return super.visitTypeParameter(node); |
| 4424 } | 4424 } |
| 4425 | 4425 |
| 4426 Object visitVariableDeclaration(VariableDeclaration node) { | 4426 Object visitVariableDeclaration(VariableDeclaration node) { |
| 4427 VariableElement element = null; | 4427 VariableElement element = null; |
| 4428 SimpleIdentifier variableName = node.name; | 4428 SimpleIdentifier variableName = node.name; |
| 4429 if (_enclosingExecutable != null) { | 4429 if (_enclosingExecutable != null) { |
| 4430 element = findIdentifier(_enclosingExecutable.localVariables, variableName
); | 4430 element = _findIdentifier(_enclosingExecutable.localVariables, variableNam
e); |
| 4431 } | 4431 } |
| 4432 if (element == null && _enclosingClass != null) { | 4432 if (element == null && _enclosingClass != null) { |
| 4433 element = findIdentifier(_enclosingClass.fields, variableName); | 4433 element = _findIdentifier(_enclosingClass.fields, variableName); |
| 4434 } | 4434 } |
| 4435 if (element == null && _enclosingUnit != null) { | 4435 if (element == null && _enclosingUnit != null) { |
| 4436 element = findIdentifier(_enclosingUnit.topLevelVariables, variableName); | 4436 element = _findIdentifier(_enclosingUnit.topLevelVariables, variableName); |
| 4437 } | 4437 } |
| 4438 Expression initializer = node.initializer; | 4438 Expression initializer = node.initializer; |
| 4439 if (initializer != null) { | 4439 if (initializer != null) { |
| 4440 ExecutableElement outerExecutable = _enclosingExecutable; | 4440 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4441 try { | 4441 try { |
| 4442 if (element == null) { | 4442 if (element == null) { |
| 4443 } else { | 4443 } else { |
| 4444 _enclosingExecutable = element.initializer; | 4444 _enclosingExecutable = element.initializer; |
| 4445 } | 4445 } |
| 4446 processElement(element); | 4446 processElement(element); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4462 } | 4462 } |
| 4463 _unmatchedElements.remove(element); | 4463 _unmatchedElements.remove(element); |
| 4464 } | 4464 } |
| 4465 | 4465 |
| 4466 /** | 4466 /** |
| 4467 * Given that the comparison is to begin with the given element, capture the e
nclosing elements | 4467 * Given that the comparison is to begin with the given element, capture the e
nclosing elements |
| 4468 * that might be used while performing the comparison. | 4468 * that might be used while performing the comparison. |
| 4469 * | 4469 * |
| 4470 * @param element the element corresponding to the AST structure to be compare
d | 4470 * @param element the element corresponding to the AST structure to be compare
d |
| 4471 */ | 4471 */ |
| 4472 void captureEnclosingElements(Element element) { | 4472 void _captureEnclosingElements(Element element) { |
| 4473 Element parent = element is CompilationUnitElement ? element : element.enclo
singElement; | 4473 Element parent = element is CompilationUnitElement ? element : element.enclo
singElement; |
| 4474 while (parent != null) { | 4474 while (parent != null) { |
| 4475 if (parent is CompilationUnitElement) { | 4475 if (parent is CompilationUnitElement) { |
| 4476 _enclosingUnit = parent as CompilationUnitElement; | 4476 _enclosingUnit = parent as CompilationUnitElement; |
| 4477 } else if (parent is ClassElement) { | 4477 } else if (parent is ClassElement) { |
| 4478 if (_enclosingClass == null) { | 4478 if (_enclosingClass == null) { |
| 4479 _enclosingClass = parent as ClassElement; | 4479 _enclosingClass = parent as ClassElement; |
| 4480 } | 4480 } |
| 4481 } else if (parent is FunctionTypeAliasElement) { | 4481 } else if (parent is FunctionTypeAliasElement) { |
| 4482 if (_enclosingAlias == null) { | 4482 if (_enclosingAlias == null) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4496 } | 4496 } |
| 4497 | 4497 |
| 4498 /** | 4498 /** |
| 4499 * Return the element in the given array of elements that was created for the
declaration at the | 4499 * Return the element in the given array of elements that was created for the
declaration at the |
| 4500 * given offset. This method should only be used when there is no name | 4500 * given offset. This method should only be used when there is no name |
| 4501 * | 4501 * |
| 4502 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 4502 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 4503 * @param offset the offset of the name of the element to be returned | 4503 * @param offset the offset of the name of the element to be returned |
| 4504 * @return the element at the given offset | 4504 * @return the element at the given offset |
| 4505 */ | 4505 */ |
| 4506 Element findAtOffset(List<Element> elements, int offset) => findWithNameAndOff
set(elements, "", offset); | 4506 Element _findAtOffset(List<Element> elements, int offset) => _findWithNameAndO
ffset(elements, "", offset); |
| 4507 | 4507 |
| 4508 /** | 4508 /** |
| 4509 * Return the export element from the given array whose library has the given
source, or | 4509 * Return the export element from the given array whose library has the given
source, or |
| 4510 * `null` if there is no such export. | 4510 * `null` if there is no such export. |
| 4511 * | 4511 * |
| 4512 * @param exports the export elements being searched | 4512 * @param exports the export elements being searched |
| 4513 * @param source the source of the library associated with the export element
to being searched | 4513 * @param source the source of the library associated with the export element
to being searched |
| 4514 * for | 4514 * for |
| 4515 * @return the export element whose library has the given source | 4515 * @return the export element whose library has the given source |
| 4516 */ | 4516 */ |
| 4517 ExportElement findExport(List<ExportElement> exports, Source source) { | 4517 ExportElement _findExport(List<ExportElement> exports, Source source) { |
| 4518 for (ExportElement export in exports) { | 4518 for (ExportElement export in exports) { |
| 4519 if (export.exportedLibrary.source == source) { | 4519 if (export.exportedLibrary.source == source) { |
| 4520 return export; | 4520 return export; |
| 4521 } | 4521 } |
| 4522 } | 4522 } |
| 4523 return null; | 4523 return null; |
| 4524 } | 4524 } |
| 4525 | 4525 |
| 4526 /** | 4526 /** |
| 4527 * Return the element in the given array of elements that was created for the
declaration with the | 4527 * Return the element in the given array of elements that was created for the
declaration with the |
| 4528 * given name. | 4528 * given name. |
| 4529 * | 4529 * |
| 4530 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 4530 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 4531 * @param identifier the name node in the declaration of the element to be ret
urned | 4531 * @param identifier the name node in the declaration of the element to be ret
urned |
| 4532 * @return the element created for the declaration with the given name | 4532 * @return the element created for the declaration with the given name |
| 4533 */ | 4533 */ |
| 4534 Element findIdentifier(List<Element> elements, SimpleIdentifier identifier) =>
findWithNameAndOffset(elements, identifier.name, identifier.offset); | 4534 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier) =
> _findWithNameAndOffset(elements, identifier.name, identifier.offset); |
| 4535 | 4535 |
| 4536 /** | 4536 /** |
| 4537 * Return the import element from the given array whose library has the given
source and that has | 4537 * Return the import element from the given array whose library has the given
source and that has |
| 4538 * the given prefix, or `null` if there is no such import. | 4538 * the given prefix, or `null` if there is no such import. |
| 4539 * | 4539 * |
| 4540 * @param imports the import elements being searched | 4540 * @param imports the import elements being searched |
| 4541 * @param source the source of the library associated with the import element
to being searched | 4541 * @param source the source of the library associated with the import element
to being searched |
| 4542 * for | 4542 * for |
| 4543 * @param prefix the prefix with which the library was imported | 4543 * @param prefix the prefix with which the library was imported |
| 4544 * @return the import element whose library has the given source and prefix | 4544 * @return the import element whose library has the given source and prefix |
| 4545 */ | 4545 */ |
| 4546 ImportElement findImport(List<ImportElement> imports, Source source, SimpleIde
ntifier prefix) { | 4546 ImportElement _findImport(List<ImportElement> imports, Source source, SimpleId
entifier prefix) { |
| 4547 for (ImportElement element in imports) { | 4547 for (ImportElement element in imports) { |
| 4548 if (element.importedLibrary.source == source) { | 4548 if (element.importedLibrary.source == source) { |
| 4549 PrefixElement prefixElement = element.prefix; | 4549 PrefixElement prefixElement = element.prefix; |
| 4550 if (prefix == null) { | 4550 if (prefix == null) { |
| 4551 if (prefixElement == null) { | 4551 if (prefixElement == null) { |
| 4552 return element; | 4552 return element; |
| 4553 } | 4553 } |
| 4554 } else { | 4554 } else { |
| 4555 if (prefixElement != null && prefix.name == prefixElement.displayName)
{ | 4555 if (prefixElement != null && prefix.name == prefixElement.displayName)
{ |
| 4556 return element; | 4556 return element; |
| 4557 } | 4557 } |
| 4558 } | 4558 } |
| 4559 } | 4559 } |
| 4560 } | 4560 } |
| 4561 return null; | 4561 return null; |
| 4562 } | 4562 } |
| 4563 | 4563 |
| 4564 /** | 4564 /** |
| 4565 * Return the element for the part with the given source, or `null` if there i
s no element | 4565 * Return the element for the part with the given source, or `null` if there i
s no element |
| 4566 * for the given source. | 4566 * for the given source. |
| 4567 * | 4567 * |
| 4568 * @param parts the elements for the parts | 4568 * @param parts the elements for the parts |
| 4569 * @param partSource the source for the part whose element is to be returned | 4569 * @param partSource the source for the part whose element is to be returned |
| 4570 * @return the element for the part with the given source | 4570 * @return the element for the part with the given source |
| 4571 */ | 4571 */ |
| 4572 CompilationUnitElement findPart(List<CompilationUnitElement> parts, Source par
tSource) { | 4572 CompilationUnitElement _findPart(List<CompilationUnitElement> parts, Source pa
rtSource) { |
| 4573 for (CompilationUnitElement part in parts) { | 4573 for (CompilationUnitElement part in parts) { |
| 4574 if (part.source == partSource) { | 4574 if (part.source == partSource) { |
| 4575 return part; | 4575 return part; |
| 4576 } | 4576 } |
| 4577 } | 4577 } |
| 4578 return null; | 4578 return null; |
| 4579 } | 4579 } |
| 4580 | 4580 |
| 4581 /** | 4581 /** |
| 4582 * Return the element in the given array of elements that was created for the
declaration with the | 4582 * Return the element in the given array of elements that was created for the
declaration with the |
| 4583 * given name at the given offset. | 4583 * given name at the given offset. |
| 4584 * | 4584 * |
| 4585 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 4585 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 4586 * @param name the name of the element to be returned | 4586 * @param name the name of the element to be returned |
| 4587 * @param offset the offset of the name of the element to be returned | 4587 * @param offset the offset of the name of the element to be returned |
| 4588 * @return the element with the given name and offset | 4588 * @return the element with the given name and offset |
| 4589 */ | 4589 */ |
| 4590 Element findWithNameAndOffset(List<Element> elements, String name, int offset)
{ | 4590 Element _findWithNameAndOffset(List<Element> elements, String name, int offset
) { |
| 4591 for (Element element in elements) { | 4591 for (Element element in elements) { |
| 4592 if (element.displayName == name && element.nameOffset == offset) { | 4592 if (element.displayName == name && element.nameOffset == offset) { |
| 4593 return element; | 4593 return element; |
| 4594 } | 4594 } |
| 4595 } | 4595 } |
| 4596 return null; | 4596 return null; |
| 4597 } | 4597 } |
| 4598 | 4598 |
| 4599 void gatherElements(Element element) { | 4599 void _gatherElements(Element element) { |
| 4600 element.accept(new GeneralizingElementVisitor_DeclarationMatcher_gatherEleme
nts(this)); | 4600 element.accept(new GeneralizingElementVisitor_DeclarationMatcher_gatherEleme
nts(this)); |
| 4601 } | 4601 } |
| 4602 | 4602 |
| 4603 /** | 4603 /** |
| 4604 * Search the most closely enclosing list of parameters for a parameter with t
he given name. | 4604 * Search the most closely enclosing list of parameters for a parameter with t
he given name. |
| 4605 * | 4605 * |
| 4606 * @param node the node defining the parameter with the given name | 4606 * @param node the node defining the parameter with the given name |
| 4607 * @param parameterName the name of the parameter being searched for | 4607 * @param parameterName the name of the parameter being searched for |
| 4608 * @return the element representing the parameter with that name | 4608 * @return the element representing the parameter with that name |
| 4609 */ | 4609 */ |
| 4610 ParameterElement getElementForParameter(FormalParameter node, SimpleIdentifier
parameterName) { | 4610 ParameterElement _getElementForParameter(FormalParameter node, SimpleIdentifie
r parameterName) { |
| 4611 List<ParameterElement> parameters = null; | 4611 List<ParameterElement> parameters = null; |
| 4612 if (_enclosingParameter != null) { | 4612 if (_enclosingParameter != null) { |
| 4613 parameters = _enclosingParameter.parameters; | 4613 parameters = _enclosingParameter.parameters; |
| 4614 } | 4614 } |
| 4615 if (parameters == null && _enclosingExecutable != null) { | 4615 if (parameters == null && _enclosingExecutable != null) { |
| 4616 parameters = _enclosingExecutable.parameters; | 4616 parameters = _enclosingExecutable.parameters; |
| 4617 } | 4617 } |
| 4618 if (parameters == null && _enclosingAlias != null) { | 4618 if (parameters == null && _enclosingAlias != null) { |
| 4619 parameters = _enclosingAlias.parameters; | 4619 parameters = _enclosingAlias.parameters; |
| 4620 } | 4620 } |
| 4621 return parameters == null ? null : findIdentifier(parameters, parameterName)
; | 4621 return parameters == null ? null : _findIdentifier(parameters, parameterName
); |
| 4622 } | 4622 } |
| 4623 | 4623 |
| 4624 /** | 4624 /** |
| 4625 * Return the value of the given string literal, or `null` if the string is no
t a constant | 4625 * Return the value of the given string literal, or `null` if the string is no
t a constant |
| 4626 * string without any string interpolation. | 4626 * string without any string interpolation. |
| 4627 * | 4627 * |
| 4628 * @param literal the string literal whose value is to be returned | 4628 * @param literal the string literal whose value is to be returned |
| 4629 * @return the value of the given string literal | 4629 * @return the value of the given string literal |
| 4630 */ | 4630 */ |
| 4631 String getStringValue(StringLiteral literal) { | 4631 String _getStringValue(StringLiteral literal) { |
| 4632 if (literal is StringInterpolation) { | 4632 if (literal is StringInterpolation) { |
| 4633 return null; | 4633 return null; |
| 4634 } | 4634 } |
| 4635 return literal.stringValue; | 4635 return literal.stringValue; |
| 4636 } | 4636 } |
| 4637 | 4637 |
| 4638 /** | 4638 /** |
| 4639 * Return `true` if the given class defines at least one constructor. | 4639 * Return `true` if the given class defines at least one constructor. |
| 4640 * | 4640 * |
| 4641 * @param node the class being tested | 4641 * @param node the class being tested |
| 4642 * @return `true` if the class defines at least one constructor | 4642 * @return `true` if the class defines at least one constructor |
| 4643 */ | 4643 */ |
| 4644 bool hasConstructor(ClassDeclaration node) { | 4644 bool _hasConstructor(ClassDeclaration node) { |
| 4645 for (ClassMember member in node.members) { | 4645 for (ClassMember member in node.members) { |
| 4646 if (member is ConstructorDeclaration) { | 4646 if (member is ConstructorDeclaration) { |
| 4647 return true; | 4647 return true; |
| 4648 } | 4648 } |
| 4649 } | 4649 } |
| 4650 return false; | 4650 return false; |
| 4651 } | 4651 } |
| 4652 } | 4652 } |
| 4653 | 4653 |
| 4654 /** | 4654 /** |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4715 void resolve(CompilationUnit unit, CompilationUnitElement element) { | 4715 void resolve(CompilationUnit unit, CompilationUnitElement element) { |
| 4716 _enclosingUnit = element; | 4716 _enclosingUnit = element; |
| 4717 unit.element = element; | 4717 unit.element = element; |
| 4718 unit.accept(this); | 4718 unit.accept(this); |
| 4719 } | 4719 } |
| 4720 | 4720 |
| 4721 Object visitCatchClause(CatchClause node) { | 4721 Object visitCatchClause(CatchClause node) { |
| 4722 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 4722 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
| 4723 if (exceptionParameter != null) { | 4723 if (exceptionParameter != null) { |
| 4724 List<LocalVariableElement> localVariables = _enclosingExecutable.localVari
ables; | 4724 List<LocalVariableElement> localVariables = _enclosingExecutable.localVari
ables; |
| 4725 findIdentifier(localVariables, exceptionParameter); | 4725 _findIdentifier(localVariables, exceptionParameter); |
| 4726 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | 4726 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
| 4727 if (stackTraceParameter != null) { | 4727 if (stackTraceParameter != null) { |
| 4728 findIdentifier(localVariables, stackTraceParameter); | 4728 _findIdentifier(localVariables, stackTraceParameter); |
| 4729 } | 4729 } |
| 4730 } | 4730 } |
| 4731 return super.visitCatchClause(node); | 4731 return super.visitCatchClause(node); |
| 4732 } | 4732 } |
| 4733 | 4733 |
| 4734 Object visitClassDeclaration(ClassDeclaration node) { | 4734 Object visitClassDeclaration(ClassDeclaration node) { |
| 4735 ClassElement outerClass = _enclosingClass; | 4735 ClassElement outerClass = _enclosingClass; |
| 4736 try { | 4736 try { |
| 4737 SimpleIdentifier className = node.name; | 4737 SimpleIdentifier className = node.name; |
| 4738 _enclosingClass = findIdentifier(_enclosingUnit.types, className); | 4738 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 4739 return super.visitClassDeclaration(node); | 4739 return super.visitClassDeclaration(node); |
| 4740 } finally { | 4740 } finally { |
| 4741 _enclosingClass = outerClass; | 4741 _enclosingClass = outerClass; |
| 4742 } | 4742 } |
| 4743 } | 4743 } |
| 4744 | 4744 |
| 4745 Object visitClassTypeAlias(ClassTypeAlias node) { | 4745 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 4746 ClassElement outerClass = _enclosingClass; | 4746 ClassElement outerClass = _enclosingClass; |
| 4747 try { | 4747 try { |
| 4748 SimpleIdentifier className = node.name; | 4748 SimpleIdentifier className = node.name; |
| 4749 _enclosingClass = findIdentifier(_enclosingUnit.types, className); | 4749 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); |
| 4750 return super.visitClassTypeAlias(node); | 4750 return super.visitClassTypeAlias(node); |
| 4751 } finally { | 4751 } finally { |
| 4752 _enclosingClass = outerClass; | 4752 _enclosingClass = outerClass; |
| 4753 } | 4753 } |
| 4754 } | 4754 } |
| 4755 | 4755 |
| 4756 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 4756 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 4757 ExecutableElement outerExecutable = _enclosingExecutable; | 4757 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4758 try { | 4758 try { |
| 4759 SimpleIdentifier constructorName = node.name; | 4759 SimpleIdentifier constructorName = node.name; |
| 4760 if (constructorName == null) { | 4760 if (constructorName == null) { |
| 4761 _enclosingExecutable = _enclosingClass.unnamedConstructor; | 4761 _enclosingExecutable = _enclosingClass.unnamedConstructor; |
| 4762 } else { | 4762 } else { |
| 4763 _enclosingExecutable = _enclosingClass.getNamedConstructor(constructorNa
me.name); | 4763 _enclosingExecutable = _enclosingClass.getNamedConstructor(constructorNa
me.name); |
| 4764 constructorName.staticElement = _enclosingExecutable; | 4764 constructorName.staticElement = _enclosingExecutable; |
| 4765 } | 4765 } |
| 4766 node.element = _enclosingExecutable as ConstructorElement; | 4766 node.element = _enclosingExecutable as ConstructorElement; |
| 4767 return super.visitConstructorDeclaration(node); | 4767 return super.visitConstructorDeclaration(node); |
| 4768 } finally { | 4768 } finally { |
| 4769 _enclosingExecutable = outerExecutable; | 4769 _enclosingExecutable = outerExecutable; |
| 4770 } | 4770 } |
| 4771 } | 4771 } |
| 4772 | 4772 |
| 4773 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 4773 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 4774 SimpleIdentifier variableName = node.identifier; | 4774 SimpleIdentifier variableName = node.identifier; |
| 4775 findIdentifier(_enclosingExecutable.localVariables, variableName); | 4775 _findIdentifier(_enclosingExecutable.localVariables, variableName); |
| 4776 return super.visitDeclaredIdentifier(node); | 4776 return super.visitDeclaredIdentifier(node); |
| 4777 } | 4777 } |
| 4778 | 4778 |
| 4779 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 4779 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 4780 SimpleIdentifier parameterName = node.parameter.identifier; | 4780 SimpleIdentifier parameterName = node.parameter.identifier; |
| 4781 ParameterElement element = getElementForParameter(node, parameterName); | 4781 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4782 Expression defaultValue = node.defaultValue; | 4782 Expression defaultValue = node.defaultValue; |
| 4783 if (defaultValue != null) { | 4783 if (defaultValue != null) { |
| 4784 ExecutableElement outerExecutable = _enclosingExecutable; | 4784 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4785 try { | 4785 try { |
| 4786 if (element == null) { | 4786 if (element == null) { |
| 4787 } else { | 4787 } else { |
| 4788 _enclosingExecutable = element.initializer; | 4788 _enclosingExecutable = element.initializer; |
| 4789 } | 4789 } |
| 4790 defaultValue.accept(this); | 4790 defaultValue.accept(this); |
| 4791 } finally { | 4791 } finally { |
| 4792 _enclosingExecutable = outerExecutable; | 4792 _enclosingExecutable = outerExecutable; |
| 4793 } | 4793 } |
| 4794 } | 4794 } |
| 4795 ParameterElement outerParameter = _enclosingParameter; | 4795 ParameterElement outerParameter = _enclosingParameter; |
| 4796 try { | 4796 try { |
| 4797 _enclosingParameter = element; | 4797 _enclosingParameter = element; |
| 4798 return super.visitDefaultFormalParameter(node); | 4798 return super.visitDefaultFormalParameter(node); |
| 4799 } finally { | 4799 } finally { |
| 4800 _enclosingParameter = outerParameter; | 4800 _enclosingParameter = outerParameter; |
| 4801 } | 4801 } |
| 4802 } | 4802 } |
| 4803 | 4803 |
| 4804 Object visitExportDirective(ExportDirective node) { | 4804 Object visitExportDirective(ExportDirective node) { |
| 4805 String uri = getStringValue(node.uri); | 4805 String uri = _getStringValue(node.uri); |
| 4806 if (uri != null) { | 4806 if (uri != null) { |
| 4807 LibraryElement library = _enclosingUnit.library; | 4807 LibraryElement library = _enclosingUnit.library; |
| 4808 ExportElement exportElement = findExport(library.exports, _enclosingUnit.c
ontext.sourceFactory.resolveUri(_enclosingUnit.source, uri)); | 4808 ExportElement exportElement = _findExport(library.exports, _enclosingUnit.
context.sourceFactory.resolveUri(_enclosingUnit.source, uri)); |
| 4809 node.element = exportElement; | 4809 node.element = exportElement; |
| 4810 } | 4810 } |
| 4811 return super.visitExportDirective(node); | 4811 return super.visitExportDirective(node); |
| 4812 } | 4812 } |
| 4813 | 4813 |
| 4814 Object visitFieldFormalParameter(FieldFormalParameter node) { | 4814 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 4815 if (node.parent is! DefaultFormalParameter) { | 4815 if (node.parent is! DefaultFormalParameter) { |
| 4816 SimpleIdentifier parameterName = node.identifier; | 4816 SimpleIdentifier parameterName = node.identifier; |
| 4817 ParameterElement element = getElementForParameter(node, parameterName); | 4817 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4818 ParameterElement outerParameter = _enclosingParameter; | 4818 ParameterElement outerParameter = _enclosingParameter; |
| 4819 try { | 4819 try { |
| 4820 _enclosingParameter = element; | 4820 _enclosingParameter = element; |
| 4821 return super.visitFieldFormalParameter(node); | 4821 return super.visitFieldFormalParameter(node); |
| 4822 } finally { | 4822 } finally { |
| 4823 _enclosingParameter = outerParameter; | 4823 _enclosingParameter = outerParameter; |
| 4824 } | 4824 } |
| 4825 } else { | 4825 } else { |
| 4826 return super.visitFieldFormalParameter(node); | 4826 return super.visitFieldFormalParameter(node); |
| 4827 } | 4827 } |
| 4828 } | 4828 } |
| 4829 | 4829 |
| 4830 Object visitFunctionDeclaration(FunctionDeclaration node) { | 4830 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 4831 ExecutableElement outerExecutable = _enclosingExecutable; | 4831 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4832 try { | 4832 try { |
| 4833 SimpleIdentifier functionName = node.name; | 4833 SimpleIdentifier functionName = node.name; |
| 4834 sc.Token property = node.propertyKeyword; | 4834 sc.Token property = node.propertyKeyword; |
| 4835 if (property == null) { | 4835 if (property == null) { |
| 4836 if (_enclosingExecutable != null) { | 4836 if (_enclosingExecutable != null) { |
| 4837 _enclosingExecutable = findIdentifier(_enclosingExecutable.functions,
functionName); | 4837 _enclosingExecutable = _findIdentifier(_enclosingExecutable.functions,
functionName); |
| 4838 } else { | 4838 } else { |
| 4839 _enclosingExecutable = findIdentifier(_enclosingUnit.functions, functi
onName); | 4839 _enclosingExecutable = _findIdentifier(_enclosingUnit.functions, funct
ionName); |
| 4840 } | 4840 } |
| 4841 } else { | 4841 } else { |
| 4842 PropertyAccessorElement accessor = findIdentifier(_enclosingUnit.accesso
rs, functionName); | 4842 PropertyAccessorElement accessor = _findIdentifier(_enclosingUnit.access
ors, functionName); |
| 4843 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { | 4843 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { |
| 4844 accessor = accessor.variable.setter; | 4844 accessor = accessor.variable.setter; |
| 4845 functionName.staticElement = accessor; | 4845 functionName.staticElement = accessor; |
| 4846 } | 4846 } |
| 4847 _enclosingExecutable = accessor; | 4847 _enclosingExecutable = accessor; |
| 4848 } | 4848 } |
| 4849 node.functionExpression.element = _enclosingExecutable; | 4849 node.functionExpression.element = _enclosingExecutable; |
| 4850 return super.visitFunctionDeclaration(node); | 4850 return super.visitFunctionDeclaration(node); |
| 4851 } finally { | 4851 } finally { |
| 4852 _enclosingExecutable = outerExecutable; | 4852 _enclosingExecutable = outerExecutable; |
| 4853 } | 4853 } |
| 4854 } | 4854 } |
| 4855 | 4855 |
| 4856 Object visitFunctionExpression(FunctionExpression node) { | 4856 Object visitFunctionExpression(FunctionExpression node) { |
| 4857 if (node.parent is! FunctionDeclaration) { | 4857 if (node.parent is! FunctionDeclaration) { |
| 4858 FunctionElement element = findAtOffset(_enclosingExecutable.functions, nod
e.beginToken.offset); | 4858 FunctionElement element = _findAtOffset(_enclosingExecutable.functions, no
de.beginToken.offset); |
| 4859 node.element = element; | 4859 node.element = element; |
| 4860 } | 4860 } |
| 4861 ExecutableElement outerExecutable = _enclosingExecutable; | 4861 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4862 try { | 4862 try { |
| 4863 _enclosingExecutable = node.element; | 4863 _enclosingExecutable = node.element; |
| 4864 return super.visitFunctionExpression(node); | 4864 return super.visitFunctionExpression(node); |
| 4865 } finally { | 4865 } finally { |
| 4866 _enclosingExecutable = outerExecutable; | 4866 _enclosingExecutable = outerExecutable; |
| 4867 } | 4867 } |
| 4868 } | 4868 } |
| 4869 | 4869 |
| 4870 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 4870 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 4871 FunctionTypeAliasElement outerAlias = _enclosingAlias; | 4871 FunctionTypeAliasElement outerAlias = _enclosingAlias; |
| 4872 try { | 4872 try { |
| 4873 SimpleIdentifier aliasName = node.name; | 4873 SimpleIdentifier aliasName = node.name; |
| 4874 _enclosingAlias = findIdentifier(_enclosingUnit.functionTypeAliases, alias
Name); | 4874 _enclosingAlias = _findIdentifier(_enclosingUnit.functionTypeAliases, alia
sName); |
| 4875 return super.visitFunctionTypeAlias(node); | 4875 return super.visitFunctionTypeAlias(node); |
| 4876 } finally { | 4876 } finally { |
| 4877 _enclosingAlias = outerAlias; | 4877 _enclosingAlias = outerAlias; |
| 4878 } | 4878 } |
| 4879 } | 4879 } |
| 4880 | 4880 |
| 4881 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 4881 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 4882 if (node.parent is! DefaultFormalParameter) { | 4882 if (node.parent is! DefaultFormalParameter) { |
| 4883 SimpleIdentifier parameterName = node.identifier; | 4883 SimpleIdentifier parameterName = node.identifier; |
| 4884 ParameterElement element = getElementForParameter(node, parameterName); | 4884 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4885 ParameterElement outerParameter = _enclosingParameter; | 4885 ParameterElement outerParameter = _enclosingParameter; |
| 4886 try { | 4886 try { |
| 4887 _enclosingParameter = element; | 4887 _enclosingParameter = element; |
| 4888 return super.visitFunctionTypedFormalParameter(node); | 4888 return super.visitFunctionTypedFormalParameter(node); |
| 4889 } finally { | 4889 } finally { |
| 4890 _enclosingParameter = outerParameter; | 4890 _enclosingParameter = outerParameter; |
| 4891 } | 4891 } |
| 4892 } else { | 4892 } else { |
| 4893 return super.visitFunctionTypedFormalParameter(node); | 4893 return super.visitFunctionTypedFormalParameter(node); |
| 4894 } | 4894 } |
| 4895 } | 4895 } |
| 4896 | 4896 |
| 4897 Object visitImportDirective(ImportDirective node) { | 4897 Object visitImportDirective(ImportDirective node) { |
| 4898 String uri = getStringValue(node.uri); | 4898 String uri = _getStringValue(node.uri); |
| 4899 if (uri != null) { | 4899 if (uri != null) { |
| 4900 LibraryElement library = _enclosingUnit.library; | 4900 LibraryElement library = _enclosingUnit.library; |
| 4901 ImportElement importElement = findImport(library.imports, _enclosingUnit.c
ontext.sourceFactory.resolveUri(_enclosingUnit.source, uri), node.prefix); | 4901 ImportElement importElement = _findImport(library.imports, _enclosingUnit.
context.sourceFactory.resolveUri(_enclosingUnit.source, uri), node.prefix); |
| 4902 node.element = importElement; | 4902 node.element = importElement; |
| 4903 } | 4903 } |
| 4904 return super.visitImportDirective(node); | 4904 return super.visitImportDirective(node); |
| 4905 } | 4905 } |
| 4906 | 4906 |
| 4907 Object visitLabeledStatement(LabeledStatement node) { | 4907 Object visitLabeledStatement(LabeledStatement node) { |
| 4908 for (Label label in node.labels) { | 4908 for (Label label in node.labels) { |
| 4909 SimpleIdentifier labelName = label.label; | 4909 SimpleIdentifier labelName = label.label; |
| 4910 findIdentifier(_enclosingExecutable.labels, labelName); | 4910 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 4911 } | 4911 } |
| 4912 return super.visitLabeledStatement(node); | 4912 return super.visitLabeledStatement(node); |
| 4913 } | 4913 } |
| 4914 | 4914 |
| 4915 Object visitLibraryDirective(LibraryDirective node) { | 4915 Object visitLibraryDirective(LibraryDirective node) { |
| 4916 node.element = _enclosingUnit.library; | 4916 node.element = _enclosingUnit.library; |
| 4917 return super.visitLibraryDirective(node); | 4917 return super.visitLibraryDirective(node); |
| 4918 } | 4918 } |
| 4919 | 4919 |
| 4920 Object visitMethodDeclaration(MethodDeclaration node) { | 4920 Object visitMethodDeclaration(MethodDeclaration node) { |
| 4921 ExecutableElement outerExecutable = _enclosingExecutable; | 4921 ExecutableElement outerExecutable = _enclosingExecutable; |
| 4922 try { | 4922 try { |
| 4923 sc.Token property = node.propertyKeyword; | 4923 sc.Token property = node.propertyKeyword; |
| 4924 SimpleIdentifier methodName = node.name; | 4924 SimpleIdentifier methodName = node.name; |
| 4925 String nameOfMethod = methodName.name; | 4925 String nameOfMethod = methodName.name; |
| 4926 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter
s.length == 0) { | 4926 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter
s.length == 0) { |
| 4927 nameOfMethod = "unary-"; | 4927 nameOfMethod = "unary-"; |
| 4928 } | 4928 } |
| 4929 if (property == null) { | 4929 if (property == null) { |
| 4930 _enclosingExecutable = findWithNameAndOffset(_enclosingClass.methods, na
meOfMethod, methodName.offset); | 4930 _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods, n
ameOfMethod, methodName.offset); |
| 4931 methodName.staticElement = _enclosingExecutable; | 4931 methodName.staticElement = _enclosingExecutable; |
| 4932 } else { | 4932 } else { |
| 4933 PropertyAccessorElement accessor = findIdentifier(_enclosingClass.access
ors, methodName); | 4933 PropertyAccessorElement accessor = _findIdentifier(_enclosingClass.acces
sors, methodName); |
| 4934 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { | 4934 if (identical((property as sc.KeywordToken).keyword, sc.Keyword.SET)) { |
| 4935 accessor = accessor.variable.setter; | 4935 accessor = accessor.variable.setter; |
| 4936 methodName.staticElement = accessor; | 4936 methodName.staticElement = accessor; |
| 4937 } | 4937 } |
| 4938 _enclosingExecutable = accessor; | 4938 _enclosingExecutable = accessor; |
| 4939 } | 4939 } |
| 4940 return super.visitMethodDeclaration(node); | 4940 return super.visitMethodDeclaration(node); |
| 4941 } finally { | 4941 } finally { |
| 4942 _enclosingExecutable = outerExecutable; | 4942 _enclosingExecutable = outerExecutable; |
| 4943 } | 4943 } |
| 4944 } | 4944 } |
| 4945 | 4945 |
| 4946 Object visitPartDirective(PartDirective node) { | 4946 Object visitPartDirective(PartDirective node) { |
| 4947 String uri = getStringValue(node.uri); | 4947 String uri = _getStringValue(node.uri); |
| 4948 if (uri != null) { | 4948 if (uri != null) { |
| 4949 Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(_enclo
singUnit.source, uri); | 4949 Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(_enclo
singUnit.source, uri); |
| 4950 node.element = findPart(_enclosingUnit.library.parts, partSource); | 4950 node.element = _findPart(_enclosingUnit.library.parts, partSource); |
| 4951 } | 4951 } |
| 4952 return super.visitPartDirective(node); | 4952 return super.visitPartDirective(node); |
| 4953 } | 4953 } |
| 4954 | 4954 |
| 4955 Object visitPartOfDirective(PartOfDirective node) { | 4955 Object visitPartOfDirective(PartOfDirective node) { |
| 4956 node.element = _enclosingUnit.library; | 4956 node.element = _enclosingUnit.library; |
| 4957 return super.visitPartOfDirective(node); | 4957 return super.visitPartOfDirective(node); |
| 4958 } | 4958 } |
| 4959 | 4959 |
| 4960 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 4960 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 4961 if (node.parent is! DefaultFormalParameter) { | 4961 if (node.parent is! DefaultFormalParameter) { |
| 4962 SimpleIdentifier parameterName = node.identifier; | 4962 SimpleIdentifier parameterName = node.identifier; |
| 4963 ParameterElement element = getElementForParameter(node, parameterName); | 4963 ParameterElement element = _getElementForParameter(node, parameterName); |
| 4964 ParameterElement outerParameter = _enclosingParameter; | 4964 ParameterElement outerParameter = _enclosingParameter; |
| 4965 try { | 4965 try { |
| 4966 _enclosingParameter = element; | 4966 _enclosingParameter = element; |
| 4967 return super.visitSimpleFormalParameter(node); | 4967 return super.visitSimpleFormalParameter(node); |
| 4968 } finally { | 4968 } finally { |
| 4969 _enclosingParameter = outerParameter; | 4969 _enclosingParameter = outerParameter; |
| 4970 } | 4970 } |
| 4971 } else { | 4971 } else { |
| 4972 } | 4972 } |
| 4973 return super.visitSimpleFormalParameter(node); | 4973 return super.visitSimpleFormalParameter(node); |
| 4974 } | 4974 } |
| 4975 | 4975 |
| 4976 Object visitSwitchCase(SwitchCase node) { | 4976 Object visitSwitchCase(SwitchCase node) { |
| 4977 for (Label label in node.labels) { | 4977 for (Label label in node.labels) { |
| 4978 SimpleIdentifier labelName = label.label; | 4978 SimpleIdentifier labelName = label.label; |
| 4979 findIdentifier(_enclosingExecutable.labels, labelName); | 4979 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 4980 } | 4980 } |
| 4981 return super.visitSwitchCase(node); | 4981 return super.visitSwitchCase(node); |
| 4982 } | 4982 } |
| 4983 | 4983 |
| 4984 Object visitSwitchDefault(SwitchDefault node) { | 4984 Object visitSwitchDefault(SwitchDefault node) { |
| 4985 for (Label label in node.labels) { | 4985 for (Label label in node.labels) { |
| 4986 SimpleIdentifier labelName = label.label; | 4986 SimpleIdentifier labelName = label.label; |
| 4987 findIdentifier(_enclosingExecutable.labels, labelName); | 4987 _findIdentifier(_enclosingExecutable.labels, labelName); |
| 4988 } | 4988 } |
| 4989 return super.visitSwitchDefault(node); | 4989 return super.visitSwitchDefault(node); |
| 4990 } | 4990 } |
| 4991 | 4991 |
| 4992 Object visitTypeParameter(TypeParameter node) { | 4992 Object visitTypeParameter(TypeParameter node) { |
| 4993 SimpleIdentifier parameterName = node.name; | 4993 SimpleIdentifier parameterName = node.name; |
| 4994 if (_enclosingClass != null) { | 4994 if (_enclosingClass != null) { |
| 4995 findIdentifier(_enclosingClass.typeParameters, parameterName); | 4995 _findIdentifier(_enclosingClass.typeParameters, parameterName); |
| 4996 } else if (_enclosingAlias != null) { | 4996 } else if (_enclosingAlias != null) { |
| 4997 findIdentifier(_enclosingAlias.typeParameters, parameterName); | 4997 _findIdentifier(_enclosingAlias.typeParameters, parameterName); |
| 4998 } | 4998 } |
| 4999 return super.visitTypeParameter(node); | 4999 return super.visitTypeParameter(node); |
| 5000 } | 5000 } |
| 5001 | 5001 |
| 5002 Object visitVariableDeclaration(VariableDeclaration node) { | 5002 Object visitVariableDeclaration(VariableDeclaration node) { |
| 5003 VariableElement element = null; | 5003 VariableElement element = null; |
| 5004 SimpleIdentifier variableName = node.name; | 5004 SimpleIdentifier variableName = node.name; |
| 5005 if (_enclosingExecutable != null) { | 5005 if (_enclosingExecutable != null) { |
| 5006 element = findIdentifier(_enclosingExecutable.localVariables, variableName
); | 5006 element = _findIdentifier(_enclosingExecutable.localVariables, variableNam
e); |
| 5007 } | 5007 } |
| 5008 if (element == null && _enclosingClass != null) { | 5008 if (element == null && _enclosingClass != null) { |
| 5009 element = findIdentifier(_enclosingClass.fields, variableName); | 5009 element = _findIdentifier(_enclosingClass.fields, variableName); |
| 5010 } | 5010 } |
| 5011 if (element == null && _enclosingUnit != null) { | 5011 if (element == null && _enclosingUnit != null) { |
| 5012 element = findIdentifier(_enclosingUnit.topLevelVariables, variableName); | 5012 element = _findIdentifier(_enclosingUnit.topLevelVariables, variableName); |
| 5013 } | 5013 } |
| 5014 Expression initializer = node.initializer; | 5014 Expression initializer = node.initializer; |
| 5015 if (initializer != null) { | 5015 if (initializer != null) { |
| 5016 ExecutableElement outerExecutable = _enclosingExecutable; | 5016 ExecutableElement outerExecutable = _enclosingExecutable; |
| 5017 try { | 5017 try { |
| 5018 if (element == null) { | 5018 if (element == null) { |
| 5019 } else { | 5019 } else { |
| 5020 _enclosingExecutable = element.initializer; | 5020 _enclosingExecutable = element.initializer; |
| 5021 } | 5021 } |
| 5022 return super.visitVariableDeclaration(node); | 5022 return super.visitVariableDeclaration(node); |
| 5023 } finally { | 5023 } finally { |
| 5024 _enclosingExecutable = outerExecutable; | 5024 _enclosingExecutable = outerExecutable; |
| 5025 } | 5025 } |
| 5026 } | 5026 } |
| 5027 return super.visitVariableDeclaration(node); | 5027 return super.visitVariableDeclaration(node); |
| 5028 } | 5028 } |
| 5029 | 5029 |
| 5030 /** | 5030 /** |
| 5031 * Return the element in the given array of elements that was created for the
declaration at the | 5031 * Return the element in the given array of elements that was created for the
declaration at the |
| 5032 * given offset. This method should only be used when there is no name | 5032 * given offset. This method should only be used when there is no name |
| 5033 * | 5033 * |
| 5034 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 5034 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 5035 * @param offset the offset of the name of the element to be returned | 5035 * @param offset the offset of the name of the element to be returned |
| 5036 * @return the element at the given offset | 5036 * @return the element at the given offset |
| 5037 */ | 5037 */ |
| 5038 Element findAtOffset(List<Element> elements, int offset) => findWithNameAndOff
set(elements, "", offset); | 5038 Element _findAtOffset(List<Element> elements, int offset) => _findWithNameAndO
ffset(elements, "", offset); |
| 5039 | 5039 |
| 5040 /** | 5040 /** |
| 5041 * Return the export element from the given array whose library has the given
source, or | 5041 * Return the export element from the given array whose library has the given
source, or |
| 5042 * `null` if there is no such export. | 5042 * `null` if there is no such export. |
| 5043 * | 5043 * |
| 5044 * @param exports the export elements being searched | 5044 * @param exports the export elements being searched |
| 5045 * @param source the source of the library associated with the export element
to being searched | 5045 * @param source the source of the library associated with the export element
to being searched |
| 5046 * for | 5046 * for |
| 5047 * @return the export element whose library has the given source | 5047 * @return the export element whose library has the given source |
| 5048 */ | 5048 */ |
| 5049 ExportElement findExport(List<ExportElement> exports, Source source) { | 5049 ExportElement _findExport(List<ExportElement> exports, Source source) { |
| 5050 for (ExportElement export in exports) { | 5050 for (ExportElement export in exports) { |
| 5051 if (export.exportedLibrary.source == source) { | 5051 if (export.exportedLibrary.source == source) { |
| 5052 return export; | 5052 return export; |
| 5053 } | 5053 } |
| 5054 } | 5054 } |
| 5055 return null; | 5055 return null; |
| 5056 } | 5056 } |
| 5057 | 5057 |
| 5058 /** | 5058 /** |
| 5059 * Return the element in the given array of elements that was created for the
declaration with the | 5059 * Return the element in the given array of elements that was created for the
declaration with the |
| 5060 * given name. | 5060 * given name. |
| 5061 * | 5061 * |
| 5062 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 5062 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 5063 * @param identifier the name node in the declaration of the element to be ret
urned | 5063 * @param identifier the name node in the declaration of the element to be ret
urned |
| 5064 * @return the element created for the declaration with the given name | 5064 * @return the element created for the declaration with the given name |
| 5065 */ | 5065 */ |
| 5066 Element findIdentifier(List<Element> elements, SimpleIdentifier identifier) { | 5066 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier) { |
| 5067 Element element = findWithNameAndOffset(elements, identifier.name, identifie
r.offset); | 5067 Element element = _findWithNameAndOffset(elements, identifier.name, identifi
er.offset); |
| 5068 identifier.staticElement = element; | 5068 identifier.staticElement = element; |
| 5069 return element; | 5069 return element; |
| 5070 } | 5070 } |
| 5071 | 5071 |
| 5072 /** | 5072 /** |
| 5073 * Return the import element from the given array whose library has the given
source and that has | 5073 * Return the import element from the given array whose library has the given
source and that has |
| 5074 * the given prefix, or `null` if there is no such import. | 5074 * the given prefix, or `null` if there is no such import. |
| 5075 * | 5075 * |
| 5076 * @param imports the import elements being searched | 5076 * @param imports the import elements being searched |
| 5077 * @param source the source of the library associated with the import element
to being searched | 5077 * @param source the source of the library associated with the import element
to being searched |
| 5078 * for | 5078 * for |
| 5079 * @param prefix the prefix with which the library was imported | 5079 * @param prefix the prefix with which the library was imported |
| 5080 * @return the import element whose library has the given source and prefix | 5080 * @return the import element whose library has the given source and prefix |
| 5081 */ | 5081 */ |
| 5082 ImportElement findImport(List<ImportElement> imports, Source source, SimpleIde
ntifier prefix) { | 5082 ImportElement _findImport(List<ImportElement> imports, Source source, SimpleId
entifier prefix) { |
| 5083 for (ImportElement element in imports) { | 5083 for (ImportElement element in imports) { |
| 5084 if (element.importedLibrary.source == source) { | 5084 if (element.importedLibrary.source == source) { |
| 5085 PrefixElement prefixElement = element.prefix; | 5085 PrefixElement prefixElement = element.prefix; |
| 5086 if (prefix == null) { | 5086 if (prefix == null) { |
| 5087 if (prefixElement == null) { | 5087 if (prefixElement == null) { |
| 5088 return element; | 5088 return element; |
| 5089 } | 5089 } |
| 5090 } else { | 5090 } else { |
| 5091 if (prefixElement != null && prefix.name == prefixElement.displayName)
{ | 5091 if (prefixElement != null && prefix.name == prefixElement.displayName)
{ |
| 5092 return element; | 5092 return element; |
| 5093 } | 5093 } |
| 5094 } | 5094 } |
| 5095 } | 5095 } |
| 5096 } | 5096 } |
| 5097 return null; | 5097 return null; |
| 5098 } | 5098 } |
| 5099 | 5099 |
| 5100 /** | 5100 /** |
| 5101 * Return the element for the part with the given source, or `null` if there i
s no element | 5101 * Return the element for the part with the given source, or `null` if there i
s no element |
| 5102 * for the given source. | 5102 * for the given source. |
| 5103 * | 5103 * |
| 5104 * @param parts the elements for the parts | 5104 * @param parts the elements for the parts |
| 5105 * @param partSource the source for the part whose element is to be returned | 5105 * @param partSource the source for the part whose element is to be returned |
| 5106 * @return the element for the part with the given source | 5106 * @return the element for the part with the given source |
| 5107 */ | 5107 */ |
| 5108 CompilationUnitElement findPart(List<CompilationUnitElement> parts, Source par
tSource) { | 5108 CompilationUnitElement _findPart(List<CompilationUnitElement> parts, Source pa
rtSource) { |
| 5109 for (CompilationUnitElement part in parts) { | 5109 for (CompilationUnitElement part in parts) { |
| 5110 if (part.source == partSource) { | 5110 if (part.source == partSource) { |
| 5111 return part; | 5111 return part; |
| 5112 } | 5112 } |
| 5113 } | 5113 } |
| 5114 return null; | 5114 return null; |
| 5115 } | 5115 } |
| 5116 | 5116 |
| 5117 /** | 5117 /** |
| 5118 * Return the element in the given array of elements that was created for the
declaration with the | 5118 * Return the element in the given array of elements that was created for the
declaration with the |
| 5119 * given name at the given offset. | 5119 * given name at the given offset. |
| 5120 * | 5120 * |
| 5121 * @param elements the elements of the appropriate kind that exist in the curr
ent context | 5121 * @param elements the elements of the appropriate kind that exist in the curr
ent context |
| 5122 * @param name the name of the element to be returned | 5122 * @param name the name of the element to be returned |
| 5123 * @param offset the offset of the name of the element to be returned | 5123 * @param offset the offset of the name of the element to be returned |
| 5124 * @return the element with the given name and offset | 5124 * @return the element with the given name and offset |
| 5125 */ | 5125 */ |
| 5126 Element findWithNameAndOffset(List<Element> elements, String name, int offset)
{ | 5126 Element _findWithNameAndOffset(List<Element> elements, String name, int offset
) { |
| 5127 for (Element element in elements) { | 5127 for (Element element in elements) { |
| 5128 if (element.displayName == name && element.nameOffset == offset) { | 5128 if (element.displayName == name && element.nameOffset == offset) { |
| 5129 return element; | 5129 return element; |
| 5130 } | 5130 } |
| 5131 } | 5131 } |
| 5132 return null; | 5132 return null; |
| 5133 } | 5133 } |
| 5134 | 5134 |
| 5135 /** | 5135 /** |
| 5136 * Search the most closely enclosing list of parameters for a parameter with t
he given name. | 5136 * Search the most closely enclosing list of parameters for a parameter with t
he given name. |
| 5137 * | 5137 * |
| 5138 * @param node the node defining the parameter with the given name | 5138 * @param node the node defining the parameter with the given name |
| 5139 * @param parameterName the name of the parameter being searched for | 5139 * @param parameterName the name of the parameter being searched for |
| 5140 * @return the element representing the parameter with that name | 5140 * @return the element representing the parameter with that name |
| 5141 */ | 5141 */ |
| 5142 ParameterElement getElementForParameter(FormalParameter node, SimpleIdentifier
parameterName) { | 5142 ParameterElement _getElementForParameter(FormalParameter node, SimpleIdentifie
r parameterName) { |
| 5143 List<ParameterElement> parameters = null; | 5143 List<ParameterElement> parameters = null; |
| 5144 if (_enclosingParameter != null) { | 5144 if (_enclosingParameter != null) { |
| 5145 parameters = _enclosingParameter.parameters; | 5145 parameters = _enclosingParameter.parameters; |
| 5146 } | 5146 } |
| 5147 if (parameters == null && _enclosingExecutable != null) { | 5147 if (parameters == null && _enclosingExecutable != null) { |
| 5148 parameters = _enclosingExecutable.parameters; | 5148 parameters = _enclosingExecutable.parameters; |
| 5149 } | 5149 } |
| 5150 if (parameters == null && _enclosingAlias != null) { | 5150 if (parameters == null && _enclosingAlias != null) { |
| 5151 parameters = _enclosingAlias.parameters; | 5151 parameters = _enclosingAlias.parameters; |
| 5152 } | 5152 } |
| 5153 ParameterElement element = parameters == null ? null : findIdentifier(parame
ters, parameterName); | 5153 ParameterElement element = parameters == null ? null : _findIdentifier(param
eters, parameterName); |
| 5154 if (element == null) { | 5154 if (element == null) { |
| 5155 PrintStringWriter writer = new PrintStringWriter(); | 5155 PrintStringWriter writer = new PrintStringWriter(); |
| 5156 writer.println("Invalid state found in the Analysis Engine:"); | 5156 writer.println("Invalid state found in the Analysis Engine:"); |
| 5157 writer.println("DeclarationResolver.getElementForParameter() is visiting a
parameter that does not appear to be in a method or function."); | 5157 writer.println("DeclarationResolver.getElementForParameter() is visiting a
parameter that does not appear to be in a method or function."); |
| 5158 writer.println("Ancestors:"); | 5158 writer.println("Ancestors:"); |
| 5159 AstNode parent = node.parent; | 5159 AstNode parent = node.parent; |
| 5160 while (parent != null) { | 5160 while (parent != null) { |
| 5161 writer.println(parent.runtimeType.toString()); | 5161 writer.println(parent.runtimeType.toString()); |
| 5162 writer.println("---------"); | 5162 writer.println("---------"); |
| 5163 parent = parent.parent; | 5163 parent = parent.parent; |
| 5164 } | 5164 } |
| 5165 AnalysisEngine.instance.logger.logError2(writer.toString(), new AnalysisEx
ception()); | 5165 AnalysisEngine.instance.logger.logError2(writer.toString(), new AnalysisEx
ception()); |
| 5166 } | 5166 } |
| 5167 return element; | 5167 return element; |
| 5168 } | 5168 } |
| 5169 | 5169 |
| 5170 /** | 5170 /** |
| 5171 * Return the value of the given string literal, or `null` if the string is no
t a constant | 5171 * Return the value of the given string literal, or `null` if the string is no
t a constant |
| 5172 * string without any string interpolation. | 5172 * string without any string interpolation. |
| 5173 * | 5173 * |
| 5174 * @param literal the string literal whose value is to be returned | 5174 * @param literal the string literal whose value is to be returned |
| 5175 * @return the value of the given string literal | 5175 * @return the value of the given string literal |
| 5176 */ | 5176 */ |
| 5177 String getStringValue(StringLiteral literal) { | 5177 String _getStringValue(StringLiteral literal) { |
| 5178 if (literal is StringInterpolation) { | 5178 if (literal is StringInterpolation) { |
| 5179 return null; | 5179 return null; |
| 5180 } | 5180 } |
| 5181 return literal.stringValue; | 5181 return literal.stringValue; |
| 5182 } | 5182 } |
| 5183 } | 5183 } |
| 5184 | 5184 |
| 5185 /** | 5185 /** |
| 5186 * Instances of the class `ElementResolver` are used by instances of [ResolverVi
sitor] | 5186 * Instances of the class `ElementResolver` are used by instances of [ResolverVi
sitor] |
| 5187 * to resolve references within the AST structure to the elements being referenc
ed. The requirements | 5187 * to resolve references within the AST structure to the elements being referenc
ed. The requirements |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5249 } | 5249 } |
| 5250 } | 5250 } |
| 5251 return null; | 5251 return null; |
| 5252 } | 5252 } |
| 5253 | 5253 |
| 5254 /** | 5254 /** |
| 5255 * Return `true` if the given identifier is the return type of a constructor d
eclaration. | 5255 * Return `true` if the given identifier is the return type of a constructor d
eclaration. |
| 5256 * | 5256 * |
| 5257 * @return `true` if the given identifier is the return type of a constructor
declaration. | 5257 * @return `true` if the given identifier is the return type of a constructor
declaration. |
| 5258 */ | 5258 */ |
| 5259 static bool isConstructorReturnType(SimpleIdentifier identifier) { | 5259 static bool _isConstructorReturnType(SimpleIdentifier identifier) { |
| 5260 AstNode parent = identifier.parent; | 5260 AstNode parent = identifier.parent; |
| 5261 if (parent is ConstructorDeclaration) { | 5261 if (parent is ConstructorDeclaration) { |
| 5262 return identical(parent.returnType, identifier); | 5262 return identical(parent.returnType, identifier); |
| 5263 } | 5263 } |
| 5264 return false; | 5264 return false; |
| 5265 } | 5265 } |
| 5266 | 5266 |
| 5267 /** | 5267 /** |
| 5268 * Return `true` if the given identifier is the return type of a factory const
ructor. | 5268 * Return `true` if the given identifier is the return type of a factory const
ructor. |
| 5269 * | 5269 * |
| 5270 * @return `true` if the given identifier is the return type of a factory cons
tructor | 5270 * @return `true` if the given identifier is the return type of a factory cons
tructor |
| 5271 * declaration. | 5271 * declaration. |
| 5272 */ | 5272 */ |
| 5273 static bool isFactoryConstructorReturnType(SimpleIdentifier node) { | 5273 static bool _isFactoryConstructorReturnType(SimpleIdentifier node) { |
| 5274 AstNode parent = node.parent; | 5274 AstNode parent = node.parent; |
| 5275 if (parent is ConstructorDeclaration) { | 5275 if (parent is ConstructorDeclaration) { |
| 5276 ConstructorDeclaration constructor = parent; | 5276 ConstructorDeclaration constructor = parent; |
| 5277 return identical(constructor.returnType, node) && constructor.factoryKeywo
rd != null; | 5277 return identical(constructor.returnType, node) && constructor.factoryKeywo
rd != null; |
| 5278 } | 5278 } |
| 5279 return false; | 5279 return false; |
| 5280 } | 5280 } |
| 5281 | 5281 |
| 5282 /** | 5282 /** |
| 5283 * Return `true` if the given 'super' expression is used in a valid context. | 5283 * Return `true` if the given 'super' expression is used in a valid context. |
| 5284 * | 5284 * |
| 5285 * @param node the 'super' expression to analyze | 5285 * @param node the 'super' expression to analyze |
| 5286 * @return `true` if the 'super' expression is in a valid context | 5286 * @return `true` if the 'super' expression is in a valid context |
| 5287 */ | 5287 */ |
| 5288 static bool isSuperInValidContext(SuperExpression node) { | 5288 static bool _isSuperInValidContext(SuperExpression node) { |
| 5289 for (AstNode n = node; n != null; n = n.parent) { | 5289 for (AstNode n = node; n != null; n = n.parent) { |
| 5290 if (n is CompilationUnit) { | 5290 if (n is CompilationUnit) { |
| 5291 return false; | 5291 return false; |
| 5292 } | 5292 } |
| 5293 if (n is ConstructorDeclaration) { | 5293 if (n is ConstructorDeclaration) { |
| 5294 ConstructorDeclaration constructor = n as ConstructorDeclaration; | 5294 ConstructorDeclaration constructor = n as ConstructorDeclaration; |
| 5295 return constructor.factoryKeyword == null; | 5295 return constructor.factoryKeyword == null; |
| 5296 } | 5296 } |
| 5297 if (n is ConstructorFieldInitializer) { | 5297 if (n is ConstructorFieldInitializer) { |
| 5298 return false; | 5298 return false; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5365 _dynamicType = resolver.typeProvider.dynamicType; | 5365 _dynamicType = resolver.typeProvider.dynamicType; |
| 5366 _typeType = resolver.typeProvider.typeType; | 5366 _typeType = resolver.typeProvider.typeType; |
| 5367 _subtypeManager = new SubtypeManager(); | 5367 _subtypeManager = new SubtypeManager(); |
| 5368 _promoteManager = resolver.promoteManager; | 5368 _promoteManager = resolver.promoteManager; |
| 5369 } | 5369 } |
| 5370 | 5370 |
| 5371 Object visitAssignmentExpression(AssignmentExpression node) { | 5371 Object visitAssignmentExpression(AssignmentExpression node) { |
| 5372 sc.Token operator = node.operator; | 5372 sc.Token operator = node.operator; |
| 5373 sc.TokenType operatorType = operator.type; | 5373 sc.TokenType operatorType = operator.type; |
| 5374 if (operatorType != sc.TokenType.EQ) { | 5374 if (operatorType != sc.TokenType.EQ) { |
| 5375 operatorType = operatorFromCompoundAssignment(operatorType); | 5375 operatorType = _operatorFromCompoundAssignment(operatorType); |
| 5376 Expression leftHandSide = node.leftHandSide; | 5376 Expression leftHandSide = node.leftHandSide; |
| 5377 if (leftHandSide != null) { | 5377 if (leftHandSide != null) { |
| 5378 String methodName = operatorType.lexeme; | 5378 String methodName = operatorType.lexeme; |
| 5379 Type2 staticType = getStaticType(leftHandSide); | 5379 Type2 staticType = _getStaticType(leftHandSide); |
| 5380 MethodElement staticMethod = lookUpMethod(leftHandSide, staticType, meth
odName); | 5380 MethodElement staticMethod = _lookUpMethod(leftHandSide, staticType, met
hodName); |
| 5381 node.staticElement = staticMethod; | 5381 node.staticElement = staticMethod; |
| 5382 Type2 propagatedType = getPropagatedType(leftHandSide); | 5382 Type2 propagatedType = _getPropagatedType(leftHandSide); |
| 5383 MethodElement propagatedMethod = lookUpMethod(leftHandSide, propagatedTy
pe, methodName); | 5383 MethodElement propagatedMethod = _lookUpMethod(leftHandSide, propagatedT
ype, methodName); |
| 5384 node.propagatedElement = propagatedMethod; | 5384 node.propagatedElement = propagatedMethod; |
| 5385 if (shouldReportMissingMember(staticType, staticMethod)) { | 5385 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 5386 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element,
StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displ
ayName]); | 5386 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element,
StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displ
ayName]); |
| 5387 } else if (_enableHints && shouldReportMissingMember(propagatedType, pro
pagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, tru
e, false)) { | 5387 } else if (_enableHints && _shouldReportMissingMember(propagatedType, pr
opagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, t
rue, false)) { |
| 5388 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.elem
ent, HintCode.UNDEFINED_METHOD, operator, [methodName, propagatedType.displayNam
e]); | 5388 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.elem
ent, HintCode.UNDEFINED_METHOD, operator, [methodName, propagatedType.displayNam
e]); |
| 5389 } | 5389 } |
| 5390 } | 5390 } |
| 5391 } | 5391 } |
| 5392 return null; | 5392 return null; |
| 5393 } | 5393 } |
| 5394 | 5394 |
| 5395 Object visitBinaryExpression(BinaryExpression node) { | 5395 Object visitBinaryExpression(BinaryExpression node) { |
| 5396 sc.Token operator = node.operator; | 5396 sc.Token operator = node.operator; |
| 5397 if (operator.isUserDefinableOperator) { | 5397 if (operator.isUserDefinableOperator) { |
| 5398 Expression leftOperand = node.leftOperand; | 5398 Expression leftOperand = node.leftOperand; |
| 5399 if (leftOperand != null) { | 5399 if (leftOperand != null) { |
| 5400 String methodName = operator.lexeme; | 5400 String methodName = operator.lexeme; |
| 5401 Type2 staticType = getStaticType(leftOperand); | 5401 Type2 staticType = _getStaticType(leftOperand); |
| 5402 MethodElement staticMethod = lookUpMethod(leftOperand, staticType, metho
dName); | 5402 MethodElement staticMethod = _lookUpMethod(leftOperand, staticType, meth
odName); |
| 5403 node.staticElement = staticMethod; | 5403 node.staticElement = staticMethod; |
| 5404 Type2 propagatedType = getPropagatedType(leftOperand); | 5404 Type2 propagatedType = _getPropagatedType(leftOperand); |
| 5405 MethodElement propagatedMethod = lookUpMethod(leftOperand, propagatedTyp
e, methodName); | 5405 MethodElement propagatedMethod = _lookUpMethod(leftOperand, propagatedTy
pe, methodName); |
| 5406 node.propagatedElement = propagatedMethod; | 5406 node.propagatedElement = propagatedMethod; |
| 5407 if (shouldReportMissingMember(staticType, staticMethod)) { | 5407 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 5408 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element,
StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.dis
playName]); | 5408 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element,
StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.dis
playName]); |
| 5409 } else if (_enableHints && shouldReportMissingMember(propagatedType, pro
pagatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, tru
e, false)) { | 5409 } else if (_enableHints && _shouldReportMissingMember(propagatedType, pr
opagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, t
rue, false)) { |
| 5410 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.elem
ent, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayN
ame]); | 5410 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.elem
ent, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayN
ame]); |
| 5411 } | 5411 } |
| 5412 } | 5412 } |
| 5413 } | 5413 } |
| 5414 return null; | 5414 return null; |
| 5415 } | 5415 } |
| 5416 | 5416 |
| 5417 Object visitBreakStatement(BreakStatement node) { | 5417 Object visitBreakStatement(BreakStatement node) { |
| 5418 lookupLabel(node, node.label); | 5418 _lookupLabel(node, node.label); |
| 5419 return null; | 5419 return null; |
| 5420 } | 5420 } |
| 5421 | 5421 |
| 5422 Object visitClassDeclaration(ClassDeclaration node) { | 5422 Object visitClassDeclaration(ClassDeclaration node) { |
| 5423 setMetadata(node.element, node); | 5423 _setMetadata(node.element, node); |
| 5424 return null; | 5424 return null; |
| 5425 } | 5425 } |
| 5426 | 5426 |
| 5427 Object visitClassTypeAlias(ClassTypeAlias node) { | 5427 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 5428 setMetadata(node.element, node); | 5428 _setMetadata(node.element, node); |
| 5429 return null; | 5429 return null; |
| 5430 } | 5430 } |
| 5431 | 5431 |
| 5432 Object visitCommentReference(CommentReference node) { | 5432 Object visitCommentReference(CommentReference node) { |
| 5433 Identifier identifier = node.identifier; | 5433 Identifier identifier = node.identifier; |
| 5434 if (identifier is SimpleIdentifier) { | 5434 if (identifier is SimpleIdentifier) { |
| 5435 SimpleIdentifier simpleIdentifier = identifier; | 5435 SimpleIdentifier simpleIdentifier = identifier; |
| 5436 Element element = resolveSimpleIdentifier(simpleIdentifier); | 5436 Element element = _resolveSimpleIdentifier(simpleIdentifier); |
| 5437 if (element == null) { | 5437 if (element == null) { |
| 5438 // | 5438 // |
| 5439 // This might be a reference to an imported name that is missing the pre
fix. | 5439 // This might be a reference to an imported name that is missing the pre
fix. |
| 5440 // | 5440 // |
| 5441 element = findImportWithoutPrefix(simpleIdentifier); | 5441 element = _findImportWithoutPrefix(simpleIdentifier); |
| 5442 if (element is MultiplyDefinedElement) { | 5442 if (element is MultiplyDefinedElement) { |
| 5443 // TODO(brianwilkerson) Report this error? | 5443 // TODO(brianwilkerson) Report this error? |
| 5444 element = null; | 5444 element = null; |
| 5445 } | 5445 } |
| 5446 } | 5446 } |
| 5447 if (element == null) { | 5447 if (element == null) { |
| 5448 } else { | 5448 } else { |
| 5449 if (element.library == null || element.library != _definingLibrary) { | 5449 if (element.library == null || element.library != _definingLibrary) { |
| 5450 } | 5450 } |
| 5451 simpleIdentifier.staticElement = element; | 5451 simpleIdentifier.staticElement = element; |
| 5452 if (node.newKeyword != null) { | 5452 if (node.newKeyword != null) { |
| 5453 if (element is ClassElement) { | 5453 if (element is ClassElement) { |
| 5454 ConstructorElement constructor = (element as ClassElement).unnamedCo
nstructor; | 5454 ConstructorElement constructor = (element as ClassElement).unnamedCo
nstructor; |
| 5455 if (constructor == null) { | 5455 if (constructor == null) { |
| 5456 } else { | 5456 } else { |
| 5457 simpleIdentifier.staticElement = constructor; | 5457 simpleIdentifier.staticElement = constructor; |
| 5458 } | 5458 } |
| 5459 } else { | 5459 } else { |
| 5460 } | 5460 } |
| 5461 } | 5461 } |
| 5462 } | 5462 } |
| 5463 } else if (identifier is PrefixedIdentifier) { | 5463 } else if (identifier is PrefixedIdentifier) { |
| 5464 PrefixedIdentifier prefixedIdentifier = identifier; | 5464 PrefixedIdentifier prefixedIdentifier = identifier; |
| 5465 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 5465 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
| 5466 SimpleIdentifier name = prefixedIdentifier.identifier; | 5466 SimpleIdentifier name = prefixedIdentifier.identifier; |
| 5467 Element element = resolveSimpleIdentifier(prefix); | 5467 Element element = _resolveSimpleIdentifier(prefix); |
| 5468 if (element == null) { | 5468 if (element == null) { |
| 5469 } else { | 5469 } else { |
| 5470 if (element is PrefixElement) { | 5470 if (element is PrefixElement) { |
| 5471 prefix.staticElement = element; | 5471 prefix.staticElement = element; |
| 5472 // TODO(brianwilkerson) Report this error? | 5472 // TODO(brianwilkerson) Report this error? |
| 5473 element = _resolver.nameScope.lookup(identifier, _definingLibrary); | 5473 element = _resolver.nameScope.lookup(identifier, _definingLibrary); |
| 5474 name.staticElement = element; | 5474 name.staticElement = element; |
| 5475 return null; | 5475 return null; |
| 5476 } | 5476 } |
| 5477 LibraryElement library = element.library; | 5477 LibraryElement library = element.library; |
| 5478 if (library == null) { | 5478 if (library == null) { |
| 5479 // TODO(brianwilkerson) We need to understand how the library could ev
er be null. | 5479 // TODO(brianwilkerson) We need to understand how the library could ev
er be null. |
| 5480 AnalysisEngine.instance.logger.logError("Found element with null libra
ry: ${element.name}"); | 5480 AnalysisEngine.instance.logger.logError("Found element with null libra
ry: ${element.name}"); |
| 5481 } else if (library != _definingLibrary) { | 5481 } else if (library != _definingLibrary) { |
| 5482 } | 5482 } |
| 5483 name.staticElement = element; | 5483 name.staticElement = element; |
| 5484 if (node.newKeyword == null) { | 5484 if (node.newKeyword == null) { |
| 5485 if (element is ClassElement) { | 5485 if (element is ClassElement) { |
| 5486 Element memberElement = lookupGetterOrMethod((element as ClassElemen
t).type, name.name); | 5486 Element memberElement = _lookupGetterOrMethod((element as ClassEleme
nt).type, name.name); |
| 5487 if (memberElement == null) { | 5487 if (memberElement == null) { |
| 5488 memberElement = (element as ClassElement).getNamedConstructor(name
.name); | 5488 memberElement = (element as ClassElement).getNamedConstructor(name
.name); |
| 5489 if (memberElement == null) { | 5489 if (memberElement == null) { |
| 5490 memberElement = lookUpSetter(prefix, (element as ClassElement).t
ype, name.name); | 5490 memberElement = _lookUpSetter(prefix, (element as ClassElement).
type, name.name); |
| 5491 } | 5491 } |
| 5492 } | 5492 } |
| 5493 if (memberElement == null) { | 5493 if (memberElement == null) { |
| 5494 } else { | 5494 } else { |
| 5495 name.staticElement = memberElement; | 5495 name.staticElement = memberElement; |
| 5496 } | 5496 } |
| 5497 } else { | 5497 } else { |
| 5498 } | 5498 } |
| 5499 } else { | 5499 } else { |
| 5500 if (element is ClassElement) { | 5500 if (element is ClassElement) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5523 constructorElement.redirectedConstructor = redirectedElement; | 5523 constructorElement.redirectedConstructor = redirectedElement; |
| 5524 } else { | 5524 } else { |
| 5525 // set redirected generative constructor | 5525 // set redirected generative constructor |
| 5526 for (ConstructorInitializer initializer in node.initializers) { | 5526 for (ConstructorInitializer initializer in node.initializers) { |
| 5527 if (initializer is RedirectingConstructorInvocation) { | 5527 if (initializer is RedirectingConstructorInvocation) { |
| 5528 ConstructorElement redirectedElement = initializer.staticElement; | 5528 ConstructorElement redirectedElement = initializer.staticElement; |
| 5529 constructorElement.redirectedConstructor = redirectedElement; | 5529 constructorElement.redirectedConstructor = redirectedElement; |
| 5530 } | 5530 } |
| 5531 } | 5531 } |
| 5532 } | 5532 } |
| 5533 setMetadata(constructorElement, node); | 5533 _setMetadata(constructorElement, node); |
| 5534 } | 5534 } |
| 5535 return null; | 5535 return null; |
| 5536 } | 5536 } |
| 5537 | 5537 |
| 5538 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 5538 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 5539 SimpleIdentifier fieldName = node.fieldName; | 5539 SimpleIdentifier fieldName = node.fieldName; |
| 5540 ClassElement enclosingClass = _resolver.enclosingClass; | 5540 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5541 FieldElement fieldElement = enclosingClass.getField(fieldName.name); | 5541 FieldElement fieldElement = enclosingClass.getField(fieldName.name); |
| 5542 fieldName.staticElement = fieldElement; | 5542 fieldName.staticElement = fieldElement; |
| 5543 return null; | 5543 return null; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5569 constructor = interfaceType.lookUpConstructor(null, _definingLibrary); | 5569 constructor = interfaceType.lookUpConstructor(null, _definingLibrary); |
| 5570 } else { | 5570 } else { |
| 5571 constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary)
; | 5571 constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary)
; |
| 5572 name.staticElement = constructor; | 5572 name.staticElement = constructor; |
| 5573 } | 5573 } |
| 5574 node.staticElement = constructor; | 5574 node.staticElement = constructor; |
| 5575 return null; | 5575 return null; |
| 5576 } | 5576 } |
| 5577 | 5577 |
| 5578 Object visitContinueStatement(ContinueStatement node) { | 5578 Object visitContinueStatement(ContinueStatement node) { |
| 5579 lookupLabel(node, node.label); | 5579 _lookupLabel(node, node.label); |
| 5580 return null; | 5580 return null; |
| 5581 } | 5581 } |
| 5582 | 5582 |
| 5583 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 5583 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 5584 setMetadata(node.element, node); | 5584 _setMetadata(node.element, node); |
| 5585 return null; | 5585 return null; |
| 5586 } | 5586 } |
| 5587 | 5587 |
| 5588 Object visitExportDirective(ExportDirective node) { | 5588 Object visitExportDirective(ExportDirective node) { |
| 5589 ExportElement exportElement = node.element; | 5589 ExportElement exportElement = node.element; |
| 5590 if (exportElement != null) { | 5590 if (exportElement != null) { |
| 5591 // The element is null when the URI is invalid | 5591 // The element is null when the URI is invalid |
| 5592 // TODO(brianwilkerson) Figure out whether the element can ever be somethi
ng other than an | 5592 // TODO(brianwilkerson) Figure out whether the element can ever be somethi
ng other than an |
| 5593 // ExportElement | 5593 // ExportElement |
| 5594 resolveCombinators(exportElement.exportedLibrary, node.combinators); | 5594 _resolveCombinators(exportElement.exportedLibrary, node.combinators); |
| 5595 setMetadata(exportElement, node); | 5595 _setMetadata(exportElement, node); |
| 5596 } | 5596 } |
| 5597 return null; | 5597 return null; |
| 5598 } | 5598 } |
| 5599 | 5599 |
| 5600 Object visitFieldFormalParameter(FieldFormalParameter node) { | 5600 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 5601 setMetadataForParameter(node.element, node); | 5601 _setMetadataForParameter(node.element, node); |
| 5602 return super.visitFieldFormalParameter(node); | 5602 return super.visitFieldFormalParameter(node); |
| 5603 } | 5603 } |
| 5604 | 5604 |
| 5605 Object visitFunctionDeclaration(FunctionDeclaration node) { | 5605 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 5606 setMetadata(node.element, node); | 5606 _setMetadata(node.element, node); |
| 5607 return null; | 5607 return null; |
| 5608 } | 5608 } |
| 5609 | 5609 |
| 5610 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 5610 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 5611 // TODO(brianwilkerson) Can we ever resolve the function being invoked? | 5611 // TODO(brianwilkerson) Can we ever resolve the function being invoked? |
| 5612 Expression expression = node.function; | 5612 Expression expression = node.function; |
| 5613 if (expression is FunctionExpression) { | 5613 if (expression is FunctionExpression) { |
| 5614 FunctionExpression functionExpression = expression; | 5614 FunctionExpression functionExpression = expression; |
| 5615 ExecutableElement functionElement = functionExpression.element; | 5615 ExecutableElement functionElement = functionExpression.element; |
| 5616 ArgumentList argumentList = node.argumentList; | 5616 ArgumentList argumentList = node.argumentList; |
| 5617 List<ParameterElement> parameters = resolveArgumentsToFunction(false, argu
mentList, functionElement); | 5617 List<ParameterElement> parameters = _resolveArgumentsToFunction(false, arg
umentList, functionElement); |
| 5618 if (parameters != null) { | 5618 if (parameters != null) { |
| 5619 argumentList.correspondingStaticParameters = parameters; | 5619 argumentList.correspondingStaticParameters = parameters; |
| 5620 } | 5620 } |
| 5621 } | 5621 } |
| 5622 return null; | 5622 return null; |
| 5623 } | 5623 } |
| 5624 | 5624 |
| 5625 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 5625 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 5626 setMetadata(node.element, node); | 5626 _setMetadata(node.element, node); |
| 5627 return null; | 5627 return null; |
| 5628 } | 5628 } |
| 5629 | 5629 |
| 5630 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 5630 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 5631 setMetadataForParameter(node.element, node); | 5631 _setMetadataForParameter(node.element, node); |
| 5632 return null; | 5632 return null; |
| 5633 } | 5633 } |
| 5634 | 5634 |
| 5635 Object visitImportDirective(ImportDirective node) { | 5635 Object visitImportDirective(ImportDirective node) { |
| 5636 SimpleIdentifier prefixNode = node.prefix; | 5636 SimpleIdentifier prefixNode = node.prefix; |
| 5637 if (prefixNode != null) { | 5637 if (prefixNode != null) { |
| 5638 String prefixName = prefixNode.name; | 5638 String prefixName = prefixNode.name; |
| 5639 for (PrefixElement prefixElement in _definingLibrary.prefixes) { | 5639 for (PrefixElement prefixElement in _definingLibrary.prefixes) { |
| 5640 if (prefixElement.displayName == prefixName) { | 5640 if (prefixElement.displayName == prefixName) { |
| 5641 prefixNode.staticElement = prefixElement; | 5641 prefixNode.staticElement = prefixElement; |
| 5642 break; | 5642 break; |
| 5643 } | 5643 } |
| 5644 } | 5644 } |
| 5645 } | 5645 } |
| 5646 ImportElement importElement = node.element; | 5646 ImportElement importElement = node.element; |
| 5647 if (importElement != null) { | 5647 if (importElement != null) { |
| 5648 // The element is null when the URI is invalid | 5648 // The element is null when the URI is invalid |
| 5649 LibraryElement library = importElement.importedLibrary; | 5649 LibraryElement library = importElement.importedLibrary; |
| 5650 if (library != null) { | 5650 if (library != null) { |
| 5651 resolveCombinators(library, node.combinators); | 5651 _resolveCombinators(library, node.combinators); |
| 5652 } | 5652 } |
| 5653 setMetadata(importElement, node); | 5653 _setMetadata(importElement, node); |
| 5654 } | 5654 } |
| 5655 return null; | 5655 return null; |
| 5656 } | 5656 } |
| 5657 | 5657 |
| 5658 Object visitIndexExpression(IndexExpression node) { | 5658 Object visitIndexExpression(IndexExpression node) { |
| 5659 Expression target = node.realTarget; | 5659 Expression target = node.realTarget; |
| 5660 Type2 staticType = getStaticType(target); | 5660 Type2 staticType = _getStaticType(target); |
| 5661 Type2 propagatedType = getPropagatedType(target); | 5661 Type2 propagatedType = _getPropagatedType(target); |
| 5662 String getterMethodName = sc.TokenType.INDEX.lexeme; | 5662 String getterMethodName = sc.TokenType.INDEX.lexeme; |
| 5663 String setterMethodName = sc.TokenType.INDEX_EQ.lexeme; | 5663 String setterMethodName = sc.TokenType.INDEX_EQ.lexeme; |
| 5664 bool isInGetterContext = node.inGetterContext(); | 5664 bool isInGetterContext = node.inGetterContext(); |
| 5665 bool isInSetterContext = node.inSetterContext(); | 5665 bool isInSetterContext = node.inSetterContext(); |
| 5666 if (isInGetterContext && isInSetterContext) { | 5666 if (isInGetterContext && isInSetterContext) { |
| 5667 // lookup setter | 5667 // lookup setter |
| 5668 MethodElement setterStaticMethod = lookUpMethod(target, staticType, setter
MethodName); | 5668 MethodElement setterStaticMethod = _lookUpMethod(target, staticType, sette
rMethodName); |
| 5669 MethodElement setterPropagatedMethod = lookUpMethod(target, propagatedType
, setterMethodName); | 5669 MethodElement setterPropagatedMethod = _lookUpMethod(target, propagatedTyp
e, setterMethodName); |
| 5670 // set setter element | 5670 // set setter element |
| 5671 node.staticElement = setterStaticMethod; | 5671 node.staticElement = setterStaticMethod; |
| 5672 node.propagatedElement = setterPropagatedMethod; | 5672 node.propagatedElement = setterPropagatedMethod; |
| 5673 // generate undefined method warning | 5673 // generate undefined method warning |
| 5674 checkForUndefinedIndexOperator(node, target, getterMethodName, setterStati
cMethod, setterPropagatedMethod, staticType, propagatedType); | 5674 _checkForUndefinedIndexOperator(node, target, getterMethodName, setterStat
icMethod, setterPropagatedMethod, staticType, propagatedType); |
| 5675 // lookup getter method | 5675 // lookup getter method |
| 5676 MethodElement getterStaticMethod = lookUpMethod(target, staticType, getter
MethodName); | 5676 MethodElement getterStaticMethod = _lookUpMethod(target, staticType, gette
rMethodName); |
| 5677 MethodElement getterPropagatedMethod = lookUpMethod(target, propagatedType
, getterMethodName); | 5677 MethodElement getterPropagatedMethod = _lookUpMethod(target, propagatedTyp
e, getterMethodName); |
| 5678 // set getter element | 5678 // set getter element |
| 5679 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMe
thod, getterPropagatedMethod); | 5679 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMe
thod, getterPropagatedMethod); |
| 5680 node.auxiliaryElements = auxiliaryElements; | 5680 node.auxiliaryElements = auxiliaryElements; |
| 5681 // generate undefined method warning | 5681 // generate undefined method warning |
| 5682 checkForUndefinedIndexOperator(node, target, getterMethodName, getterStati
cMethod, getterPropagatedMethod, staticType, propagatedType); | 5682 _checkForUndefinedIndexOperator(node, target, getterMethodName, getterStat
icMethod, getterPropagatedMethod, staticType, propagatedType); |
| 5683 } else if (isInGetterContext) { | 5683 } else if (isInGetterContext) { |
| 5684 // lookup getter method | 5684 // lookup getter method |
| 5685 MethodElement staticMethod = lookUpMethod(target, staticType, getterMethod
Name); | 5685 MethodElement staticMethod = _lookUpMethod(target, staticType, getterMetho
dName); |
| 5686 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, gett
erMethodName); | 5686 MethodElement propagatedMethod = _lookUpMethod(target, propagatedType, get
terMethodName); |
| 5687 // set getter element | 5687 // set getter element |
| 5688 node.staticElement = staticMethod; | 5688 node.staticElement = staticMethod; |
| 5689 node.propagatedElement = propagatedMethod; | 5689 node.propagatedElement = propagatedMethod; |
| 5690 // generate undefined method warning | 5690 // generate undefined method warning |
| 5691 checkForUndefinedIndexOperator(node, target, getterMethodName, staticMetho
d, propagatedMethod, staticType, propagatedType); | 5691 _checkForUndefinedIndexOperator(node, target, getterMethodName, staticMeth
od, propagatedMethod, staticType, propagatedType); |
| 5692 } else if (isInSetterContext) { | 5692 } else if (isInSetterContext) { |
| 5693 // lookup setter method | 5693 // lookup setter method |
| 5694 MethodElement staticMethod = lookUpMethod(target, staticType, setterMethod
Name); | 5694 MethodElement staticMethod = _lookUpMethod(target, staticType, setterMetho
dName); |
| 5695 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, sett
erMethodName); | 5695 MethodElement propagatedMethod = _lookUpMethod(target, propagatedType, set
terMethodName); |
| 5696 // set setter element | 5696 // set setter element |
| 5697 node.staticElement = staticMethod; | 5697 node.staticElement = staticMethod; |
| 5698 node.propagatedElement = propagatedMethod; | 5698 node.propagatedElement = propagatedMethod; |
| 5699 // generate undefined method warning | 5699 // generate undefined method warning |
| 5700 checkForUndefinedIndexOperator(node, target, setterMethodName, staticMetho
d, propagatedMethod, staticType, propagatedType); | 5700 _checkForUndefinedIndexOperator(node, target, setterMethodName, staticMeth
od, propagatedMethod, staticType, propagatedType); |
| 5701 } | 5701 } |
| 5702 return null; | 5702 return null; |
| 5703 } | 5703 } |
| 5704 | 5704 |
| 5705 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 5705 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 5706 ConstructorElement invokedConstructor = node.constructorName.staticElement; | 5706 ConstructorElement invokedConstructor = node.constructorName.staticElement; |
| 5707 node.staticElement = invokedConstructor; | 5707 node.staticElement = invokedConstructor; |
| 5708 ArgumentList argumentList = node.argumentList; | 5708 ArgumentList argumentList = node.argumentList; |
| 5709 List<ParameterElement> parameters = resolveArgumentsToFunction(node.isConst,
argumentList, invokedConstructor); | 5709 List<ParameterElement> parameters = _resolveArgumentsToFunction(node.isConst
, argumentList, invokedConstructor); |
| 5710 if (parameters != null) { | 5710 if (parameters != null) { |
| 5711 argumentList.correspondingStaticParameters = parameters; | 5711 argumentList.correspondingStaticParameters = parameters; |
| 5712 } | 5712 } |
| 5713 return null; | 5713 return null; |
| 5714 } | 5714 } |
| 5715 | 5715 |
| 5716 Object visitLibraryDirective(LibraryDirective node) { | 5716 Object visitLibraryDirective(LibraryDirective node) { |
| 5717 setMetadata(node.element, node); | 5717 _setMetadata(node.element, node); |
| 5718 return null; | 5718 return null; |
| 5719 } | 5719 } |
| 5720 | 5720 |
| 5721 Object visitMethodDeclaration(MethodDeclaration node) { | 5721 Object visitMethodDeclaration(MethodDeclaration node) { |
| 5722 setMetadata(node.element, node); | 5722 _setMetadata(node.element, node); |
| 5723 return null; | 5723 return null; |
| 5724 } | 5724 } |
| 5725 | 5725 |
| 5726 Object visitMethodInvocation(MethodInvocation node) { | 5726 Object visitMethodInvocation(MethodInvocation node) { |
| 5727 SimpleIdentifier methodName = node.methodName; | 5727 SimpleIdentifier methodName = node.methodName; |
| 5728 // | 5728 // |
| 5729 // Synthetic identifiers have been already reported during parsing. | 5729 // Synthetic identifiers have been already reported during parsing. |
| 5730 // | 5730 // |
| 5731 if (methodName.isSynthetic) { | 5731 if (methodName.isSynthetic) { |
| 5732 return null; | 5732 return null; |
| 5733 } | 5733 } |
| 5734 // | 5734 // |
| 5735 // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm
(a1, ..., an)'. The | 5735 // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm
(a1, ..., an)'. The |
| 5736 // first step is to figure out which executable is being invoked, using both
the static and the | 5736 // first step is to figure out which executable is being invoked, using both
the static and the |
| 5737 // propagated type information. | 5737 // propagated type information. |
| 5738 // | 5738 // |
| 5739 Expression target = node.realTarget; | 5739 Expression target = node.realTarget; |
| 5740 if (target is SuperExpression && !isSuperInValidContext(target)) { | 5740 if (target is SuperExpression && !_isSuperInValidContext(target)) { |
| 5741 return null; | 5741 return null; |
| 5742 } | 5742 } |
| 5743 Element staticElement; | 5743 Element staticElement; |
| 5744 Element propagatedElement; | 5744 Element propagatedElement; |
| 5745 if (target == null) { | 5745 if (target == null) { |
| 5746 staticElement = resolveInvokedElement(methodName); | 5746 staticElement = _resolveInvokedElement(methodName); |
| 5747 propagatedElement = null; | 5747 propagatedElement = null; |
| 5748 } else { | 5748 } else { |
| 5749 Type2 staticType = getStaticType(target); | 5749 Type2 staticType = _getStaticType(target); |
| 5750 // | 5750 // |
| 5751 // If this method invocation is of the form 'C.m' where 'C' is a class, th
en we don't call | 5751 // If this method invocation is of the form 'C.m' where 'C' is a class, th
en we don't call |
| 5752 // resolveInvokedElement(..) which walks up the class hierarchy, instead w
e just look for the | 5752 // resolveInvokedElement(..) which walks up the class hierarchy, instead w
e just look for the |
| 5753 // member in the type only. | 5753 // member in the type only. |
| 5754 // | 5754 // |
| 5755 ClassElementImpl typeReference = getTypeReference(target); | 5755 ClassElementImpl typeReference = getTypeReference(target); |
| 5756 if (typeReference != null) { | 5756 if (typeReference != null) { |
| 5757 staticElement = propagatedElement = resolveElement(typeReference, method
Name); | 5757 staticElement = propagatedElement = _resolveElement(typeReference, metho
dName); |
| 5758 } else { | 5758 } else { |
| 5759 staticElement = resolveInvokedElementWithTarget(target, staticType, meth
odName); | 5759 staticElement = _resolveInvokedElementWithTarget(target, staticType, met
hodName); |
| 5760 propagatedElement = resolveInvokedElementWithTarget(target, getPropagate
dType(target), methodName); | 5760 propagatedElement = _resolveInvokedElementWithTarget(target, _getPropaga
tedType(target), methodName); |
| 5761 } | 5761 } |
| 5762 } | 5762 } |
| 5763 staticElement = convertSetterToGetter(staticElement); | 5763 staticElement = _convertSetterToGetter(staticElement); |
| 5764 propagatedElement = convertSetterToGetter(propagatedElement); | 5764 propagatedElement = _convertSetterToGetter(propagatedElement); |
| 5765 // | 5765 // |
| 5766 // Record the results. | 5766 // Record the results. |
| 5767 // | 5767 // |
| 5768 methodName.staticElement = staticElement; | 5768 methodName.staticElement = staticElement; |
| 5769 methodName.propagatedElement = propagatedElement; | 5769 methodName.propagatedElement = propagatedElement; |
| 5770 ArgumentList argumentList = node.argumentList; | 5770 ArgumentList argumentList = node.argumentList; |
| 5771 if (staticElement != null) { | 5771 if (staticElement != null) { |
| 5772 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, staticElement); | 5772 List<ParameterElement> parameters = _computeCorrespondingParameters(argume
ntList, staticElement); |
| 5773 if (parameters != null) { | 5773 if (parameters != null) { |
| 5774 argumentList.correspondingStaticParameters = parameters; | 5774 argumentList.correspondingStaticParameters = parameters; |
| 5775 } | 5775 } |
| 5776 } | 5776 } |
| 5777 if (propagatedElement != null) { | 5777 if (propagatedElement != null) { |
| 5778 List<ParameterElement> parameters = computeCorrespondingParameters(argumen
tList, propagatedElement); | 5778 List<ParameterElement> parameters = _computeCorrespondingParameters(argume
ntList, propagatedElement); |
| 5779 if (parameters != null) { | 5779 if (parameters != null) { |
| 5780 argumentList.correspondingPropagatedParameters = parameters; | 5780 argumentList.correspondingPropagatedParameters = parameters; |
| 5781 } | 5781 } |
| 5782 } | 5782 } |
| 5783 // | 5783 // |
| 5784 // Then check for error conditions. | 5784 // Then check for error conditions. |
| 5785 // | 5785 // |
| 5786 ErrorCode errorCode = checkForInvocationError(target, true, staticElement); | 5786 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement); |
| 5787 bool generatedWithTypePropagation = false; | 5787 bool generatedWithTypePropagation = false; |
| 5788 if (_enableHints && errorCode == null && staticElement == null) { | 5788 if (_enableHints && errorCode == null && staticElement == null) { |
| 5789 errorCode = checkForInvocationError(target, false, propagatedElement); | 5789 errorCode = _checkForInvocationError(target, false, propagatedElement); |
| 5790 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 5790 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 5791 ClassElement classElementContext = null; | 5791 ClassElement classElementContext = null; |
| 5792 if (target == null) { | 5792 if (target == null) { |
| 5793 classElementContext = _resolver.enclosingClass; | 5793 classElementContext = _resolver.enclosingClass; |
| 5794 } else { | 5794 } else { |
| 5795 Type2 type = target.bestType; | 5795 Type2 type = target.bestType; |
| 5796 if (type != null) { | 5796 if (type != null) { |
| 5797 if (type.element is ClassElement) { | 5797 if (type.element is ClassElement) { |
| 5798 classElementContext = type.element as ClassElement; | 5798 classElementContext = type.element as ClassElement; |
| 5799 } | 5799 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 5824 ClassElement enclosingClass = _resolver.enclosingClass; | 5824 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5825 targetTypeName = enclosingClass.displayName; | 5825 targetTypeName = enclosingClass.displayName; |
| 5826 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; | 5826 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; |
| 5827 _resolver.reportProxyConditionalErrorForNode(_resolver.enclosingClass, p
roxyErrorCode, methodName, [methodName.name, targetTypeName]); | 5827 _resolver.reportProxyConditionalErrorForNode(_resolver.enclosingClass, p
roxyErrorCode, methodName, [methodName.name, targetTypeName]); |
| 5828 } else { | 5828 } else { |
| 5829 // ignore Function "call" | 5829 // ignore Function "call" |
| 5830 // (if we are about to create a hint using type propagation, then we can
use type | 5830 // (if we are about to create a hint using type propagation, then we can
use type |
| 5831 // propagation here as well) | 5831 // propagation here as well) |
| 5832 Type2 targetType = null; | 5832 Type2 targetType = null; |
| 5833 if (!generatedWithTypePropagation) { | 5833 if (!generatedWithTypePropagation) { |
| 5834 targetType = getStaticType(target); | 5834 targetType = _getStaticType(target); |
| 5835 } else { | 5835 } else { |
| 5836 // choose the best type | 5836 // choose the best type |
| 5837 targetType = getPropagatedType(target); | 5837 targetType = _getPropagatedType(target); |
| 5838 if (targetType == null) { | 5838 if (targetType == null) { |
| 5839 targetType = getStaticType(target); | 5839 targetType = _getStaticType(target); |
| 5840 } | 5840 } |
| 5841 } | 5841 } |
| 5842 if (targetType != null && targetType.isDartCoreFunction && methodName.na
me == CALL_METHOD_NAME) { | 5842 if (targetType != null && targetType.isDartCoreFunction && methodName.na
me == CALL_METHOD_NAME) { |
| 5843 // TODO(brianwilkerson) Can we ever resolve the function being invoked
? | 5843 // TODO(brianwilkerson) Can we ever resolve the function being invoked
? |
| 5844 //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction
); | 5844 //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction
); |
| 5845 return null; | 5845 return null; |
| 5846 } | 5846 } |
| 5847 targetTypeName = targetType == null ? null : targetType.displayName; | 5847 targetTypeName = targetType == null ? null : targetType.displayName; |
| 5848 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; | 5848 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDE
FINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD) as ErrorCode; |
| 5849 _resolver.reportProxyConditionalErrorForNode(targetType.element, proxyEr
rorCode, methodName, [methodName.name, targetTypeName]); | 5849 _resolver.reportProxyConditionalErrorForNode(targetType.element, proxyEr
rorCode, methodName, [methodName.name, targetTypeName]); |
| 5850 } | 5850 } |
| 5851 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD
)) { | 5851 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD
)) { |
| 5852 // Generate the type name. | 5852 // Generate the type name. |
| 5853 // The error code will never be generated via type propagation | 5853 // The error code will never be generated via type propagation |
| 5854 Type2 targetType = getStaticType(target); | 5854 Type2 targetType = _getStaticType(target); |
| 5855 String targetTypeName = targetType == null ? null : targetType.name; | 5855 String targetTypeName = targetType == null ? null : targetType.name; |
| 5856 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
methodName, [methodName.name, targetTypeName]); | 5856 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
methodName, [methodName.name, targetTypeName]); |
| 5857 } | 5857 } |
| 5858 return null; | 5858 return null; |
| 5859 } | 5859 } |
| 5860 | 5860 |
| 5861 Object visitPartDirective(PartDirective node) { | 5861 Object visitPartDirective(PartDirective node) { |
| 5862 setMetadata(node.element, node); | 5862 _setMetadata(node.element, node); |
| 5863 return null; | 5863 return null; |
| 5864 } | 5864 } |
| 5865 | 5865 |
| 5866 Object visitPartOfDirective(PartOfDirective node) { | 5866 Object visitPartOfDirective(PartOfDirective node) { |
| 5867 setMetadata(node.element, node); | 5867 _setMetadata(node.element, node); |
| 5868 return null; | 5868 return null; |
| 5869 } | 5869 } |
| 5870 | 5870 |
| 5871 Object visitPostfixExpression(PostfixExpression node) { | 5871 Object visitPostfixExpression(PostfixExpression node) { |
| 5872 Expression operand = node.operand; | 5872 Expression operand = node.operand; |
| 5873 String methodName = getPostfixOperator(node); | 5873 String methodName = _getPostfixOperator(node); |
| 5874 Type2 staticType = getStaticType(operand); | 5874 Type2 staticType = _getStaticType(operand); |
| 5875 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName); | 5875 MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName); |
| 5876 node.staticElement = staticMethod; | 5876 node.staticElement = staticMethod; |
| 5877 Type2 propagatedType = getPropagatedType(operand); | 5877 Type2 propagatedType = _getPropagatedType(operand); |
| 5878 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, metho
dName); | 5878 MethodElement propagatedMethod = _lookUpMethod(operand, propagatedType, meth
odName); |
| 5879 node.propagatedElement = propagatedMethod; | 5879 node.propagatedElement = propagatedMethod; |
| 5880 if (shouldReportMissingMember(staticType, staticMethod)) { | 5880 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 5881 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, Sta
ticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.di
splayName]); | 5881 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, Sta
ticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.di
splayName]); |
| 5882 } else if (_enableHints && shouldReportMissingMember(propagatedType, propaga
tedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true, f
alse)) { | 5882 } else if (_enableHints && _shouldReportMissingMember(propagatedType, propag
atedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true,
false)) { |
| 5883 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.element,
HintCode.UNDEFINED_OPERATOR, node.operator, [methodName, propagatedType.display
Name]); | 5883 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.element,
HintCode.UNDEFINED_OPERATOR, node.operator, [methodName, propagatedType.display
Name]); |
| 5884 } | 5884 } |
| 5885 return null; | 5885 return null; |
| 5886 } | 5886 } |
| 5887 | 5887 |
| 5888 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 5888 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 5889 SimpleIdentifier prefix = node.prefix; | 5889 SimpleIdentifier prefix = node.prefix; |
| 5890 SimpleIdentifier identifier = node.identifier; | 5890 SimpleIdentifier identifier = node.identifier; |
| 5891 // | 5891 // |
| 5892 // First, check to see whether the prefix is really a prefix. | 5892 // First, check to see whether the prefix is really a prefix. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 5917 element = setter; | 5917 element = setter; |
| 5918 } | 5918 } |
| 5919 } | 5919 } |
| 5920 } | 5920 } |
| 5921 // TODO(brianwilkerson) The prefix needs to be resolved to the element for
the import that | 5921 // TODO(brianwilkerson) The prefix needs to be resolved to the element for
the import that |
| 5922 // defines the prefix, not the prefix's element. | 5922 // defines the prefix, not the prefix's element. |
| 5923 identifier.staticElement = element; | 5923 identifier.staticElement = element; |
| 5924 // Validate annotation element. | 5924 // Validate annotation element. |
| 5925 if (node.parent is Annotation) { | 5925 if (node.parent is Annotation) { |
| 5926 Annotation annotation = node.parent as Annotation; | 5926 Annotation annotation = node.parent as Annotation; |
| 5927 resolveAnnotationElement(annotation); | 5927 _resolveAnnotationElement(annotation); |
| 5928 return null; | 5928 return null; |
| 5929 } | 5929 } |
| 5930 return null; | 5930 return null; |
| 5931 } | 5931 } |
| 5932 // May be annotation, resolve invocation of "const" constructor. | 5932 // May be annotation, resolve invocation of "const" constructor. |
| 5933 if (node.parent is Annotation) { | 5933 if (node.parent is Annotation) { |
| 5934 Annotation annotation = node.parent as Annotation; | 5934 Annotation annotation = node.parent as Annotation; |
| 5935 resolveAnnotationElement(annotation); | 5935 _resolveAnnotationElement(annotation); |
| 5936 } | 5936 } |
| 5937 // | 5937 // |
| 5938 // Otherwise, the prefix is really an expression that happens to be a simple
identifier and this | 5938 // Otherwise, the prefix is really an expression that happens to be a simple
identifier and this |
| 5939 // is really equivalent to a property access node. | 5939 // is really equivalent to a property access node. |
| 5940 // | 5940 // |
| 5941 resolvePropertyAccess(prefix, identifier); | 5941 _resolvePropertyAccess(prefix, identifier); |
| 5942 return null; | 5942 return null; |
| 5943 } | 5943 } |
| 5944 | 5944 |
| 5945 Object visitPrefixExpression(PrefixExpression node) { | 5945 Object visitPrefixExpression(PrefixExpression node) { |
| 5946 sc.Token operator = node.operator; | 5946 sc.Token operator = node.operator; |
| 5947 sc.TokenType operatorType = operator.type; | 5947 sc.TokenType operatorType = operator.type; |
| 5948 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token
Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { | 5948 if (operatorType.isUserDefinableOperator || identical(operatorType, sc.Token
Type.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { |
| 5949 Expression operand = node.operand; | 5949 Expression operand = node.operand; |
| 5950 String methodName = getPrefixOperator(node); | 5950 String methodName = _getPrefixOperator(node); |
| 5951 Type2 staticType = getStaticType(operand); | 5951 Type2 staticType = _getStaticType(operand); |
| 5952 MethodElement staticMethod = lookUpMethod(operand, staticType, methodName)
; | 5952 MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName
); |
| 5953 node.staticElement = staticMethod; | 5953 node.staticElement = staticMethod; |
| 5954 Type2 propagatedType = getPropagatedType(operand); | 5954 Type2 propagatedType = _getPropagatedType(operand); |
| 5955 MethodElement propagatedMethod = lookUpMethod(operand, propagatedType, met
hodName); | 5955 MethodElement propagatedMethod = _lookUpMethod(operand, propagatedType, me
thodName); |
| 5956 node.propagatedElement = propagatedMethod; | 5956 node.propagatedElement = propagatedMethod; |
| 5957 if (shouldReportMissingMember(staticType, staticMethod)) { | 5957 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 5958 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, S
taticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displ
ayName]); | 5958 _resolver.reportErrorProxyConditionalAnalysisError(staticType.element, S
taticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displ
ayName]); |
| 5959 } else if (_enableHints && shouldReportMissingMember(propagatedType, propa
gatedMethod) && !memberFoundInSubclass(propagatedType.element, methodName, true,
false)) { | 5959 } else if (_enableHints && _shouldReportMissingMember(propagatedType, prop
agatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, tru
e, false)) { |
| 5960 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.elemen
t, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayNam
e]); | 5960 _resolver.reportErrorProxyConditionalAnalysisError(propagatedType.elemen
t, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayNam
e]); |
| 5961 } | 5961 } |
| 5962 } | 5962 } |
| 5963 return null; | 5963 return null; |
| 5964 } | 5964 } |
| 5965 | 5965 |
| 5966 Object visitPropertyAccess(PropertyAccess node) { | 5966 Object visitPropertyAccess(PropertyAccess node) { |
| 5967 Expression target = node.realTarget; | 5967 Expression target = node.realTarget; |
| 5968 if (target is SuperExpression && !isSuperInValidContext(target)) { | 5968 if (target is SuperExpression && !_isSuperInValidContext(target)) { |
| 5969 return null; | 5969 return null; |
| 5970 } | 5970 } |
| 5971 SimpleIdentifier propertyName = node.propertyName; | 5971 SimpleIdentifier propertyName = node.propertyName; |
| 5972 resolvePropertyAccess(target, propertyName); | 5972 _resolvePropertyAccess(target, propertyName); |
| 5973 return null; | 5973 return null; |
| 5974 } | 5974 } |
| 5975 | 5975 |
| 5976 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { | 5976 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { |
| 5977 ClassElement enclosingClass = _resolver.enclosingClass; | 5977 ClassElement enclosingClass = _resolver.enclosingClass; |
| 5978 if (enclosingClass == null) { | 5978 if (enclosingClass == null) { |
| 5979 // TODO(brianwilkerson) Report this error. | 5979 // TODO(brianwilkerson) Report this error. |
| 5980 return null; | 5980 return null; |
| 5981 } | 5981 } |
| 5982 SimpleIdentifier name = node.constructorName; | 5982 SimpleIdentifier name = node.constructorName; |
| 5983 ConstructorElement element; | 5983 ConstructorElement element; |
| 5984 if (name == null) { | 5984 if (name == null) { |
| 5985 element = enclosingClass.unnamedConstructor; | 5985 element = enclosingClass.unnamedConstructor; |
| 5986 } else { | 5986 } else { |
| 5987 element = enclosingClass.getNamedConstructor(name.name); | 5987 element = enclosingClass.getNamedConstructor(name.name); |
| 5988 } | 5988 } |
| 5989 if (element == null) { | 5989 if (element == null) { |
| 5990 // TODO(brianwilkerson) Report this error and decide what element to assoc
iate with the node. | 5990 // TODO(brianwilkerson) Report this error and decide what element to assoc
iate with the node. |
| 5991 return null; | 5991 return null; |
| 5992 } | 5992 } |
| 5993 if (name != null) { | 5993 if (name != null) { |
| 5994 name.staticElement = element; | 5994 name.staticElement = element; |
| 5995 } | 5995 } |
| 5996 node.staticElement = element; | 5996 node.staticElement = element; |
| 5997 ArgumentList argumentList = node.argumentList; | 5997 ArgumentList argumentList = node.argumentList; |
| 5998 List<ParameterElement> parameters = resolveArgumentsToFunction(false, argume
ntList, element); | 5998 List<ParameterElement> parameters = _resolveArgumentsToFunction(false, argum
entList, element); |
| 5999 if (parameters != null) { | 5999 if (parameters != null) { |
| 6000 argumentList.correspondingStaticParameters = parameters; | 6000 argumentList.correspondingStaticParameters = parameters; |
| 6001 } | 6001 } |
| 6002 return null; | 6002 return null; |
| 6003 } | 6003 } |
| 6004 | 6004 |
| 6005 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 6005 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 6006 setMetadataForParameter(node.element, node); | 6006 _setMetadataForParameter(node.element, node); |
| 6007 return null; | 6007 return null; |
| 6008 } | 6008 } |
| 6009 | 6009 |
| 6010 Object visitSimpleIdentifier(SimpleIdentifier node) { | 6010 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 6011 // | 6011 // |
| 6012 // Synthetic identifiers have been already reported during parsing. | 6012 // Synthetic identifiers have been already reported during parsing. |
| 6013 // | 6013 // |
| 6014 if (node.isSynthetic) { | 6014 if (node.isSynthetic) { |
| 6015 return null; | 6015 return null; |
| 6016 } | 6016 } |
| 6017 // | 6017 // |
| 6018 // We ignore identifiers that have already been resolved, such as identifier
s representing the | 6018 // We ignore identifiers that have already been resolved, such as identifier
s representing the |
| 6019 // name in a declaration. | 6019 // name in a declaration. |
| 6020 // | 6020 // |
| 6021 if (node.staticElement != null) { | 6021 if (node.staticElement != null) { |
| 6022 return null; | 6022 return null; |
| 6023 } | 6023 } |
| 6024 // | 6024 // |
| 6025 // The name dynamic denotes a Type object even though dynamic is not a class
. | 6025 // The name dynamic denotes a Type object even though dynamic is not a class
. |
| 6026 // | 6026 // |
| 6027 if (node.name == _dynamicType.name) { | 6027 if (node.name == _dynamicType.name) { |
| 6028 node.staticElement = _dynamicType.element; | 6028 node.staticElement = _dynamicType.element; |
| 6029 node.staticType = _typeType; | 6029 node.staticType = _typeType; |
| 6030 return null; | 6030 return null; |
| 6031 } | 6031 } |
| 6032 // | 6032 // |
| 6033 // Otherwise, the node should be resolved. | 6033 // Otherwise, the node should be resolved. |
| 6034 // | 6034 // |
| 6035 Element element = resolveSimpleIdentifier(node); | 6035 Element element = _resolveSimpleIdentifier(node); |
| 6036 ClassElement enclosingClass = _resolver.enclosingClass; | 6036 ClassElement enclosingClass = _resolver.enclosingClass; |
| 6037 if (isFactoryConstructorReturnType(node) && element != enclosingClass) { | 6037 if (_isFactoryConstructorReturnType(node) && element != enclosingClass) { |
| 6038 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT
_A_CLASS, node, []); | 6038 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT
_A_CLASS, node, []); |
| 6039 } else if (isConstructorReturnType(node) && element != enclosingClass) { | 6039 } else if (_isConstructorReturnType(node) && element != enclosingClass) { |
| 6040 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME
, node, []); | 6040 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME
, node, []); |
| 6041 element = null; | 6041 element = null; |
| 6042 } else if (element == null || (element is PrefixElement && !isValidAsPrefix(
node))) { | 6042 } else if (element == null || (element is PrefixElement && !_isValidAsPrefix
(node))) { |
| 6043 // TODO(brianwilkerson) Recover from this error. | 6043 // TODO(brianwilkerson) Recover from this error. |
| 6044 if (isConstructorReturnType(node)) { | 6044 if (_isConstructorReturnType(node)) { |
| 6045 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NA
ME, node, []); | 6045 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NA
ME, node, []); |
| 6046 } else if (node.parent is Annotation) { | 6046 } else if (node.parent is Annotation) { |
| 6047 Annotation annotation = node.parent as Annotation; | 6047 Annotation annotation = node.parent as Annotation; |
| 6048 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, an
notation, []); | 6048 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, an
notation, []); |
| 6049 } else { | 6049 } else { |
| 6050 _resolver.reportProxyConditionalErrorForNode(_resolver.enclosingClass, S
taticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); | 6050 _resolver.reportProxyConditionalErrorForNode(_resolver.enclosingClass, S
taticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); |
| 6051 } | 6051 } |
| 6052 } | 6052 } |
| 6053 node.staticElement = element; | 6053 node.staticElement = element; |
| 6054 if (node.inSetterContext() && node.inGetterContext() && enclosingClass != nu
ll) { | 6054 if (node.inSetterContext() && node.inGetterContext() && enclosingClass != nu
ll) { |
| 6055 InterfaceType enclosingType = enclosingClass.type; | 6055 InterfaceType enclosingType = enclosingClass.type; |
| 6056 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(lookUpGetter(n
ull, enclosingType, node.name), null); | 6056 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(_lookUpGetter(
null, enclosingType, node.name), null); |
| 6057 node.auxiliaryElements = auxiliaryElements; | 6057 node.auxiliaryElements = auxiliaryElements; |
| 6058 } | 6058 } |
| 6059 // | 6059 // |
| 6060 // Validate annotation element. | 6060 // Validate annotation element. |
| 6061 // | 6061 // |
| 6062 if (node.parent is Annotation) { | 6062 if (node.parent is Annotation) { |
| 6063 Annotation annotation = node.parent as Annotation; | 6063 Annotation annotation = node.parent as Annotation; |
| 6064 resolveAnnotationElement(annotation); | 6064 _resolveAnnotationElement(annotation); |
| 6065 } | 6065 } |
| 6066 return null; | 6066 return null; |
| 6067 } | 6067 } |
| 6068 | 6068 |
| 6069 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 6069 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 6070 ClassElement enclosingClass = _resolver.enclosingClass; | 6070 ClassElement enclosingClass = _resolver.enclosingClass; |
| 6071 if (enclosingClass == null) { | 6071 if (enclosingClass == null) { |
| 6072 // TODO(brianwilkerson) Report this error. | 6072 // TODO(brianwilkerson) Report this error. |
| 6073 return null; | 6073 return null; |
| 6074 } | 6074 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6090 } else { | 6090 } else { |
| 6091 if (element.isFactory) { | 6091 if (element.isFactory) { |
| 6092 _resolver.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRU
CTOR, node, [element]); | 6092 _resolver.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRU
CTOR, node, [element]); |
| 6093 } | 6093 } |
| 6094 } | 6094 } |
| 6095 if (name != null) { | 6095 if (name != null) { |
| 6096 name.staticElement = element; | 6096 name.staticElement = element; |
| 6097 } | 6097 } |
| 6098 node.staticElement = element; | 6098 node.staticElement = element; |
| 6099 ArgumentList argumentList = node.argumentList; | 6099 ArgumentList argumentList = node.argumentList; |
| 6100 List<ParameterElement> parameters = resolveArgumentsToFunction(isInConstCons
tructor, argumentList, element); | 6100 List<ParameterElement> parameters = _resolveArgumentsToFunction(isInConstCon
structor, argumentList, element); |
| 6101 if (parameters != null) { | 6101 if (parameters != null) { |
| 6102 argumentList.correspondingStaticParameters = parameters; | 6102 argumentList.correspondingStaticParameters = parameters; |
| 6103 } | 6103 } |
| 6104 return null; | 6104 return null; |
| 6105 } | 6105 } |
| 6106 | 6106 |
| 6107 Object visitSuperExpression(SuperExpression node) { | 6107 Object visitSuperExpression(SuperExpression node) { |
| 6108 if (!isSuperInValidContext(node)) { | 6108 if (!_isSuperInValidContext(node)) { |
| 6109 _resolver.reportErrorForNode(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT
, node, []); | 6109 _resolver.reportErrorForNode(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT
, node, []); |
| 6110 } | 6110 } |
| 6111 return super.visitSuperExpression(node); | 6111 return super.visitSuperExpression(node); |
| 6112 } | 6112 } |
| 6113 | 6113 |
| 6114 Object visitTypeParameter(TypeParameter node) { | 6114 Object visitTypeParameter(TypeParameter node) { |
| 6115 setMetadata(node.element, node); | 6115 _setMetadata(node.element, node); |
| 6116 return null; | 6116 return null; |
| 6117 } | 6117 } |
| 6118 | 6118 |
| 6119 Object visitVariableDeclaration(VariableDeclaration node) { | 6119 Object visitVariableDeclaration(VariableDeclaration node) { |
| 6120 setMetadata(node.element, node); | 6120 _setMetadata(node.element, node); |
| 6121 return null; | 6121 return null; |
| 6122 } | 6122 } |
| 6123 | 6123 |
| 6124 /** | 6124 /** |
| 6125 * Generate annotation elements for each of the annotations in the given node
list and add them to | 6125 * Generate annotation elements for each of the annotations in the given node
list and add them to |
| 6126 * the given list of elements. | 6126 * the given list of elements. |
| 6127 * | 6127 * |
| 6128 * @param annotationList the list of elements to which new elements are to be
added | 6128 * @param annotationList the list of elements to which new elements are to be
added |
| 6129 * @param annotations the AST nodes used to generate new elements | 6129 * @param annotations the AST nodes used to generate new elements |
| 6130 */ | 6130 */ |
| 6131 void addAnnotations(List<ElementAnnotationImpl> annotationList, NodeList<Annot
ation> annotations) { | 6131 void _addAnnotations(List<ElementAnnotationImpl> annotationList, NodeList<Anno
tation> annotations) { |
| 6132 int annotationCount = annotations.length; | 6132 int annotationCount = annotations.length; |
| 6133 for (int i = 0; i < annotationCount; i++) { | 6133 for (int i = 0; i < annotationCount; i++) { |
| 6134 Element resolvedElement = annotations[i].element; | 6134 Element resolvedElement = annotations[i].element; |
| 6135 if (resolvedElement != null) { | 6135 if (resolvedElement != null) { |
| 6136 annotationList.add(new ElementAnnotationImpl(resolvedElement)); | 6136 annotationList.add(new ElementAnnotationImpl(resolvedElement)); |
| 6137 } | 6137 } |
| 6138 } | 6138 } |
| 6139 } | 6139 } |
| 6140 | 6140 |
| 6141 /** | 6141 /** |
| 6142 * Given that we have found code to invoke the given element, return the error
code that should be | 6142 * Given that we have found code to invoke the given element, return the error
code that should be |
| 6143 * reported, or `null` if no error should be reported. | 6143 * reported, or `null` if no error should be reported. |
| 6144 * | 6144 * |
| 6145 * @param target the target of the invocation, or `null` if there was no targe
t | 6145 * @param target the target of the invocation, or `null` if there was no targe
t |
| 6146 * @param useStaticContext | 6146 * @param useStaticContext |
| 6147 * @param element the element to be invoked | 6147 * @param element the element to be invoked |
| 6148 * @return the error code that should be reported | 6148 * @return the error code that should be reported |
| 6149 */ | 6149 */ |
| 6150 ErrorCode checkForInvocationError(Expression target, bool useStaticContext, El
ement element) { | 6150 ErrorCode _checkForInvocationError(Expression target, bool useStaticContext, E
lement element) { |
| 6151 // Prefix is not declared, instead "prefix.id" are declared. | 6151 // Prefix is not declared, instead "prefix.id" are declared. |
| 6152 if (element is PrefixElement) { | 6152 if (element is PrefixElement) { |
| 6153 element = null; | 6153 element = null; |
| 6154 } | 6154 } |
| 6155 if (element is PropertyAccessorElement) { | 6155 if (element is PropertyAccessorElement) { |
| 6156 // | 6156 // |
| 6157 // This is really a function expression invocation. | 6157 // This is really a function expression invocation. |
| 6158 // | 6158 // |
| 6159 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. | 6159 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 6160 FunctionType getterType = element.type; | 6160 FunctionType getterType = element.type; |
| 6161 if (getterType != null) { | 6161 if (getterType != null) { |
| 6162 Type2 returnType = getterType.returnType; | 6162 Type2 returnType = getterType.returnType; |
| 6163 if (!isExecutableType(returnType)) { | 6163 if (!_isExecutableType(returnType)) { |
| 6164 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 6164 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 6165 } | 6165 } |
| 6166 } | 6166 } |
| 6167 } else if (element is ExecutableElement) { | 6167 } else if (element is ExecutableElement) { |
| 6168 return null; | 6168 return null; |
| 6169 } else if (element == null && target is SuperExpression) { | 6169 } else if (element == null && target is SuperExpression) { |
| 6170 // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes,
this one, and | 6170 // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes,
this one, and |
| 6171 // a code that describes the situation where the method was found, but it
was not | 6171 // a code that describes the situation where the method was found, but it
was not |
| 6172 // accessible from the current library. | 6172 // accessible from the current library. |
| 6173 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; | 6173 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD; |
| 6174 } else { | 6174 } else { |
| 6175 // | 6175 // |
| 6176 // This is really a function expression invocation. | 6176 // This is really a function expression invocation. |
| 6177 // | 6177 // |
| 6178 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. | 6178 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 6179 if (element is PropertyInducingElement) { | 6179 if (element is PropertyInducingElement) { |
| 6180 PropertyAccessorElement getter = element.getter; | 6180 PropertyAccessorElement getter = element.getter; |
| 6181 FunctionType getterType = getter.type; | 6181 FunctionType getterType = getter.type; |
| 6182 if (getterType != null) { | 6182 if (getterType != null) { |
| 6183 Type2 returnType = getterType.returnType; | 6183 Type2 returnType = getterType.returnType; |
| 6184 if (!isExecutableType(returnType)) { | 6184 if (!_isExecutableType(returnType)) { |
| 6185 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 6185 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 6186 } | 6186 } |
| 6187 } | 6187 } |
| 6188 } else if (element is VariableElement) { | 6188 } else if (element is VariableElement) { |
| 6189 Type2 variableType = element.type; | 6189 Type2 variableType = element.type; |
| 6190 if (!isExecutableType(variableType)) { | 6190 if (!_isExecutableType(variableType)) { |
| 6191 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 6191 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 6192 } | 6192 } |
| 6193 } else { | 6193 } else { |
| 6194 if (target == null) { | 6194 if (target == null) { |
| 6195 ClassElement enclosingClass = _resolver.enclosingClass; | 6195 ClassElement enclosingClass = _resolver.enclosingClass; |
| 6196 if (enclosingClass == null) { | 6196 if (enclosingClass == null) { |
| 6197 return CompileTimeErrorCode.UNDEFINED_FUNCTION; | 6197 return CompileTimeErrorCode.UNDEFINED_FUNCTION; |
| 6198 } else if (element == null) { | 6198 } else if (element == null) { |
| 6199 // Proxy-conditional warning, based on state of resolver.getEnclosin
gClass() | 6199 // Proxy-conditional warning, based on state of resolver.getEnclosin
gClass() |
| 6200 return StaticTypeWarningCode.UNDEFINED_METHOD; | 6200 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 6201 } else { | 6201 } else { |
| 6202 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; | 6202 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; |
| 6203 } | 6203 } |
| 6204 } else { | 6204 } else { |
| 6205 Type2 targetType; | 6205 Type2 targetType; |
| 6206 if (useStaticContext) { | 6206 if (useStaticContext) { |
| 6207 targetType = getStaticType(target); | 6207 targetType = _getStaticType(target); |
| 6208 } else { | 6208 } else { |
| 6209 // Compute and use the propagated type, if it is null, then it may b
e the case that | 6209 // Compute and use the propagated type, if it is null, then it may b
e the case that |
| 6210 // static type is some type, in which the static type should be used
. | 6210 // static type is some type, in which the static type should be used
. |
| 6211 targetType = target.bestType; | 6211 targetType = target.bestType; |
| 6212 } | 6212 } |
| 6213 if (targetType == null) { | 6213 if (targetType == null) { |
| 6214 return CompileTimeErrorCode.UNDEFINED_FUNCTION; | 6214 return CompileTimeErrorCode.UNDEFINED_FUNCTION; |
| 6215 } else if (!targetType.isDynamic && !targetType.isBottom) { | 6215 } else if (!targetType.isDynamic && !targetType.isBottom) { |
| 6216 // Proxy-conditional warning, based on state of targetType.getElemen
t() | 6216 // Proxy-conditional warning, based on state of targetType.getElemen
t() |
| 6217 return StaticTypeWarningCode.UNDEFINED_METHOD; | 6217 return StaticTypeWarningCode.UNDEFINED_METHOD; |
| 6218 } | 6218 } |
| 6219 } | 6219 } |
| 6220 } | 6220 } |
| 6221 } | 6221 } |
| 6222 return null; | 6222 return null; |
| 6223 } | 6223 } |
| 6224 | 6224 |
| 6225 /** | 6225 /** |
| 6226 * Check that the for some index expression that the method element was resolv
ed, otherwise a | 6226 * Check that the for some index expression that the method element was resolv
ed, otherwise a |
| 6227 * [StaticWarningCode#UNDEFINED_OPERATOR] is generated. | 6227 * [StaticWarningCode#UNDEFINED_OPERATOR] is generated. |
| 6228 * | 6228 * |
| 6229 * @param node the index expression to resolve | 6229 * @param node the index expression to resolve |
| 6230 * @param target the target of the expression | 6230 * @param target the target of the expression |
| 6231 * @param methodName the name of the operator associated with the context of u
sing of the given | 6231 * @param methodName the name of the operator associated with the context of u
sing of the given |
| 6232 * index expression | 6232 * index expression |
| 6233 * @return `true` if and only if an error code is generated on the passed node | 6233 * @return `true` if and only if an error code is generated on the passed node |
| 6234 */ | 6234 */ |
| 6235 bool checkForUndefinedIndexOperator(IndexExpression node, Expression target, S
tring methodName, MethodElement staticMethod, MethodElement propagatedMethod, Ty
pe2 staticType, Type2 propagatedType) { | 6235 bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target,
String methodName, MethodElement staticMethod, MethodElement propagatedMethod, T
ype2 staticType, Type2 propagatedType) { |
| 6236 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticMethod); | 6236 bool shouldReportMissingMember_static = _shouldReportMissingMember(staticTyp
e, staticMethod); |
| 6237 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints && shouldReportMissingMember(propagatedType, propagatedMethod)
&& !memberFoundInSubclass(propagatedType.element, methodName, true, false); | 6237 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod
) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false); |
| 6238 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { | 6238 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { |
| 6239 sc.Token leftBracket = node.leftBracket; | 6239 sc.Token leftBracket = node.leftBracket; |
| 6240 sc.Token rightBracket = node.rightBracket; | 6240 sc.Token rightBracket = node.rightBracket; |
| 6241 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin
gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; | 6241 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarnin
gCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR) as ErrorCode; |
| 6242 if (leftBracket == null || rightBracket == null) { | 6242 if (leftBracket == null || rightBracket == null) { |
| 6243 _resolver.reportProxyConditionalErrorForNode(shouldReportMissingMember_s
tatic ? staticType.element : propagatedType.element, errorCode, node, [ | 6243 _resolver.reportProxyConditionalErrorForNode(shouldReportMissingMember_s
tatic ? staticType.element : propagatedType.element, errorCode, node, [ |
| 6244 methodName, | 6244 methodName, |
| 6245 shouldReportMissingMember_static ? staticType.displayName : propagat
edType.displayName]); | 6245 shouldReportMissingMember_static ? staticType.displayName : propagat
edType.displayName]); |
| 6246 } else { | 6246 } else { |
| 6247 int offset = leftBracket.offset; | 6247 int offset = leftBracket.offset; |
| 6248 int length = rightBracket.offset - offset + 1; | 6248 int length = rightBracket.offset - offset + 1; |
| 6249 _resolver.reportProxyConditionalErrorForOffset(shouldReportMissingMember
_static ? staticType.element : propagatedType.element, errorCode, offset, length
, [ | 6249 _resolver.reportProxyConditionalErrorForOffset(shouldReportMissingMember
_static ? staticType.element : propagatedType.element, errorCode, offset, length
, [ |
| 6250 methodName, | 6250 methodName, |
| 6251 shouldReportMissingMember_static ? staticType.displayName : propagat
edType.displayName]); | 6251 shouldReportMissingMember_static ? staticType.displayName : propagat
edType.displayName]); |
| 6252 } | 6252 } |
| 6253 return true; | 6253 return true; |
| 6254 } | 6254 } |
| 6255 return false; | 6255 return false; |
| 6256 } | 6256 } |
| 6257 | 6257 |
| 6258 /** | 6258 /** |
| 6259 * Given a list of arguments and the element that will be invoked using those
argument, compute | 6259 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 6260 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 6260 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 6261 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 6261 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 6262 * | 6262 * |
| 6263 * @param argumentList the list of arguments being passed to the element | 6263 * @param argumentList the list of arguments being passed to the element |
| 6264 * @param executableElement the element that will be invoked with the argument
s | 6264 * @param executableElement the element that will be invoked with the argument
s |
| 6265 * @return the parameters that correspond to the arguments | 6265 * @return the parameters that correspond to the arguments |
| 6266 */ | 6266 */ |
| 6267 List<ParameterElement> computeCorrespondingParameters(ArgumentList argumentLis
t, Element element) { | 6267 List<ParameterElement> _computeCorrespondingParameters(ArgumentList argumentLi
st, Element element) { |
| 6268 if (element is PropertyAccessorElement) { | 6268 if (element is PropertyAccessorElement) { |
| 6269 // | 6269 // |
| 6270 // This is an invocation of the call method defined on the value returned
by the getter. | 6270 // This is an invocation of the call method defined on the value returned
by the getter. |
| 6271 // | 6271 // |
| 6272 FunctionType getterType = element.type; | 6272 FunctionType getterType = element.type; |
| 6273 if (getterType != null) { | 6273 if (getterType != null) { |
| 6274 Type2 getterReturnType = getterType.returnType; | 6274 Type2 getterReturnType = getterType.returnType; |
| 6275 if (getterReturnType is InterfaceType) { | 6275 if (getterReturnType is InterfaceType) { |
| 6276 MethodElement callMethod = getterReturnType.lookUpMethod(CALL_METHOD_N
AME, _definingLibrary); | 6276 MethodElement callMethod = getterReturnType.lookUpMethod(CALL_METHOD_N
AME, _definingLibrary); |
| 6277 if (callMethod != null) { | 6277 if (callMethod != null) { |
| 6278 return resolveArgumentsToFunction(false, argumentList, callMethod); | 6278 return _resolveArgumentsToFunction(false, argumentList, callMethod); |
| 6279 } | 6279 } |
| 6280 } else if (getterReturnType is FunctionType) { | 6280 } else if (getterReturnType is FunctionType) { |
| 6281 Element functionElement = getterReturnType.element; | 6281 Element functionElement = getterReturnType.element; |
| 6282 if (functionElement is ExecutableElement) { | 6282 if (functionElement is ExecutableElement) { |
| 6283 return resolveArgumentsToFunction(false, argumentList, functionEleme
nt); | 6283 return _resolveArgumentsToFunction(false, argumentList, functionElem
ent); |
| 6284 } | 6284 } |
| 6285 } | 6285 } |
| 6286 } | 6286 } |
| 6287 } else if (element is ExecutableElement) { | 6287 } else if (element is ExecutableElement) { |
| 6288 return resolveArgumentsToFunction(false, argumentList, element); | 6288 return _resolveArgumentsToFunction(false, argumentList, element); |
| 6289 } else if (element is VariableElement) { | 6289 } else if (element is VariableElement) { |
| 6290 VariableElement variable = element; | 6290 VariableElement variable = element; |
| 6291 Type2 type = _promoteManager.getStaticType(variable); | 6291 Type2 type = _promoteManager.getStaticType(variable); |
| 6292 if (type is FunctionType) { | 6292 if (type is FunctionType) { |
| 6293 FunctionType functionType = type; | 6293 FunctionType functionType = type; |
| 6294 List<ParameterElement> parameters = functionType.parameters; | 6294 List<ParameterElement> parameters = functionType.parameters; |
| 6295 return resolveArgumentsToParameters(false, argumentList, parameters); | 6295 return _resolveArgumentsToParameters(false, argumentList, parameters); |
| 6296 } else if (type is InterfaceType) { | 6296 } else if (type is InterfaceType) { |
| 6297 // "call" invocation | 6297 // "call" invocation |
| 6298 MethodElement callMethod = type.lookUpMethod(CALL_METHOD_NAME, _defining
Library); | 6298 MethodElement callMethod = type.lookUpMethod(CALL_METHOD_NAME, _defining
Library); |
| 6299 if (callMethod != null) { | 6299 if (callMethod != null) { |
| 6300 List<ParameterElement> parameters = callMethod.parameters; | 6300 List<ParameterElement> parameters = callMethod.parameters; |
| 6301 return resolveArgumentsToParameters(false, argumentList, parameters); | 6301 return _resolveArgumentsToParameters(false, argumentList, parameters); |
| 6302 } | 6302 } |
| 6303 } | 6303 } |
| 6304 } | 6304 } |
| 6305 return null; | 6305 return null; |
| 6306 } | 6306 } |
| 6307 | 6307 |
| 6308 /** | 6308 /** |
| 6309 * If the given element is a setter, return the getter associated with it. Oth
erwise, return the | 6309 * If the given element is a setter, return the getter associated with it. Oth
erwise, return the |
| 6310 * element unchanged. | 6310 * element unchanged. |
| 6311 * | 6311 * |
| 6312 * @param element the element to be normalized | 6312 * @param element the element to be normalized |
| 6313 * @return a non-setter element derived from the given element | 6313 * @return a non-setter element derived from the given element |
| 6314 */ | 6314 */ |
| 6315 Element convertSetterToGetter(Element element) { | 6315 Element _convertSetterToGetter(Element element) { |
| 6316 // TODO(brianwilkerson) Determine whether and why the element could ever be
a setter. | 6316 // TODO(brianwilkerson) Determine whether and why the element could ever be
a setter. |
| 6317 if (element is PropertyAccessorElement) { | 6317 if (element is PropertyAccessorElement) { |
| 6318 return element.variable.getter; | 6318 return element.variable.getter; |
| 6319 } | 6319 } |
| 6320 return element; | 6320 return element; |
| 6321 } | 6321 } |
| 6322 | 6322 |
| 6323 /** | 6323 /** |
| 6324 * Look for any declarations of the given identifier that are imported using a
prefix. Return the | 6324 * Look for any declarations of the given identifier that are imported using a
prefix. Return the |
| 6325 * element that was found, or `null` if the name is not imported using a prefi
x. | 6325 * element that was found, or `null` if the name is not imported using a prefi
x. |
| 6326 * | 6326 * |
| 6327 * @param identifier the identifier that might have been imported using a pref
ix | 6327 * @param identifier the identifier that might have been imported using a pref
ix |
| 6328 * @return the element that was found | 6328 * @return the element that was found |
| 6329 */ | 6329 */ |
| 6330 Element findImportWithoutPrefix(SimpleIdentifier identifier) { | 6330 Element _findImportWithoutPrefix(SimpleIdentifier identifier) { |
| 6331 Element element = null; | 6331 Element element = null; |
| 6332 Scope nameScope = _resolver.nameScope; | 6332 Scope nameScope = _resolver.nameScope; |
| 6333 for (ImportElement importElement in _definingLibrary.imports) { | 6333 for (ImportElement importElement in _definingLibrary.imports) { |
| 6334 PrefixElement prefixElement = importElement.prefix; | 6334 PrefixElement prefixElement = importElement.prefix; |
| 6335 if (prefixElement != null) { | 6335 if (prefixElement != null) { |
| 6336 Identifier prefixedIdentifier = new ElementResolver_SyntheticIdentifier(
"${prefixElement.name}.${identifier.name}"); | 6336 Identifier prefixedIdentifier = new ElementResolver_SyntheticIdentifier(
"${prefixElement.name}.${identifier.name}"); |
| 6337 Element importedElement = nameScope.lookup(prefixedIdentifier, _defining
Library); | 6337 Element importedElement = nameScope.lookup(prefixedIdentifier, _defining
Library); |
| 6338 if (importedElement != null) { | 6338 if (importedElement != null) { |
| 6339 if (element == null) { | 6339 if (element == null) { |
| 6340 element = importedElement; | 6340 element = importedElement; |
| 6341 } else { | 6341 } else { |
| 6342 element = MultiplyDefinedElementImpl.fromElements(_definingLibrary.c
ontext, element, importedElement); | 6342 element = MultiplyDefinedElementImpl.fromElements(_definingLibrary.c
ontext, element, importedElement); |
| 6343 } | 6343 } |
| 6344 } | 6344 } |
| 6345 } | 6345 } |
| 6346 } | 6346 } |
| 6347 return element; | 6347 return element; |
| 6348 } | 6348 } |
| 6349 | 6349 |
| 6350 /** | 6350 /** |
| 6351 * Return the name of the method invoked by the given postfix expression. | 6351 * Return the name of the method invoked by the given postfix expression. |
| 6352 * | 6352 * |
| 6353 * @param node the postfix expression being invoked | 6353 * @param node the postfix expression being invoked |
| 6354 * @return the name of the method invoked by the expression | 6354 * @return the name of the method invoked by the expression |
| 6355 */ | 6355 */ |
| 6356 String getPostfixOperator(PostfixExpression node) => (identical(node.operator.
type, sc.TokenType.PLUS_PLUS)) ? sc.TokenType.PLUS.lexeme : sc.TokenType.MINUS.l
exeme; | 6356 String _getPostfixOperator(PostfixExpression node) => (identical(node.operator
.type, sc.TokenType.PLUS_PLUS)) ? sc.TokenType.PLUS.lexeme : sc.TokenType.MINUS.
lexeme; |
| 6357 | 6357 |
| 6358 /** | 6358 /** |
| 6359 * Return the name of the method invoked by the given postfix expression. | 6359 * Return the name of the method invoked by the given postfix expression. |
| 6360 * | 6360 * |
| 6361 * @param node the postfix expression being invoked | 6361 * @param node the postfix expression being invoked |
| 6362 * @return the name of the method invoked by the expression | 6362 * @return the name of the method invoked by the expression |
| 6363 */ | 6363 */ |
| 6364 String getPrefixOperator(PrefixExpression node) { | 6364 String _getPrefixOperator(PrefixExpression node) { |
| 6365 sc.Token operator = node.operator; | 6365 sc.Token operator = node.operator; |
| 6366 sc.TokenType operatorType = operator.type; | 6366 sc.TokenType operatorType = operator.type; |
| 6367 if (identical(operatorType, sc.TokenType.PLUS_PLUS)) { | 6367 if (identical(operatorType, sc.TokenType.PLUS_PLUS)) { |
| 6368 return sc.TokenType.PLUS.lexeme; | 6368 return sc.TokenType.PLUS.lexeme; |
| 6369 } else if (identical(operatorType, sc.TokenType.MINUS_MINUS)) { | 6369 } else if (identical(operatorType, sc.TokenType.MINUS_MINUS)) { |
| 6370 return sc.TokenType.MINUS.lexeme; | 6370 return sc.TokenType.MINUS.lexeme; |
| 6371 } else if (identical(operatorType, sc.TokenType.MINUS)) { | 6371 } else if (identical(operatorType, sc.TokenType.MINUS)) { |
| 6372 return "unary-"; | 6372 return "unary-"; |
| 6373 } else { | 6373 } else { |
| 6374 return operator.lexeme; | 6374 return operator.lexeme; |
| 6375 } | 6375 } |
| 6376 } | 6376 } |
| 6377 | 6377 |
| 6378 /** | 6378 /** |
| 6379 * Return the propagated type of the given expression that is to be used for t
ype analysis. | 6379 * Return the propagated type of the given expression that is to be used for t
ype analysis. |
| 6380 * | 6380 * |
| 6381 * @param expression the expression whose type is to be returned | 6381 * @param expression the expression whose type is to be returned |
| 6382 * @return the type of the given expression | 6382 * @return the type of the given expression |
| 6383 */ | 6383 */ |
| 6384 Type2 getPropagatedType(Expression expression) { | 6384 Type2 _getPropagatedType(Expression expression) { |
| 6385 Type2 propagatedType = resolveTypeParameter(expression.propagatedType); | 6385 Type2 propagatedType = _resolveTypeParameter(expression.propagatedType); |
| 6386 if (propagatedType is FunctionType) { | 6386 if (propagatedType is FunctionType) { |
| 6387 // | 6387 // |
| 6388 // All function types are subtypes of 'Function', which is itself a subcla
ss of 'Object'. | 6388 // All function types are subtypes of 'Function', which is itself a subcla
ss of 'Object'. |
| 6389 // | 6389 // |
| 6390 propagatedType = _resolver.typeProvider.functionType; | 6390 propagatedType = _resolver.typeProvider.functionType; |
| 6391 } | 6391 } |
| 6392 return propagatedType; | 6392 return propagatedType; |
| 6393 } | 6393 } |
| 6394 | 6394 |
| 6395 /** | 6395 /** |
| 6396 * Return the static type of the given expression that is to be used for type
analysis. | 6396 * Return the static type of the given expression that is to be used for type
analysis. |
| 6397 * | 6397 * |
| 6398 * @param expression the expression whose type is to be returned | 6398 * @param expression the expression whose type is to be returned |
| 6399 * @return the type of the given expression | 6399 * @return the type of the given expression |
| 6400 */ | 6400 */ |
| 6401 Type2 getStaticType(Expression expression) { | 6401 Type2 _getStaticType(Expression expression) { |
| 6402 if (expression is NullLiteral) { | 6402 if (expression is NullLiteral) { |
| 6403 return _resolver.typeProvider.bottomType; | 6403 return _resolver.typeProvider.bottomType; |
| 6404 } | 6404 } |
| 6405 Type2 staticType = resolveTypeParameter(expression.staticType); | 6405 Type2 staticType = _resolveTypeParameter(expression.staticType); |
| 6406 if (staticType is FunctionType) { | 6406 if (staticType is FunctionType) { |
| 6407 // | 6407 // |
| 6408 // All function types are subtypes of 'Function', which is itself a subcla
ss of 'Object'. | 6408 // All function types are subtypes of 'Function', which is itself a subcla
ss of 'Object'. |
| 6409 // | 6409 // |
| 6410 staticType = _resolver.typeProvider.functionType; | 6410 staticType = _resolver.typeProvider.functionType; |
| 6411 } | 6411 } |
| 6412 return staticType; | 6412 return staticType; |
| 6413 } | 6413 } |
| 6414 | 6414 |
| 6415 /** | 6415 /** |
| 6416 * Return `true` if the given type represents an object that could be invoked
using the call | 6416 * Return `true` if the given type represents an object that could be invoked
using the call |
| 6417 * operator '()'. | 6417 * operator '()'. |
| 6418 * | 6418 * |
| 6419 * @param type the type being tested | 6419 * @param type the type being tested |
| 6420 * @return `true` if the given type represents an object that could be invoked | 6420 * @return `true` if the given type represents an object that could be invoked |
| 6421 */ | 6421 */ |
| 6422 bool isExecutableType(Type2 type) { | 6422 bool _isExecutableType(Type2 type) { |
| 6423 if (type.isDynamic || (type is FunctionType) || type.isDartCoreFunction || t
ype.isObject) { | 6423 if (type.isDynamic || (type is FunctionType) || type.isDartCoreFunction || t
ype.isObject) { |
| 6424 return true; | 6424 return true; |
| 6425 } else if (type is InterfaceType) { | 6425 } else if (type is InterfaceType) { |
| 6426 ClassElement classElement = type.element; | 6426 ClassElement classElement = type.element; |
| 6427 MethodElement methodElement = classElement.lookUpMethod(CALL_METHOD_NAME,
_definingLibrary); | 6427 MethodElement methodElement = classElement.lookUpMethod(CALL_METHOD_NAME,
_definingLibrary); |
| 6428 return methodElement != null; | 6428 return methodElement != null; |
| 6429 } | 6429 } |
| 6430 return false; | 6430 return false; |
| 6431 } | 6431 } |
| 6432 | 6432 |
| 6433 /** | 6433 /** |
| 6434 * @return `true` iff current enclosing function is constant constructor decla
ration. | 6434 * @return `true` iff current enclosing function is constant constructor decla
ration. |
| 6435 */ | 6435 */ |
| 6436 bool get isInConstConstructor { | 6436 bool get isInConstConstructor { |
| 6437 ExecutableElement function = _resolver.enclosingFunction; | 6437 ExecutableElement function = _resolver.enclosingFunction; |
| 6438 if (function is ConstructorElement) { | 6438 if (function is ConstructorElement) { |
| 6439 return function.isConst; | 6439 return function.isConst; |
| 6440 } | 6440 } |
| 6441 return false; | 6441 return false; |
| 6442 } | 6442 } |
| 6443 | 6443 |
| 6444 /** | 6444 /** |
| 6445 * Return `true` if the given element is a static element. | 6445 * Return `true` if the given element is a static element. |
| 6446 * | 6446 * |
| 6447 * @param element the element being tested | 6447 * @param element the element being tested |
| 6448 * @return `true` if the given element is a static element | 6448 * @return `true` if the given element is a static element |
| 6449 */ | 6449 */ |
| 6450 bool isStatic(Element element) { | 6450 bool _isStatic(Element element) { |
| 6451 if (element is ExecutableElement) { | 6451 if (element is ExecutableElement) { |
| 6452 return element.isStatic; | 6452 return element.isStatic; |
| 6453 } else if (element is PropertyInducingElement) { | 6453 } else if (element is PropertyInducingElement) { |
| 6454 return element.isStatic; | 6454 return element.isStatic; |
| 6455 } | 6455 } |
| 6456 return false; | 6456 return false; |
| 6457 } | 6457 } |
| 6458 | 6458 |
| 6459 /** | 6459 /** |
| 6460 * Return `true` if the given node can validly be resolved to a prefix: | 6460 * Return `true` if the given node can validly be resolved to a prefix: |
| 6461 * * it is the prefix in an import directive, or | 6461 * * it is the prefix in an import directive, or |
| 6462 * * it is the prefix in a prefixed identifier. | 6462 * * it is the prefix in a prefixed identifier. |
| 6463 * | 6463 * |
| 6464 * @param node the node being tested | 6464 * @param node the node being tested |
| 6465 * @return `true` if the given node is the prefix in an import directive | 6465 * @return `true` if the given node is the prefix in an import directive |
| 6466 */ | 6466 */ |
| 6467 bool isValidAsPrefix(SimpleIdentifier node) { | 6467 bool _isValidAsPrefix(SimpleIdentifier node) { |
| 6468 AstNode parent = node.parent; | 6468 AstNode parent = node.parent; |
| 6469 if (parent is ImportDirective) { | 6469 if (parent is ImportDirective) { |
| 6470 return identical(parent.prefix, node); | 6470 return identical(parent.prefix, node); |
| 6471 } else if (parent is PrefixedIdentifier) { | 6471 } else if (parent is PrefixedIdentifier) { |
| 6472 return true; | 6472 return true; |
| 6473 } else if (parent is MethodInvocation) { | 6473 } else if (parent is MethodInvocation) { |
| 6474 return identical(parent.target, node); | 6474 return identical(parent.target, node); |
| 6475 } | 6475 } |
| 6476 return false; | 6476 return false; |
| 6477 } | 6477 } |
| 6478 | 6478 |
| 6479 /** | 6479 /** |
| 6480 * Look up the getter with the given name in the given type. Return the elemen
t representing the | 6480 * Look up the getter with the given name in the given type. Return the elemen
t representing the |
| 6481 * getter that was found, or `null` if there is no getter with the given name. | 6481 * getter that was found, or `null` if there is no getter with the given name. |
| 6482 * | 6482 * |
| 6483 * @param target the target of the invocation, or `null` if there is no target | 6483 * @param target the target of the invocation, or `null` if there is no target |
| 6484 * @param type the type in which the getter is defined | 6484 * @param type the type in which the getter is defined |
| 6485 * @param getterName the name of the getter being looked up | 6485 * @param getterName the name of the getter being looked up |
| 6486 * @return the element representing the getter that was found | 6486 * @return the element representing the getter that was found |
| 6487 */ | 6487 */ |
| 6488 PropertyAccessorElement lookUpGetter(Expression target, Type2 type, String get
terName) { | 6488 PropertyAccessorElement _lookUpGetter(Expression target, Type2 type, String ge
tterName) { |
| 6489 type = resolveTypeParameter(type); | 6489 type = _resolveTypeParameter(type); |
| 6490 if (type is InterfaceType) { | 6490 if (type is InterfaceType) { |
| 6491 InterfaceType interfaceType = type; | 6491 InterfaceType interfaceType = type; |
| 6492 PropertyAccessorElement accessor; | 6492 PropertyAccessorElement accessor; |
| 6493 if (target is SuperExpression) { | 6493 if (target is SuperExpression) { |
| 6494 accessor = interfaceType.lookUpGetterInSuperclass(getterName, _definingL
ibrary); | 6494 accessor = interfaceType.lookUpGetterInSuperclass(getterName, _definingL
ibrary); |
| 6495 } else { | 6495 } else { |
| 6496 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary); | 6496 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary); |
| 6497 } | 6497 } |
| 6498 if (accessor != null) { | 6498 if (accessor != null) { |
| 6499 return accessor; | 6499 return accessor; |
| 6500 } | 6500 } |
| 6501 return lookUpGetterInInterfaces(interfaceType, false, getterName, new Set<
ClassElement>()); | 6501 return _lookUpGetterInInterfaces(interfaceType, false, getterName, new Set
<ClassElement>()); |
| 6502 } | 6502 } |
| 6503 return null; | 6503 return null; |
| 6504 } | 6504 } |
| 6505 | 6505 |
| 6506 /** | 6506 /** |
| 6507 * Look up the getter with the given name in the interfaces implemented by the
given type, either | 6507 * Look up the getter with the given name in the interfaces implemented by the
given type, either |
| 6508 * directly or indirectly. Return the element representing the getter that was
found, or | 6508 * directly or indirectly. Return the element representing the getter that was
found, or |
| 6509 * `null` if there is no getter with the given name. | 6509 * `null` if there is no getter with the given name. |
| 6510 * | 6510 * |
| 6511 * @param targetType the type in which the getter might be defined | 6511 * @param targetType the type in which the getter might be defined |
| 6512 * @param includeTargetType `true` if the search should include the target typ
e | 6512 * @param includeTargetType `true` if the search should include the target typ
e |
| 6513 * @param getterName the name of the getter being looked up | 6513 * @param getterName the name of the getter being looked up |
| 6514 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6514 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 6515 * to prevent infinite recursion and to optimize the search | 6515 * to prevent infinite recursion and to optimize the search |
| 6516 * @return the element representing the getter that was found | 6516 * @return the element representing the getter that was found |
| 6517 */ | 6517 */ |
| 6518 PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, boo
l includeTargetType, String getterName, Set<ClassElement> visitedInterfaces) { | 6518 PropertyAccessorElement _lookUpGetterInInterfaces(InterfaceType targetType, bo
ol includeTargetType, String getterName, Set<ClassElement> visitedInterfaces) { |
| 6519 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled | 6519 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6520 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for | 6520 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6521 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the | 6521 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6522 // 80% case. | 6522 // 80% case. |
| 6523 ClassElement targetClass = targetType.element; | 6523 ClassElement targetClass = targetType.element; |
| 6524 if (visitedInterfaces.contains(targetClass)) { | 6524 if (visitedInterfaces.contains(targetClass)) { |
| 6525 return null; | 6525 return null; |
| 6526 } | 6526 } |
| 6527 visitedInterfaces.add(targetClass); | 6527 visitedInterfaces.add(targetClass); |
| 6528 if (includeTargetType) { | 6528 if (includeTargetType) { |
| 6529 PropertyAccessorElement getter = targetType.getGetter(getterName); | 6529 PropertyAccessorElement getter = targetType.getGetter(getterName); |
| 6530 if (getter != null && getter.isAccessibleIn(_definingLibrary)) { | 6530 if (getter != null && getter.isAccessibleIn(_definingLibrary)) { |
| 6531 return getter; | 6531 return getter; |
| 6532 } | 6532 } |
| 6533 } | 6533 } |
| 6534 for (InterfaceType interfaceType in targetType.interfaces) { | 6534 for (InterfaceType interfaceType in targetType.interfaces) { |
| 6535 PropertyAccessorElement getter = lookUpGetterInInterfaces(interfaceType, t
rue, getterName, visitedInterfaces); | 6535 PropertyAccessorElement getter = _lookUpGetterInInterfaces(interfaceType,
true, getterName, visitedInterfaces); |
| 6536 if (getter != null) { | 6536 if (getter != null) { |
| 6537 return getter; | 6537 return getter; |
| 6538 } | 6538 } |
| 6539 } | 6539 } |
| 6540 for (InterfaceType mixinType in targetType.mixins) { | 6540 for (InterfaceType mixinType in targetType.mixins) { |
| 6541 PropertyAccessorElement getter = lookUpGetterInInterfaces(mixinType, true,
getterName, visitedInterfaces); | 6541 PropertyAccessorElement getter = _lookUpGetterInInterfaces(mixinType, true
, getterName, visitedInterfaces); |
| 6542 if (getter != null) { | 6542 if (getter != null) { |
| 6543 return getter; | 6543 return getter; |
| 6544 } | 6544 } |
| 6545 } | 6545 } |
| 6546 InterfaceType superclass = targetType.superclass; | 6546 InterfaceType superclass = targetType.superclass; |
| 6547 if (superclass == null) { | 6547 if (superclass == null) { |
| 6548 return null; | 6548 return null; |
| 6549 } | 6549 } |
| 6550 return lookUpGetterInInterfaces(superclass, true, getterName, visitedInterfa
ces); | 6550 return _lookUpGetterInInterfaces(superclass, true, getterName, visitedInterf
aces); |
| 6551 } | 6551 } |
| 6552 | 6552 |
| 6553 /** | 6553 /** |
| 6554 * Look up the method or getter with the given name in the given type. Return
the element | 6554 * Look up the method or getter with the given name in the given type. Return
the element |
| 6555 * representing the method or getter that was found, or `null` if there is no
method or | 6555 * representing the method or getter that was found, or `null` if there is no
method or |
| 6556 * getter with the given name. | 6556 * getter with the given name. |
| 6557 * | 6557 * |
| 6558 * @param type the type in which the method or getter is defined | 6558 * @param type the type in which the method or getter is defined |
| 6559 * @param memberName the name of the method or getter being looked up | 6559 * @param memberName the name of the method or getter being looked up |
| 6560 * @return the element representing the method or getter that was found | 6560 * @return the element representing the method or getter that was found |
| 6561 */ | 6561 */ |
| 6562 ExecutableElement lookupGetterOrMethod(Type2 type, String memberName) { | 6562 ExecutableElement _lookupGetterOrMethod(Type2 type, String memberName) { |
| 6563 type = resolveTypeParameter(type); | 6563 type = _resolveTypeParameter(type); |
| 6564 if (type is InterfaceType) { | 6564 if (type is InterfaceType) { |
| 6565 InterfaceType interfaceType = type; | 6565 InterfaceType interfaceType = type; |
| 6566 ExecutableElement member = interfaceType.lookUpMethod(memberName, _definin
gLibrary); | 6566 ExecutableElement member = interfaceType.lookUpMethod(memberName, _definin
gLibrary); |
| 6567 if (member != null) { | 6567 if (member != null) { |
| 6568 return member; | 6568 return member; |
| 6569 } | 6569 } |
| 6570 member = interfaceType.lookUpGetter(memberName, _definingLibrary); | 6570 member = interfaceType.lookUpGetter(memberName, _definingLibrary); |
| 6571 if (member != null) { | 6571 if (member != null) { |
| 6572 return member; | 6572 return member; |
| 6573 } | 6573 } |
| 6574 return lookUpGetterOrMethodInInterfaces(interfaceType, false, memberName,
new Set<ClassElement>()); | 6574 return _lookUpGetterOrMethodInInterfaces(interfaceType, false, memberName,
new Set<ClassElement>()); |
| 6575 } | 6575 } |
| 6576 return null; | 6576 return null; |
| 6577 } | 6577 } |
| 6578 | 6578 |
| 6579 /** | 6579 /** |
| 6580 * Look up the method or getter with the given name in the interfaces implemen
ted by the given | 6580 * Look up the method or getter with the given name in the interfaces implemen
ted by the given |
| 6581 * type, either directly or indirectly. Return the element representing the me
thod or getter that | 6581 * type, either directly or indirectly. Return the element representing the me
thod or getter that |
| 6582 * was found, or `null` if there is no method or getter with the given name. | 6582 * was found, or `null` if there is no method or getter with the given name. |
| 6583 * | 6583 * |
| 6584 * @param targetType the type in which the method or getter might be defined | 6584 * @param targetType the type in which the method or getter might be defined |
| 6585 * @param includeTargetType `true` if the search should include the target typ
e | 6585 * @param includeTargetType `true` if the search should include the target typ
e |
| 6586 * @param memberName the name of the method or getter being looked up | 6586 * @param memberName the name of the method or getter being looked up |
| 6587 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6587 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 6588 * to prevent infinite recursion and to optimize the search | 6588 * to prevent infinite recursion and to optimize the search |
| 6589 * @return the element representing the method or getter that was found | 6589 * @return the element representing the method or getter that was found |
| 6590 */ | 6590 */ |
| 6591 ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, b
ool includeTargetType, String memberName, Set<ClassElement> visitedInterfaces) { | 6591 ExecutableElement _lookUpGetterOrMethodInInterfaces(InterfaceType targetType,
bool includeTargetType, String memberName, Set<ClassElement> visitedInterfaces)
{ |
| 6592 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled | 6592 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6593 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for | 6593 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6594 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the | 6594 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6595 // 80% case. | 6595 // 80% case. |
| 6596 ClassElement targetClass = targetType.element; | 6596 ClassElement targetClass = targetType.element; |
| 6597 if (visitedInterfaces.contains(targetClass)) { | 6597 if (visitedInterfaces.contains(targetClass)) { |
| 6598 return null; | 6598 return null; |
| 6599 } | 6599 } |
| 6600 visitedInterfaces.add(targetClass); | 6600 visitedInterfaces.add(targetClass); |
| 6601 if (includeTargetType) { | 6601 if (includeTargetType) { |
| 6602 ExecutableElement member = targetType.getMethod(memberName); | 6602 ExecutableElement member = targetType.getMethod(memberName); |
| 6603 if (member != null) { | 6603 if (member != null) { |
| 6604 return member; | 6604 return member; |
| 6605 } | 6605 } |
| 6606 member = targetType.getGetter(memberName); | 6606 member = targetType.getGetter(memberName); |
| 6607 if (member != null) { | 6607 if (member != null) { |
| 6608 return member; | 6608 return member; |
| 6609 } | 6609 } |
| 6610 } | 6610 } |
| 6611 for (InterfaceType interfaceType in targetType.interfaces) { | 6611 for (InterfaceType interfaceType in targetType.interfaces) { |
| 6612 ExecutableElement member = lookUpGetterOrMethodInInterfaces(interfaceType,
true, memberName, visitedInterfaces); | 6612 ExecutableElement member = _lookUpGetterOrMethodInInterfaces(interfaceType
, true, memberName, visitedInterfaces); |
| 6613 if (member != null) { | 6613 if (member != null) { |
| 6614 return member; | 6614 return member; |
| 6615 } | 6615 } |
| 6616 } | 6616 } |
| 6617 for (InterfaceType mixinType in targetType.mixins) { | 6617 for (InterfaceType mixinType in targetType.mixins) { |
| 6618 ExecutableElement member = lookUpGetterOrMethodInInterfaces(mixinType, tru
e, memberName, visitedInterfaces); | 6618 ExecutableElement member = _lookUpGetterOrMethodInInterfaces(mixinType, tr
ue, memberName, visitedInterfaces); |
| 6619 if (member != null) { | 6619 if (member != null) { |
| 6620 return member; | 6620 return member; |
| 6621 } | 6621 } |
| 6622 } | 6622 } |
| 6623 InterfaceType superclass = targetType.superclass; | 6623 InterfaceType superclass = targetType.superclass; |
| 6624 if (superclass == null) { | 6624 if (superclass == null) { |
| 6625 return null; | 6625 return null; |
| 6626 } | 6626 } |
| 6627 return lookUpGetterOrMethodInInterfaces(superclass, true, memberName, visite
dInterfaces); | 6627 return _lookUpGetterOrMethodInInterfaces(superclass, true, memberName, visit
edInterfaces); |
| 6628 } | 6628 } |
| 6629 | 6629 |
| 6630 /** | 6630 /** |
| 6631 * Find the element corresponding to the given label node in the current label
scope. | 6631 * Find the element corresponding to the given label node in the current label
scope. |
| 6632 * | 6632 * |
| 6633 * @param parentNode the node containing the given label | 6633 * @param parentNode the node containing the given label |
| 6634 * @param labelNode the node representing the label being looked up | 6634 * @param labelNode the node representing the label being looked up |
| 6635 * @return the element corresponding to the given label node in the current sc
ope | 6635 * @return the element corresponding to the given label node in the current sc
ope |
| 6636 */ | 6636 */ |
| 6637 LabelElementImpl lookupLabel(AstNode parentNode, SimpleIdentifier labelNode) { | 6637 LabelElementImpl _lookupLabel(AstNode parentNode, SimpleIdentifier labelNode)
{ |
| 6638 LabelScope labelScope = _resolver.labelScope; | 6638 LabelScope labelScope = _resolver.labelScope; |
| 6639 LabelElementImpl labelElement = null; | 6639 LabelElementImpl labelElement = null; |
| 6640 if (labelNode == null) { | 6640 if (labelNode == null) { |
| 6641 if (labelScope == null) { | 6641 if (labelScope == null) { |
| 6642 } else { | 6642 } else { |
| 6643 labelElement = labelScope.lookup(LabelScope.EMPTY_LABEL) as LabelElement
Impl; | 6643 labelElement = labelScope.lookup(LabelScope.EMPTY_LABEL) as LabelElement
Impl; |
| 6644 if (labelElement == null) { | 6644 if (labelElement == null) { |
| 6645 } | 6645 } |
| 6646 // | 6646 // |
| 6647 // The label element that was returned was a marker for look-up and isn'
t stored in the | 6647 // The label element that was returned was a marker for look-up and isn'
t stored in the |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6673 | 6673 |
| 6674 /** | 6674 /** |
| 6675 * Look up the method with the given name in the given type. Return the elemen
t representing the | 6675 * Look up the method with the given name in the given type. Return the elemen
t representing the |
| 6676 * method that was found, or `null` if there is no method with the given name. | 6676 * method that was found, or `null` if there is no method with the given name. |
| 6677 * | 6677 * |
| 6678 * @param target the target of the invocation, or `null` if there is no target | 6678 * @param target the target of the invocation, or `null` if there is no target |
| 6679 * @param type the type in which the method is defined | 6679 * @param type the type in which the method is defined |
| 6680 * @param methodName the name of the method being looked up | 6680 * @param methodName the name of the method being looked up |
| 6681 * @return the element representing the method that was found | 6681 * @return the element representing the method that was found |
| 6682 */ | 6682 */ |
| 6683 MethodElement lookUpMethod(Expression target, Type2 type, String methodName) { | 6683 MethodElement _lookUpMethod(Expression target, Type2 type, String methodName)
{ |
| 6684 type = resolveTypeParameter(type); | 6684 type = _resolveTypeParameter(type); |
| 6685 if (type is InterfaceType) { | 6685 if (type is InterfaceType) { |
| 6686 InterfaceType interfaceType = type; | 6686 InterfaceType interfaceType = type; |
| 6687 MethodElement method; | 6687 MethodElement method; |
| 6688 if (target is SuperExpression) { | 6688 if (target is SuperExpression) { |
| 6689 method = interfaceType.lookUpMethodInSuperclass(methodName, _definingLib
rary); | 6689 method = interfaceType.lookUpMethodInSuperclass(methodName, _definingLib
rary); |
| 6690 } else { | 6690 } else { |
| 6691 method = interfaceType.lookUpMethod(methodName, _definingLibrary); | 6691 method = interfaceType.lookUpMethod(methodName, _definingLibrary); |
| 6692 } | 6692 } |
| 6693 if (method != null) { | 6693 if (method != null) { |
| 6694 return method; | 6694 return method; |
| 6695 } | 6695 } |
| 6696 return lookUpMethodInInterfaces(interfaceType, false, methodName, new Set<
ClassElement>()); | 6696 return _lookUpMethodInInterfaces(interfaceType, false, methodName, new Set
<ClassElement>()); |
| 6697 } | 6697 } |
| 6698 return null; | 6698 return null; |
| 6699 } | 6699 } |
| 6700 | 6700 |
| 6701 /** | 6701 /** |
| 6702 * Look up the method with the given name in the interfaces implemented by the
given type, either | 6702 * Look up the method with the given name in the interfaces implemented by the
given type, either |
| 6703 * directly or indirectly. Return the element representing the method that was
found, or | 6703 * directly or indirectly. Return the element representing the method that was
found, or |
| 6704 * `null` if there is no method with the given name. | 6704 * `null` if there is no method with the given name. |
| 6705 * | 6705 * |
| 6706 * @param targetType the type in which the member might be defined | 6706 * @param targetType the type in which the member might be defined |
| 6707 * @param includeTargetType `true` if the search should include the target typ
e | 6707 * @param includeTargetType `true` if the search should include the target typ
e |
| 6708 * @param methodName the name of the method being looked up | 6708 * @param methodName the name of the method being looked up |
| 6709 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6709 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 6710 * to prevent infinite recursion and to optimize the search | 6710 * to prevent infinite recursion and to optimize the search |
| 6711 * @return the element representing the method that was found | 6711 * @return the element representing the method that was found |
| 6712 */ | 6712 */ |
| 6713 MethodElement lookUpMethodInInterfaces(InterfaceType targetType, bool includeT
argetType, String methodName, Set<ClassElement> visitedInterfaces) { | 6713 MethodElement _lookUpMethodInInterfaces(InterfaceType targetType, bool include
TargetType, String methodName, Set<ClassElement> visitedInterfaces) { |
| 6714 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled | 6714 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6715 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for | 6715 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6716 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the | 6716 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6717 // 80% case. | 6717 // 80% case. |
| 6718 ClassElement targetClass = targetType.element; | 6718 ClassElement targetClass = targetType.element; |
| 6719 if (visitedInterfaces.contains(targetClass)) { | 6719 if (visitedInterfaces.contains(targetClass)) { |
| 6720 return null; | 6720 return null; |
| 6721 } | 6721 } |
| 6722 visitedInterfaces.add(targetClass); | 6722 visitedInterfaces.add(targetClass); |
| 6723 if (includeTargetType) { | 6723 if (includeTargetType) { |
| 6724 MethodElement method = targetType.getMethod(methodName); | 6724 MethodElement method = targetType.getMethod(methodName); |
| 6725 if (method != null && method.isAccessibleIn(_definingLibrary)) { | 6725 if (method != null && method.isAccessibleIn(_definingLibrary)) { |
| 6726 return method; | 6726 return method; |
| 6727 } | 6727 } |
| 6728 } | 6728 } |
| 6729 for (InterfaceType interfaceType in targetType.interfaces) { | 6729 for (InterfaceType interfaceType in targetType.interfaces) { |
| 6730 MethodElement method = lookUpMethodInInterfaces(interfaceType, true, metho
dName, visitedInterfaces); | 6730 MethodElement method = _lookUpMethodInInterfaces(interfaceType, true, meth
odName, visitedInterfaces); |
| 6731 if (method != null) { | 6731 if (method != null) { |
| 6732 return method; | 6732 return method; |
| 6733 } | 6733 } |
| 6734 } | 6734 } |
| 6735 for (InterfaceType mixinType in targetType.mixins) { | 6735 for (InterfaceType mixinType in targetType.mixins) { |
| 6736 MethodElement method = lookUpMethodInInterfaces(mixinType, true, methodNam
e, visitedInterfaces); | 6736 MethodElement method = _lookUpMethodInInterfaces(mixinType, true, methodNa
me, visitedInterfaces); |
| 6737 if (method != null) { | 6737 if (method != null) { |
| 6738 return method; | 6738 return method; |
| 6739 } | 6739 } |
| 6740 } | 6740 } |
| 6741 InterfaceType superclass = targetType.superclass; | 6741 InterfaceType superclass = targetType.superclass; |
| 6742 if (superclass == null) { | 6742 if (superclass == null) { |
| 6743 return null; | 6743 return null; |
| 6744 } | 6744 } |
| 6745 return lookUpMethodInInterfaces(superclass, true, methodName, visitedInterfa
ces); | 6745 return _lookUpMethodInInterfaces(superclass, true, methodName, visitedInterf
aces); |
| 6746 } | 6746 } |
| 6747 | 6747 |
| 6748 /** | 6748 /** |
| 6749 * Look up the setter with the given name in the given type. Return the elemen
t representing the | 6749 * Look up the setter with the given name in the given type. Return the elemen
t representing the |
| 6750 * setter that was found, or `null` if there is no setter with the given name. | 6750 * setter that was found, or `null` if there is no setter with the given name. |
| 6751 * | 6751 * |
| 6752 * @param target the target of the invocation, or `null` if there is no target | 6752 * @param target the target of the invocation, or `null` if there is no target |
| 6753 * @param type the type in which the setter is defined | 6753 * @param type the type in which the setter is defined |
| 6754 * @param setterName the name of the setter being looked up | 6754 * @param setterName the name of the setter being looked up |
| 6755 * @return the element representing the setter that was found | 6755 * @return the element representing the setter that was found |
| 6756 */ | 6756 */ |
| 6757 PropertyAccessorElement lookUpSetter(Expression target, Type2 type, String set
terName) { | 6757 PropertyAccessorElement _lookUpSetter(Expression target, Type2 type, String se
tterName) { |
| 6758 type = resolveTypeParameter(type); | 6758 type = _resolveTypeParameter(type); |
| 6759 if (type is InterfaceType) { | 6759 if (type is InterfaceType) { |
| 6760 InterfaceType interfaceType = type; | 6760 InterfaceType interfaceType = type; |
| 6761 PropertyAccessorElement accessor; | 6761 PropertyAccessorElement accessor; |
| 6762 if (target is SuperExpression) { | 6762 if (target is SuperExpression) { |
| 6763 accessor = interfaceType.lookUpSetterInSuperclass(setterName, _definingL
ibrary); | 6763 accessor = interfaceType.lookUpSetterInSuperclass(setterName, _definingL
ibrary); |
| 6764 } else { | 6764 } else { |
| 6765 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary); | 6765 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary); |
| 6766 } | 6766 } |
| 6767 if (accessor != null) { | 6767 if (accessor != null) { |
| 6768 return accessor; | 6768 return accessor; |
| 6769 } | 6769 } |
| 6770 return lookUpSetterInInterfaces(interfaceType, false, setterName, new Set<
ClassElement>()); | 6770 return _lookUpSetterInInterfaces(interfaceType, false, setterName, new Set
<ClassElement>()); |
| 6771 } | 6771 } |
| 6772 return null; | 6772 return null; |
| 6773 } | 6773 } |
| 6774 | 6774 |
| 6775 /** | 6775 /** |
| 6776 * Look up the setter with the given name in the interfaces implemented by the
given type, either | 6776 * Look up the setter with the given name in the interfaces implemented by the
given type, either |
| 6777 * directly or indirectly. Return the element representing the setter that was
found, or | 6777 * directly or indirectly. Return the element representing the setter that was
found, or |
| 6778 * `null` if there is no setter with the given name. | 6778 * `null` if there is no setter with the given name. |
| 6779 * | 6779 * |
| 6780 * @param targetType the type in which the setter might be defined | 6780 * @param targetType the type in which the setter might be defined |
| 6781 * @param includeTargetType `true` if the search should include the target typ
e | 6781 * @param includeTargetType `true` if the search should include the target typ
e |
| 6782 * @param setterName the name of the setter being looked up | 6782 * @param setterName the name of the setter being looked up |
| 6783 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used | 6783 * @param visitedInterfaces a set containing all of the interfaces that have b
een examined, used |
| 6784 * to prevent infinite recursion and to optimize the search | 6784 * to prevent infinite recursion and to optimize the search |
| 6785 * @return the element representing the setter that was found | 6785 * @return the element representing the setter that was found |
| 6786 */ | 6786 */ |
| 6787 PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, boo
l includeTargetType, String setterName, Set<ClassElement> visitedInterfaces) { | 6787 PropertyAccessorElement _lookUpSetterInInterfaces(InterfaceType targetType, bo
ol includeTargetType, String setterName, Set<ClassElement> visitedInterfaces) { |
| 6788 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled | 6788 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specificati
on (titled |
| 6789 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for | 6789 // "Inheritance and Overriding" under "Interfaces") describes a much more co
mplex scheme for |
| 6790 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the | 6790 // finding the inherited member. We need to follow that scheme. The code bel
ow should cover the |
| 6791 // 80% case. | 6791 // 80% case. |
| 6792 ClassElement targetClass = targetType.element; | 6792 ClassElement targetClass = targetType.element; |
| 6793 if (visitedInterfaces.contains(targetClass)) { | 6793 if (visitedInterfaces.contains(targetClass)) { |
| 6794 return null; | 6794 return null; |
| 6795 } | 6795 } |
| 6796 visitedInterfaces.add(targetClass); | 6796 visitedInterfaces.add(targetClass); |
| 6797 if (includeTargetType) { | 6797 if (includeTargetType) { |
| 6798 PropertyAccessorElement setter = targetType.getSetter(setterName); | 6798 PropertyAccessorElement setter = targetType.getSetter(setterName); |
| 6799 if (setter != null && setter.isAccessibleIn(_definingLibrary)) { | 6799 if (setter != null && setter.isAccessibleIn(_definingLibrary)) { |
| 6800 return setter; | 6800 return setter; |
| 6801 } | 6801 } |
| 6802 } | 6802 } |
| 6803 for (InterfaceType interfaceType in targetType.interfaces) { | 6803 for (InterfaceType interfaceType in targetType.interfaces) { |
| 6804 PropertyAccessorElement setter = lookUpSetterInInterfaces(interfaceType, t
rue, setterName, visitedInterfaces); | 6804 PropertyAccessorElement setter = _lookUpSetterInInterfaces(interfaceType,
true, setterName, visitedInterfaces); |
| 6805 if (setter != null) { | 6805 if (setter != null) { |
| 6806 return setter; | 6806 return setter; |
| 6807 } | 6807 } |
| 6808 } | 6808 } |
| 6809 for (InterfaceType mixinType in targetType.mixins) { | 6809 for (InterfaceType mixinType in targetType.mixins) { |
| 6810 PropertyAccessorElement setter = lookUpSetterInInterfaces(mixinType, true,
setterName, visitedInterfaces); | 6810 PropertyAccessorElement setter = _lookUpSetterInInterfaces(mixinType, true
, setterName, visitedInterfaces); |
| 6811 if (setter != null) { | 6811 if (setter != null) { |
| 6812 return setter; | 6812 return setter; |
| 6813 } | 6813 } |
| 6814 } | 6814 } |
| 6815 InterfaceType superclass = targetType.superclass; | 6815 InterfaceType superclass = targetType.superclass; |
| 6816 if (superclass == null) { | 6816 if (superclass == null) { |
| 6817 return null; | 6817 return null; |
| 6818 } | 6818 } |
| 6819 return lookUpSetterInInterfaces(superclass, true, setterName, visitedInterfa
ces); | 6819 return _lookUpSetterInInterfaces(superclass, true, setterName, visitedInterf
aces); |
| 6820 } | 6820 } |
| 6821 | 6821 |
| 6822 /** | 6822 /** |
| 6823 * Given some class element, this method uses [subtypeManager] to find the set
of all | 6823 * Given some class element, this method uses [subtypeManager] to find the set
of all |
| 6824 * subtypes; the subtypes are then searched for a member (method, getter, or s
etter), that matches | 6824 * subtypes; the subtypes are then searched for a member (method, getter, or s
etter), that matches |
| 6825 * a passed | 6825 * a passed |
| 6826 * | 6826 * |
| 6827 * @param element the class element to search the subtypes of, if a non-ClassE
lement element is | 6827 * @param element the class element to search the subtypes of, if a non-ClassE
lement element is |
| 6828 * passed, then `false` is returned | 6828 * passed, then `false` is returned |
| 6829 * @param memberName the member name to search for | 6829 * @param memberName the member name to search for |
| 6830 * @param asMethod `true` if the methods should be searched for in the subtype
s | 6830 * @param asMethod `true` if the methods should be searched for in the subtype
s |
| 6831 * @param asAccessor `true` if the accessors (getters and setters) should be s
earched for in | 6831 * @param asAccessor `true` if the accessors (getters and setters) should be s
earched for in |
| 6832 * the subtypes | 6832 * the subtypes |
| 6833 * @return `true` if and only if the passed memberName was found in a subtype | 6833 * @return `true` if and only if the passed memberName was found in a subtype |
| 6834 */ | 6834 */ |
| 6835 bool memberFoundInSubclass(Element element, String memberName, bool asMethod,
bool asAccessor) { | 6835 bool _memberFoundInSubclass(Element element, String memberName, bool asMethod,
bool asAccessor) { |
| 6836 if (element is ClassElement) { | 6836 if (element is ClassElement) { |
| 6837 _subtypeManager.ensureLibraryVisited(_definingLibrary); | 6837 _subtypeManager.ensureLibraryVisited(_definingLibrary); |
| 6838 Set<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(ele
ment); | 6838 Set<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(ele
ment); |
| 6839 for (ClassElement subtypeElement in subtypeElements) { | 6839 for (ClassElement subtypeElement in subtypeElements) { |
| 6840 if (asMethod && subtypeElement.getMethod(memberName) != null) { | 6840 if (asMethod && subtypeElement.getMethod(memberName) != null) { |
| 6841 return true; | 6841 return true; |
| 6842 } else if (asAccessor && (subtypeElement.getGetter(memberName) != null |
| subtypeElement.getSetter(memberName) != null)) { | 6842 } else if (asAccessor && (subtypeElement.getGetter(memberName) != null |
| subtypeElement.getSetter(memberName) != null)) { |
| 6843 return true; | 6843 return true; |
| 6844 } | 6844 } |
| 6845 } | 6845 } |
| 6846 } | 6846 } |
| 6847 return false; | 6847 return false; |
| 6848 } | 6848 } |
| 6849 | 6849 |
| 6850 /** | 6850 /** |
| 6851 * Return the binary operator that is invoked by the given compound assignment
operator. | 6851 * Return the binary operator that is invoked by the given compound assignment
operator. |
| 6852 * | 6852 * |
| 6853 * @param operator the assignment operator being mapped | 6853 * @param operator the assignment operator being mapped |
| 6854 * @return the binary operator that invoked by the given assignment operator | 6854 * @return the binary operator that invoked by the given assignment operator |
| 6855 */ | 6855 */ |
| 6856 sc.TokenType operatorFromCompoundAssignment(sc.TokenType operator) { | 6856 sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) { |
| 6857 while (true) { | 6857 while (true) { |
| 6858 if (operator == sc.TokenType.AMPERSAND_EQ) { | 6858 if (operator == sc.TokenType.AMPERSAND_EQ) { |
| 6859 return sc.TokenType.AMPERSAND; | 6859 return sc.TokenType.AMPERSAND; |
| 6860 } else if (operator == sc.TokenType.BAR_EQ) { | 6860 } else if (operator == sc.TokenType.BAR_EQ) { |
| 6861 return sc.TokenType.BAR; | 6861 return sc.TokenType.BAR; |
| 6862 } else if (operator == sc.TokenType.CARET_EQ) { | 6862 } else if (operator == sc.TokenType.CARET_EQ) { |
| 6863 return sc.TokenType.CARET; | 6863 return sc.TokenType.CARET; |
| 6864 } else if (operator == sc.TokenType.GT_GT_EQ) { | 6864 } else if (operator == sc.TokenType.GT_GT_EQ) { |
| 6865 return sc.TokenType.GT_GT; | 6865 return sc.TokenType.GT_GT; |
| 6866 } else if (operator == sc.TokenType.LT_LT_EQ) { | 6866 } else if (operator == sc.TokenType.LT_LT_EQ) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6879 return sc.TokenType.TILDE_SLASH; | 6879 return sc.TokenType.TILDE_SLASH; |
| 6880 } else { | 6880 } else { |
| 6881 // Internal error: Unmapped assignment operator. | 6881 // Internal error: Unmapped assignment operator. |
| 6882 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme
} to it's corresponding operator"); | 6882 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme
} to it's corresponding operator"); |
| 6883 return operator; | 6883 return operator; |
| 6884 } | 6884 } |
| 6885 break; | 6885 break; |
| 6886 } | 6886 } |
| 6887 } | 6887 } |
| 6888 | 6888 |
| 6889 void resolveAnnotationConstructorInvocationArguments(Annotation annotation, Co
nstructorElement constructor) { | 6889 void _resolveAnnotationConstructorInvocationArguments(Annotation annotation, C
onstructorElement constructor) { |
| 6890 ArgumentList argumentList = annotation.arguments; | 6890 ArgumentList argumentList = annotation.arguments; |
| 6891 // error will be reported in ConstantVerifier | 6891 // error will be reported in ConstantVerifier |
| 6892 if (argumentList == null) { | 6892 if (argumentList == null) { |
| 6893 return; | 6893 return; |
| 6894 } | 6894 } |
| 6895 // resolve arguments to parameters | 6895 // resolve arguments to parameters |
| 6896 List<ParameterElement> parameters = resolveArgumentsToFunction(true, argumen
tList, constructor); | 6896 List<ParameterElement> parameters = _resolveArgumentsToFunction(true, argume
ntList, constructor); |
| 6897 if (parameters != null) { | 6897 if (parameters != null) { |
| 6898 argumentList.correspondingStaticParameters = parameters; | 6898 argumentList.correspondingStaticParameters = parameters; |
| 6899 } | 6899 } |
| 6900 } | 6900 } |
| 6901 | 6901 |
| 6902 /** | 6902 /** |
| 6903 * Continues resolution of the given [Annotation]. | 6903 * Continues resolution of the given [Annotation]. |
| 6904 * | 6904 * |
| 6905 * @param annotation the [Annotation] to resolve | 6905 * @param annotation the [Annotation] to resolve |
| 6906 */ | 6906 */ |
| 6907 void resolveAnnotationElement(Annotation annotation) { | 6907 void _resolveAnnotationElement(Annotation annotation) { |
| 6908 SimpleIdentifier nameNode1; | 6908 SimpleIdentifier nameNode1; |
| 6909 SimpleIdentifier nameNode2; | 6909 SimpleIdentifier nameNode2; |
| 6910 { | 6910 { |
| 6911 Identifier annName = annotation.name; | 6911 Identifier annName = annotation.name; |
| 6912 if (annName is PrefixedIdentifier) { | 6912 if (annName is PrefixedIdentifier) { |
| 6913 PrefixedIdentifier prefixed = annName; | 6913 PrefixedIdentifier prefixed = annName; |
| 6914 nameNode1 = prefixed.prefix; | 6914 nameNode1 = prefixed.prefix; |
| 6915 nameNode2 = prefixed.identifier; | 6915 nameNode2 = prefixed.identifier; |
| 6916 } else { | 6916 } else { |
| 6917 nameNode1 = annName as SimpleIdentifier; | 6917 nameNode1 = annName as SimpleIdentifier; |
| 6918 nameNode2 = null; | 6918 nameNode2 = null; |
| 6919 } | 6919 } |
| 6920 } | 6920 } |
| 6921 SimpleIdentifier nameNode3 = annotation.constructorName; | 6921 SimpleIdentifier nameNode3 = annotation.constructorName; |
| 6922 ConstructorElement constructor = null; | 6922 ConstructorElement constructor = null; |
| 6923 // | 6923 // |
| 6924 // CONST or Class(args) | 6924 // CONST or Class(args) |
| 6925 // | 6925 // |
| 6926 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { | 6926 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { |
| 6927 Element element1 = nameNode1.staticElement; | 6927 Element element1 = nameNode1.staticElement; |
| 6928 // CONST | 6928 // CONST |
| 6929 if (element1 is PropertyAccessorElement) { | 6929 if (element1 is PropertyAccessorElement) { |
| 6930 resolveAnnotationElementGetter(annotation, element1); | 6930 _resolveAnnotationElementGetter(annotation, element1); |
| 6931 return; | 6931 return; |
| 6932 } | 6932 } |
| 6933 // Class(args) | 6933 // Class(args) |
| 6934 if (element1 is ClassElement) { | 6934 if (element1 is ClassElement) { |
| 6935 ClassElement classElement = element1; | 6935 ClassElement classElement = element1; |
| 6936 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(null, _definingLibrary); | 6936 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(null, _definingLibrary); |
| 6937 } | 6937 } |
| 6938 } | 6938 } |
| 6939 // | 6939 // |
| 6940 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) | 6940 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) |
| 6941 // | 6941 // |
| 6942 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { | 6942 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { |
| 6943 Element element1 = nameNode1.staticElement; | 6943 Element element1 = nameNode1.staticElement; |
| 6944 Element element2 = nameNode2.staticElement; | 6944 Element element2 = nameNode2.staticElement; |
| 6945 // Class.CONST - not resolved yet | 6945 // Class.CONST - not resolved yet |
| 6946 if (element1 is ClassElement) { | 6946 if (element1 is ClassElement) { |
| 6947 ClassElement classElement = element1; | 6947 ClassElement classElement = element1; |
| 6948 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); | 6948 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); |
| 6949 } | 6949 } |
| 6950 // prefix.CONST or Class.CONST | 6950 // prefix.CONST or Class.CONST |
| 6951 if (element2 is PropertyAccessorElement) { | 6951 if (element2 is PropertyAccessorElement) { |
| 6952 nameNode2.staticElement = element2; | 6952 nameNode2.staticElement = element2; |
| 6953 annotation.element = element2; | 6953 annotation.element = element2; |
| 6954 resolveAnnotationElementGetter(annotation, element2 as PropertyAccessorE
lement); | 6954 _resolveAnnotationElementGetter(annotation, element2 as PropertyAccessor
Element); |
| 6955 return; | 6955 return; |
| 6956 } | 6956 } |
| 6957 // prefix.Class() | 6957 // prefix.Class() |
| 6958 if (element2 is ClassElement) { | 6958 if (element2 is ClassElement) { |
| 6959 ClassElement classElement = element2 as ClassElement; | 6959 ClassElement classElement = element2 as ClassElement; |
| 6960 constructor = classElement.unnamedConstructor; | 6960 constructor = classElement.unnamedConstructor; |
| 6961 } | 6961 } |
| 6962 // Class.constructor(args) | 6962 // Class.constructor(args) |
| 6963 if (element1 is ClassElement) { | 6963 if (element1 is ClassElement) { |
| 6964 ClassElement classElement = element1; | 6964 ClassElement classElement = element1; |
| 6965 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(nameNode2.name, _definingLibrary); | 6965 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(nameNode2.name, _definingLibrary); |
| 6966 nameNode2.staticElement = constructor; | 6966 nameNode2.staticElement = constructor; |
| 6967 } | 6967 } |
| 6968 } | 6968 } |
| 6969 // | 6969 // |
| 6970 // prefix.Class.CONST or prefix.Class.constructor(args) | 6970 // prefix.Class.CONST or prefix.Class.constructor(args) |
| 6971 // | 6971 // |
| 6972 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { | 6972 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { |
| 6973 Element element2 = nameNode2.staticElement; | 6973 Element element2 = nameNode2.staticElement; |
| 6974 // element2 should be ClassElement | 6974 // element2 should be ClassElement |
| 6975 if (element2 is ClassElement) { | 6975 if (element2 is ClassElement) { |
| 6976 ClassElement classElement = element2; | 6976 ClassElement classElement = element2; |
| 6977 String name3 = nameNode3.name; | 6977 String name3 = nameNode3.name; |
| 6978 // prefix.Class.CONST | 6978 // prefix.Class.CONST |
| 6979 PropertyAccessorElement getter = classElement.lookUpGetter(name3, _defin
ingLibrary); | 6979 PropertyAccessorElement getter = classElement.lookUpGetter(name3, _defin
ingLibrary); |
| 6980 if (getter != null) { | 6980 if (getter != null) { |
| 6981 nameNode3.staticElement = getter; | 6981 nameNode3.staticElement = getter; |
| 6982 annotation.element = element2; | 6982 annotation.element = element2; |
| 6983 resolveAnnotationElementGetter(annotation, getter); | 6983 _resolveAnnotationElementGetter(annotation, getter); |
| 6984 return; | 6984 return; |
| 6985 } | 6985 } |
| 6986 // prefix.Class.constructor(args) | 6986 // prefix.Class.constructor(args) |
| 6987 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(name3, _definingLibrary); | 6987 constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor
(name3, _definingLibrary); |
| 6988 nameNode3.staticElement = constructor; | 6988 nameNode3.staticElement = constructor; |
| 6989 } | 6989 } |
| 6990 } | 6990 } |
| 6991 // we need constructor | 6991 // we need constructor |
| 6992 if (constructor == null) { | 6992 if (constructor == null) { |
| 6993 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, anno
tation, []); | 6993 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, anno
tation, []); |
| 6994 return; | 6994 return; |
| 6995 } | 6995 } |
| 6996 // record element | 6996 // record element |
| 6997 annotation.element = constructor; | 6997 annotation.element = constructor; |
| 6998 // resolve arguments | 6998 // resolve arguments |
| 6999 resolveAnnotationConstructorInvocationArguments(annotation, constructor); | 6999 _resolveAnnotationConstructorInvocationArguments(annotation, constructor); |
| 7000 } | 7000 } |
| 7001 | 7001 |
| 7002 void resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorEle
ment accessorElement) { | 7002 void _resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorEl
ement accessorElement) { |
| 7003 // accessor should be synthetic | 7003 // accessor should be synthetic |
| 7004 if (!accessorElement.isSynthetic) { | 7004 if (!accessorElement.isSynthetic) { |
| 7005 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, anno
tation, []); | 7005 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, anno
tation, []); |
| 7006 return; | 7006 return; |
| 7007 } | 7007 } |
| 7008 // variable should be constant | 7008 // variable should be constant |
| 7009 VariableElement variableElement = accessorElement.variable; | 7009 VariableElement variableElement = accessorElement.variable; |
| 7010 if (!variableElement.isConst) { | 7010 if (!variableElement.isConst) { |
| 7011 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, anno
tation, []); | 7011 _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, anno
tation, []); |
| 7012 } | 7012 } |
| 7013 // OK | 7013 // OK |
| 7014 return; | 7014 return; |
| 7015 } | 7015 } |
| 7016 | 7016 |
| 7017 /** | 7017 /** |
| 7018 * Given a list of arguments and the element that will be invoked using those
argument, compute | 7018 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 7019 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 7019 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 7020 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 7020 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 7021 * | 7021 * |
| 7022 * @param reportError if `true` then compile-time error should be reported; if
`false` | 7022 * @param reportError if `true` then compile-time error should be reported; if
`false` |
| 7023 * then compile-time warning | 7023 * then compile-time warning |
| 7024 * @param argumentList the list of arguments being passed to the element | 7024 * @param argumentList the list of arguments being passed to the element |
| 7025 * @param executableElement the element that will be invoked with the argument
s | 7025 * @param executableElement the element that will be invoked with the argument
s |
| 7026 * @return the parameters that correspond to the arguments | 7026 * @return the parameters that correspond to the arguments |
| 7027 */ | 7027 */ |
| 7028 List<ParameterElement> resolveArgumentsToFunction(bool reportError, ArgumentLi
st argumentList, ExecutableElement executableElement) { | 7028 List<ParameterElement> _resolveArgumentsToFunction(bool reportError, ArgumentL
ist argumentList, ExecutableElement executableElement) { |
| 7029 if (executableElement == null) { | 7029 if (executableElement == null) { |
| 7030 return null; | 7030 return null; |
| 7031 } | 7031 } |
| 7032 List<ParameterElement> parameters = executableElement.parameters; | 7032 List<ParameterElement> parameters = executableElement.parameters; |
| 7033 return resolveArgumentsToParameters(reportError, argumentList, parameters); | 7033 return _resolveArgumentsToParameters(reportError, argumentList, parameters); |
| 7034 } | 7034 } |
| 7035 | 7035 |
| 7036 /** | 7036 /** |
| 7037 * Given a list of arguments and the parameters related to the element that wi
ll be invoked using | 7037 * Given a list of arguments and the parameters related to the element that wi
ll be invoked using |
| 7038 * those argument, compute the list of parameters that correspond to the list
of arguments. Return | 7038 * those argument, compute the list of parameters that correspond to the list
of arguments. Return |
| 7039 * the parameters that correspond to the arguments. | 7039 * the parameters that correspond to the arguments. |
| 7040 * | 7040 * |
| 7041 * @param reportError if `true` then compile-time error should be reported; if
`false` | 7041 * @param reportError if `true` then compile-time error should be reported; if
`false` |
| 7042 * then compile-time warning | 7042 * then compile-time warning |
| 7043 * @param argumentList the list of arguments being passed to the element | 7043 * @param argumentList the list of arguments being passed to the element |
| 7044 * @param parameters the of the function that will be invoked with the argumen
ts | 7044 * @param parameters the of the function that will be invoked with the argumen
ts |
| 7045 * @return the parameters that correspond to the arguments | 7045 * @return the parameters that correspond to the arguments |
| 7046 */ | 7046 */ |
| 7047 List<ParameterElement> resolveArgumentsToParameters(bool reportError, Argument
List argumentList, List<ParameterElement> parameters) { | 7047 List<ParameterElement> _resolveArgumentsToParameters(bool reportError, Argumen
tList argumentList, List<ParameterElement> parameters) { |
| 7048 List<ParameterElement> requiredParameters = new List<ParameterElement>(); | 7048 List<ParameterElement> requiredParameters = new List<ParameterElement>(); |
| 7049 List<ParameterElement> positionalParameters = new List<ParameterElement>(); | 7049 List<ParameterElement> positionalParameters = new List<ParameterElement>(); |
| 7050 Map<String, ParameterElement> namedParameters = new Map<String, ParameterEle
ment>(); | 7050 Map<String, ParameterElement> namedParameters = new Map<String, ParameterEle
ment>(); |
| 7051 for (ParameterElement parameter in parameters) { | 7051 for (ParameterElement parameter in parameters) { |
| 7052 ParameterKind kind = parameter.parameterKind; | 7052 ParameterKind kind = parameter.parameterKind; |
| 7053 if (identical(kind, ParameterKind.REQUIRED)) { | 7053 if (identical(kind, ParameterKind.REQUIRED)) { |
| 7054 requiredParameters.add(parameter); | 7054 requiredParameters.add(parameter); |
| 7055 } else if (identical(kind, ParameterKind.POSITIONAL)) { | 7055 } else if (identical(kind, ParameterKind.POSITIONAL)) { |
| 7056 positionalParameters.add(parameter); | 7056 positionalParameters.add(parameter); |
| 7057 } else { | 7057 } else { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7099 } | 7099 } |
| 7100 return resolvedParameters; | 7100 return resolvedParameters; |
| 7101 } | 7101 } |
| 7102 | 7102 |
| 7103 /** | 7103 /** |
| 7104 * Resolve the names in the given combinators in the scope of the given librar
y. | 7104 * Resolve the names in the given combinators in the scope of the given librar
y. |
| 7105 * | 7105 * |
| 7106 * @param library the library that defines the names | 7106 * @param library the library that defines the names |
| 7107 * @param combinators the combinators containing the names to be resolved | 7107 * @param combinators the combinators containing the names to be resolved |
| 7108 */ | 7108 */ |
| 7109 void resolveCombinators(LibraryElement library, NodeList<Combinator> combinato
rs) { | 7109 void _resolveCombinators(LibraryElement library, NodeList<Combinator> combinat
ors) { |
| 7110 if (library == null) { | 7110 if (library == null) { |
| 7111 // | 7111 // |
| 7112 // The library will be null if the directive containing the combinators ha
s a URI that is not | 7112 // The library will be null if the directive containing the combinators ha
s a URI that is not |
| 7113 // valid. | 7113 // valid. |
| 7114 // | 7114 // |
| 7115 return; | 7115 return; |
| 7116 } | 7116 } |
| 7117 Namespace namespace = new NamespaceBuilder().createExportNamespaceForLibrary
(library); | 7117 Namespace namespace = new NamespaceBuilder().createExportNamespaceForLibrary
(library); |
| 7118 for (Combinator combinator in combinators) { | 7118 for (Combinator combinator in combinators) { |
| 7119 NodeList<SimpleIdentifier> names; | 7119 NodeList<SimpleIdentifier> names; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 7131 } | 7131 } |
| 7132 } | 7132 } |
| 7133 | 7133 |
| 7134 /** | 7134 /** |
| 7135 * Given an invocation of the form 'C.x()' where 'C' is a class, find and retu
rn the element 'x' | 7135 * Given an invocation of the form 'C.x()' where 'C' is a class, find and retu
rn the element 'x' |
| 7136 * in 'C'. | 7136 * in 'C'. |
| 7137 * | 7137 * |
| 7138 * @param classElement the class element | 7138 * @param classElement the class element |
| 7139 * @param nameNode the member name node | 7139 * @param nameNode the member name node |
| 7140 */ | 7140 */ |
| 7141 Element resolveElement(ClassElementImpl classElement, SimpleIdentifier nameNod
e) { | 7141 Element _resolveElement(ClassElementImpl classElement, SimpleIdentifier nameNo
de) { |
| 7142 String name = nameNode.name; | 7142 String name = nameNode.name; |
| 7143 Element element = null; | 7143 Element element = null; |
| 7144 element = classElement.getMethod(name); | 7144 element = classElement.getMethod(name); |
| 7145 if (element == null && nameNode.inSetterContext()) { | 7145 if (element == null && nameNode.inSetterContext()) { |
| 7146 element = classElement.getSetter(name); | 7146 element = classElement.getSetter(name); |
| 7147 } | 7147 } |
| 7148 if (element == null && nameNode.inGetterContext()) { | 7148 if (element == null && nameNode.inGetterContext()) { |
| 7149 element = classElement.getGetter(name); | 7149 element = classElement.getGetter(name); |
| 7150 } | 7150 } |
| 7151 if (element != null && element.isAccessibleIn(_definingLibrary)) { | 7151 if (element != null && element.isAccessibleIn(_definingLibrary)) { |
| 7152 return element; | 7152 return element; |
| 7153 } | 7153 } |
| 7154 return null; | 7154 return null; |
| 7155 } | 7155 } |
| 7156 | 7156 |
| 7157 /** | 7157 /** |
| 7158 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the elemen
t being invoked. If | 7158 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the elemen
t being invoked. If |
| 7159 * the returned element is a method, then the method will be invoked. If the r
eturned element is a | 7159 * the returned element is a method, then the method will be invoked. If the r
eturned element is a |
| 7160 * getter, the getter will be invoked without arguments and the result of that
invocation will | 7160 * getter, the getter will be invoked without arguments and the result of that
invocation will |
| 7161 * then be invoked with the arguments. | 7161 * then be invoked with the arguments. |
| 7162 * | 7162 * |
| 7163 * @param methodName the name of the method being invoked ('m') | 7163 * @param methodName the name of the method being invoked ('m') |
| 7164 * @return the element being invoked | 7164 * @return the element being invoked |
| 7165 */ | 7165 */ |
| 7166 Element resolveInvokedElement(SimpleIdentifier methodName) { | 7166 Element _resolveInvokedElement(SimpleIdentifier methodName) { |
| 7167 // | 7167 // |
| 7168 // Look first in the lexical scope. | 7168 // Look first in the lexical scope. |
| 7169 // | 7169 // |
| 7170 Element element = _resolver.nameScope.lookup(methodName, _definingLibrary); | 7170 Element element = _resolver.nameScope.lookup(methodName, _definingLibrary); |
| 7171 if (element == null) { | 7171 if (element == null) { |
| 7172 // | 7172 // |
| 7173 // If it isn't defined in the lexical scope, and the invocation is within
a class, then look | 7173 // If it isn't defined in the lexical scope, and the invocation is within
a class, then look |
| 7174 // in the inheritance scope. | 7174 // in the inheritance scope. |
| 7175 // | 7175 // |
| 7176 ClassElement enclosingClass = _resolver.enclosingClass; | 7176 ClassElement enclosingClass = _resolver.enclosingClass; |
| 7177 if (enclosingClass != null) { | 7177 if (enclosingClass != null) { |
| 7178 InterfaceType enclosingType = enclosingClass.type; | 7178 InterfaceType enclosingType = enclosingClass.type; |
| 7179 element = lookUpMethod(null, enclosingType, methodName.name); | 7179 element = _lookUpMethod(null, enclosingType, methodName.name); |
| 7180 if (element == null) { | 7180 if (element == null) { |
| 7181 // | 7181 // |
| 7182 // If there's no method, then it's possible that 'm' is a getter that
returns a function. | 7182 // If there's no method, then it's possible that 'm' is a getter that
returns a function. |
| 7183 // | 7183 // |
| 7184 element = lookUpGetter(null, enclosingType, methodName.name); | 7184 element = _lookUpGetter(null, enclosingType, methodName.name); |
| 7185 } | 7185 } |
| 7186 } | 7186 } |
| 7187 } | 7187 } |
| 7188 // TODO(brianwilkerson) Report this error. | 7188 // TODO(brianwilkerson) Report this error. |
| 7189 return element; | 7189 return element; |
| 7190 } | 7190 } |
| 7191 | 7191 |
| 7192 /** | 7192 /** |
| 7193 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the el
ement being invoked. | 7193 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the el
ement being invoked. |
| 7194 * If the returned element is a method, then the method will be invoked. If th
e returned element | 7194 * If the returned element is a method, then the method will be invoked. If th
e returned element |
| 7195 * is a getter, the getter will be invoked without arguments and the result of
that invocation | 7195 * is a getter, the getter will be invoked without arguments and the result of
that invocation |
| 7196 * will then be invoked with the arguments. | 7196 * will then be invoked with the arguments. |
| 7197 * | 7197 * |
| 7198 * @param target the target of the invocation ('e') | 7198 * @param target the target of the invocation ('e') |
| 7199 * @param targetType the type of the target | 7199 * @param targetType the type of the target |
| 7200 * @param methodName the name of the method being invoked ('m') | 7200 * @param methodName the name of the method being invoked ('m') |
| 7201 * @return the element being invoked | 7201 * @return the element being invoked |
| 7202 */ | 7202 */ |
| 7203 Element resolveInvokedElementWithTarget(Expression target, Type2 targetType, S
impleIdentifier methodName) { | 7203 Element _resolveInvokedElementWithTarget(Expression target, Type2 targetType,
SimpleIdentifier methodName) { |
| 7204 if (targetType is InterfaceType) { | 7204 if (targetType is InterfaceType) { |
| 7205 InterfaceType classType = targetType; | 7205 InterfaceType classType = targetType; |
| 7206 Element element = lookUpMethod(target, classType, methodName.name); | 7206 Element element = _lookUpMethod(target, classType, methodName.name); |
| 7207 if (element == null) { | 7207 if (element == null) { |
| 7208 // | 7208 // |
| 7209 // If there's no method, then it's possible that 'm' is a getter that re
turns a function. | 7209 // If there's no method, then it's possible that 'm' is a getter that re
turns a function. |
| 7210 // | 7210 // |
| 7211 element = lookUpGetter(target, classType, methodName.name); | 7211 element = _lookUpGetter(target, classType, methodName.name); |
| 7212 } | 7212 } |
| 7213 return element; | 7213 return element; |
| 7214 } else if (target is SimpleIdentifier) { | 7214 } else if (target is SimpleIdentifier) { |
| 7215 Element targetElement = target.staticElement; | 7215 Element targetElement = target.staticElement; |
| 7216 if (targetElement is PrefixElement) { | 7216 if (targetElement is PrefixElement) { |
| 7217 // | 7217 // |
| 7218 // Look to see whether the name of the method is really part of a prefix
ed identifier for an | 7218 // Look to see whether the name of the method is really part of a prefix
ed identifier for an |
| 7219 // imported top-level function or top-level getter that returns a functi
on. | 7219 // imported top-level function or top-level getter that returns a functi
on. |
| 7220 // | 7220 // |
| 7221 String name = "${target.name}.${methodName}"; | 7221 String name = "${target.name}.${methodName}"; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 7234 | 7234 |
| 7235 /** | 7235 /** |
| 7236 * Given that we are accessing a property of the given type with the given nam
e, return the | 7236 * Given that we are accessing a property of the given type with the given nam
e, return the |
| 7237 * element that represents the property. | 7237 * element that represents the property. |
| 7238 * | 7238 * |
| 7239 * @param target the target of the invocation ('e') | 7239 * @param target the target of the invocation ('e') |
| 7240 * @param targetType the type in which the search for the property should begi
n | 7240 * @param targetType the type in which the search for the property should begi
n |
| 7241 * @param propertyName the name of the property being accessed | 7241 * @param propertyName the name of the property being accessed |
| 7242 * @return the element that represents the property | 7242 * @return the element that represents the property |
| 7243 */ | 7243 */ |
| 7244 ExecutableElement resolveProperty(Expression target, Type2 targetType, SimpleI
dentifier propertyName) { | 7244 ExecutableElement _resolveProperty(Expression target, Type2 targetType, Simple
Identifier propertyName) { |
| 7245 ExecutableElement memberElement = null; | 7245 ExecutableElement memberElement = null; |
| 7246 if (propertyName.inSetterContext()) { | 7246 if (propertyName.inSetterContext()) { |
| 7247 memberElement = lookUpSetter(target, targetType, propertyName.name); | 7247 memberElement = _lookUpSetter(target, targetType, propertyName.name); |
| 7248 } | 7248 } |
| 7249 if (memberElement == null) { | 7249 if (memberElement == null) { |
| 7250 memberElement = lookUpGetter(target, targetType, propertyName.name); | 7250 memberElement = _lookUpGetter(target, targetType, propertyName.name); |
| 7251 } | 7251 } |
| 7252 if (memberElement == null) { | 7252 if (memberElement == null) { |
| 7253 memberElement = lookUpMethod(target, targetType, propertyName.name); | 7253 memberElement = _lookUpMethod(target, targetType, propertyName.name); |
| 7254 } | 7254 } |
| 7255 return memberElement; | 7255 return memberElement; |
| 7256 } | 7256 } |
| 7257 | 7257 |
| 7258 void resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) { | 7258 void _resolvePropertyAccess(Expression target, SimpleIdentifier propertyName)
{ |
| 7259 Type2 staticType = getStaticType(target); | 7259 Type2 staticType = _getStaticType(target); |
| 7260 Type2 propagatedType = getPropagatedType(target); | 7260 Type2 propagatedType = _getPropagatedType(target); |
| 7261 Element staticElement = null; | 7261 Element staticElement = null; |
| 7262 Element propagatedElement = null; | 7262 Element propagatedElement = null; |
| 7263 // | 7263 // |
| 7264 // If this property access is of the form 'C.m' where 'C' is a class, then w
e don't call | 7264 // If this property access is of the form 'C.m' where 'C' is a class, then w
e don't call |
| 7265 // resolveProperty(..) which walks up the class hierarchy, instead we just l
ook for the | 7265 // resolveProperty(..) which walks up the class hierarchy, instead we just l
ook for the |
| 7266 // member in the type only. | 7266 // member in the type only. |
| 7267 // | 7267 // |
| 7268 ClassElementImpl typeReference = getTypeReference(target); | 7268 ClassElementImpl typeReference = getTypeReference(target); |
| 7269 if (typeReference != null) { | 7269 if (typeReference != null) { |
| 7270 staticElement = propagatedElement = resolveElement(typeReference, property
Name); | 7270 staticElement = propagatedElement = _resolveElement(typeReference, propert
yName); |
| 7271 } else { | 7271 } else { |
| 7272 staticElement = resolveProperty(target, staticType, propertyName); | 7272 staticElement = _resolveProperty(target, staticType, propertyName); |
| 7273 propagatedElement = resolveProperty(target, propagatedType, propertyName); | 7273 propagatedElement = _resolveProperty(target, propagatedType, propertyName)
; |
| 7274 } | 7274 } |
| 7275 // May be part of annotation, record property element only if exists. | 7275 // May be part of annotation, record property element only if exists. |
| 7276 // Error was already reported in validateAnnotationElement(). | 7276 // Error was already reported in validateAnnotationElement(). |
| 7277 if (target.parent.parent is Annotation) { | 7277 if (target.parent.parent is Annotation) { |
| 7278 if (staticElement != null) { | 7278 if (staticElement != null) { |
| 7279 propertyName.staticElement = staticElement; | 7279 propertyName.staticElement = staticElement; |
| 7280 } | 7280 } |
| 7281 return; | 7281 return; |
| 7282 } | 7282 } |
| 7283 propertyName.staticElement = staticElement; | 7283 propertyName.staticElement = staticElement; |
| 7284 propertyName.propagatedElement = propagatedElement; | 7284 propertyName.propagatedElement = propagatedElement; |
| 7285 bool shouldReportMissingMember_static = shouldReportMissingMember(staticType
, staticElement); | 7285 bool shouldReportMissingMember_static = _shouldReportMissingMember(staticTyp
e, staticElement); |
| 7286 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? shouldReportMissingMember(propagatedType, propagatedElement)
: false; | 7286 bool shouldReportMissingMember_propagated = !shouldReportMissingMember_stati
c && _enableHints ? _shouldReportMissingMember(propagatedType, propagatedElement
) : false; |
| 7287 // If we are about to generate the hint (propagated version of this warning)
, then check | 7287 // If we are about to generate the hint (propagated version of this warning)
, then check |
| 7288 // that the member is not in a subtype of the propagated type. | 7288 // that the member is not in a subtype of the propagated type. |
| 7289 if (shouldReportMissingMember_propagated) { | 7289 if (shouldReportMissingMember_propagated) { |
| 7290 if (memberFoundInSubclass(propagatedType.element, propertyName.name, false
, true)) { | 7290 if (_memberFoundInSubclass(propagatedType.element, propertyName.name, fals
e, true)) { |
| 7291 shouldReportMissingMember_propagated = false; | 7291 shouldReportMissingMember_propagated = false; |
| 7292 } | 7292 } |
| 7293 } | 7293 } |
| 7294 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { | 7294 if (shouldReportMissingMember_static || shouldReportMissingMember_propagated
) { |
| 7295 if (staticType.isVoid) { | 7295 if (staticType.isVoid) { |
| 7296 if (propertyName.inSetterContext()) { | 7296 if (propertyName.inSetterContext()) { |
| 7297 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; | 7297 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; |
| 7298 _resolver.reportErrorForNode(errorCode, propertyName, [propertyName.na
me, staticType.displayName]); | 7298 _resolver.reportErrorForNode(errorCode, propertyName, [propertyName.na
me, staticType.displayName]); |
| 7299 } else if (propertyName.inGetterContext()) { | 7299 } else if (propertyName.inGetterContext()) { |
| 7300 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode; | 7300 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWa
rningCode.UNDEFINED_GETTER : HintCode.UNDEFINED_GETTER) as ErrorCode; |
| 7301 _resolver.reportErrorForNode(errorCode, propertyName, [propertyName.na
me, staticType.displayName]); | 7301 _resolver.reportErrorForNode(errorCode, propertyName, [propertyName.na
me, staticType.displayName]); |
| 7302 } else { | 7302 } else { |
| 7303 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_IDENTIFIER, p
ropertyName, [propertyName.name]); | 7303 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_IDENTIFIER, p
ropertyName, [propertyName.name]); |
| 7304 } | 7304 } |
| 7305 } | 7305 } |
| 7306 Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static
? staticType.element : propagatedType.element; | 7306 Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static
? staticType.element : propagatedType.element; |
| 7307 if (staticOrPropagatedEnclosingElt != null) { | 7307 if (staticOrPropagatedEnclosingElt != null) { |
| 7308 bool isStaticProperty = isStatic(staticOrPropagatedEnclosingElt); | 7308 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt); |
| 7309 if (propertyName.inSetterContext()) { | 7309 if (propertyName.inSetterContext()) { |
| 7310 if (isStaticProperty) { | 7310 if (isStaticProperty) { |
| 7311 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarn
ingCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; | 7311 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticWarn
ingCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; |
| 7312 _resolver.reportProxyConditionalErrorForNode(staticOrPropagatedEnclo
singElt, errorCode, propertyName, [ | 7312 _resolver.reportProxyConditionalErrorForNode(staticOrPropagatedEnclo
singElt, errorCode, propertyName, [ |
| 7313 propertyName.name, | 7313 propertyName.name, |
| 7314 staticOrPropagatedEnclosingElt.displayName]); | 7314 staticOrPropagatedEnclosingElt.displayName]); |
| 7315 } else { | 7315 } else { |
| 7316 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticType
WarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; | 7316 ErrorCode errorCode = (shouldReportMissingMember_static ? StaticType
WarningCode.UNDEFINED_SETTER : HintCode.UNDEFINED_SETTER) as ErrorCode; |
| 7317 _resolver.reportProxyConditionalErrorForNode(staticOrPropagatedEnclo
singElt, errorCode, propertyName, [ | 7317 _resolver.reportProxyConditionalErrorForNode(staticOrPropagatedEnclo
singElt, errorCode, propertyName, [ |
| 7318 propertyName.name, | 7318 propertyName.name, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7338 } | 7338 } |
| 7339 | 7339 |
| 7340 /** | 7340 /** |
| 7341 * Resolve the given simple identifier if possible. Return the element to whic
h it could be | 7341 * Resolve the given simple identifier if possible. Return the element to whic
h it could be |
| 7342 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the | 7342 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the |
| 7343 * resolution. | 7343 * resolution. |
| 7344 * | 7344 * |
| 7345 * @param node the identifier to be resolved | 7345 * @param node the identifier to be resolved |
| 7346 * @return the element to which the identifier could be resolved | 7346 * @return the element to which the identifier could be resolved |
| 7347 */ | 7347 */ |
| 7348 Element resolveSimpleIdentifier(SimpleIdentifier node) { | 7348 Element _resolveSimpleIdentifier(SimpleIdentifier node) { |
| 7349 Element element = _resolver.nameScope.lookup(node, _definingLibrary); | 7349 Element element = _resolver.nameScope.lookup(node, _definingLibrary); |
| 7350 if (element is PropertyAccessorElement && node.inSetterContext()) { | 7350 if (element is PropertyAccessorElement && node.inSetterContext()) { |
| 7351 PropertyInducingElement variable = (element as PropertyAccessorElement).va
riable; | 7351 PropertyInducingElement variable = (element as PropertyAccessorElement).va
riable; |
| 7352 if (variable != null) { | 7352 if (variable != null) { |
| 7353 PropertyAccessorElement setter = variable.setter; | 7353 PropertyAccessorElement setter = variable.setter; |
| 7354 if (setter == null) { | 7354 if (setter == null) { |
| 7355 // | 7355 // |
| 7356 // Check to see whether there might be a locally defined getter and an
inherited setter. | 7356 // Check to see whether there might be a locally defined getter and an
inherited setter. |
| 7357 // | 7357 // |
| 7358 ClassElement enclosingClass = _resolver.enclosingClass; | 7358 ClassElement enclosingClass = _resolver.enclosingClass; |
| 7359 if (enclosingClass != null) { | 7359 if (enclosingClass != null) { |
| 7360 setter = lookUpSetter(null, enclosingClass.type, node.name); | 7360 setter = _lookUpSetter(null, enclosingClass.type, node.name); |
| 7361 } | 7361 } |
| 7362 } | 7362 } |
| 7363 if (setter != null) { | 7363 if (setter != null) { |
| 7364 element = setter; | 7364 element = setter; |
| 7365 } | 7365 } |
| 7366 } | 7366 } |
| 7367 } else if (element == null && node.inSetterContext()) { | 7367 } else if (element == null && node.inSetterContext()) { |
| 7368 element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifi
er("${node.name}="), _definingLibrary); | 7368 element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifi
er("${node.name}="), _definingLibrary); |
| 7369 } | 7369 } |
| 7370 ClassElement enclosingClass = _resolver.enclosingClass; | 7370 ClassElement enclosingClass = _resolver.enclosingClass; |
| 7371 if (element == null && enclosingClass != null) { | 7371 if (element == null && enclosingClass != null) { |
| 7372 InterfaceType enclosingType = enclosingClass.type; | 7372 InterfaceType enclosingType = enclosingClass.type; |
| 7373 if (element == null && node.inSetterContext()) { | 7373 if (element == null && node.inSetterContext()) { |
| 7374 element = lookUpSetter(null, enclosingType, node.name); | 7374 element = _lookUpSetter(null, enclosingType, node.name); |
| 7375 } | 7375 } |
| 7376 if (element == null && node.inGetterContext()) { | 7376 if (element == null && node.inGetterContext()) { |
| 7377 element = lookUpGetter(null, enclosingType, node.name); | 7377 element = _lookUpGetter(null, enclosingType, node.name); |
| 7378 } | 7378 } |
| 7379 if (element == null) { | 7379 if (element == null) { |
| 7380 element = lookUpMethod(null, enclosingType, node.name); | 7380 element = _lookUpMethod(null, enclosingType, node.name); |
| 7381 } | 7381 } |
| 7382 } | 7382 } |
| 7383 return element; | 7383 return element; |
| 7384 } | 7384 } |
| 7385 | 7385 |
| 7386 /** | 7386 /** |
| 7387 * If the given type is a type parameter, resolve it to the type that should b
e used when looking | 7387 * If the given type is a type parameter, resolve it to the type that should b
e used when looking |
| 7388 * up members. Otherwise, return the original type. | 7388 * up members. Otherwise, return the original type. |
| 7389 * | 7389 * |
| 7390 * @param type the type that is to be resolved if it is a type parameter | 7390 * @param type the type that is to be resolved if it is a type parameter |
| 7391 * @return the type that should be used in place of the argument if it is a ty
pe parameter, or the | 7391 * @return the type that should be used in place of the argument if it is a ty
pe parameter, or the |
| 7392 * original argument if it isn't a type parameter | 7392 * original argument if it isn't a type parameter |
| 7393 */ | 7393 */ |
| 7394 Type2 resolveTypeParameter(Type2 type) { | 7394 Type2 _resolveTypeParameter(Type2 type) { |
| 7395 if (type is TypeParameterType) { | 7395 if (type is TypeParameterType) { |
| 7396 Type2 bound = type.element.bound; | 7396 Type2 bound = type.element.bound; |
| 7397 if (bound == null) { | 7397 if (bound == null) { |
| 7398 return _resolver.typeProvider.objectType; | 7398 return _resolver.typeProvider.objectType; |
| 7399 } | 7399 } |
| 7400 return bound; | 7400 return bound; |
| 7401 } | 7401 } |
| 7402 return type; | 7402 return type; |
| 7403 } | 7403 } |
| 7404 | 7404 |
| 7405 /** | 7405 /** |
| 7406 * Given a node that can have annotations associated with it and the element t
o which that node | 7406 * Given a node that can have annotations associated with it and the element t
o which that node |
| 7407 * has been resolved, create the annotations in the element model representing
the annotations on | 7407 * has been resolved, create the annotations in the element model representing
the annotations on |
| 7408 * the node. | 7408 * the node. |
| 7409 * | 7409 * |
| 7410 * @param element the element to which the node has been resolved | 7410 * @param element the element to which the node has been resolved |
| 7411 * @param node the node that can have annotations associated with it | 7411 * @param node the node that can have annotations associated with it |
| 7412 */ | 7412 */ |
| 7413 void setMetadata(Element element, AnnotatedNode node) { | 7413 void _setMetadata(Element element, AnnotatedNode node) { |
| 7414 if (element is! ElementImpl) { | 7414 if (element is! ElementImpl) { |
| 7415 return; | 7415 return; |
| 7416 } | 7416 } |
| 7417 List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>
(); | 7417 List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>
(); |
| 7418 addAnnotations(annotationList, node.metadata); | 7418 _addAnnotations(annotationList, node.metadata); |
| 7419 if (node is VariableDeclaration && node.parent is VariableDeclarationList) { | 7419 if (node is VariableDeclaration && node.parent is VariableDeclarationList) { |
| 7420 VariableDeclarationList list = node.parent as VariableDeclarationList; | 7420 VariableDeclarationList list = node.parent as VariableDeclarationList; |
| 7421 addAnnotations(annotationList, list.metadata); | 7421 _addAnnotations(annotationList, list.metadata); |
| 7422 if (list.parent is FieldDeclaration) { | 7422 if (list.parent is FieldDeclaration) { |
| 7423 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration; | 7423 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration; |
| 7424 addAnnotations(annotationList, fieldDeclaration.metadata); | 7424 _addAnnotations(annotationList, fieldDeclaration.metadata); |
| 7425 } else if (list.parent is TopLevelVariableDeclaration) { | 7425 } else if (list.parent is TopLevelVariableDeclaration) { |
| 7426 TopLevelVariableDeclaration variableDeclaration = list.parent as TopLeve
lVariableDeclaration; | 7426 TopLevelVariableDeclaration variableDeclaration = list.parent as TopLeve
lVariableDeclaration; |
| 7427 addAnnotations(annotationList, variableDeclaration.metadata); | 7427 _addAnnotations(annotationList, variableDeclaration.metadata); |
| 7428 } | 7428 } |
| 7429 } | 7429 } |
| 7430 if (!annotationList.isEmpty) { | 7430 if (!annotationList.isEmpty) { |
| 7431 (element as ElementImpl).metadata = new List.from(annotationList); | 7431 (element as ElementImpl).metadata = new List.from(annotationList); |
| 7432 } | 7432 } |
| 7433 } | 7433 } |
| 7434 | 7434 |
| 7435 /** | 7435 /** |
| 7436 * Given a node that can have annotations associated with it and the element t
o which that node | 7436 * Given a node that can have annotations associated with it and the element t
o which that node |
| 7437 * has been resolved, create the annotations in the element model representing
the annotations on | 7437 * has been resolved, create the annotations in the element model representing
the annotations on |
| 7438 * the node. | 7438 * the node. |
| 7439 * | 7439 * |
| 7440 * @param element the element to which the node has been resolved | 7440 * @param element the element to which the node has been resolved |
| 7441 * @param node the node that can have annotations associated with it | 7441 * @param node the node that can have annotations associated with it |
| 7442 */ | 7442 */ |
| 7443 void setMetadataForParameter(Element element, NormalFormalParameter node) { | 7443 void _setMetadataForParameter(Element element, NormalFormalParameter node) { |
| 7444 if (element is! ElementImpl) { | 7444 if (element is! ElementImpl) { |
| 7445 return; | 7445 return; |
| 7446 } | 7446 } |
| 7447 List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>
(); | 7447 List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>
(); |
| 7448 addAnnotations(annotationList, node.metadata); | 7448 _addAnnotations(annotationList, node.metadata); |
| 7449 if (!annotationList.isEmpty) { | 7449 if (!annotationList.isEmpty) { |
| 7450 (element as ElementImpl).metadata = new List.from(annotationList); | 7450 (element as ElementImpl).metadata = new List.from(annotationList); |
| 7451 } | 7451 } |
| 7452 } | 7452 } |
| 7453 | 7453 |
| 7454 /** | 7454 /** |
| 7455 * Return `true` if we should report an error as a result of looking up a memb
er in the | 7455 * Return `true` if we should report an error as a result of looking up a memb
er in the |
| 7456 * given type and not finding any member. | 7456 * given type and not finding any member. |
| 7457 * | 7457 * |
| 7458 * @param type the type in which we attempted to perform the look-up | 7458 * @param type the type in which we attempted to perform the look-up |
| 7459 * @param member the result of the look-up | 7459 * @param member the result of the look-up |
| 7460 * @return `true` if we should report an error | 7460 * @return `true` if we should report an error |
| 7461 */ | 7461 */ |
| 7462 bool shouldReportMissingMember(Type2 type, Element member) { | 7462 bool _shouldReportMissingMember(Type2 type, Element member) { |
| 7463 if (member != null || type == null || type.isDynamic || type.isBottom) { | 7463 if (member != null || type == null || type.isDynamic || type.isBottom) { |
| 7464 return false; | 7464 return false; |
| 7465 } | 7465 } |
| 7466 return true; | 7466 return true; |
| 7467 } | 7467 } |
| 7468 } | 7468 } |
| 7469 | 7469 |
| 7470 /** | 7470 /** |
| 7471 * Instances of the class `SyntheticIdentifier` implement an identifier that can
be used to | 7471 * Instances of the class `SyntheticIdentifier` implement an identifier that can
be used to |
| 7472 * look up names in the lexical scope when there is no identifier in the AST str
ucture. There is | 7472 * look up names in the lexical scope when there is no identifier in the AST str
ucture. There is |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7547 this._errorListener = errorListener; | 7547 this._errorListener = errorListener; |
| 7548 } | 7548 } |
| 7549 | 7549 |
| 7550 /** | 7550 /** |
| 7551 * Resolve the given node, reporting any errors or warnings to the given liste
ner. | 7551 * Resolve the given node, reporting any errors or warnings to the given liste
ner. |
| 7552 * | 7552 * |
| 7553 * @param node the root of the AST structure to be resolved | 7553 * @param node the root of the AST structure to be resolved |
| 7554 * @throws AnalysisException if the node could not be resolved | 7554 * @throws AnalysisException if the node could not be resolved |
| 7555 */ | 7555 */ |
| 7556 void resolve(AstNode node) { | 7556 void resolve(AstNode node) { |
| 7557 AstNode rootNode = findResolutionRoot(node); | 7557 AstNode rootNode = _findResolutionRoot(node); |
| 7558 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); | 7558 Scope scope = ScopeBuilder.scopeFor(rootNode, _errorListener); |
| 7559 if (elementModelChanged(rootNode.parent)) { | 7559 if (_elementModelChanged(rootNode.parent)) { |
| 7560 throw new AnalysisException.con1("Cannot resolve node: element model chang
ed"); | 7560 throw new AnalysisException.con1("Cannot resolve node: element model chang
ed"); |
| 7561 } | 7561 } |
| 7562 resolveTypes(node, scope); | 7562 _resolveTypes(node, scope); |
| 7563 resolveVariables(node, scope); | 7563 _resolveVariables(node, scope); |
| 7564 resolveReferences(node, scope); | 7564 _resolveReferences(node, scope); |
| 7565 } | 7565 } |
| 7566 | 7566 |
| 7567 /** | 7567 /** |
| 7568 * Return `true` if the given node can be resolved independently of any other
nodes. | 7568 * Return `true` if the given node can be resolved independently of any other
nodes. |
| 7569 * | 7569 * |
| 7570 * <b>Note:</b> This method needs to be kept in sync with [ScopeBuilder#scopeF
orAstNode]. | 7570 * <b>Note:</b> This method needs to be kept in sync with [ScopeBuilder#scopeF
orAstNode]. |
| 7571 * | 7571 * |
| 7572 * @param node the node being tested | 7572 * @param node the node being tested |
| 7573 * @return `true` if the given node can be resolved independently of any other
nodes | 7573 * @return `true` if the given node can be resolved independently of any other
nodes |
| 7574 */ | 7574 */ |
| 7575 bool canBeResolved(AstNode node) => node is ClassDeclaration || node is ClassT
ypeAlias || node is CompilationUnit || node is ConstructorDeclaration || node is
FunctionDeclaration || node is FunctionTypeAlias || node is MethodDeclaration; | 7575 bool _canBeResolved(AstNode node) => node is ClassDeclaration || node is Class
TypeAlias || node is CompilationUnit || node is ConstructorDeclaration || node i
s FunctionDeclaration || node is FunctionTypeAlias || node is MethodDeclaration; |
| 7576 | 7576 |
| 7577 /** | 7577 /** |
| 7578 * Return `true` if the portion of the element model defined by the given node
has changed. | 7578 * Return `true` if the portion of the element model defined by the given node
has changed. |
| 7579 * | 7579 * |
| 7580 * @param node the node defining the portion of the element model being tested | 7580 * @param node the node defining the portion of the element model being tested |
| 7581 * @return `true` if the element model defined by the given node has changed | 7581 * @return `true` if the element model defined by the given node has changed |
| 7582 * @throws AnalysisException if the correctness of the element model cannot be
determined | 7582 * @throws AnalysisException if the correctness of the element model cannot be
determined |
| 7583 */ | 7583 */ |
| 7584 bool elementModelChanged(AstNode node) { | 7584 bool _elementModelChanged(AstNode node) { |
| 7585 Element element = getElement(node); | 7585 Element element = _getElement(node); |
| 7586 if (element == null) { | 7586 if (element == null) { |
| 7587 throw new AnalysisException.con1("Cannot resolve node: a ${node.runtimeTyp
e.toString()} does not define an element"); | 7587 throw new AnalysisException.con1("Cannot resolve node: a ${node.runtimeTyp
e.toString()} does not define an element"); |
| 7588 } | 7588 } |
| 7589 DeclarationMatcher matcher = new DeclarationMatcher(); | 7589 DeclarationMatcher matcher = new DeclarationMatcher(); |
| 7590 return !matcher.matches(node, element); | 7590 return !matcher.matches(node, element); |
| 7591 } | 7591 } |
| 7592 | 7592 |
| 7593 /** | 7593 /** |
| 7594 * Starting at the given node, find the smallest AST node that can be resolved
independently of | 7594 * Starting at the given node, find the smallest AST node that can be resolved
independently of |
| 7595 * any other nodes. Return the node that was found. | 7595 * any other nodes. Return the node that was found. |
| 7596 * | 7596 * |
| 7597 * @param node the node at which the search is to begin | 7597 * @param node the node at which the search is to begin |
| 7598 * @return the smallest AST node that can be resolved independently of any oth
er nodes | 7598 * @return the smallest AST node that can be resolved independently of any oth
er nodes |
| 7599 * @throws AnalysisException if there is no such node | 7599 * @throws AnalysisException if there is no such node |
| 7600 */ | 7600 */ |
| 7601 AstNode findResolutionRoot(AstNode node) { | 7601 AstNode _findResolutionRoot(AstNode node) { |
| 7602 AstNode result = node; | 7602 AstNode result = node; |
| 7603 AstNode parent = result.parent; | 7603 AstNode parent = result.parent; |
| 7604 while (parent != null && !canBeResolved(parent)) { | 7604 while (parent != null && !_canBeResolved(parent)) { |
| 7605 result = parent; | 7605 result = parent; |
| 7606 parent = result.parent; | 7606 parent = result.parent; |
| 7607 } | 7607 } |
| 7608 if (parent == null) { | 7608 if (parent == null) { |
| 7609 throw new AnalysisException.con1("Cannot resolve node: no resolvable node"
); | 7609 throw new AnalysisException.con1("Cannot resolve node: no resolvable node"
); |
| 7610 } | 7610 } |
| 7611 return result; | 7611 return result; |
| 7612 } | 7612 } |
| 7613 | 7613 |
| 7614 /** | 7614 /** |
| 7615 * Return the element defined by the given node, or `null` if the node does no
t define an | 7615 * Return the element defined by the given node, or `null` if the node does no
t define an |
| 7616 * element. | 7616 * element. |
| 7617 * | 7617 * |
| 7618 * @param node the node defining the element to be returned | 7618 * @param node the node defining the element to be returned |
| 7619 * @return the element defined by the given node | 7619 * @return the element defined by the given node |
| 7620 */ | 7620 */ |
| 7621 Element getElement(AstNode node) { | 7621 Element _getElement(AstNode node) { |
| 7622 if (node is Declaration) { | 7622 if (node is Declaration) { |
| 7623 return node.element; | 7623 return node.element; |
| 7624 } else if (node is CompilationUnit) { | 7624 } else if (node is CompilationUnit) { |
| 7625 return node.element; | 7625 return node.element; |
| 7626 } | 7626 } |
| 7627 return null; | 7627 return null; |
| 7628 } | 7628 } |
| 7629 | 7629 |
| 7630 void resolveReferences(AstNode node, Scope scope) { | 7630 void _resolveReferences(AstNode node, Scope scope) { |
| 7631 ResolverVisitor visitor = new ResolverVisitor.con3(_definingLibrary, _source
, _typeProvider, scope, _errorListener); | 7631 ResolverVisitor visitor = new ResolverVisitor.con3(_definingLibrary, _source
, _typeProvider, scope, _errorListener); |
| 7632 node.accept(visitor); | 7632 node.accept(visitor); |
| 7633 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondition
alAnalysisErrors) { | 7633 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondition
alAnalysisErrors) { |
| 7634 if (conditionalCode.shouldIncludeErrorCode()) { | 7634 if (conditionalCode.shouldIncludeErrorCode()) { |
| 7635 visitor.reportError(conditionalCode.analysisError); | 7635 visitor.reportError(conditionalCode.analysisError); |
| 7636 } | 7636 } |
| 7637 } | 7637 } |
| 7638 } | 7638 } |
| 7639 | 7639 |
| 7640 void resolveTypes(AstNode node, Scope scope) { | 7640 void _resolveTypes(AstNode node, Scope scope) { |
| 7641 TypeResolverVisitor visitor = new TypeResolverVisitor.con3(_definingLibrary,
_source, _typeProvider, scope, _errorListener); | 7641 TypeResolverVisitor visitor = new TypeResolverVisitor.con3(_definingLibrary,
_source, _typeProvider, scope, _errorListener); |
| 7642 node.accept(visitor); | 7642 node.accept(visitor); |
| 7643 } | 7643 } |
| 7644 | 7644 |
| 7645 void resolveVariables(AstNode node, Scope scope) { | 7645 void _resolveVariables(AstNode node, Scope scope) { |
| 7646 VariableResolverVisitor visitor = new VariableResolverVisitor.con2(_defining
Library, _source, _typeProvider, scope, _errorListener); | 7646 VariableResolverVisitor visitor = new VariableResolverVisitor.con2(_defining
Library, _source, _typeProvider, scope, _errorListener); |
| 7647 node.accept(visitor); | 7647 node.accept(visitor); |
| 7648 } | 7648 } |
| 7649 } | 7649 } |
| 7650 | 7650 |
| 7651 /** | 7651 /** |
| 7652 * Instances of the class `InheritanceManager` manage the knowledge of where cla
ss members | 7652 * Instances of the class `InheritanceManager` manage the knowledge of where cla
ss members |
| 7653 * (methods, getters & setters) are inherited from. | 7653 * (methods, getters & setters) are inherited from. |
| 7654 */ | 7654 */ |
| 7655 class InheritanceManager { | 7655 class InheritanceManager { |
| 7656 /** | 7656 /** |
| 7657 * Given some array of [ExecutableElement]s, this method creates a synthetic e
lement as | 7657 * Given some array of [ExecutableElement]s, this method creates a synthetic e
lement as |
| 7658 * described in the Superinterfaces section of Inheritance and Overriding. | 7658 * described in the Superinterfaces section of Inheritance and Overriding. |
| 7659 * | 7659 * |
| 7660 * TODO (jwren) Copy contents from the Spec into this javadoc. | 7660 * TODO (jwren) Copy contents from the Spec into this javadoc. |
| 7661 * | 7661 * |
| 7662 * TODO (jwren) Associate a propagated type to the synthetic method element us
ing least upper | 7662 * TODO (jwren) Associate a propagated type to the synthetic method element us
ing least upper |
| 7663 * bound calls | 7663 * bound calls |
| 7664 */ | 7664 */ |
| 7665 static ExecutableElement computeMergedExecutableElement(List<ExecutableElement
> elementArrayToMerge) { | 7665 static ExecutableElement _computeMergedExecutableElement(List<ExecutableElemen
t> elementArrayToMerge) { |
| 7666 int h = getNumOfPositionalParameters(elementArrayToMerge[0]); | 7666 int h = _getNumOfPositionalParameters(elementArrayToMerge[0]); |
| 7667 int r = getNumOfRequiredParameters(elementArrayToMerge[0]); | 7667 int r = _getNumOfRequiredParameters(elementArrayToMerge[0]); |
| 7668 Set<String> namedParametersList = new Set<String>(); | 7668 Set<String> namedParametersList = new Set<String>(); |
| 7669 for (int i = 1; i < elementArrayToMerge.length; i++) { | 7669 for (int i = 1; i < elementArrayToMerge.length; i++) { |
| 7670 ExecutableElement element = elementArrayToMerge[i]; | 7670 ExecutableElement element = elementArrayToMerge[i]; |
| 7671 int numOfPositionalParams = getNumOfPositionalParameters(element); | 7671 int numOfPositionalParams = _getNumOfPositionalParameters(element); |
| 7672 if (h < numOfPositionalParams) { | 7672 if (h < numOfPositionalParams) { |
| 7673 h = numOfPositionalParams; | 7673 h = numOfPositionalParams; |
| 7674 } | 7674 } |
| 7675 int numOfRequiredParams = getNumOfRequiredParameters(element); | 7675 int numOfRequiredParams = _getNumOfRequiredParameters(element); |
| 7676 if (r > numOfRequiredParams) { | 7676 if (r > numOfRequiredParams) { |
| 7677 r = numOfRequiredParams; | 7677 r = numOfRequiredParams; |
| 7678 } | 7678 } |
| 7679 namedParametersList.addAll(getNamedParameterNames(element)); | 7679 namedParametersList.addAll(_getNamedParameterNames(element)); |
| 7680 } | 7680 } |
| 7681 if (r > h) { | 7681 if (r > h) { |
| 7682 return null; | 7682 return null; |
| 7683 } | 7683 } |
| 7684 return createSyntheticExecutableElement(elementArrayToMerge, elementArrayToM
erge[0].displayName, r, h - r, new List.from(namedParametersList)); | 7684 return _createSyntheticExecutableElement(elementArrayToMerge, elementArrayTo
Merge[0].displayName, r, h - r, new List.from(namedParametersList)); |
| 7685 } | 7685 } |
| 7686 | 7686 |
| 7687 /** | 7687 /** |
| 7688 * Used by [computeMergedExecutableElement] to actually create the | 7688 * Used by [computeMergedExecutableElement] to actually create the |
| 7689 * synthetic element. | 7689 * synthetic element. |
| 7690 * | 7690 * |
| 7691 * @param elementArrayToMerge the array used to create the synthetic element | 7691 * @param elementArrayToMerge the array used to create the synthetic element |
| 7692 * @param name the name of the method, getter or setter | 7692 * @param name the name of the method, getter or setter |
| 7693 * @param numOfRequiredParameters the number of required parameters | 7693 * @param numOfRequiredParameters the number of required parameters |
| 7694 * @param numOfPositionalParameters the number of positional parameters | 7694 * @param numOfPositionalParameters the number of positional parameters |
| 7695 * @param namedParameters the list of [String]s that are the named parameters | 7695 * @param namedParameters the list of [String]s that are the named parameters |
| 7696 * @return the created synthetic element | 7696 * @return the created synthetic element |
| 7697 */ | 7697 */ |
| 7698 static ExecutableElement createSyntheticExecutableElement(List<ExecutableEleme
nt> elementArrayToMerge, String name, int numOfRequiredParameters, int numOfPosi
tionalParameters, List<String> namedParameters) { | 7698 static ExecutableElement _createSyntheticExecutableElement(List<ExecutableElem
ent> elementArrayToMerge, String name, int numOfRequiredParameters, int numOfPos
itionalParameters, List<String> namedParameters) { |
| 7699 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; | 7699 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; |
| 7700 SimpleIdentifier nameIdentifier = new SimpleIdentifier(new sc.StringToken(sc
.TokenType.IDENTIFIER, name, 0)); | 7700 SimpleIdentifier nameIdentifier = new SimpleIdentifier(new sc.StringToken(sc
.TokenType.IDENTIFIER, name, 0)); |
| 7701 ExecutableElementImpl executable; | 7701 ExecutableElementImpl executable; |
| 7702 if (elementArrayToMerge[0] is MethodElement) { | 7702 if (elementArrayToMerge[0] is MethodElement) { |
| 7703 MultiplyInheritedMethodElementImpl unionedMethod = new MultiplyInheritedMe
thodElementImpl(nameIdentifier); | 7703 MultiplyInheritedMethodElementImpl unionedMethod = new MultiplyInheritedMe
thodElementImpl(nameIdentifier); |
| 7704 unionedMethod.inheritedElements = elementArrayToMerge; | 7704 unionedMethod.inheritedElements = elementArrayToMerge; |
| 7705 executable = unionedMethod; | 7705 executable = unionedMethod; |
| 7706 } else { | 7706 } else { |
| 7707 MultiplyInheritedPropertyAccessorElementImpl unionedPropertyAccessor = new
MultiplyInheritedPropertyAccessorElementImpl(nameIdentifier); | 7707 MultiplyInheritedPropertyAccessorElementImpl unionedPropertyAccessor = new
MultiplyInheritedPropertyAccessorElementImpl(nameIdentifier); |
| 7708 unionedPropertyAccessor.getter = (elementArrayToMerge[0] as PropertyAccess
orElement).isGetter; | 7708 unionedPropertyAccessor.getter = (elementArrayToMerge[0] as PropertyAccess
orElement).isGetter; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 7734 executable.returnType = dynamicType; | 7734 executable.returnType = dynamicType; |
| 7735 executable.parameters = parameters; | 7735 executable.parameters = parameters; |
| 7736 FunctionTypeImpl methodType = new FunctionTypeImpl.con1(executable); | 7736 FunctionTypeImpl methodType = new FunctionTypeImpl.con1(executable); |
| 7737 executable.type = methodType; | 7737 executable.type = methodType; |
| 7738 return executable; | 7738 return executable; |
| 7739 } | 7739 } |
| 7740 | 7740 |
| 7741 /** | 7741 /** |
| 7742 * Given some [ExecutableElement], return the list of named parameters. | 7742 * Given some [ExecutableElement], return the list of named parameters. |
| 7743 */ | 7743 */ |
| 7744 static List<String> getNamedParameterNames(ExecutableElement executableElement
) { | 7744 static List<String> _getNamedParameterNames(ExecutableElement executableElemen
t) { |
| 7745 List<String> namedParameterNames = new List<String>(); | 7745 List<String> namedParameterNames = new List<String>(); |
| 7746 List<ParameterElement> parameters = executableElement.parameters; | 7746 List<ParameterElement> parameters = executableElement.parameters; |
| 7747 for (int i = 0; i < parameters.length; i++) { | 7747 for (int i = 0; i < parameters.length; i++) { |
| 7748 ParameterElement parameterElement = parameters[i]; | 7748 ParameterElement parameterElement = parameters[i]; |
| 7749 if (identical(parameterElement.parameterKind, ParameterKind.NAMED)) { | 7749 if (identical(parameterElement.parameterKind, ParameterKind.NAMED)) { |
| 7750 namedParameterNames.add(parameterElement.name); | 7750 namedParameterNames.add(parameterElement.name); |
| 7751 } | 7751 } |
| 7752 } | 7752 } |
| 7753 return namedParameterNames; | 7753 return namedParameterNames; |
| 7754 } | 7754 } |
| 7755 | 7755 |
| 7756 /** | 7756 /** |
| 7757 * Given some [ExecutableElement] return the number of parameters of the speci
fied kind. | 7757 * Given some [ExecutableElement] return the number of parameters of the speci
fied kind. |
| 7758 */ | 7758 */ |
| 7759 static int getNumOfParameters(ExecutableElement executableElement, ParameterKi
nd parameterKind) { | 7759 static int _getNumOfParameters(ExecutableElement executableElement, ParameterK
ind parameterKind) { |
| 7760 int parameterCount = 0; | 7760 int parameterCount = 0; |
| 7761 List<ParameterElement> parameters = executableElement.parameters; | 7761 List<ParameterElement> parameters = executableElement.parameters; |
| 7762 for (int i = 0; i < parameters.length; i++) { | 7762 for (int i = 0; i < parameters.length; i++) { |
| 7763 ParameterElement parameterElement = parameters[i]; | 7763 ParameterElement parameterElement = parameters[i]; |
| 7764 if (identical(parameterElement.parameterKind, parameterKind)) { | 7764 if (identical(parameterElement.parameterKind, parameterKind)) { |
| 7765 parameterCount++; | 7765 parameterCount++; |
| 7766 } | 7766 } |
| 7767 } | 7767 } |
| 7768 return parameterCount; | 7768 return parameterCount; |
| 7769 } | 7769 } |
| 7770 | 7770 |
| 7771 /** | 7771 /** |
| 7772 * Given some [ExecutableElement] return the number of positional parameters. | 7772 * Given some [ExecutableElement] return the number of positional parameters. |
| 7773 * | 7773 * |
| 7774 * Note: by positional we mean [ParameterKind#REQUIRED] or [ParameterKind#POSI
TIONAL]. | 7774 * Note: by positional we mean [ParameterKind#REQUIRED] or [ParameterKind#POSI
TIONAL]. |
| 7775 */ | 7775 */ |
| 7776 static int getNumOfPositionalParameters(ExecutableElement executableElement) =
> getNumOfParameters(executableElement, ParameterKind.REQUIRED) + getNumOfParame
ters(executableElement, ParameterKind.POSITIONAL); | 7776 static int _getNumOfPositionalParameters(ExecutableElement executableElement)
=> _getNumOfParameters(executableElement, ParameterKind.REQUIRED) + _getNumOfPar
ameters(executableElement, ParameterKind.POSITIONAL); |
| 7777 | 7777 |
| 7778 /** | 7778 /** |
| 7779 * Given some [ExecutableElement] return the number of required parameters. | 7779 * Given some [ExecutableElement] return the number of required parameters. |
| 7780 */ | 7780 */ |
| 7781 static int getNumOfRequiredParameters(ExecutableElement executableElement) =>
getNumOfParameters(executableElement, ParameterKind.REQUIRED); | 7781 static int _getNumOfRequiredParameters(ExecutableElement executableElement) =>
_getNumOfParameters(executableElement, ParameterKind.REQUIRED); |
| 7782 | 7782 |
| 7783 /** | 7783 /** |
| 7784 * Given some [ExecutableElement] returns `true` if it is an abstract member o
f a | 7784 * Given some [ExecutableElement] returns `true` if it is an abstract member o
f a |
| 7785 * class. | 7785 * class. |
| 7786 * | 7786 * |
| 7787 * @param executableElement some [ExecutableElement] to evaluate | 7787 * @param executableElement some [ExecutableElement] to evaluate |
| 7788 * @return `true` if the given element is an abstract member of a class | 7788 * @return `true` if the given element is an abstract member of a class |
| 7789 */ | 7789 */ |
| 7790 static bool isAbstract(ExecutableElement executableElement) { | 7790 static bool _isAbstract(ExecutableElement executableElement) { |
| 7791 if (executableElement is MethodElement) { | 7791 if (executableElement is MethodElement) { |
| 7792 return executableElement.isAbstract; | 7792 return executableElement.isAbstract; |
| 7793 } else if (executableElement is PropertyAccessorElement) { | 7793 } else if (executableElement is PropertyAccessorElement) { |
| 7794 return executableElement.isAbstract; | 7794 return executableElement.isAbstract; |
| 7795 } | 7795 } |
| 7796 return false; | 7796 return false; |
| 7797 } | 7797 } |
| 7798 | 7798 |
| 7799 /** | 7799 /** |
| 7800 * The [LibraryElement] that is managed by this manager. | 7800 * The [LibraryElement] that is managed by this manager. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7841 Set<AnalysisError> getErrors(ClassElement classElt) => _errorsInClassElement[c
lassElt]; | 7841 Set<AnalysisError> getErrors(ClassElement classElt) => _errorsInClassElement[c
lassElt]; |
| 7842 | 7842 |
| 7843 /** | 7843 /** |
| 7844 * Get and return a mapping between the set of all string names of the members
inherited from the | 7844 * Get and return a mapping between the set of all string names of the members
inherited from the |
| 7845 * passed [ClassElement] superclass hierarchy, and the associated [ExecutableE
lement]. | 7845 * passed [ClassElement] superclass hierarchy, and the associated [ExecutableE
lement]. |
| 7846 * | 7846 * |
| 7847 * @param classElt the class element to query | 7847 * @param classElt the class element to query |
| 7848 * @return a mapping between the set of all members inherited from the passed
[ClassElement] | 7848 * @return a mapping between the set of all members inherited from the passed
[ClassElement] |
| 7849 * superclass hierarchy, and the associated [ExecutableElement] | 7849 * superclass hierarchy, and the associated [ExecutableElement] |
| 7850 */ | 7850 */ |
| 7851 MemberMap getMapOfMembersInheritedFromClasses(ClassElement classElt) => comput
eClassChainLookupMap(classElt, new Set<ClassElement>()); | 7851 MemberMap getMapOfMembersInheritedFromClasses(ClassElement classElt) => _compu
teClassChainLookupMap(classElt, new Set<ClassElement>()); |
| 7852 | 7852 |
| 7853 /** | 7853 /** |
| 7854 * Get and return a mapping between the set of all string names of the members
inherited from the | 7854 * Get and return a mapping between the set of all string names of the members
inherited from the |
| 7855 * passed [ClassElement] interface hierarchy, and the associated [ExecutableEl
ement]. | 7855 * passed [ClassElement] interface hierarchy, and the associated [ExecutableEl
ement]. |
| 7856 * | 7856 * |
| 7857 * @param classElt the class element to query | 7857 * @param classElt the class element to query |
| 7858 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 7858 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 7859 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement]. | 7859 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement]. |
| 7860 */ | 7860 */ |
| 7861 MemberMap getMapOfMembersInheritedFromInterfaces(ClassElement classElt) => com
puteInterfaceLookupMap(classElt, new Set<ClassElement>()); | 7861 MemberMap getMapOfMembersInheritedFromInterfaces(ClassElement classElt) => _co
mputeInterfaceLookupMap(classElt, new Set<ClassElement>()); |
| 7862 | 7862 |
| 7863 /** | 7863 /** |
| 7864 * Given some [ClassElement] and some member name, this returns the | 7864 * Given some [ClassElement] and some member name, this returns the |
| 7865 * [ExecutableElement] that the class inherits from the mixins, | 7865 * [ExecutableElement] that the class inherits from the mixins, |
| 7866 * superclasses or interfaces, that has the member name, if no member is inher
ited `null` is | 7866 * superclasses or interfaces, that has the member name, if no member is inher
ited `null` is |
| 7867 * returned. | 7867 * returned. |
| 7868 * | 7868 * |
| 7869 * @param classElt the class element to query | 7869 * @param classElt the class element to query |
| 7870 * @param memberName the name of the executable element to find and return | 7870 * @param memberName the name of the executable element to find and return |
| 7871 * @return the inherited executable element with the member name, or `null` if
no such | 7871 * @return the inherited executable element with the member name, or `null` if
no such |
| 7872 * member exists | 7872 * member exists |
| 7873 */ | 7873 */ |
| 7874 ExecutableElement lookupInheritance(ClassElement classElt, String memberName)
{ | 7874 ExecutableElement lookupInheritance(ClassElement classElt, String memberName)
{ |
| 7875 if (memberName == null || memberName.isEmpty) { | 7875 if (memberName == null || memberName.isEmpty) { |
| 7876 return null; | 7876 return null; |
| 7877 } | 7877 } |
| 7878 ExecutableElement executable = computeClassChainLookupMap(classElt, new Set<
ClassElement>()).get(memberName); | 7878 ExecutableElement executable = _computeClassChainLookupMap(classElt, new Set
<ClassElement>()).get(memberName); |
| 7879 if (executable == null) { | 7879 if (executable == null) { |
| 7880 return computeInterfaceLookupMap(classElt, new Set<ClassElement>()).get(me
mberName); | 7880 return _computeInterfaceLookupMap(classElt, new Set<ClassElement>()).get(m
emberName); |
| 7881 } | 7881 } |
| 7882 return executable; | 7882 return executable; |
| 7883 } | 7883 } |
| 7884 | 7884 |
| 7885 /** | 7885 /** |
| 7886 * Given some [ClassElement] and some member name, this returns the | 7886 * Given some [ClassElement] and some member name, this returns the |
| 7887 * [ExecutableElement] that the class either declares itself, or | 7887 * [ExecutableElement] that the class either declares itself, or |
| 7888 * inherits, that has the member name, if no member is inherited `null` is ret
urned. | 7888 * inherits, that has the member name, if no member is inherited `null` is ret
urned. |
| 7889 * | 7889 * |
| 7890 * @param classElt the class element to query | 7890 * @param classElt the class element to query |
| 7891 * @param memberName the name of the executable element to find and return | 7891 * @param memberName the name of the executable element to find and return |
| 7892 * @return the inherited executable element with the member name, or `null` if
no such | 7892 * @return the inherited executable element with the member name, or `null` if
no such |
| 7893 * member exists | 7893 * member exists |
| 7894 */ | 7894 */ |
| 7895 ExecutableElement lookupMember(ClassElement classElt, String memberName) { | 7895 ExecutableElement lookupMember(ClassElement classElt, String memberName) { |
| 7896 ExecutableElement element = lookupMemberInClass(classElt, memberName); | 7896 ExecutableElement element = _lookupMemberInClass(classElt, memberName); |
| 7897 if (element != null) { | 7897 if (element != null) { |
| 7898 return element; | 7898 return element; |
| 7899 } | 7899 } |
| 7900 return lookupInheritance(classElt, memberName); | 7900 return lookupInheritance(classElt, memberName); |
| 7901 } | 7901 } |
| 7902 | 7902 |
| 7903 /** | 7903 /** |
| 7904 * Given some [InterfaceType] and some member name, this returns the | 7904 * Given some [InterfaceType] and some member name, this returns the |
| 7905 * [FunctionType] of the [ExecutableElement] that the | 7905 * [FunctionType] of the [ExecutableElement] that the |
| 7906 * class either declares itself, or inherits, that has the member name, if no
member is inherited | 7906 * class either declares itself, or inherits, that has the member name, if no
member is inherited |
| (...skipping 30 matching lines...) Expand all Loading... |
| 7937 * override | 7937 * override |
| 7938 * @param definingType the type that is overriding the member | 7938 * @param definingType the type that is overriding the member |
| 7939 * @return the passed function type with any parameterized types substituted | 7939 * @return the passed function type with any parameterized types substituted |
| 7940 */ | 7940 */ |
| 7941 FunctionType substituteTypeArgumentsInMemberFromInheritance(FunctionType baseF
unctionType, String memberName, InterfaceType definingType) { | 7941 FunctionType substituteTypeArgumentsInMemberFromInheritance(FunctionType baseF
unctionType, String memberName, InterfaceType definingType) { |
| 7942 if (baseFunctionType == null) { | 7942 if (baseFunctionType == null) { |
| 7943 return baseFunctionType; | 7943 return baseFunctionType; |
| 7944 } | 7944 } |
| 7945 // First, generate the path from the defining type to the overridden member | 7945 // First, generate the path from the defining type to the overridden member |
| 7946 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>(); | 7946 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>(); |
| 7947 computeInheritancePath(inheritancePath, definingType, memberName); | 7947 _computeInheritancePath(inheritancePath, definingType, memberName); |
| 7948 if (inheritancePath == null || inheritancePath.isEmpty) { | 7948 if (inheritancePath == null || inheritancePath.isEmpty) { |
| 7949 // TODO(jwren) log analysis engine error | 7949 // TODO(jwren) log analysis engine error |
| 7950 return baseFunctionType; | 7950 return baseFunctionType; |
| 7951 } | 7951 } |
| 7952 FunctionType functionTypeToReturn = baseFunctionType; | 7952 FunctionType functionTypeToReturn = baseFunctionType; |
| 7953 // loop backward through the list substituting as we go: | 7953 // loop backward through the list substituting as we go: |
| 7954 while (!inheritancePath.isEmpty) { | 7954 while (!inheritancePath.isEmpty) { |
| 7955 InterfaceType lastType = inheritancePath.removeLast(); | 7955 InterfaceType lastType = inheritancePath.removeLast(); |
| 7956 List<Type2> parameterTypes = lastType.element.type.typeArguments; | 7956 List<Type2> parameterTypes = lastType.element.type.typeArguments; |
| 7957 List<Type2> argumentTypes = lastType.typeArguments; | 7957 List<Type2> argumentTypes = lastType.typeArguments; |
| 7958 functionTypeToReturn = functionTypeToReturn.substitute2(argumentTypes, par
ameterTypes); | 7958 functionTypeToReturn = functionTypeToReturn.substitute2(argumentTypes, par
ameterTypes); |
| 7959 } | 7959 } |
| 7960 return functionTypeToReturn; | 7960 return functionTypeToReturn; |
| 7961 } | 7961 } |
| 7962 | 7962 |
| 7963 /** | 7963 /** |
| 7964 * Compute and return a mapping between the set of all string names of the mem
bers inherited from | 7964 * Compute and return a mapping between the set of all string names of the mem
bers inherited from |
| 7965 * the passed [ClassElement] superclass hierarchy, and the associated | 7965 * the passed [ClassElement] superclass hierarchy, and the associated |
| 7966 * [ExecutableElement]. | 7966 * [ExecutableElement]. |
| 7967 * | 7967 * |
| 7968 * @param classElt the class element to query | 7968 * @param classElt the class element to query |
| 7969 * @param visitedClasses a set of visited classes passed back into this method
when it calls | 7969 * @param visitedClasses a set of visited classes passed back into this method
when it calls |
| 7970 * itself recursively | 7970 * itself recursively |
| 7971 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 7971 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 7972 * [ClassElement] superclass hierarchy, and the associated [Executable
Element] | 7972 * [ClassElement] superclass hierarchy, and the associated [Executable
Element] |
| 7973 */ | 7973 */ |
| 7974 MemberMap computeClassChainLookupMap(ClassElement classElt, Set<ClassElement>
visitedClasses) { | 7974 MemberMap _computeClassChainLookupMap(ClassElement classElt, Set<ClassElement>
visitedClasses) { |
| 7975 MemberMap resultMap = _classLookup[classElt]; | 7975 MemberMap resultMap = _classLookup[classElt]; |
| 7976 if (resultMap != null) { | 7976 if (resultMap != null) { |
| 7977 return resultMap; | 7977 return resultMap; |
| 7978 } else { | 7978 } else { |
| 7979 resultMap = new MemberMap(); | 7979 resultMap = new MemberMap(); |
| 7980 } | 7980 } |
| 7981 ClassElement superclassElt = null; | 7981 ClassElement superclassElt = null; |
| 7982 InterfaceType supertype = classElt.supertype; | 7982 InterfaceType supertype = classElt.supertype; |
| 7983 if (supertype != null) { | 7983 if (supertype != null) { |
| 7984 superclassElt = supertype.element; | 7984 superclassElt = supertype.element; |
| 7985 } else { | 7985 } else { |
| 7986 // classElt is Object | 7986 // classElt is Object |
| 7987 _classLookup[classElt] = resultMap; | 7987 _classLookup[classElt] = resultMap; |
| 7988 return resultMap; | 7988 return resultMap; |
| 7989 } | 7989 } |
| 7990 if (superclassElt != null) { | 7990 if (superclassElt != null) { |
| 7991 if (!visitedClasses.contains(superclassElt)) { | 7991 if (!visitedClasses.contains(superclassElt)) { |
| 7992 visitedClasses.add(superclassElt); | 7992 visitedClasses.add(superclassElt); |
| 7993 try { | 7993 try { |
| 7994 resultMap = new MemberMap.con2(computeClassChainLookupMap(superclassEl
t, visitedClasses)); | 7994 resultMap = new MemberMap.con2(_computeClassChainLookupMap(superclassE
lt, visitedClasses)); |
| 7995 // | 7995 // |
| 7996 // Substitute the super types down the hierarchy. | 7996 // Substitute the super types down the hierarchy. |
| 7997 // | 7997 // |
| 7998 substituteTypeParametersDownHierarchy(supertype, resultMap); | 7998 _substituteTypeParametersDownHierarchy(supertype, resultMap); |
| 7999 // | 7999 // |
| 8000 // Include the members from the superclass in the resultMap. | 8000 // Include the members from the superclass in the resultMap. |
| 8001 // | 8001 // |
| 8002 recordMapWithClassMembers(resultMap, supertype, false); | 8002 _recordMapWithClassMembers(resultMap, supertype, false); |
| 8003 } finally { | 8003 } finally { |
| 8004 visitedClasses.remove(superclassElt); | 8004 visitedClasses.remove(superclassElt); |
| 8005 } | 8005 } |
| 8006 } else { | 8006 } else { |
| 8007 // This case happens only when the superclass was previously visited and
not in the lookup, | 8007 // This case happens only when the superclass was previously visited and
not in the lookup, |
| 8008 // meaning this is meant to shorten the compute for recursive cases. | 8008 // meaning this is meant to shorten the compute for recursive cases. |
| 8009 _classLookup[superclassElt] = resultMap; | 8009 _classLookup[superclassElt] = resultMap; |
| 8010 return resultMap; | 8010 return resultMap; |
| 8011 } | 8011 } |
| 8012 } | 8012 } |
| 8013 // | 8013 // |
| 8014 // Include the members from the mixins in the resultMap | 8014 // Include the members from the mixins in the resultMap |
| 8015 // | 8015 // |
| 8016 List<InterfaceType> mixins = classElt.mixins; | 8016 List<InterfaceType> mixins = classElt.mixins; |
| 8017 for (int i = mixins.length - 1; i >= 0; i--) { | 8017 for (int i = mixins.length - 1; i >= 0; i--) { |
| 8018 ClassElement mixinElement = mixins[i].element; | 8018 ClassElement mixinElement = mixins[i].element; |
| 8019 if (mixinElement != null) { | 8019 if (mixinElement != null) { |
| 8020 if (!visitedClasses.contains(mixinElement)) { | 8020 if (!visitedClasses.contains(mixinElement)) { |
| 8021 visitedClasses.add(mixinElement); | 8021 visitedClasses.add(mixinElement); |
| 8022 try { | 8022 try { |
| 8023 MemberMap map = new MemberMap.con2(computeClassChainLookupMap(mixinE
lement, visitedClasses)); | 8023 MemberMap map = new MemberMap.con2(_computeClassChainLookupMap(mixin
Element, visitedClasses)); |
| 8024 // | 8024 // |
| 8025 // Substitute the super types down the hierarchy. | 8025 // Substitute the super types down the hierarchy. |
| 8026 // | 8026 // |
| 8027 substituteTypeParametersDownHierarchy(mixins[i], map); | 8027 _substituteTypeParametersDownHierarchy(mixins[i], map); |
| 8028 // | 8028 // |
| 8029 // Include the members from the superclass in the resultMap. | 8029 // Include the members from the superclass in the resultMap. |
| 8030 // | 8030 // |
| 8031 recordMapWithClassMembers(map, mixins[i], false); | 8031 _recordMapWithClassMembers(map, mixins[i], false); |
| 8032 // | 8032 // |
| 8033 // Add the members from map into result map. | 8033 // Add the members from map into result map. |
| 8034 // | 8034 // |
| 8035 for (int j = 0; j < map.size; j++) { | 8035 for (int j = 0; j < map.size; j++) { |
| 8036 String key = map.getKey(j); | 8036 String key = map.getKey(j); |
| 8037 ExecutableElement value = map.getValue(j); | 8037 ExecutableElement value = map.getValue(j); |
| 8038 if (key != null) { | 8038 if (key != null) { |
| 8039 if (resultMap.get(key) == null || (resultMap.get(key) != null &&
!isAbstract(value))) { | 8039 if (resultMap.get(key) == null || (resultMap.get(key) != null &&
!_isAbstract(value))) { |
| 8040 resultMap.put(key, value); | 8040 resultMap.put(key, value); |
| 8041 } | 8041 } |
| 8042 } | 8042 } |
| 8043 } | 8043 } |
| 8044 } finally { | 8044 } finally { |
| 8045 visitedClasses.remove(mixinElement); | 8045 visitedClasses.remove(mixinElement); |
| 8046 } | 8046 } |
| 8047 } else { | 8047 } else { |
| 8048 // This case happens only when the superclass was previously visited a
nd not in the lookup, | 8048 // This case happens only when the superclass was previously visited a
nd not in the lookup, |
| 8049 // meaning this is meant to shorten the compute for recursive cases. | 8049 // meaning this is meant to shorten the compute for recursive cases. |
| 8050 _classLookup[mixinElement] = resultMap; | 8050 _classLookup[mixinElement] = resultMap; |
| 8051 return resultMap; | 8051 return resultMap; |
| 8052 } | 8052 } |
| 8053 } | 8053 } |
| 8054 } | 8054 } |
| 8055 _classLookup[classElt] = resultMap; | 8055 _classLookup[classElt] = resultMap; |
| 8056 return resultMap; | 8056 return resultMap; |
| 8057 } | 8057 } |
| 8058 | 8058 |
| 8059 /** | 8059 /** |
| 8060 * Compute and return the inheritance path given the context of a type and a m
ember that is | 8060 * Compute and return the inheritance path given the context of a type and a m
ember that is |
| 8061 * overridden in the inheritance path (for which the type is in the path). | 8061 * overridden in the inheritance path (for which the type is in the path). |
| 8062 * | 8062 * |
| 8063 * @param chain the inheritance path that is built up as this method calls its
elf recursively, | 8063 * @param chain the inheritance path that is built up as this method calls its
elf recursively, |
| 8064 * when this method is called an empty [LinkedList] should be provide
d | 8064 * when this method is called an empty [LinkedList] should be provide
d |
| 8065 * @param currentType the current type in the inheritance path | 8065 * @param currentType the current type in the inheritance path |
| 8066 * @param memberName the name of the member that is being looked up the inheri
tance path | 8066 * @param memberName the name of the member that is being looked up the inheri
tance path |
| 8067 */ | 8067 */ |
| 8068 void computeInheritancePath(Queue<InterfaceType> chain, InterfaceType currentT
ype, String memberName) { | 8068 void _computeInheritancePath(Queue<InterfaceType> chain, InterfaceType current
Type, String memberName) { |
| 8069 // TODO (jwren) create a public version of this method which doesn't require
the initial chain | 8069 // TODO (jwren) create a public version of this method which doesn't require
the initial chain |
| 8070 // to be provided, then provided tests for this functionality in Inheritance
ManagerTest | 8070 // to be provided, then provided tests for this functionality in Inheritance
ManagerTest |
| 8071 chain.add(currentType); | 8071 chain.add(currentType); |
| 8072 ClassElement classElt = currentType.element; | 8072 ClassElement classElt = currentType.element; |
| 8073 InterfaceType supertype = classElt.supertype; | 8073 InterfaceType supertype = classElt.supertype; |
| 8074 // Base case- reached Object | 8074 // Base case- reached Object |
| 8075 if (supertype == null) { | 8075 if (supertype == null) { |
| 8076 // Looked up the chain all the way to Object, return null. | 8076 // Looked up the chain all the way to Object, return null. |
| 8077 // This should never happen. | 8077 // This should never happen. |
| 8078 return; | 8078 return; |
| 8079 } | 8079 } |
| 8080 // If we are done, return the chain | 8080 // If we are done, return the chain |
| 8081 // We are not done if this is the first recursive call on this method. | 8081 // We are not done if this is the first recursive call on this method. |
| 8082 if (chain.length != 1) { | 8082 if (chain.length != 1) { |
| 8083 // We are done however if the member is in this classElt | 8083 // We are done however if the member is in this classElt |
| 8084 if (lookupMemberInClass(classElt, memberName) != null) { | 8084 if (_lookupMemberInClass(classElt, memberName) != null) { |
| 8085 return; | 8085 return; |
| 8086 } | 8086 } |
| 8087 } | 8087 } |
| 8088 // Mixins- note that mixins call lookupMemberInClass, not lookupMember | 8088 // Mixins- note that mixins call lookupMemberInClass, not lookupMember |
| 8089 List<InterfaceType> mixins = classElt.mixins; | 8089 List<InterfaceType> mixins = classElt.mixins; |
| 8090 for (int i = mixins.length - 1; i >= 0; i--) { | 8090 for (int i = mixins.length - 1; i >= 0; i--) { |
| 8091 ClassElement mixinElement = mixins[i].element; | 8091 ClassElement mixinElement = mixins[i].element; |
| 8092 if (mixinElement != null) { | 8092 if (mixinElement != null) { |
| 8093 ExecutableElement elt = lookupMemberInClass(mixinElement, memberName); | 8093 ExecutableElement elt = _lookupMemberInClass(mixinElement, memberName); |
| 8094 if (elt != null) { | 8094 if (elt != null) { |
| 8095 // this is equivalent (but faster than) calling this method recursivel
y | 8095 // this is equivalent (but faster than) calling this method recursivel
y |
| 8096 // (return computeInheritancePath(chain, mixins[i], memberName);) | 8096 // (return computeInheritancePath(chain, mixins[i], memberName);) |
| 8097 chain.add(mixins[i]); | 8097 chain.add(mixins[i]); |
| 8098 return; | 8098 return; |
| 8099 } | 8099 } |
| 8100 } | 8100 } |
| 8101 } | 8101 } |
| 8102 // Superclass | 8102 // Superclass |
| 8103 ClassElement superclassElt = supertype.element; | 8103 ClassElement superclassElt = supertype.element; |
| 8104 if (lookupMember(superclassElt, memberName) != null) { | 8104 if (lookupMember(superclassElt, memberName) != null) { |
| 8105 computeInheritancePath(chain, supertype, memberName); | 8105 _computeInheritancePath(chain, supertype, memberName); |
| 8106 return; | 8106 return; |
| 8107 } | 8107 } |
| 8108 // Interfaces | 8108 // Interfaces |
| 8109 List<InterfaceType> interfaces = classElt.interfaces; | 8109 List<InterfaceType> interfaces = classElt.interfaces; |
| 8110 for (InterfaceType interfaceType in interfaces) { | 8110 for (InterfaceType interfaceType in interfaces) { |
| 8111 ClassElement interfaceElement = interfaceType.element; | 8111 ClassElement interfaceElement = interfaceType.element; |
| 8112 if (interfaceElement != null && lookupMember(interfaceElement, memberName)
!= null) { | 8112 if (interfaceElement != null && lookupMember(interfaceElement, memberName)
!= null) { |
| 8113 computeInheritancePath(chain, interfaceType, memberName); | 8113 _computeInheritancePath(chain, interfaceType, memberName); |
| 8114 return; | 8114 return; |
| 8115 } | 8115 } |
| 8116 } | 8116 } |
| 8117 } | 8117 } |
| 8118 | 8118 |
| 8119 /** | 8119 /** |
| 8120 * Compute and return a mapping between the set of all string names of the mem
bers inherited from | 8120 * Compute and return a mapping between the set of all string names of the mem
bers inherited from |
| 8121 * the passed [ClassElement] interface hierarchy, and the associated | 8121 * the passed [ClassElement] interface hierarchy, and the associated |
| 8122 * [ExecutableElement]. | 8122 * [ExecutableElement]. |
| 8123 * | 8123 * |
| 8124 * @param classElt the class element to query | 8124 * @param classElt the class element to query |
| 8125 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls | 8125 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls |
| 8126 * itself recursively | 8126 * itself recursively |
| 8127 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 8127 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 8128 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement] | 8128 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement] |
| 8129 */ | 8129 */ |
| 8130 MemberMap computeInterfaceLookupMap(ClassElement classElt, Set<ClassElement> v
isitedInterfaces) { | 8130 MemberMap _computeInterfaceLookupMap(ClassElement classElt, Set<ClassElement>
visitedInterfaces) { |
| 8131 MemberMap resultMap = _interfaceLookup[classElt]; | 8131 MemberMap resultMap = _interfaceLookup[classElt]; |
| 8132 if (resultMap != null) { | 8132 if (resultMap != null) { |
| 8133 return resultMap; | 8133 return resultMap; |
| 8134 } else { | 8134 } else { |
| 8135 resultMap = new MemberMap(); | 8135 resultMap = new MemberMap(); |
| 8136 } | 8136 } |
| 8137 InterfaceType supertype = classElt.supertype; | 8137 InterfaceType supertype = classElt.supertype; |
| 8138 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; | 8138 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; |
| 8139 List<InterfaceType> mixins = classElt.mixins; | 8139 List<InterfaceType> mixins = classElt.mixins; |
| 8140 List<InterfaceType> interfaces = classElt.interfaces; | 8140 List<InterfaceType> interfaces = classElt.interfaces; |
| 8141 // Recursively collect the list of mappings from all of the interface types | 8141 // Recursively collect the list of mappings from all of the interface types |
| 8142 List<MemberMap> lookupMaps = new List<MemberMap>(); | 8142 List<MemberMap> lookupMaps = new List<MemberMap>(); |
| 8143 // | 8143 // |
| 8144 // Superclass element | 8144 // Superclass element |
| 8145 // | 8145 // |
| 8146 if (superclassElement != null) { | 8146 if (superclassElement != null) { |
| 8147 if (!visitedInterfaces.contains(superclassElement)) { | 8147 if (!visitedInterfaces.contains(superclassElement)) { |
| 8148 try { | 8148 try { |
| 8149 visitedInterfaces.add(superclassElement); | 8149 visitedInterfaces.add(superclassElement); |
| 8150 // | 8150 // |
| 8151 // Recursively compute the map for the super type. | 8151 // Recursively compute the map for the super type. |
| 8152 // | 8152 // |
| 8153 MemberMap map = computeInterfaceLookupMap(superclassElement, visitedIn
terfaces); | 8153 MemberMap map = _computeInterfaceLookupMap(superclassElement, visitedI
nterfaces); |
| 8154 map = new MemberMap.con2(map); | 8154 map = new MemberMap.con2(map); |
| 8155 // | 8155 // |
| 8156 // Substitute the super type down the hierarchy. | 8156 // Substitute the super type down the hierarchy. |
| 8157 // | 8157 // |
| 8158 substituteTypeParametersDownHierarchy(supertype, map); | 8158 _substituteTypeParametersDownHierarchy(supertype, map); |
| 8159 // | 8159 // |
| 8160 // Add any members from the super type into the map as well. | 8160 // Add any members from the super type into the map as well. |
| 8161 // | 8161 // |
| 8162 recordMapWithClassMembers(map, supertype, true); | 8162 _recordMapWithClassMembers(map, supertype, true); |
| 8163 lookupMaps.add(map); | 8163 lookupMaps.add(map); |
| 8164 } finally { | 8164 } finally { |
| 8165 visitedInterfaces.remove(superclassElement); | 8165 visitedInterfaces.remove(superclassElement); |
| 8166 } | 8166 } |
| 8167 } else { | 8167 } else { |
| 8168 MemberMap map = _interfaceLookup[classElt]; | 8168 MemberMap map = _interfaceLookup[classElt]; |
| 8169 if (map != null) { | 8169 if (map != null) { |
| 8170 lookupMaps.add(map); | 8170 lookupMaps.add(map); |
| 8171 } else { | 8171 } else { |
| 8172 _interfaceLookup[superclassElement] = resultMap; | 8172 _interfaceLookup[superclassElement] = resultMap; |
| 8173 return resultMap; | 8173 return resultMap; |
| 8174 } | 8174 } |
| 8175 } | 8175 } |
| 8176 } | 8176 } |
| 8177 // | 8177 // |
| 8178 // Mixin elements | 8178 // Mixin elements |
| 8179 // | 8179 // |
| 8180 for (int i = mixins.length - 1; i >= 0; i--) { | 8180 for (int i = mixins.length - 1; i >= 0; i--) { |
| 8181 InterfaceType mixinType = mixins[i]; | 8181 InterfaceType mixinType = mixins[i]; |
| 8182 ClassElement mixinElement = mixinType.element; | 8182 ClassElement mixinElement = mixinType.element; |
| 8183 if (mixinElement != null) { | 8183 if (mixinElement != null) { |
| 8184 if (!visitedInterfaces.contains(mixinElement)) { | 8184 if (!visitedInterfaces.contains(mixinElement)) { |
| 8185 try { | 8185 try { |
| 8186 visitedInterfaces.add(mixinElement); | 8186 visitedInterfaces.add(mixinElement); |
| 8187 // | 8187 // |
| 8188 // Recursively compute the map for the mixin. | 8188 // Recursively compute the map for the mixin. |
| 8189 // | 8189 // |
| 8190 MemberMap map = computeInterfaceLookupMap(mixinElement, visitedInter
faces); | 8190 MemberMap map = _computeInterfaceLookupMap(mixinElement, visitedInte
rfaces); |
| 8191 map = new MemberMap.con2(map); | 8191 map = new MemberMap.con2(map); |
| 8192 // | 8192 // |
| 8193 // Substitute the mixin type down the hierarchy. | 8193 // Substitute the mixin type down the hierarchy. |
| 8194 // | 8194 // |
| 8195 substituteTypeParametersDownHierarchy(mixinType, map); | 8195 _substituteTypeParametersDownHierarchy(mixinType, map); |
| 8196 // | 8196 // |
| 8197 // Add any members from the mixin type into the map as well. | 8197 // Add any members from the mixin type into the map as well. |
| 8198 // | 8198 // |
| 8199 recordMapWithClassMembers(map, mixinType, true); | 8199 _recordMapWithClassMembers(map, mixinType, true); |
| 8200 lookupMaps.add(map); | 8200 lookupMaps.add(map); |
| 8201 } finally { | 8201 } finally { |
| 8202 visitedInterfaces.remove(mixinElement); | 8202 visitedInterfaces.remove(mixinElement); |
| 8203 } | 8203 } |
| 8204 } else { | 8204 } else { |
| 8205 MemberMap map = _interfaceLookup[classElt]; | 8205 MemberMap map = _interfaceLookup[classElt]; |
| 8206 if (map != null) { | 8206 if (map != null) { |
| 8207 lookupMaps.add(map); | 8207 lookupMaps.add(map); |
| 8208 } else { | 8208 } else { |
| 8209 _interfaceLookup[mixinElement] = resultMap; | 8209 _interfaceLookup[mixinElement] = resultMap; |
| 8210 return resultMap; | 8210 return resultMap; |
| 8211 } | 8211 } |
| 8212 } | 8212 } |
| 8213 } | 8213 } |
| 8214 } | 8214 } |
| 8215 // | 8215 // |
| 8216 // Interface elements | 8216 // Interface elements |
| 8217 // | 8217 // |
| 8218 for (InterfaceType interfaceType in interfaces) { | 8218 for (InterfaceType interfaceType in interfaces) { |
| 8219 ClassElement interfaceElement = interfaceType.element; | 8219 ClassElement interfaceElement = interfaceType.element; |
| 8220 if (interfaceElement != null) { | 8220 if (interfaceElement != null) { |
| 8221 if (!visitedInterfaces.contains(interfaceElement)) { | 8221 if (!visitedInterfaces.contains(interfaceElement)) { |
| 8222 try { | 8222 try { |
| 8223 visitedInterfaces.add(interfaceElement); | 8223 visitedInterfaces.add(interfaceElement); |
| 8224 // | 8224 // |
| 8225 // Recursively compute the map for the interfaces. | 8225 // Recursively compute the map for the interfaces. |
| 8226 // | 8226 // |
| 8227 MemberMap map = computeInterfaceLookupMap(interfaceElement, visitedI
nterfaces); | 8227 MemberMap map = _computeInterfaceLookupMap(interfaceElement, visited
Interfaces); |
| 8228 map = new MemberMap.con2(map); | 8228 map = new MemberMap.con2(map); |
| 8229 // | 8229 // |
| 8230 // Substitute the supertypes down the hierarchy | 8230 // Substitute the supertypes down the hierarchy |
| 8231 // | 8231 // |
| 8232 substituteTypeParametersDownHierarchy(interfaceType, map); | 8232 _substituteTypeParametersDownHierarchy(interfaceType, map); |
| 8233 // | 8233 // |
| 8234 // And add any members from the interface into the map as well. | 8234 // And add any members from the interface into the map as well. |
| 8235 // | 8235 // |
| 8236 recordMapWithClassMembers(map, interfaceType, true); | 8236 _recordMapWithClassMembers(map, interfaceType, true); |
| 8237 lookupMaps.add(map); | 8237 lookupMaps.add(map); |
| 8238 } finally { | 8238 } finally { |
| 8239 visitedInterfaces.remove(interfaceElement); | 8239 visitedInterfaces.remove(interfaceElement); |
| 8240 } | 8240 } |
| 8241 } else { | 8241 } else { |
| 8242 MemberMap map = _interfaceLookup[classElt]; | 8242 MemberMap map = _interfaceLookup[classElt]; |
| 8243 if (map != null) { | 8243 if (map != null) { |
| 8244 lookupMaps.add(map); | 8244 lookupMaps.add(map); |
| 8245 } else { | 8245 } else { |
| 8246 _interfaceLookup[interfaceElement] = resultMap; | 8246 _interfaceLookup[interfaceElement] = resultMap; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8379 // | 8379 // |
| 8380 resultMap.put(key, elements[subtypesOfAllOtherTypesIndexes[0]]); | 8380 resultMap.put(key, elements[subtypesOfAllOtherTypesIndexes[0]]); |
| 8381 } else { | 8381 } else { |
| 8382 if (subtypesOfAllOtherTypesIndexes.isEmpty) { | 8382 if (subtypesOfAllOtherTypesIndexes.isEmpty) { |
| 8383 // | 8383 // |
| 8384 // Example: class A inherited only 2 method named 'm'. One has the
function type | 8384 // Example: class A inherited only 2 method named 'm'. One has the
function type |
| 8385 // '() -> int' and one has the function type '() -> String'. Since
neither is a subtype | 8385 // '() -> int' and one has the function type '() -> String'. Since
neither is a subtype |
| 8386 // of the other, we create a warning, and have this class inherit
nothing. | 8386 // of the other, we create a warning, and have this class inherit
nothing. |
| 8387 // | 8387 // |
| 8388 String firstTwoFuntionTypesStr = "${executableElementTypes[0].toSt
ring()}, ${executableElementTypes[1].toString()}"; | 8388 String firstTwoFuntionTypesStr = "${executableElementTypes[0].toSt
ring()}, ${executableElementTypes[1].toString()}"; |
| 8389 reportError(classElt, classElt.nameOffset, classElt.displayName.le
ngth, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFunti
onTypesStr]); | 8389 _reportError(classElt, classElt.nameOffset, classElt.displayName.l
ength, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFunt
ionTypesStr]); |
| 8390 } else { | 8390 } else { |
| 8391 // | 8391 // |
| 8392 // Example: class A inherits 2 methods named 'm'. One has the func
tion type | 8392 // Example: class A inherits 2 methods named 'm'. One has the func
tion type |
| 8393 // '(int) -> dynamic' and one has the function type '(num) -> dyna
mic'. Since they are | 8393 // '(int) -> dynamic' and one has the function type '(num) -> dyna
mic'. Since they are |
| 8394 // both a subtype of the other, a synthetic function '(dynamic) ->
dynamic' is | 8394 // both a subtype of the other, a synthetic function '(dynamic) ->
dynamic' is |
| 8395 // inherited. | 8395 // inherited. |
| 8396 // Tests: test_getMapOfMembersInheritedFromInterfaces_union_multip
leSubtypes_* | 8396 // Tests: test_getMapOfMembersInheritedFromInterfaces_union_multip
leSubtypes_* |
| 8397 // | 8397 // |
| 8398 List<ExecutableElement> elementArrayToMerge = new List<ExecutableE
lement>(subtypesOfAllOtherTypesIndexes.length); | 8398 List<ExecutableElement> elementArrayToMerge = new List<ExecutableE
lement>(subtypesOfAllOtherTypesIndexes.length); |
| 8399 for (int i = 0; i < elementArrayToMerge.length; i++) { | 8399 for (int i = 0; i < elementArrayToMerge.length; i++) { |
| 8400 elementArrayToMerge[i] = elements[subtypesOfAllOtherTypesIndexes
[i]]; | 8400 elementArrayToMerge[i] = elements[subtypesOfAllOtherTypesIndexes
[i]]; |
| 8401 } | 8401 } |
| 8402 ExecutableElement mergedExecutableElement = computeMergedExecutabl
eElement(elementArrayToMerge); | 8402 ExecutableElement mergedExecutableElement = _computeMergedExecutab
leElement(elementArrayToMerge); |
| 8403 if (mergedExecutableElement != null) { | 8403 if (mergedExecutableElement != null) { |
| 8404 resultMap.put(key, mergedExecutableElement); | 8404 resultMap.put(key, mergedExecutableElement); |
| 8405 } | 8405 } |
| 8406 } | 8406 } |
| 8407 } | 8407 } |
| 8408 } else { | 8408 } else { |
| 8409 reportError(classElt, classElt.nameOffset, classElt.displayName.length
, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]); | 8409 _reportError(classElt, classElt.nameOffset, classElt.displayName.lengt
h, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]); |
| 8410 } | 8410 } |
| 8411 } | 8411 } |
| 8412 } | 8412 } |
| 8413 _interfaceLookup[classElt] = resultMap; | 8413 _interfaceLookup[classElt] = resultMap; |
| 8414 return resultMap; | 8414 return resultMap; |
| 8415 } | 8415 } |
| 8416 | 8416 |
| 8417 /** | 8417 /** |
| 8418 * Given some [ClassElement], this method finds and returns the [ExecutableEle
ment] of | 8418 * Given some [ClassElement], this method finds and returns the [ExecutableEle
ment] of |
| 8419 * the passed name in the class element. Static members, members in super type
s and members not | 8419 * the passed name in the class element. Static members, members in super type
s and members not |
| 8420 * accessible from the current library are not considered. | 8420 * accessible from the current library are not considered. |
| 8421 * | 8421 * |
| 8422 * @param classElt the class element to query | 8422 * @param classElt the class element to query |
| 8423 * @param memberName the name of the member to lookup in the class | 8423 * @param memberName the name of the member to lookup in the class |
| 8424 * @return the found [ExecutableElement], or `null` if no such member was foun
d | 8424 * @return the found [ExecutableElement], or `null` if no such member was foun
d |
| 8425 */ | 8425 */ |
| 8426 ExecutableElement lookupMemberInClass(ClassElement classElt, String memberName
) { | 8426 ExecutableElement _lookupMemberInClass(ClassElement classElt, String memberNam
e) { |
| 8427 List<MethodElement> methods = classElt.methods; | 8427 List<MethodElement> methods = classElt.methods; |
| 8428 for (MethodElement method in methods) { | 8428 for (MethodElement method in methods) { |
| 8429 if (memberName == method.name && method.isAccessibleIn(_library) && !metho
d.isStatic) { | 8429 if (memberName == method.name && method.isAccessibleIn(_library) && !metho
d.isStatic) { |
| 8430 return method; | 8430 return method; |
| 8431 } | 8431 } |
| 8432 } | 8432 } |
| 8433 List<PropertyAccessorElement> accessors = classElt.accessors; | 8433 List<PropertyAccessorElement> accessors = classElt.accessors; |
| 8434 for (PropertyAccessorElement accessor in accessors) { | 8434 for (PropertyAccessorElement accessor in accessors) { |
| 8435 if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !a
ccessor.isStatic) { | 8435 if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !a
ccessor.isStatic) { |
| 8436 return accessor; | 8436 return accessor; |
| 8437 } | 8437 } |
| 8438 } | 8438 } |
| 8439 return null; | 8439 return null; |
| 8440 } | 8440 } |
| 8441 | 8441 |
| 8442 /** | 8442 /** |
| 8443 * Record the passed map with the set of all members (methods, getters and set
ters) in the type | 8443 * Record the passed map with the set of all members (methods, getters and set
ters) in the type |
| 8444 * into the passed map. | 8444 * into the passed map. |
| 8445 * | 8445 * |
| 8446 * @param map some non-`null` map to put the methods and accessors from the pa
ssed | 8446 * @param map some non-`null` map to put the methods and accessors from the pa
ssed |
| 8447 * [ClassElement] into | 8447 * [ClassElement] into |
| 8448 * @param type the type that will be recorded into the passed map | 8448 * @param type the type that will be recorded into the passed map |
| 8449 * @param doIncludeAbstract `true` if abstract members will be put into the ma
p | 8449 * @param doIncludeAbstract `true` if abstract members will be put into the ma
p |
| 8450 */ | 8450 */ |
| 8451 void recordMapWithClassMembers(MemberMap map, InterfaceType type, bool doInclu
deAbstract) { | 8451 void _recordMapWithClassMembers(MemberMap map, InterfaceType type, bool doIncl
udeAbstract) { |
| 8452 List<MethodElement> methods = type.methods; | 8452 List<MethodElement> methods = type.methods; |
| 8453 for (MethodElement method in methods) { | 8453 for (MethodElement method in methods) { |
| 8454 if (method.isAccessibleIn(_library) && !method.isStatic && (doIncludeAbstr
act || !method.isAbstract)) { | 8454 if (method.isAccessibleIn(_library) && !method.isStatic && (doIncludeAbstr
act || !method.isAbstract)) { |
| 8455 map.put(method.name, method); | 8455 map.put(method.name, method); |
| 8456 } | 8456 } |
| 8457 } | 8457 } |
| 8458 List<PropertyAccessorElement> accessors = type.accessors; | 8458 List<PropertyAccessorElement> accessors = type.accessors; |
| 8459 for (PropertyAccessorElement accessor in accessors) { | 8459 for (PropertyAccessorElement accessor in accessors) { |
| 8460 if (accessor.isAccessibleIn(_library) && !accessor.isStatic && (doIncludeA
bstract || !accessor.isAbstract)) { | 8460 if (accessor.isAccessibleIn(_library) && !accessor.isStatic && (doIncludeA
bstract || !accessor.isAbstract)) { |
| 8461 map.put(accessor.name, accessor); | 8461 map.put(accessor.name, accessor); |
| 8462 } | 8462 } |
| 8463 } | 8463 } |
| 8464 } | 8464 } |
| 8465 | 8465 |
| 8466 /** | 8466 /** |
| 8467 * This method is used to report errors on when they are found computing inher
itance information. | 8467 * This method is used to report errors on when they are found computing inher
itance information. |
| 8468 * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where thes
e generated | 8468 * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where thes
e generated |
| 8469 * error codes are reported back into the analysis engine. | 8469 * error codes are reported back into the analysis engine. |
| 8470 * | 8470 * |
| 8471 * @param classElt the location of the source for which the exception occurred | 8471 * @param classElt the location of the source for which the exception occurred |
| 8472 * @param offset the offset of the location of the error | 8472 * @param offset the offset of the location of the error |
| 8473 * @param length the length of the location of the error | 8473 * @param length the length of the location of the error |
| 8474 * @param errorCode the error code to be associated with this error | 8474 * @param errorCode the error code to be associated with this error |
| 8475 * @param arguments the arguments used to build the error message | 8475 * @param arguments the arguments used to build the error message |
| 8476 */ | 8476 */ |
| 8477 void reportError(ClassElement classElt, int offset, int length, ErrorCode erro
rCode, List<Object> arguments) { | 8477 void _reportError(ClassElement classElt, int offset, int length, ErrorCode err
orCode, List<Object> arguments) { |
| 8478 Set<AnalysisError> errorSet = _errorsInClassElement[classElt]; | 8478 Set<AnalysisError> errorSet = _errorsInClassElement[classElt]; |
| 8479 if (errorSet == null) { | 8479 if (errorSet == null) { |
| 8480 errorSet = new Set<AnalysisError>(); | 8480 errorSet = new Set<AnalysisError>(); |
| 8481 _errorsInClassElement[classElt] = errorSet; | 8481 _errorsInClassElement[classElt] = errorSet; |
| 8482 } | 8482 } |
| 8483 errorSet.add(new AnalysisError.con2(classElt.source, offset, length, errorCo
de, arguments)); | 8483 errorSet.add(new AnalysisError.con2(classElt.source, offset, length, errorCo
de, arguments)); |
| 8484 } | 8484 } |
| 8485 | 8485 |
| 8486 /** | 8486 /** |
| 8487 * Loop through all of the members in some [MemberMap], performing type parame
ter | 8487 * Loop through all of the members in some [MemberMap], performing type parame
ter |
| 8488 * substitutions using a passed supertype. | 8488 * substitutions using a passed supertype. |
| 8489 * | 8489 * |
| 8490 * @param superType the supertype to substitute into the members of the [Membe
rMap] | 8490 * @param superType the supertype to substitute into the members of the [Membe
rMap] |
| 8491 * @param map the MemberMap to perform the substitutions on | 8491 * @param map the MemberMap to perform the substitutions on |
| 8492 */ | 8492 */ |
| 8493 void substituteTypeParametersDownHierarchy(InterfaceType superType, MemberMap
map) { | 8493 void _substituteTypeParametersDownHierarchy(InterfaceType superType, MemberMap
map) { |
| 8494 for (int i = 0; i < map.size; i++) { | 8494 for (int i = 0; i < map.size; i++) { |
| 8495 ExecutableElement executableElement = map.getValue(i); | 8495 ExecutableElement executableElement = map.getValue(i); |
| 8496 if (executableElement is MethodMember) { | 8496 if (executableElement is MethodMember) { |
| 8497 executableElement = MethodMember.from(executableElement as MethodMember,
superType); | 8497 executableElement = MethodMember.from(executableElement as MethodMember,
superType); |
| 8498 map.setValue(i, executableElement); | 8498 map.setValue(i, executableElement); |
| 8499 } else if (executableElement is PropertyAccessorMember) { | 8499 } else if (executableElement is PropertyAccessorMember) { |
| 8500 executableElement = PropertyAccessorMember.from(executableElement as Pro
pertyAccessorMember, superType); | 8500 executableElement = PropertyAccessorMember.from(executableElement as Pro
pertyAccessorMember, superType); |
| 8501 map.setValue(i, executableElement); | 8501 map.setValue(i, executableElement); |
| 8502 } | 8502 } |
| 8503 } | 8503 } |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8848 * @throws AnalysisException if the analysis could not be performed | 8848 * @throws AnalysisException if the analysis could not be performed |
| 8849 */ | 8849 */ |
| 8850 LibraryElementImpl buildLibrary(Library library) { | 8850 LibraryElementImpl buildLibrary(Library library) { |
| 8851 CompilationUnitBuilder builder = new CompilationUnitBuilder(); | 8851 CompilationUnitBuilder builder = new CompilationUnitBuilder(); |
| 8852 Source librarySource = library.librarySource; | 8852 Source librarySource = library.librarySource; |
| 8853 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; | 8853 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; |
| 8854 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom
pilationUnit(librarySource, definingCompilationUnit); | 8854 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom
pilationUnit(librarySource, definingCompilationUnit); |
| 8855 NodeList<Directive> directives = definingCompilationUnit.directives; | 8855 NodeList<Directive> directives = definingCompilationUnit.directives; |
| 8856 LibraryIdentifier libraryNameNode = null; | 8856 LibraryIdentifier libraryNameNode = null; |
| 8857 bool hasPartDirective = false; | 8857 bool hasPartDirective = false; |
| 8858 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement); | 8858 FunctionElement entryPoint = _findEntryPoint(definingCompilationUnitElement)
; |
| 8859 List<Directive> directivesToResolve = new List<Directive>(); | 8859 List<Directive> directivesToResolve = new List<Directive>(); |
| 8860 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat
ionUnitElementImpl>(); | 8860 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat
ionUnitElementImpl>(); |
| 8861 for (Directive directive in directives) { | 8861 for (Directive directive in directives) { |
| 8862 // | 8862 // |
| 8863 // We do not build the elements representing the import and export directi
ves at this point. | 8863 // We do not build the elements representing the import and export directi
ves at this point. |
| 8864 // That is not done until we get to LibraryResolver.buildDirectiveModels()
because we need the | 8864 // That is not done until we get to LibraryResolver.buildDirectiveModels()
because we need the |
| 8865 // LibraryElements for the referenced libraries, which might not exist at
this point (due to | 8865 // LibraryElements for the referenced libraries, which might not exist at
this point (due to |
| 8866 // the possibility of circular references). | 8866 // the possibility of circular references). |
| 8867 // | 8867 // |
| 8868 if (directive is LibraryDirective) { | 8868 if (directive is LibraryDirective) { |
| 8869 if (libraryNameNode == null) { | 8869 if (libraryNameNode == null) { |
| 8870 libraryNameNode = directive.name; | 8870 libraryNameNode = directive.name; |
| 8871 directivesToResolve.add(directive); | 8871 directivesToResolve.add(directive); |
| 8872 } | 8872 } |
| 8873 } else if (directive is PartDirective) { | 8873 } else if (directive is PartDirective) { |
| 8874 PartDirective partDirective = directive; | 8874 PartDirective partDirective = directive; |
| 8875 StringLiteral partUri = partDirective.uri; | 8875 StringLiteral partUri = partDirective.uri; |
| 8876 Source partSource = library.getSource(partDirective); | 8876 Source partSource = library.getSource(partDirective); |
| 8877 if (_analysisContext.exists(partSource)) { | 8877 if (_analysisContext.exists(partSource)) { |
| 8878 hasPartDirective = true; | 8878 hasPartDirective = true; |
| 8879 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou
rce, library.getAST(partSource)); | 8879 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou
rce, library.getAST(partSource)); |
| 8880 part.uri = library.getUri(partDirective); | 8880 part.uri = library.getUri(partDirective); |
| 8881 // | 8881 // |
| 8882 // Validate that the part contains a part-of directive with the same n
ame as the library. | 8882 // Validate that the part contains a part-of directive with the same n
ame as the library. |
| 8883 // | 8883 // |
| 8884 String partLibraryName = getPartLibraryName(library, partSource, direc
tivesToResolve); | 8884 String partLibraryName = _getPartLibraryName(library, partSource, dire
ctivesToResolve); |
| 8885 if (partLibraryName == null) { | 8885 if (partLibraryName == null) { |
| 8886 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSourc
e()])); | 8886 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSourc
e()])); |
| 8887 } else if (libraryNameNode == null) { | 8887 } else if (libraryNameNode == null) { |
| 8888 } else if (libraryNameNode.name != partLibraryName) { | 8888 } else if (libraryNameNode.name != partLibraryName) { |
| 8889 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryNa
meNode.name, partLibraryName])); | 8889 _errorListener.onError(new AnalysisError.con2(librarySource, partUri
.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryNa
meNode.name, partLibraryName])); |
| 8890 } | 8890 } |
| 8891 if (entryPoint == null) { | 8891 if (entryPoint == null) { |
| 8892 entryPoint = findEntryPoint(part); | 8892 entryPoint = _findEntryPoint(part); |
| 8893 } | 8893 } |
| 8894 directive.element = part; | 8894 directive.element = part; |
| 8895 sourcedCompilationUnits.add(part); | 8895 sourcedCompilationUnits.add(part); |
| 8896 } | 8896 } |
| 8897 } | 8897 } |
| 8898 } | 8898 } |
| 8899 if (hasPartDirective && libraryNameNode == null) { | 8899 if (hasPartDirective && libraryNameNode == null) { |
| 8900 _errorListener.onError(new AnalysisError.con1(librarySource, ResolverError
Code.MISSING_LIBRARY_DIRECTIVE_WITH_PART, [])); | 8900 _errorListener.onError(new AnalysisError.con1(librarySource, ResolverError
Code.MISSING_LIBRARY_DIRECTIVE_WITH_PART, [])); |
| 8901 } | 8901 } |
| 8902 // | 8902 // |
| 8903 // Create and populate the library element. | 8903 // Create and populate the library element. |
| 8904 // | 8904 // |
| 8905 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext,
libraryNameNode); | 8905 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext,
libraryNameNode); |
| 8906 libraryElement.definingCompilationUnit = definingCompilationUnitElement; | 8906 libraryElement.definingCompilationUnit = definingCompilationUnitElement; |
| 8907 if (entryPoint != null) { | 8907 if (entryPoint != null) { |
| 8908 libraryElement.entryPoint = entryPoint; | 8908 libraryElement.entryPoint = entryPoint; |
| 8909 } | 8909 } |
| 8910 int sourcedUnitCount = sourcedCompilationUnits.length; | 8910 int sourcedUnitCount = sourcedCompilationUnits.length; |
| 8911 libraryElement.parts = new List.from(sourcedCompilationUnits); | 8911 libraryElement.parts = new List.from(sourcedCompilationUnits); |
| 8912 for (Directive directive in directivesToResolve) { | 8912 for (Directive directive in directivesToResolve) { |
| 8913 directive.element = libraryElement; | 8913 directive.element = libraryElement; |
| 8914 } | 8914 } |
| 8915 library.libraryElement = libraryElement; | 8915 library.libraryElement = libraryElement; |
| 8916 if (sourcedUnitCount > 0) { | 8916 if (sourcedUnitCount > 0) { |
| 8917 patchTopLevelAccessors(libraryElement); | 8917 _patchTopLevelAccessors(libraryElement); |
| 8918 } | 8918 } |
| 8919 return libraryElement; | 8919 return libraryElement; |
| 8920 } | 8920 } |
| 8921 | 8921 |
| 8922 /** | 8922 /** |
| 8923 * Add all of the non-synthetic getters and setters defined in the given compi
lation unit that | 8923 * Add all of the non-synthetic getters and setters defined in the given compi
lation unit that |
| 8924 * have no corresponding accessor to one of the given collections. | 8924 * have no corresponding accessor to one of the given collections. |
| 8925 * | 8925 * |
| 8926 * @param getters the map to which getters are to be added | 8926 * @param getters the map to which getters are to be added |
| 8927 * @param setters the list to which setters are to be added | 8927 * @param setters the list to which setters are to be added |
| 8928 * @param unit the compilation unit defining the accessors that are potentiall
y being added | 8928 * @param unit the compilation unit defining the accessors that are potentiall
y being added |
| 8929 */ | 8929 */ |
| 8930 void collectAccessors(Map<String, PropertyAccessorElement> getters, List<Prope
rtyAccessorElement> setters, CompilationUnitElement unit) { | 8930 void _collectAccessors(Map<String, PropertyAccessorElement> getters, List<Prop
ertyAccessorElement> setters, CompilationUnitElement unit) { |
| 8931 for (PropertyAccessorElement accessor in unit.accessors) { | 8931 for (PropertyAccessorElement accessor in unit.accessors) { |
| 8932 if (accessor.isGetter) { | 8932 if (accessor.isGetter) { |
| 8933 if (!accessor.isSynthetic && accessor.correspondingSetter == null) { | 8933 if (!accessor.isSynthetic && accessor.correspondingSetter == null) { |
| 8934 getters[accessor.displayName] = accessor; | 8934 getters[accessor.displayName] = accessor; |
| 8935 } | 8935 } |
| 8936 } else { | 8936 } else { |
| 8937 if (!accessor.isSynthetic && accessor.correspondingGetter == null) { | 8937 if (!accessor.isSynthetic && accessor.correspondingGetter == null) { |
| 8938 setters.add(accessor); | 8938 setters.add(accessor); |
| 8939 } | 8939 } |
| 8940 } | 8940 } |
| 8941 } | 8941 } |
| 8942 } | 8942 } |
| 8943 | 8943 |
| 8944 /** | 8944 /** |
| 8945 * Search the top-level functions defined in the given compilation unit for th
e entry point. | 8945 * Search the top-level functions defined in the given compilation unit for th
e entry point. |
| 8946 * | 8946 * |
| 8947 * @param element the compilation unit to be searched | 8947 * @param element the compilation unit to be searched |
| 8948 * @return the entry point that was found, or `null` if the compilation unit d
oes not define | 8948 * @return the entry point that was found, or `null` if the compilation unit d
oes not define |
| 8949 * an entry point | 8949 * an entry point |
| 8950 */ | 8950 */ |
| 8951 FunctionElement findEntryPoint(CompilationUnitElementImpl element) { | 8951 FunctionElement _findEntryPoint(CompilationUnitElementImpl element) { |
| 8952 for (FunctionElement function in element.functions) { | 8952 for (FunctionElement function in element.functions) { |
| 8953 if (function.name == ENTRY_POINT_NAME) { | 8953 if (function.name == ENTRY_POINT_NAME) { |
| 8954 return function; | 8954 return function; |
| 8955 } | 8955 } |
| 8956 } | 8956 } |
| 8957 return null; | 8957 return null; |
| 8958 } | 8958 } |
| 8959 | 8959 |
| 8960 /** | 8960 /** |
| 8961 * Return the name of the library that the given part is declared to be a part
of, or `null` | 8961 * Return the name of the library that the given part is declared to be a part
of, or `null` |
| 8962 * if the part does not contain a part-of directive. | 8962 * if the part does not contain a part-of directive. |
| 8963 * | 8963 * |
| 8964 * @param library the library containing the part | 8964 * @param library the library containing the part |
| 8965 * @param partSource the source representing the part | 8965 * @param partSource the source representing the part |
| 8966 * @param directivesToResolve a list of directives that should be resolved to
the library being | 8966 * @param directivesToResolve a list of directives that should be resolved to
the library being |
| 8967 * built | 8967 * built |
| 8968 * @return the name of the library that the given part is declared to be a par
t of | 8968 * @return the name of the library that the given part is declared to be a par
t of |
| 8969 */ | 8969 */ |
| 8970 String getPartLibraryName(Library library, Source partSource, List<Directive>
directivesToResolve) { | 8970 String _getPartLibraryName(Library library, Source partSource, List<Directive>
directivesToResolve) { |
| 8971 try { | 8971 try { |
| 8972 CompilationUnit partUnit = library.getAST(partSource); | 8972 CompilationUnit partUnit = library.getAST(partSource); |
| 8973 for (Directive directive in partUnit.directives) { | 8973 for (Directive directive in partUnit.directives) { |
| 8974 if (directive is PartOfDirective) { | 8974 if (directive is PartOfDirective) { |
| 8975 directivesToResolve.add(directive); | 8975 directivesToResolve.add(directive); |
| 8976 LibraryIdentifier libraryName = directive.libraryName; | 8976 LibraryIdentifier libraryName = directive.libraryName; |
| 8977 if (libraryName != null) { | 8977 if (libraryName != null) { |
| 8978 return libraryName.name; | 8978 return libraryName.name; |
| 8979 } | 8979 } |
| 8980 } | 8980 } |
| 8981 } | 8981 } |
| 8982 } on AnalysisException catch (exception) { | 8982 } on AnalysisException catch (exception) { |
| 8983 } | 8983 } |
| 8984 return null; | 8984 return null; |
| 8985 } | 8985 } |
| 8986 | 8986 |
| 8987 /** | 8987 /** |
| 8988 * Look through all of the compilation units defined for the given library, lo
oking for getters | 8988 * Look through all of the compilation units defined for the given library, lo
oking for getters |
| 8989 * and setters that are defined in different compilation units but that have t
he same names. If | 8989 * and setters that are defined in different compilation units but that have t
he same names. If |
| 8990 * any are found, make sure that they have the same variable element. | 8990 * any are found, make sure that they have the same variable element. |
| 8991 * | 8991 * |
| 8992 * @param libraryElement the library defining the compilation units to be proc
essed | 8992 * @param libraryElement the library defining the compilation units to be proc
essed |
| 8993 */ | 8993 */ |
| 8994 void patchTopLevelAccessors(LibraryElementImpl libraryElement) { | 8994 void _patchTopLevelAccessors(LibraryElementImpl libraryElement) { |
| 8995 Map<String, PropertyAccessorElement> getters = new Map<String, PropertyAcces
sorElement>(); | 8995 Map<String, PropertyAccessorElement> getters = new Map<String, PropertyAcces
sorElement>(); |
| 8996 List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>(); | 8996 List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>(); |
| 8997 collectAccessors(getters, setters, libraryElement.definingCompilationUnit); | 8997 _collectAccessors(getters, setters, libraryElement.definingCompilationUnit); |
| 8998 for (CompilationUnitElement unit in libraryElement.parts) { | 8998 for (CompilationUnitElement unit in libraryElement.parts) { |
| 8999 collectAccessors(getters, setters, unit); | 8999 _collectAccessors(getters, setters, unit); |
| 9000 } | 9000 } |
| 9001 for (PropertyAccessorElement setter in setters) { | 9001 for (PropertyAccessorElement setter in setters) { |
| 9002 PropertyAccessorElement getter = getters[setter.displayName]; | 9002 PropertyAccessorElement getter = getters[setter.displayName]; |
| 9003 if (getter != null) { | 9003 if (getter != null) { |
| 9004 PropertyInducingElementImpl variable = getter.variable as PropertyInduci
ngElementImpl; | 9004 PropertyInducingElementImpl variable = getter.variable as PropertyInduci
ngElementImpl; |
| 9005 variable.setter = setter; | 9005 variable.setter = setter; |
| 9006 (setter as PropertyAccessorElementImpl).variable = variable; | 9006 (setter as PropertyAccessorElementImpl).variable = variable; |
| 9007 } | 9007 } |
| 9008 } | 9008 } |
| 9009 } | 9009 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9089 * @throws AnalysisException if the library could not be resolved for some rea
son | 9089 * @throws AnalysisException if the library could not be resolved for some rea
son |
| 9090 */ | 9090 */ |
| 9091 LibraryElement resolveEmbeddedLibrary(Source librarySource, int modificationSt
amp, CompilationUnit unit, bool fullAnalysis) { | 9091 LibraryElement resolveEmbeddedLibrary(Source librarySource, int modificationSt
amp, CompilationUnit unit, bool fullAnalysis) { |
| 9092 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi
ne.LibraryResolver.resolveEmbeddedLibrary"); | 9092 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi
ne.LibraryResolver.resolveEmbeddedLibrary"); |
| 9093 try { | 9093 try { |
| 9094 instrumentation.metric("fullAnalysis", fullAnalysis); | 9094 instrumentation.metric("fullAnalysis", fullAnalysis); |
| 9095 instrumentation.data3("fullName", librarySource.fullName); | 9095 instrumentation.data3("fullName", librarySource.fullName); |
| 9096 // | 9096 // |
| 9097 // Create the objects representing the library being resolved and the core
library. | 9097 // Create the objects representing the library being resolved and the core
library. |
| 9098 // | 9098 // |
| 9099 Library targetLibrary = createLibraryWithUnit(librarySource, modificationS
tamp, unit); | 9099 Library targetLibrary = _createLibraryWithUnit(librarySource, modification
Stamp, unit); |
| 9100 _coreLibrary = _libraryMap[_coreLibrarySource]; | 9100 _coreLibrary = _libraryMap[_coreLibrarySource]; |
| 9101 if (_coreLibrary == null) { | 9101 if (_coreLibrary == null) { |
| 9102 // This will be true unless the library being analyzed is the core libra
ry. | 9102 // This will be true unless the library being analyzed is the core libra
ry. |
| 9103 _coreLibrary = createLibrary(_coreLibrarySource); | 9103 _coreLibrary = createLibrary(_coreLibrarySource); |
| 9104 } | 9104 } |
| 9105 instrumentation.metric3("createLibrary", "complete"); | 9105 instrumentation.metric3("createLibrary", "complete"); |
| 9106 // | 9106 // |
| 9107 // Compute the set of libraries that need to be resolved together. | 9107 // Compute the set of libraries that need to be resolved together. |
| 9108 // | 9108 // |
| 9109 computeEmbeddedLibraryDependencies(targetLibrary, unit); | 9109 _computeEmbeddedLibraryDependencies(targetLibrary, unit); |
| 9110 _librariesInCycles = computeLibrariesInCycles(targetLibrary); | 9110 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); |
| 9111 // | 9111 // |
| 9112 // Build the element models representing the libraries being resolved. Thi
s is done in three | 9112 // Build the element models representing the libraries being resolved. Thi
s is done in three |
| 9113 // steps: | 9113 // steps: |
| 9114 // | 9114 // |
| 9115 // 1. Build the basic element models without making any connections betwee
n elements other than | 9115 // 1. Build the basic element models without making any connections betwee
n elements other than |
| 9116 // the basic parent/child relationships. This includes building the ele
ments representing the | 9116 // the basic parent/child relationships. This includes building the ele
ments representing the |
| 9117 // libraries. | 9117 // libraries. |
| 9118 // 2. Build the elements for the import and export directives. This requir
es that we have the | 9118 // 2. Build the elements for the import and export directives. This requir
es that we have the |
| 9119 // elements built for the referenced libraries, but because of the poss
ibility of circular | 9119 // elements built for the referenced libraries, but because of the poss
ibility of circular |
| 9120 // references needs to happen after all of the library elements have be
en created. | 9120 // references needs to happen after all of the library elements have be
en created. |
| 9121 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This | 9121 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This |
| 9122 // requires that we be able to compute the names visible in the librari
es being resolved, | 9122 // requires that we be able to compute the names visible in the librari
es being resolved, |
| 9123 // which in turn requires that we have resolved the import directives. | 9123 // which in turn requires that we have resolved the import directives. |
| 9124 // | 9124 // |
| 9125 buildElementModels(); | 9125 _buildElementModels(); |
| 9126 instrumentation.metric3("buildElementModels", "complete"); | 9126 instrumentation.metric3("buildElementModels", "complete"); |
| 9127 LibraryElement coreElement = _coreLibrary.libraryElement; | 9127 LibraryElement coreElement = _coreLibrary.libraryElement; |
| 9128 if (coreElement == null) { | 9128 if (coreElement == null) { |
| 9129 throw new AnalysisException.con1("Could not resolve dart:core"); | 9129 throw new AnalysisException.con1("Could not resolve dart:core"); |
| 9130 } | 9130 } |
| 9131 buildDirectiveModels(); | 9131 _buildDirectiveModels(); |
| 9132 instrumentation.metric3("buildDirectiveModels", "complete"); | 9132 instrumentation.metric3("buildDirectiveModels", "complete"); |
| 9133 _typeProvider = new TypeProviderImpl(coreElement); | 9133 _typeProvider = new TypeProviderImpl(coreElement); |
| 9134 buildTypeHierarchies(); | 9134 _buildTypeHierarchies(); |
| 9135 instrumentation.metric3("buildTypeHierarchies", "complete"); | 9135 instrumentation.metric3("buildTypeHierarchies", "complete"); |
| 9136 // | 9136 // |
| 9137 // Perform resolution and type analysis. | 9137 // Perform resolution and type analysis. |
| 9138 // | 9138 // |
| 9139 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we | 9139 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we |
| 9140 // want to only resolve the target library. The advantage to resolving eve
rything is that we | 9140 // want to only resolve the target library. The advantage to resolving eve
rything is that we |
| 9141 // have already done part of the work so we'll avoid duplicated effort. Th
e disadvantage of | 9141 // have already done part of the work so we'll avoid duplicated effort. Th
e disadvantage of |
| 9142 // resolving everything is that we might do extra work that we don't reall
y care about. Another | 9142 // resolving everything is that we might do extra work that we don't reall
y care about. Another |
| 9143 // possibility is to add a parameter to this method and punt the decision
to the clients. | 9143 // possibility is to add a parameter to this method and punt the decision
to the clients. |
| 9144 // | 9144 // |
| 9145 //if (analyzeAll) { | 9145 //if (analyzeAll) { |
| 9146 resolveReferencesAndTypes(); | 9146 _resolveReferencesAndTypes(); |
| 9147 instrumentation.metric3("resolveReferencesAndTypes", "complete"); | 9147 instrumentation.metric3("resolveReferencesAndTypes", "complete"); |
| 9148 //} else { | 9148 //} else { |
| 9149 // resolveReferencesAndTypes(targetLibrary); | 9149 // resolveReferencesAndTypes(targetLibrary); |
| 9150 //} | 9150 //} |
| 9151 performConstantEvaluation(); | 9151 _performConstantEvaluation(); |
| 9152 instrumentation.metric3("performConstantEvaluation", "complete"); | 9152 instrumentation.metric3("performConstantEvaluation", "complete"); |
| 9153 return targetLibrary.libraryElement; | 9153 return targetLibrary.libraryElement; |
| 9154 } finally { | 9154 } finally { |
| 9155 instrumentation.log(); | 9155 instrumentation.log(); |
| 9156 } | 9156 } |
| 9157 } | 9157 } |
| 9158 | 9158 |
| 9159 /** | 9159 /** |
| 9160 * Resolve the library specified by the given source in the given context. | 9160 * Resolve the library specified by the given source in the given context. |
| 9161 * | 9161 * |
| (...skipping 12 matching lines...) Expand all Loading... |
| 9174 try { | 9174 try { |
| 9175 instrumentation.metric("fullAnalysis", fullAnalysis); | 9175 instrumentation.metric("fullAnalysis", fullAnalysis); |
| 9176 instrumentation.data3("fullName", librarySource.fullName); | 9176 instrumentation.data3("fullName", librarySource.fullName); |
| 9177 // | 9177 // |
| 9178 // Create the objects representing the library being resolved and the core
library. | 9178 // Create the objects representing the library being resolved and the core
library. |
| 9179 // | 9179 // |
| 9180 Library targetLibrary = createLibrary(librarySource); | 9180 Library targetLibrary = createLibrary(librarySource); |
| 9181 _coreLibrary = _libraryMap[_coreLibrarySource]; | 9181 _coreLibrary = _libraryMap[_coreLibrarySource]; |
| 9182 if (_coreLibrary == null) { | 9182 if (_coreLibrary == null) { |
| 9183 // This will be true unless the library being analyzed is the core libra
ry. | 9183 // This will be true unless the library being analyzed is the core libra
ry. |
| 9184 _coreLibrary = createLibraryOrNull(_coreLibrarySource); | 9184 _coreLibrary = _createLibraryOrNull(_coreLibrarySource); |
| 9185 if (_coreLibrary == null) { | 9185 if (_coreLibrary == null) { |
| 9186 throw new AnalysisException.con1("Core library does not exist"); | 9186 throw new AnalysisException.con1("Core library does not exist"); |
| 9187 } | 9187 } |
| 9188 } | 9188 } |
| 9189 instrumentation.metric3("createLibrary", "complete"); | 9189 instrumentation.metric3("createLibrary", "complete"); |
| 9190 // | 9190 // |
| 9191 // Compute the set of libraries that need to be resolved together. | 9191 // Compute the set of libraries that need to be resolved together. |
| 9192 // | 9192 // |
| 9193 computeLibraryDependencies(targetLibrary); | 9193 _computeLibraryDependencies(targetLibrary); |
| 9194 _librariesInCycles = computeLibrariesInCycles(targetLibrary); | 9194 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); |
| 9195 // | 9195 // |
| 9196 // Build the element models representing the libraries being resolved. Thi
s is done in three | 9196 // Build the element models representing the libraries being resolved. Thi
s is done in three |
| 9197 // steps: | 9197 // steps: |
| 9198 // | 9198 // |
| 9199 // 1. Build the basic element models without making any connections betwee
n elements other than | 9199 // 1. Build the basic element models without making any connections betwee
n elements other than |
| 9200 // the basic parent/child relationships. This includes building the ele
ments representing the | 9200 // the basic parent/child relationships. This includes building the ele
ments representing the |
| 9201 // libraries. | 9201 // libraries. |
| 9202 // 2. Build the elements for the import and export directives. This requir
es that we have the | 9202 // 2. Build the elements for the import and export directives. This requir
es that we have the |
| 9203 // elements built for the referenced libraries, but because of the poss
ibility of circular | 9203 // elements built for the referenced libraries, but because of the poss
ibility of circular |
| 9204 // references needs to happen after all of the library elements have be
en created. | 9204 // references needs to happen after all of the library elements have be
en created. |
| 9205 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This | 9205 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This |
| 9206 // requires that we be able to compute the names visible in the librari
es being resolved, | 9206 // requires that we be able to compute the names visible in the librari
es being resolved, |
| 9207 // which in turn requires that we have resolved the import directives. | 9207 // which in turn requires that we have resolved the import directives. |
| 9208 // | 9208 // |
| 9209 buildElementModels(); | 9209 _buildElementModels(); |
| 9210 instrumentation.metric3("buildElementModels", "complete"); | 9210 instrumentation.metric3("buildElementModels", "complete"); |
| 9211 LibraryElement coreElement = _coreLibrary.libraryElement; | 9211 LibraryElement coreElement = _coreLibrary.libraryElement; |
| 9212 if (coreElement == null) { | 9212 if (coreElement == null) { |
| 9213 throw new AnalysisException.con1("Could not resolve dart:core"); | 9213 throw new AnalysisException.con1("Could not resolve dart:core"); |
| 9214 } | 9214 } |
| 9215 buildDirectiveModels(); | 9215 _buildDirectiveModels(); |
| 9216 instrumentation.metric3("buildDirectiveModels", "complete"); | 9216 instrumentation.metric3("buildDirectiveModels", "complete"); |
| 9217 _typeProvider = new TypeProviderImpl(coreElement); | 9217 _typeProvider = new TypeProviderImpl(coreElement); |
| 9218 buildTypeHierarchies(); | 9218 _buildTypeHierarchies(); |
| 9219 instrumentation.metric3("buildTypeHierarchies", "complete"); | 9219 instrumentation.metric3("buildTypeHierarchies", "complete"); |
| 9220 // | 9220 // |
| 9221 // Perform resolution and type analysis. | 9221 // Perform resolution and type analysis. |
| 9222 // | 9222 // |
| 9223 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we | 9223 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we |
| 9224 // want to only resolve the target library. The advantage to resolving eve
rything is that we | 9224 // want to only resolve the target library. The advantage to resolving eve
rything is that we |
| 9225 // have already done part of the work so we'll avoid duplicated effort. Th
e disadvantage of | 9225 // have already done part of the work so we'll avoid duplicated effort. Th
e disadvantage of |
| 9226 // resolving everything is that we might do extra work that we don't reall
y care about. Another | 9226 // resolving everything is that we might do extra work that we don't reall
y care about. Another |
| 9227 // possibility is to add a parameter to this method and punt the decision
to the clients. | 9227 // possibility is to add a parameter to this method and punt the decision
to the clients. |
| 9228 // | 9228 // |
| 9229 //if (analyzeAll) { | 9229 //if (analyzeAll) { |
| 9230 resolveReferencesAndTypes(); | 9230 _resolveReferencesAndTypes(); |
| 9231 instrumentation.metric3("resolveReferencesAndTypes", "complete"); | 9231 instrumentation.metric3("resolveReferencesAndTypes", "complete"); |
| 9232 //} else { | 9232 //} else { |
| 9233 // resolveReferencesAndTypes(targetLibrary); | 9233 // resolveReferencesAndTypes(targetLibrary); |
| 9234 //} | 9234 //} |
| 9235 performConstantEvaluation(); | 9235 _performConstantEvaluation(); |
| 9236 instrumentation.metric3("performConstantEvaluation", "complete"); | 9236 instrumentation.metric3("performConstantEvaluation", "complete"); |
| 9237 instrumentation.metric2("librariesInCycles", _librariesInCycles.length); | 9237 instrumentation.metric2("librariesInCycles", _librariesInCycles.length); |
| 9238 for (Library lib in _librariesInCycles) { | 9238 for (Library lib in _librariesInCycles) { |
| 9239 instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size",
lib.compilationUnitSources.length); | 9239 instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size",
lib.compilationUnitSources.length); |
| 9240 } | 9240 } |
| 9241 return targetLibrary.libraryElement; | 9241 return targetLibrary.libraryElement; |
| 9242 } finally { | 9242 } finally { |
| 9243 instrumentation.log(); | 9243 instrumentation.log(); |
| 9244 } | 9244 } |
| 9245 } | 9245 } |
| 9246 | 9246 |
| 9247 /** | 9247 /** |
| 9248 * Create an object to represent the information about the library defined by
the compilation unit |
| 9249 * with the given source. |
| 9250 * |
| 9251 * @param librarySource the source of the library's defining compilation unit |
| 9252 * @return the library object that was created |
| 9253 * @throws AnalysisException if the library source is not valid |
| 9254 */ |
| 9255 Library createLibrary(Source librarySource) { |
| 9256 Library library = new Library(analysisContext, _errorListener, librarySource
); |
| 9257 _libraryMap[librarySource] = library; |
| 9258 return library; |
| 9259 } |
| 9260 |
| 9261 /** |
| 9248 * Add a dependency to the given map from the referencing library to the refer
enced library. | 9262 * Add a dependency to the given map from the referencing library to the refer
enced library. |
| 9249 * | 9263 * |
| 9250 * @param dependencyMap the map to which the dependency is to be added | 9264 * @param dependencyMap the map to which the dependency is to be added |
| 9251 * @param referencingLibrary the library that references the referenced librar
y | 9265 * @param referencingLibrary the library that references the referenced librar
y |
| 9252 * @param referencedLibrary the library referenced by the referencing library | 9266 * @param referencedLibrary the library referenced by the referencing library |
| 9253 */ | 9267 */ |
| 9254 void addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library ref
erencingLibrary, Library referencedLibrary) { | 9268 void _addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library re
ferencingLibrary, Library referencedLibrary) { |
| 9255 List<Library> dependentLibraries = dependencyMap[referencedLibrary]; | 9269 List<Library> dependentLibraries = dependencyMap[referencedLibrary]; |
| 9256 if (dependentLibraries == null) { | 9270 if (dependentLibraries == null) { |
| 9257 dependentLibraries = new List<Library>(); | 9271 dependentLibraries = new List<Library>(); |
| 9258 dependencyMap[referencedLibrary] = dependentLibraries; | 9272 dependencyMap[referencedLibrary] = dependentLibraries; |
| 9259 } | 9273 } |
| 9260 dependentLibraries.add(referencingLibrary); | 9274 dependentLibraries.add(referencingLibrary); |
| 9261 } | 9275 } |
| 9262 | 9276 |
| 9263 /** | 9277 /** |
| 9264 * Given a library that is part of a cycle that includes the root library, add
to the given set of | 9278 * Given a library that is part of a cycle that includes the root library, add
to the given set of |
| 9265 * libraries all of the libraries reachable from the root library that are als
o included in the | 9279 * libraries all of the libraries reachable from the root library that are als
o included in the |
| 9266 * cycle. | 9280 * cycle. |
| 9267 * | 9281 * |
| 9268 * @param library the library to be added to the collection of libraries in cy
cles | 9282 * @param library the library to be added to the collection of libraries in cy
cles |
| 9269 * @param librariesInCycle a collection of the libraries that are in the cycle | 9283 * @param librariesInCycle a collection of the libraries that are in the cycle |
| 9270 * @param dependencyMap a table mapping libraries to the collection of librari
es from which those | 9284 * @param dependencyMap a table mapping libraries to the collection of librari
es from which those |
| 9271 * libraries are referenced | 9285 * libraries are referenced |
| 9272 */ | 9286 */ |
| 9273 void addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<L
ibrary, List<Library>> dependencyMap) { | 9287 void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<
Library, List<Library>> dependencyMap) { |
| 9274 if (librariesInCycle.add(library)) { | 9288 if (librariesInCycle.add(library)) { |
| 9275 List<Library> dependentLibraries = dependencyMap[library]; | 9289 List<Library> dependentLibraries = dependencyMap[library]; |
| 9276 if (dependentLibraries != null) { | 9290 if (dependentLibraries != null) { |
| 9277 for (Library dependentLibrary in dependentLibraries) { | 9291 for (Library dependentLibrary in dependentLibraries) { |
| 9278 addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap)
; | 9292 _addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap
); |
| 9279 } | 9293 } |
| 9280 } | 9294 } |
| 9281 } | 9295 } |
| 9282 } | 9296 } |
| 9283 | 9297 |
| 9284 /** | 9298 /** |
| 9285 * Add the given library, and all libraries reachable from it that have not al
ready been visited, | 9299 * Add the given library, and all libraries reachable from it that have not al
ready been visited, |
| 9286 * to the given dependency map. | 9300 * to the given dependency map. |
| 9287 * | 9301 * |
| 9288 * @param library the library currently being added to the dependency map | 9302 * @param library the library currently being added to the dependency map |
| 9289 * @param dependencyMap the dependency map being computed | 9303 * @param dependencyMap the dependency map being computed |
| 9290 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite | 9304 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite |
| 9291 * recursion | 9305 * recursion |
| 9292 */ | 9306 */ |
| 9293 void addToDependencyMap(Library library, Map<Library, List<Library>> dependenc
yMap, Set<Library> visitedLibraries) { | 9307 void _addToDependencyMap(Library library, Map<Library, List<Library>> dependen
cyMap, Set<Library> visitedLibraries) { |
| 9294 if (visitedLibraries.add(library)) { | 9308 if (visitedLibraries.add(library)) { |
| 9295 for (Library referencedLibrary in library.importsAndExports) { | 9309 for (Library referencedLibrary in library.importsAndExports) { |
| 9296 addDependencyToMap(dependencyMap, library, referencedLibrary); | 9310 _addDependencyToMap(dependencyMap, library, referencedLibrary); |
| 9297 addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); | 9311 _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); |
| 9298 } | 9312 } |
| 9299 if (!library.explicitlyImportsCore && library != _coreLibrary) { | 9313 if (!library.explicitlyImportsCore && library != _coreLibrary) { |
| 9300 addDependencyToMap(dependencyMap, library, _coreLibrary); | 9314 _addDependencyToMap(dependencyMap, library, _coreLibrary); |
| 9301 } | 9315 } |
| 9302 } | 9316 } |
| 9303 } | 9317 } |
| 9304 | 9318 |
| 9305 /** | 9319 /** |
| 9306 * Build the element model representing the combinators declared by the given
directive. | 9320 * Build the element model representing the combinators declared by the given
directive. |
| 9307 * | 9321 * |
| 9308 * @param directive the directive that declares the combinators | 9322 * @param directive the directive that declares the combinators |
| 9309 * @return an array containing the import combinators that were built | 9323 * @return an array containing the import combinators that were built |
| 9310 */ | 9324 */ |
| 9311 List<NamespaceCombinator> buildCombinators(NamespaceDirective directive) { | 9325 List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) { |
| 9312 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>(); | 9326 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>(); |
| 9313 for (Combinator combinator in directive.combinators) { | 9327 for (Combinator combinator in directive.combinators) { |
| 9314 if (combinator is HideCombinator) { | 9328 if (combinator is HideCombinator) { |
| 9315 HideElementCombinatorImpl hide = new HideElementCombinatorImpl(); | 9329 HideElementCombinatorImpl hide = new HideElementCombinatorImpl(); |
| 9316 hide.hiddenNames = getIdentifiers(combinator.hiddenNames); | 9330 hide.hiddenNames = _getIdentifiers(combinator.hiddenNames); |
| 9317 combinators.add(hide); | 9331 combinators.add(hide); |
| 9318 } else { | 9332 } else { |
| 9319 ShowElementCombinatorImpl show = new ShowElementCombinatorImpl(); | 9333 ShowElementCombinatorImpl show = new ShowElementCombinatorImpl(); |
| 9320 show.offset = combinator.offset; | 9334 show.offset = combinator.offset; |
| 9321 show.end = combinator.end; | 9335 show.end = combinator.end; |
| 9322 show.shownNames = getIdentifiers((combinator as ShowCombinator).shownNam
es); | 9336 show.shownNames = _getIdentifiers((combinator as ShowCombinator).shownNa
mes); |
| 9323 combinators.add(show); | 9337 combinators.add(show); |
| 9324 } | 9338 } |
| 9325 } | 9339 } |
| 9326 return new List.from(combinators); | 9340 return new List.from(combinators); |
| 9327 } | 9341 } |
| 9328 | 9342 |
| 9329 /** | 9343 /** |
| 9330 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve | 9344 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve |
| 9331 * the import and export directives. | 9345 * the import and export directives. |
| 9332 * | 9346 * |
| 9333 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not | 9347 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not |
| 9334 * be accessed | 9348 * be accessed |
| 9335 */ | 9349 */ |
| 9336 void buildDirectiveModels() { | 9350 void _buildDirectiveModels() { |
| 9337 for (Library library in _librariesInCycles) { | 9351 for (Library library in _librariesInCycles) { |
| 9338 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle
mentImpl>(); | 9352 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle
mentImpl>(); |
| 9339 List<ImportElement> imports = new List<ImportElement>(); | 9353 List<ImportElement> imports = new List<ImportElement>(); |
| 9340 List<ExportElement> exports = new List<ExportElement>(); | 9354 List<ExportElement> exports = new List<ExportElement>(); |
| 9341 for (Directive directive in library.definingCompilationUnit.directives) { | 9355 for (Directive directive in library.definingCompilationUnit.directives) { |
| 9342 if (directive is ImportDirective) { | 9356 if (directive is ImportDirective) { |
| 9343 ImportDirective importDirective = directive; | 9357 ImportDirective importDirective = directive; |
| 9344 Source importedSource = library.getSource(importDirective); | 9358 Source importedSource = library.getSource(importDirective); |
| 9345 if (importedSource != null) { | 9359 if (importedSource != null) { |
| 9346 // The imported source will be null if the URI in the import directi
ve was invalid. | 9360 // The imported source will be null if the URI in the import directi
ve was invalid. |
| 9347 Library importedLibrary = _libraryMap[importedSource]; | 9361 Library importedLibrary = _libraryMap[importedSource]; |
| 9348 if (importedLibrary != null) { | 9362 if (importedLibrary != null) { |
| 9349 ImportElementImpl importElement = new ImportElementImpl(directive.
offset); | 9363 ImportElementImpl importElement = new ImportElementImpl(directive.
offset); |
| 9350 StringLiteral uriLiteral = importDirective.uri; | 9364 StringLiteral uriLiteral = importDirective.uri; |
| 9351 if (uriLiteral != null) { | 9365 if (uriLiteral != null) { |
| 9352 importElement.uriEnd = uriLiteral.end; | 9366 importElement.uriEnd = uriLiteral.end; |
| 9353 } | 9367 } |
| 9354 importElement.uri = library.getUri(importDirective); | 9368 importElement.uri = library.getUri(importDirective); |
| 9355 importElement.combinators = buildCombinators(importDirective); | 9369 importElement.combinators = _buildCombinators(importDirective); |
| 9356 LibraryElement importedLibraryElement = importedLibrary.libraryEle
ment; | 9370 LibraryElement importedLibraryElement = importedLibrary.libraryEle
ment; |
| 9357 if (importedLibraryElement != null) { | 9371 if (importedLibraryElement != null) { |
| 9358 importElement.importedLibrary = importedLibraryElement; | 9372 importElement.importedLibrary = importedLibraryElement; |
| 9359 } | 9373 } |
| 9360 SimpleIdentifier prefixNode = directive.prefix; | 9374 SimpleIdentifier prefixNode = directive.prefix; |
| 9361 if (prefixNode != null) { | 9375 if (prefixNode != null) { |
| 9362 importElement.prefixOffset = prefixNode.offset; | 9376 importElement.prefixOffset = prefixNode.offset; |
| 9363 String prefixName = prefixNode.name; | 9377 String prefixName = prefixNode.name; |
| 9364 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; | 9378 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; |
| 9365 if (prefix == null) { | 9379 if (prefix == null) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 9378 } | 9392 } |
| 9379 } else if (directive is ExportDirective) { | 9393 } else if (directive is ExportDirective) { |
| 9380 ExportDirective exportDirective = directive; | 9394 ExportDirective exportDirective = directive; |
| 9381 Source exportedSource = library.getSource(exportDirective); | 9395 Source exportedSource = library.getSource(exportDirective); |
| 9382 if (exportedSource != null) { | 9396 if (exportedSource != null) { |
| 9383 // The exported source will be null if the URI in the export directi
ve was invalid. | 9397 // The exported source will be null if the URI in the export directi
ve was invalid. |
| 9384 Library exportedLibrary = _libraryMap[exportedSource]; | 9398 Library exportedLibrary = _libraryMap[exportedSource]; |
| 9385 if (exportedLibrary != null) { | 9399 if (exportedLibrary != null) { |
| 9386 ExportElementImpl exportElement = new ExportElementImpl(); | 9400 ExportElementImpl exportElement = new ExportElementImpl(); |
| 9387 exportElement.uri = library.getUri(exportDirective); | 9401 exportElement.uri = library.getUri(exportDirective); |
| 9388 exportElement.combinators = buildCombinators(exportDirective); | 9402 exportElement.combinators = _buildCombinators(exportDirective); |
| 9389 LibraryElement exportedLibraryElement = exportedLibrary.libraryEle
ment; | 9403 LibraryElement exportedLibraryElement = exportedLibrary.libraryEle
ment; |
| 9390 if (exportedLibraryElement != null) { | 9404 if (exportedLibraryElement != null) { |
| 9391 exportElement.exportedLibrary = exportedLibraryElement; | 9405 exportElement.exportedLibrary = exportedLibraryElement; |
| 9392 } | 9406 } |
| 9393 directive.element = exportElement; | 9407 directive.element = exportElement; |
| 9394 exports.add(exportElement); | 9408 exports.add(exportElement); |
| 9395 if (analysisContext.computeKindOf(exportedSource) != SourceKind.LI
BRARY) { | 9409 if (analysisContext.computeKindOf(exportedSource) != SourceKind.LI
BRARY) { |
| 9396 StringLiteral uriLiteral = exportDirective.uri; | 9410 StringLiteral uriLiteral = exportDirective.uri; |
| 9397 _errorListener.onError(new AnalysisError.con2(library.librarySou
rce, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LI
BRARY, [uriLiteral.toSource()])); | 9411 _errorListener.onError(new AnalysisError.con2(library.librarySou
rce, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LI
BRARY, [uriLiteral.toSource()])); |
| 9398 } | 9412 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 9418 } | 9432 } |
| 9419 } | 9433 } |
| 9420 } | 9434 } |
| 9421 } | 9435 } |
| 9422 | 9436 |
| 9423 /** | 9437 /** |
| 9424 * Build element models for all of the libraries in the current cycle. | 9438 * Build element models for all of the libraries in the current cycle. |
| 9425 * | 9439 * |
| 9426 * @throws AnalysisException if any of the element models cannot be built | 9440 * @throws AnalysisException if any of the element models cannot be built |
| 9427 */ | 9441 */ |
| 9428 void buildElementModels() { | 9442 void _buildElementModels() { |
| 9429 for (Library library in _librariesInCycles) { | 9443 for (Library library in _librariesInCycles) { |
| 9430 LibraryElementBuilder builder = new LibraryElementBuilder(this); | 9444 LibraryElementBuilder builder = new LibraryElementBuilder(this); |
| 9431 LibraryElementImpl libraryElement = builder.buildLibrary(library); | 9445 LibraryElementImpl libraryElement = builder.buildLibrary(library); |
| 9432 library.libraryElement = libraryElement; | 9446 library.libraryElement = libraryElement; |
| 9433 } | 9447 } |
| 9434 } | 9448 } |
| 9435 | 9449 |
| 9436 /** | 9450 /** |
| 9437 * Resolve the type hierarchy across all of the types declared in the librarie
s in the current | 9451 * Resolve the type hierarchy across all of the types declared in the librarie
s in the current |
| 9438 * cycle. | 9452 * cycle. |
| 9439 * | 9453 * |
| 9440 * @throws AnalysisException if any of the type hierarchies could not be resol
ved | 9454 * @throws AnalysisException if any of the type hierarchies could not be resol
ved |
| 9441 */ | 9455 */ |
| 9442 void buildTypeHierarchies() { | 9456 void _buildTypeHierarchies() { |
| 9443 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.st
art(); | 9457 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.st
art(); |
| 9444 try { | 9458 try { |
| 9445 for (Library library in _librariesInCycles) { | 9459 for (Library library in _librariesInCycles) { |
| 9446 for (Source source in library.compilationUnitSources) { | 9460 for (Source source in library.compilationUnitSources) { |
| 9447 TypeResolverVisitor visitor = new TypeResolverVisitor.con1(library, so
urce, _typeProvider); | 9461 TypeResolverVisitor visitor = new TypeResolverVisitor.con1(library, so
urce, _typeProvider); |
| 9448 library.getAST(source).accept(visitor); | 9462 library.getAST(source).accept(visitor); |
| 9449 } | 9463 } |
| 9450 } | 9464 } |
| 9451 } finally { | 9465 } finally { |
| 9452 timeCounter.stop(); | 9466 timeCounter.stop(); |
| 9453 } | 9467 } |
| 9454 } | 9468 } |
| 9455 | 9469 |
| 9456 /** | 9470 /** |
| 9457 * Compute a dependency map of libraries reachable from the given library. A d
ependency map is a | 9471 * Compute a dependency map of libraries reachable from the given library. A d
ependency map is a |
| 9458 * table that maps individual libraries to a list of the libraries that either
import or export | 9472 * table that maps individual libraries to a list of the libraries that either
import or export |
| 9459 * those libraries. | 9473 * those libraries. |
| 9460 * | 9474 * |
| 9461 * This map is used to compute all of the libraries involved in a cycle that i
nclude the root | 9475 * This map is used to compute all of the libraries involved in a cycle that i
nclude the root |
| 9462 * library. Given that we only add libraries that are reachable from the root
library, when we | 9476 * library. Given that we only add libraries that are reachable from the root
library, when we |
| 9463 * work backward we are guaranteed to only get libraries in the cycle. | 9477 * work backward we are guaranteed to only get libraries in the cycle. |
| 9464 * | 9478 * |
| 9465 * @param library the library currently being added to the dependency map | 9479 * @param library the library currently being added to the dependency map |
| 9466 */ | 9480 */ |
| 9467 Map<Library, List<Library>> computeDependencyMap(Library library) { | 9481 Map<Library, List<Library>> _computeDependencyMap(Library library) { |
| 9468 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>(
); | 9482 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>(
); |
| 9469 addToDependencyMap(library, dependencyMap, new Set<Library>()); | 9483 _addToDependencyMap(library, dependencyMap, new Set<Library>()); |
| 9470 return dependencyMap; | 9484 return dependencyMap; |
| 9471 } | 9485 } |
| 9472 | 9486 |
| 9473 /** | 9487 /** |
| 9474 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 9488 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
| 9475 * class [Library] to represent them, and record the references in the library
objects. | 9489 * class [Library] to represent them, and record the references in the library
objects. |
| 9476 * | 9490 * |
| 9477 * @param library the library to be processed to find libraries that have not
yet been traversed | 9491 * @param library the library to be processed to find libraries that have not
yet been traversed |
| 9478 * @throws AnalysisException if some portion of the library graph could not be
traversed | 9492 * @throws AnalysisException if some portion of the library graph could not be
traversed |
| 9479 */ | 9493 */ |
| 9480 void computeEmbeddedLibraryDependencies(Library library, CompilationUnit unit)
{ | 9494 void _computeEmbeddedLibraryDependencies(Library library, CompilationUnit unit
) { |
| 9481 Source librarySource = library.librarySource; | 9495 Source librarySource = library.librarySource; |
| 9482 Set<Source> exportedSources = new Set<Source>(); | 9496 Set<Source> exportedSources = new Set<Source>(); |
| 9483 Set<Source> importedSources = new Set<Source>(); | 9497 Set<Source> importedSources = new Set<Source>(); |
| 9484 for (Directive directive in unit.directives) { | 9498 for (Directive directive in unit.directives) { |
| 9485 if (directive is ExportDirective) { | 9499 if (directive is ExportDirective) { |
| 9486 Source exportSource = resolveSource(librarySource, directive); | 9500 Source exportSource = _resolveSource(librarySource, directive); |
| 9487 if (exportSource != null) { | 9501 if (exportSource != null) { |
| 9488 exportedSources.add(exportSource); | 9502 exportedSources.add(exportSource); |
| 9489 } | 9503 } |
| 9490 } else if (directive is ImportDirective) { | 9504 } else if (directive is ImportDirective) { |
| 9491 Source importSource = resolveSource(librarySource, directive); | 9505 Source importSource = _resolveSource(librarySource, directive); |
| 9492 if (importSource != null) { | 9506 if (importSource != null) { |
| 9493 importedSources.add(importSource); | 9507 importedSources.add(importSource); |
| 9494 } | 9508 } |
| 9495 } | 9509 } |
| 9496 } | 9510 } |
| 9497 computeLibraryDependenciesFromDirectives(library, new List.from(importedSour
ces), new List.from(exportedSources)); | 9511 _computeLibraryDependenciesFromDirectives(library, new List.from(importedSou
rces), new List.from(exportedSources)); |
| 9498 } | 9512 } |
| 9499 | 9513 |
| 9500 /** | 9514 /** |
| 9501 * Return a collection containing all of the libraries reachable from the give
n library that are | 9515 * Return a collection containing all of the libraries reachable from the give
n library that are |
| 9502 * contained in a cycle that includes the given library. | 9516 * contained in a cycle that includes the given library. |
| 9503 * | 9517 * |
| 9504 * @param library the library that must be included in any cycles whose member
s are to be returned | 9518 * @param library the library that must be included in any cycles whose member
s are to be returned |
| 9505 * @return all of the libraries referenced by the given library that have a ci
rcular reference | 9519 * @return all of the libraries referenced by the given library that have a ci
rcular reference |
| 9506 * back to the given library | 9520 * back to the given library |
| 9507 */ | 9521 */ |
| 9508 Set<Library> computeLibrariesInCycles(Library library) { | 9522 Set<Library> _computeLibrariesInCycles(Library library) { |
| 9509 Map<Library, List<Library>> dependencyMap = computeDependencyMap(library); | 9523 Map<Library, List<Library>> dependencyMap = _computeDependencyMap(library); |
| 9510 Set<Library> librariesInCycle = new Set<Library>(); | 9524 Set<Library> librariesInCycle = new Set<Library>(); |
| 9511 addLibrariesInCycle(library, librariesInCycle, dependencyMap); | 9525 _addLibrariesInCycle(library, librariesInCycle, dependencyMap); |
| 9512 return librariesInCycle; | 9526 return librariesInCycle; |
| 9513 } | 9527 } |
| 9514 | 9528 |
| 9515 /** | 9529 /** |
| 9516 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 9530 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
| 9517 * class [Library] to represent them, and record the references in the library
objects. | 9531 * class [Library] to represent them, and record the references in the library
objects. |
| 9518 * | 9532 * |
| 9519 * @param library the library to be processed to find libraries that have not
yet been traversed | 9533 * @param library the library to be processed to find libraries that have not
yet been traversed |
| 9520 * @throws AnalysisException if some portion of the library graph could not be
traversed | 9534 * @throws AnalysisException if some portion of the library graph could not be
traversed |
| 9521 */ | 9535 */ |
| 9522 void computeLibraryDependencies(Library library) { | 9536 void _computeLibraryDependencies(Library library) { |
| 9523 Source librarySource = library.librarySource; | 9537 Source librarySource = library.librarySource; |
| 9524 computeLibraryDependenciesFromDirectives(library, analysisContext.computeImp
ortedLibraries(librarySource), analysisContext.computeExportedLibraries(libraryS
ource)); | 9538 _computeLibraryDependenciesFromDirectives(library, analysisContext.computeIm
portedLibraries(librarySource), analysisContext.computeExportedLibraries(library
Source)); |
| 9525 } | 9539 } |
| 9526 | 9540 |
| 9527 /** | 9541 /** |
| 9528 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 9542 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
| 9529 * class [Library] to represent them, and record the references in the library
objects. | 9543 * class [Library] to represent them, and record the references in the library
objects. |
| 9530 * | 9544 * |
| 9531 * @param library the library to be processed to find libraries that have not
yet been traversed | 9545 * @param library the library to be processed to find libraries that have not
yet been traversed |
| 9532 * @param importedSources an array containing the sources that are imported in
to the given library | 9546 * @param importedSources an array containing the sources that are imported in
to the given library |
| 9533 * @param exportedSources an array containing the sources that are exported fr
om the given library | 9547 * @param exportedSources an array containing the sources that are exported fr
om the given library |
| 9534 * @throws AnalysisException if some portion of the library graph could not be
traversed | 9548 * @throws AnalysisException if some portion of the library graph could not be
traversed |
| 9535 */ | 9549 */ |
| 9536 void computeLibraryDependenciesFromDirectives(Library library, List<Source> im
portedSources, List<Source> exportedSources) { | 9550 void _computeLibraryDependenciesFromDirectives(Library library, List<Source> i
mportedSources, List<Source> exportedSources) { |
| 9537 List<Library> importedLibraries = new List<Library>(); | 9551 List<Library> importedLibraries = new List<Library>(); |
| 9538 bool explicitlyImportsCore = false; | 9552 bool explicitlyImportsCore = false; |
| 9539 for (Source importedSource in importedSources) { | 9553 for (Source importedSource in importedSources) { |
| 9540 if (importedSource == _coreLibrarySource) { | 9554 if (importedSource == _coreLibrarySource) { |
| 9541 explicitlyImportsCore = true; | 9555 explicitlyImportsCore = true; |
| 9542 } | 9556 } |
| 9543 Library importedLibrary = _libraryMap[importedSource]; | 9557 Library importedLibrary = _libraryMap[importedSource]; |
| 9544 if (importedLibrary == null) { | 9558 if (importedLibrary == null) { |
| 9545 importedLibrary = createLibraryOrNull(importedSource); | 9559 importedLibrary = _createLibraryOrNull(importedSource); |
| 9546 if (importedLibrary != null) { | 9560 if (importedLibrary != null) { |
| 9547 computeLibraryDependencies(importedLibrary); | 9561 _computeLibraryDependencies(importedLibrary); |
| 9548 } | 9562 } |
| 9549 } | 9563 } |
| 9550 if (importedLibrary != null) { | 9564 if (importedLibrary != null) { |
| 9551 importedLibraries.add(importedLibrary); | 9565 importedLibraries.add(importedLibrary); |
| 9552 } | 9566 } |
| 9553 } | 9567 } |
| 9554 library.importedLibraries = new List.from(importedLibraries); | 9568 library.importedLibraries = new List.from(importedLibraries); |
| 9555 List<Library> exportedLibraries = new List<Library>(); | 9569 List<Library> exportedLibraries = new List<Library>(); |
| 9556 for (Source exportedSource in exportedSources) { | 9570 for (Source exportedSource in exportedSources) { |
| 9557 Library exportedLibrary = _libraryMap[exportedSource]; | 9571 Library exportedLibrary = _libraryMap[exportedSource]; |
| 9558 if (exportedLibrary == null) { | 9572 if (exportedLibrary == null) { |
| 9559 exportedLibrary = createLibraryOrNull(exportedSource); | 9573 exportedLibrary = _createLibraryOrNull(exportedSource); |
| 9560 if (exportedLibrary != null) { | 9574 if (exportedLibrary != null) { |
| 9561 computeLibraryDependencies(exportedLibrary); | 9575 _computeLibraryDependencies(exportedLibrary); |
| 9562 } | 9576 } |
| 9563 } | 9577 } |
| 9564 if (exportedLibrary != null) { | 9578 if (exportedLibrary != null) { |
| 9565 exportedLibraries.add(exportedLibrary); | 9579 exportedLibraries.add(exportedLibrary); |
| 9566 } | 9580 } |
| 9567 } | 9581 } |
| 9568 library.exportedLibraries = new List.from(exportedLibraries); | 9582 library.exportedLibraries = new List.from(exportedLibraries); |
| 9569 library.explicitlyImportsCore = explicitlyImportsCore; | 9583 library.explicitlyImportsCore = explicitlyImportsCore; |
| 9570 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) { | 9584 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) { |
| 9571 Library importedLibrary = _libraryMap[_coreLibrarySource]; | 9585 Library importedLibrary = _libraryMap[_coreLibrarySource]; |
| 9572 if (importedLibrary == null) { | 9586 if (importedLibrary == null) { |
| 9573 importedLibrary = createLibraryOrNull(_coreLibrarySource); | 9587 importedLibrary = _createLibraryOrNull(_coreLibrarySource); |
| 9574 if (importedLibrary != null) { | 9588 if (importedLibrary != null) { |
| 9575 computeLibraryDependencies(importedLibrary); | 9589 _computeLibraryDependencies(importedLibrary); |
| 9576 } | 9590 } |
| 9577 } | 9591 } |
| 9578 } | 9592 } |
| 9579 } | 9593 } |
| 9580 | 9594 |
| 9581 /** | 9595 /** |
| 9582 * Create an object to represent the information about the library defined by
the compilation unit | 9596 * Create an object to represent the information about the library defined by
the compilation unit |
| 9583 * with the given source. | |
| 9584 * | |
| 9585 * @param librarySource the source of the library's defining compilation unit | |
| 9586 * @return the library object that was created | |
| 9587 * @throws AnalysisException if the library source is not valid | |
| 9588 */ | |
| 9589 Library createLibrary(Source librarySource) { | |
| 9590 Library library = new Library(analysisContext, _errorListener, librarySource
); | |
| 9591 _libraryMap[librarySource] = library; | |
| 9592 return library; | |
| 9593 } | |
| 9594 | |
| 9595 /** | |
| 9596 * Create an object to represent the information about the library defined by
the compilation unit | |
| 9597 * with the given source. Return the library object that was created, or `null
` if the | 9597 * with the given source. Return the library object that was created, or `null
` if the |
| 9598 * source is not valid. | 9598 * source is not valid. |
| 9599 * | 9599 * |
| 9600 * @param librarySource the source of the library's defining compilation unit | 9600 * @param librarySource the source of the library's defining compilation unit |
| 9601 * @return the library object that was created | 9601 * @return the library object that was created |
| 9602 */ | 9602 */ |
| 9603 Library createLibraryOrNull(Source librarySource) { | 9603 Library _createLibraryOrNull(Source librarySource) { |
| 9604 if (!analysisContext.exists(librarySource)) { | 9604 if (!analysisContext.exists(librarySource)) { |
| 9605 return null; | 9605 return null; |
| 9606 } | 9606 } |
| 9607 Library library = new Library(analysisContext, _errorListener, librarySource
); | 9607 Library library = new Library(analysisContext, _errorListener, librarySource
); |
| 9608 _libraryMap[librarySource] = library; | 9608 _libraryMap[librarySource] = library; |
| 9609 return library; | 9609 return library; |
| 9610 } | 9610 } |
| 9611 | 9611 |
| 9612 /** | 9612 /** |
| 9613 * Create an object to represent the information about the library defined by
the compilation unit | 9613 * Create an object to represent the information about the library defined by
the compilation unit |
| 9614 * with the given source. | 9614 * with the given source. |
| 9615 * | 9615 * |
| 9616 * @param librarySource the source of the library's defining compilation unit | 9616 * @param librarySource the source of the library's defining compilation unit |
| 9617 * @param modificationStamp the modification time of the source from which the
compilation unit | 9617 * @param modificationStamp the modification time of the source from which the
compilation unit |
| 9618 * was created | 9618 * was created |
| 9619 * @param unit the compilation unit that defines the library | 9619 * @param unit the compilation unit that defines the library |
| 9620 * @return the library object that was created | 9620 * @return the library object that was created |
| 9621 * @throws AnalysisException if the library source is not valid | 9621 * @throws AnalysisException if the library source is not valid |
| 9622 */ | 9622 */ |
| 9623 Library createLibraryWithUnit(Source librarySource, int modificationStamp, Com
pilationUnit unit) { | 9623 Library _createLibraryWithUnit(Source librarySource, int modificationStamp, Co
mpilationUnit unit) { |
| 9624 Library library = new Library(analysisContext, _errorListener, librarySource
); | 9624 Library library = new Library(analysisContext, _errorListener, librarySource
); |
| 9625 library.setDefiningCompilationUnit(modificationStamp, unit); | 9625 library.setDefiningCompilationUnit(modificationStamp, unit); |
| 9626 _libraryMap[librarySource] = library; | 9626 _libraryMap[librarySource] = library; |
| 9627 return library; | 9627 return library; |
| 9628 } | 9628 } |
| 9629 | 9629 |
| 9630 /** | 9630 /** |
| 9631 * Return an array containing the lexical identifiers associated with the node
s in the given list. | 9631 * Return an array containing the lexical identifiers associated with the node
s in the given list. |
| 9632 * | 9632 * |
| 9633 * @param names the AST nodes representing the identifiers | 9633 * @param names the AST nodes representing the identifiers |
| 9634 * @return the lexical identifiers associated with the nodes in the list | 9634 * @return the lexical identifiers associated with the nodes in the list |
| 9635 */ | 9635 */ |
| 9636 List<String> getIdentifiers(NodeList<SimpleIdentifier> names) { | 9636 List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) { |
| 9637 int count = names.length; | 9637 int count = names.length; |
| 9638 List<String> identifiers = new List<String>(count); | 9638 List<String> identifiers = new List<String>(count); |
| 9639 for (int i = 0; i < count; i++) { | 9639 for (int i = 0; i < count; i++) { |
| 9640 identifiers[i] = names[i].name; | 9640 identifiers[i] = names[i].name; |
| 9641 } | 9641 } |
| 9642 return identifiers; | 9642 return identifiers; |
| 9643 } | 9643 } |
| 9644 | 9644 |
| 9645 /** | 9645 /** |
| 9646 * Compute a value for all of the constants in the libraries being analyzed. | 9646 * Compute a value for all of the constants in the libraries being analyzed. |
| 9647 */ | 9647 */ |
| 9648 void performConstantEvaluation() { | 9648 void _performConstantEvaluation() { |
| 9649 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.st
art(); | 9649 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.st
art(); |
| 9650 try { | 9650 try { |
| 9651 ConstantValueComputer computer = new ConstantValueComputer(_typeProvider); | 9651 ConstantValueComputer computer = new ConstantValueComputer(_typeProvider); |
| 9652 for (Library library in _librariesInCycles) { | 9652 for (Library library in _librariesInCycles) { |
| 9653 for (Source source in library.compilationUnitSources) { | 9653 for (Source source in library.compilationUnitSources) { |
| 9654 try { | 9654 try { |
| 9655 CompilationUnit unit = library.getAST(source); | 9655 CompilationUnit unit = library.getAST(source); |
| 9656 if (unit != null) { | 9656 if (unit != null) { |
| 9657 computer.add(unit); | 9657 computer.add(unit); |
| 9658 } | 9658 } |
| 9659 } on AnalysisException catch (exception) { | 9659 } on AnalysisException catch (exception) { |
| 9660 AnalysisEngine.instance.logger.logError2("Internal Error: Could not
access AST for ${source.fullName} during constant evaluation", exception); | 9660 AnalysisEngine.instance.logger.logError2("Internal Error: Could not
access AST for ${source.fullName} during constant evaluation", exception); |
| 9661 } | 9661 } |
| 9662 } | 9662 } |
| 9663 } | 9663 } |
| 9664 computer.computeValues(); | 9664 computer.computeValues(); |
| 9665 } finally { | 9665 } finally { |
| 9666 timeCounter.stop(); | 9666 timeCounter.stop(); |
| 9667 } | 9667 } |
| 9668 } | 9668 } |
| 9669 | 9669 |
| 9670 /** | 9670 /** |
| 9671 * Resolve the identifiers and perform type analysis in the libraries in the c
urrent cycle. | 9671 * Resolve the identifiers and perform type analysis in the libraries in the c
urrent cycle. |
| 9672 * | 9672 * |
| 9673 * @throws AnalysisException if any of the identifiers could not be resolved o
r if any of the | 9673 * @throws AnalysisException if any of the identifiers could not be resolved o
r if any of the |
| 9674 * libraries could not have their types analyzed | 9674 * libraries could not have their types analyzed |
| 9675 */ | 9675 */ |
| 9676 void resolveReferencesAndTypes() { | 9676 void _resolveReferencesAndTypes() { |
| 9677 for (Library library in _librariesInCycles) { | 9677 for (Library library in _librariesInCycles) { |
| 9678 resolveReferencesAndTypesInLibrary(library); | 9678 _resolveReferencesAndTypesInLibrary(library); |
| 9679 } | 9679 } |
| 9680 } | 9680 } |
| 9681 | 9681 |
| 9682 /** | 9682 /** |
| 9683 * Resolve the identifiers and perform type analysis in the given library. | 9683 * Resolve the identifiers and perform type analysis in the given library. |
| 9684 * | 9684 * |
| 9685 * @param library the library to be resolved | 9685 * @param library the library to be resolved |
| 9686 * @throws AnalysisException if any of the identifiers could not be resolved o
r if the types in | 9686 * @throws AnalysisException if any of the identifiers could not be resolved o
r if the types in |
| 9687 * the library cannot be analyzed | 9687 * the library cannot be analyzed |
| 9688 */ | 9688 */ |
| 9689 void resolveReferencesAndTypesInLibrary(Library library) { | 9689 void _resolveReferencesAndTypesInLibrary(Library library) { |
| 9690 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.st
art(); | 9690 TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.st
art(); |
| 9691 try { | 9691 try { |
| 9692 for (Source source in library.compilationUnitSources) { | 9692 for (Source source in library.compilationUnitSources) { |
| 9693 CompilationUnit ast = library.getAST(source); | 9693 CompilationUnit ast = library.getAST(source); |
| 9694 ast.accept(new VariableResolverVisitor.con1(library, source, _typeProvid
er)); | 9694 ast.accept(new VariableResolverVisitor.con1(library, source, _typeProvid
er)); |
| 9695 ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typ
eProvider); | 9695 ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typ
eProvider); |
| 9696 ast.accept(visitor); | 9696 ast.accept(visitor); |
| 9697 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondi
tionalAnalysisErrors) { | 9697 for (ProxyConditionalAnalysisError conditionalCode in visitor.proxyCondi
tionalAnalysisErrors) { |
| 9698 if (conditionalCode.shouldIncludeErrorCode()) { | 9698 if (conditionalCode.shouldIncludeErrorCode()) { |
| 9699 visitor.reportError(conditionalCode.analysisError); | 9699 visitor.reportError(conditionalCode.analysisError); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 9716 } | 9716 } |
| 9717 | 9717 |
| 9718 /** | 9718 /** |
| 9719 * Return the result of resolving the URI of the given URI-based directive aga
inst the URI of the | 9719 * Return the result of resolving the URI of the given URI-based directive aga
inst the URI of the |
| 9720 * given library, or `null` if the URI is not valid. | 9720 * given library, or `null` if the URI is not valid. |
| 9721 * | 9721 * |
| 9722 * @param librarySource the source representing the library containing the dir
ective | 9722 * @param librarySource the source representing the library containing the dir
ective |
| 9723 * @param directive the directive which URI should be resolved | 9723 * @param directive the directive which URI should be resolved |
| 9724 * @return the result of resolving the URI against the URI of the library | 9724 * @return the result of resolving the URI against the URI of the library |
| 9725 */ | 9725 */ |
| 9726 Source resolveSource(Source librarySource, UriBasedDirective directive) { | 9726 Source _resolveSource(Source librarySource, UriBasedDirective directive) { |
| 9727 StringLiteral uriLiteral = directive.uri; | 9727 StringLiteral uriLiteral = directive.uri; |
| 9728 if (uriLiteral is StringInterpolation) { | 9728 if (uriLiteral is StringInterpolation) { |
| 9729 return null; | 9729 return null; |
| 9730 } | 9730 } |
| 9731 String uriContent = uriLiteral.stringValue.trim(); | 9731 String uriContent = uriLiteral.stringValue.trim(); |
| 9732 if (uriContent == null || uriContent.isEmpty) { | 9732 if (uriContent == null || uriContent.isEmpty) { |
| 9733 return null; | 9733 return null; |
| 9734 } | 9734 } |
| 9735 uriContent = Uri.encodeFull(uriContent); | 9735 uriContent = Uri.encodeFull(uriContent); |
| 9736 return analysisContext.sourceFactory.resolveUri(librarySource, uriContent); | 9736 return analysisContext.sourceFactory.resolveUri(librarySource, uriContent); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9761 * Default constructor. | 9761 * Default constructor. |
| 9762 */ | 9762 */ |
| 9763 MemberMap() : this.con1(10); | 9763 MemberMap() : this.con1(10); |
| 9764 | 9764 |
| 9765 /** | 9765 /** |
| 9766 * This constructor takes an initial capacity of the map. | 9766 * This constructor takes an initial capacity of the map. |
| 9767 * | 9767 * |
| 9768 * @param initialCapacity the initial capacity | 9768 * @param initialCapacity the initial capacity |
| 9769 */ | 9769 */ |
| 9770 MemberMap.con1(int initialCapacity) { | 9770 MemberMap.con1(int initialCapacity) { |
| 9771 initArrays(initialCapacity); | 9771 _initArrays(initialCapacity); |
| 9772 } | 9772 } |
| 9773 | 9773 |
| 9774 /** | 9774 /** |
| 9775 * Copy constructor. | 9775 * Copy constructor. |
| 9776 */ | 9776 */ |
| 9777 MemberMap.con2(MemberMap memberMap) { | 9777 MemberMap.con2(MemberMap memberMap) { |
| 9778 initArrays(memberMap._size + 5); | 9778 _initArrays(memberMap._size + 5); |
| 9779 for (int i = 0; i < memberMap._size; i++) { | 9779 for (int i = 0; i < memberMap._size; i++) { |
| 9780 _keys[i] = memberMap._keys[i]; | 9780 _keys[i] = memberMap._keys[i]; |
| 9781 _values[i] = memberMap._values[i]; | 9781 _values[i] = memberMap._values[i]; |
| 9782 } | 9782 } |
| 9783 _size = memberMap._size; | 9783 _size = memberMap._size; |
| 9784 } | 9784 } |
| 9785 | 9785 |
| 9786 /** | 9786 /** |
| 9787 * Given some key, return the ExecutableElement value from the map, if the key
does not exist in | 9787 * Given some key, return the ExecutableElement value from the map, if the key
does not exist in |
| 9788 * the map, `null` is returned. | 9788 * the map, `null` is returned. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9887 * @param i some non-zero value less than size | 9887 * @param i some non-zero value less than size |
| 9888 * @param value the ExecutableElement value to store in the map | 9888 * @param value the ExecutableElement value to store in the map |
| 9889 */ | 9889 */ |
| 9890 void setValue(int i, ExecutableElement value) { | 9890 void setValue(int i, ExecutableElement value) { |
| 9891 _values[i] = value; | 9891 _values[i] = value; |
| 9892 } | 9892 } |
| 9893 | 9893 |
| 9894 /** | 9894 /** |
| 9895 * Initializes [keys] and [values]. | 9895 * Initializes [keys] and [values]. |
| 9896 */ | 9896 */ |
| 9897 void initArrays(int initialCapacity) { | 9897 void _initArrays(int initialCapacity) { |
| 9898 _keys = new List<String>(initialCapacity); | 9898 _keys = new List<String>(initialCapacity); |
| 9899 _values = new List<ExecutableElement>(initialCapacity); | 9899 _values = new List<ExecutableElement>(initialCapacity); |
| 9900 } | 9900 } |
| 9901 } | 9901 } |
| 9902 | 9902 |
| 9903 /** | 9903 /** |
| 9904 * This class is a wrapper for an [AnalysisError] which can also be queried afte
r resolution | 9904 * This class is a wrapper for an [AnalysisError] which can also be queried afte
r resolution |
| 9905 * to find out if the error should actually be reported. In this case, these err
ors are conditional | 9905 * to find out if the error should actually be reported. In this case, these err
ors are conditional |
| 9906 * on the non-existence of an `@proxy` annotation. | 9906 * on the non-existence of an `@proxy` annotation. |
| 9907 * | 9907 * |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10060 List<ProxyConditionalAnalysisError> get proxyConditionalAnalysisErrors => _pro
xyConditionalAnalysisErrors; | 10060 List<ProxyConditionalAnalysisError> get proxyConditionalAnalysisErrors => _pro
xyConditionalAnalysisErrors; |
| 10061 | 10061 |
| 10062 Object visitAsExpression(AsExpression node) { | 10062 Object visitAsExpression(AsExpression node) { |
| 10063 super.visitAsExpression(node); | 10063 super.visitAsExpression(node); |
| 10064 overrideExpression(node.expression, node.type.type); | 10064 overrideExpression(node.expression, node.type.type); |
| 10065 return null; | 10065 return null; |
| 10066 } | 10066 } |
| 10067 | 10067 |
| 10068 Object visitAssertStatement(AssertStatement node) { | 10068 Object visitAssertStatement(AssertStatement node) { |
| 10069 super.visitAssertStatement(node); | 10069 super.visitAssertStatement(node); |
| 10070 propagateTrueState(node.condition); | 10070 _propagateTrueState(node.condition); |
| 10071 return null; | 10071 return null; |
| 10072 } | 10072 } |
| 10073 | 10073 |
| 10074 Object visitBinaryExpression(BinaryExpression node) { | 10074 Object visitBinaryExpression(BinaryExpression node) { |
| 10075 sc.TokenType operatorType = node.operator.type; | 10075 sc.TokenType operatorType = node.operator.type; |
| 10076 Expression leftOperand = node.leftOperand; | 10076 Expression leftOperand = node.leftOperand; |
| 10077 Expression rightOperand = node.rightOperand; | 10077 Expression rightOperand = node.rightOperand; |
| 10078 if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) { | 10078 if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) { |
| 10079 safelyVisit(leftOperand); | 10079 safelyVisit(leftOperand); |
| 10080 if (rightOperand != null) { | 10080 if (rightOperand != null) { |
| 10081 try { | 10081 try { |
| 10082 _overrideManager.enterScope(); | 10082 _overrideManager.enterScope(); |
| 10083 _promoteManager.enterScope(); | 10083 _promoteManager.enterScope(); |
| 10084 propagateTrueState(leftOperand); | 10084 _propagateTrueState(leftOperand); |
| 10085 // Type promotion. | 10085 // Type promotion. |
| 10086 promoteTypes(leftOperand); | 10086 _promoteTypes(leftOperand); |
| 10087 clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); | 10087 _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand); |
| 10088 clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); | 10088 _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand); |
| 10089 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(rightOper
and); | 10089 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(rightOpe
rand); |
| 10090 // Visit right operand. | 10090 // Visit right operand. |
| 10091 rightOperand.accept(this); | 10091 rightOperand.accept(this); |
| 10092 } finally { | 10092 } finally { |
| 10093 _overrideManager.exitScope(); | 10093 _overrideManager.exitScope(); |
| 10094 _promoteManager.exitScope(); | 10094 _promoteManager.exitScope(); |
| 10095 } | 10095 } |
| 10096 } | 10096 } |
| 10097 } else if (identical(operatorType, sc.TokenType.BAR_BAR)) { | 10097 } else if (identical(operatorType, sc.TokenType.BAR_BAR)) { |
| 10098 safelyVisit(leftOperand); | 10098 safelyVisit(leftOperand); |
| 10099 if (rightOperand != null) { | 10099 if (rightOperand != null) { |
| 10100 try { | 10100 try { |
| 10101 _overrideManager.enterScope(); | 10101 _overrideManager.enterScope(); |
| 10102 propagateFalseState(leftOperand); | 10102 _propagateFalseState(leftOperand); |
| 10103 rightOperand.accept(this); | 10103 rightOperand.accept(this); |
| 10104 } finally { | 10104 } finally { |
| 10105 _overrideManager.exitScope(); | 10105 _overrideManager.exitScope(); |
| 10106 } | 10106 } |
| 10107 } | 10107 } |
| 10108 } else { | 10108 } else { |
| 10109 safelyVisit(leftOperand); | 10109 safelyVisit(leftOperand); |
| 10110 safelyVisit(rightOperand); | 10110 safelyVisit(rightOperand); |
| 10111 } | 10111 } |
| 10112 node.accept(_elementResolver); | 10112 node.accept(_elementResolver); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10207 } | 10207 } |
| 10208 | 10208 |
| 10209 Object visitConditionalExpression(ConditionalExpression node) { | 10209 Object visitConditionalExpression(ConditionalExpression node) { |
| 10210 Expression condition = node.condition; | 10210 Expression condition = node.condition; |
| 10211 safelyVisit(condition); | 10211 safelyVisit(condition); |
| 10212 Expression thenExpression = node.thenExpression; | 10212 Expression thenExpression = node.thenExpression; |
| 10213 if (thenExpression != null) { | 10213 if (thenExpression != null) { |
| 10214 try { | 10214 try { |
| 10215 _overrideManager.enterScope(); | 10215 _overrideManager.enterScope(); |
| 10216 _promoteManager.enterScope(); | 10216 _promoteManager.enterScope(); |
| 10217 propagateTrueState(condition); | 10217 _propagateTrueState(condition); |
| 10218 // Type promotion. | 10218 // Type promotion. |
| 10219 promoteTypes(condition); | 10219 _promoteTypes(condition); |
| 10220 clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); | 10220 _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression); |
| 10221 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenExpress
ion); | 10221 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenExpres
sion); |
| 10222 // Visit "then" expression. | 10222 // Visit "then" expression. |
| 10223 thenExpression.accept(this); | 10223 thenExpression.accept(this); |
| 10224 } finally { | 10224 } finally { |
| 10225 _overrideManager.exitScope(); | 10225 _overrideManager.exitScope(); |
| 10226 _promoteManager.exitScope(); | 10226 _promoteManager.exitScope(); |
| 10227 } | 10227 } |
| 10228 } | 10228 } |
| 10229 Expression elseExpression = node.elseExpression; | 10229 Expression elseExpression = node.elseExpression; |
| 10230 if (elseExpression != null) { | 10230 if (elseExpression != null) { |
| 10231 try { | 10231 try { |
| 10232 _overrideManager.enterScope(); | 10232 _overrideManager.enterScope(); |
| 10233 propagateFalseState(condition); | 10233 _propagateFalseState(condition); |
| 10234 elseExpression.accept(this); | 10234 elseExpression.accept(this); |
| 10235 } finally { | 10235 } finally { |
| 10236 _overrideManager.exitScope(); | 10236 _overrideManager.exitScope(); |
| 10237 } | 10237 } |
| 10238 } | 10238 } |
| 10239 node.accept(_elementResolver); | 10239 node.accept(_elementResolver); |
| 10240 node.accept(_typeAnalyzer); | 10240 node.accept(_typeAnalyzer); |
| 10241 bool thenIsAbrupt = isAbruptTerminationExpression(thenExpression); | 10241 bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression); |
| 10242 bool elseIsAbrupt = isAbruptTerminationExpression(elseExpression); | 10242 bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression); |
| 10243 if (elseIsAbrupt && !thenIsAbrupt) { | 10243 if (elseIsAbrupt && !thenIsAbrupt) { |
| 10244 propagateTrueState(condition); | 10244 _propagateTrueState(condition); |
| 10245 propagateState(thenExpression); | 10245 _propagateState(thenExpression); |
| 10246 } else if (thenIsAbrupt && !elseIsAbrupt) { | 10246 } else if (thenIsAbrupt && !elseIsAbrupt) { |
| 10247 propagateFalseState(condition); | 10247 _propagateFalseState(condition); |
| 10248 propagateState(elseExpression); | 10248 _propagateState(elseExpression); |
| 10249 } | 10249 } |
| 10250 return null; | 10250 return null; |
| 10251 } | 10251 } |
| 10252 | 10252 |
| 10253 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 10253 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 10254 ExecutableElement outerFunction = _enclosingFunction; | 10254 ExecutableElement outerFunction = _enclosingFunction; |
| 10255 try { | 10255 try { |
| 10256 _enclosingFunction = node.element; | 10256 _enclosingFunction = node.element; |
| 10257 super.visitConstructorDeclaration(node); | 10257 super.visitConstructorDeclaration(node); |
| 10258 } finally { | 10258 } finally { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10372 } finally { | 10372 } finally { |
| 10373 _overrideManager.exitScope(); | 10373 _overrideManager.exitScope(); |
| 10374 _enclosingFunction = outerFunction; | 10374 _enclosingFunction = outerFunction; |
| 10375 } | 10375 } |
| 10376 return null; | 10376 return null; |
| 10377 } | 10377 } |
| 10378 | 10378 |
| 10379 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 10379 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 10380 safelyVisit(node.function); | 10380 safelyVisit(node.function); |
| 10381 node.accept(_elementResolver); | 10381 node.accept(_elementResolver); |
| 10382 inferFunctionExpressionsParametersTypes(node.argumentList); | 10382 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 10383 safelyVisit(node.argumentList); | 10383 safelyVisit(node.argumentList); |
| 10384 node.accept(_typeAnalyzer); | 10384 node.accept(_typeAnalyzer); |
| 10385 return null; | 10385 return null; |
| 10386 } | 10386 } |
| 10387 | 10387 |
| 10388 Object visitHideCombinator(HideCombinator node) => null; | 10388 Object visitHideCombinator(HideCombinator node) => null; |
| 10389 | 10389 |
| 10390 Object visitIfStatement(IfStatement node) { | 10390 Object visitIfStatement(IfStatement node) { |
| 10391 Expression condition = node.condition; | 10391 Expression condition = node.condition; |
| 10392 safelyVisit(condition); | 10392 safelyVisit(condition); |
| 10393 Map<Element, Type2> thenOverrides = null; | 10393 Map<Element, Type2> thenOverrides = null; |
| 10394 Statement thenStatement = node.thenStatement; | 10394 Statement thenStatement = node.thenStatement; |
| 10395 if (thenStatement != null) { | 10395 if (thenStatement != null) { |
| 10396 try { | 10396 try { |
| 10397 _overrideManager.enterScope(); | 10397 _overrideManager.enterScope(); |
| 10398 _promoteManager.enterScope(); | 10398 _promoteManager.enterScope(); |
| 10399 propagateTrueState(condition); | 10399 _propagateTrueState(condition); |
| 10400 // Type promotion. | 10400 // Type promotion. |
| 10401 promoteTypes(condition); | 10401 _promoteTypes(condition); |
| 10402 clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); | 10402 _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); |
| 10403 clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStateme
nt); | 10403 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStatem
ent); |
| 10404 // Visit "then". | 10404 // Visit "then". |
| 10405 visitStatementInScope(thenStatement); | 10405 visitStatementInScope(thenStatement); |
| 10406 } finally { | 10406 } finally { |
| 10407 thenOverrides = _overrideManager.captureLocalOverrides(); | 10407 thenOverrides = _overrideManager.captureLocalOverrides(); |
| 10408 _overrideManager.exitScope(); | 10408 _overrideManager.exitScope(); |
| 10409 _promoteManager.exitScope(); | 10409 _promoteManager.exitScope(); |
| 10410 } | 10410 } |
| 10411 } | 10411 } |
| 10412 Map<Element, Type2> elseOverrides = null; | 10412 Map<Element, Type2> elseOverrides = null; |
| 10413 Statement elseStatement = node.elseStatement; | 10413 Statement elseStatement = node.elseStatement; |
| 10414 if (elseStatement != null) { | 10414 if (elseStatement != null) { |
| 10415 try { | 10415 try { |
| 10416 _overrideManager.enterScope(); | 10416 _overrideManager.enterScope(); |
| 10417 propagateFalseState(condition); | 10417 _propagateFalseState(condition); |
| 10418 visitStatementInScope(elseStatement); | 10418 visitStatementInScope(elseStatement); |
| 10419 } finally { | 10419 } finally { |
| 10420 elseOverrides = _overrideManager.captureLocalOverrides(); | 10420 elseOverrides = _overrideManager.captureLocalOverrides(); |
| 10421 _overrideManager.exitScope(); | 10421 _overrideManager.exitScope(); |
| 10422 } | 10422 } |
| 10423 } | 10423 } |
| 10424 node.accept(_elementResolver); | 10424 node.accept(_elementResolver); |
| 10425 node.accept(_typeAnalyzer); | 10425 node.accept(_typeAnalyzer); |
| 10426 bool thenIsAbrupt = isAbruptTerminationStatement(thenStatement); | 10426 bool thenIsAbrupt = _isAbruptTerminationStatement(thenStatement); |
| 10427 bool elseIsAbrupt = isAbruptTerminationStatement(elseStatement); | 10427 bool elseIsAbrupt = _isAbruptTerminationStatement(elseStatement); |
| 10428 if (elseIsAbrupt && !thenIsAbrupt) { | 10428 if (elseIsAbrupt && !thenIsAbrupt) { |
| 10429 propagateTrueState(condition); | 10429 _propagateTrueState(condition); |
| 10430 if (thenOverrides != null) { | 10430 if (thenOverrides != null) { |
| 10431 _overrideManager.applyOverrides(thenOverrides); | 10431 _overrideManager.applyOverrides(thenOverrides); |
| 10432 } | 10432 } |
| 10433 } else if (thenIsAbrupt && !elseIsAbrupt) { | 10433 } else if (thenIsAbrupt && !elseIsAbrupt) { |
| 10434 propagateFalseState(condition); | 10434 _propagateFalseState(condition); |
| 10435 if (elseOverrides != null) { | 10435 if (elseOverrides != null) { |
| 10436 _overrideManager.applyOverrides(elseOverrides); | 10436 _overrideManager.applyOverrides(elseOverrides); |
| 10437 } | 10437 } |
| 10438 } | 10438 } |
| 10439 return null; | 10439 return null; |
| 10440 } | 10440 } |
| 10441 | 10441 |
| 10442 Object visitLabel(Label node) => null; | 10442 Object visitLabel(Label node) => null; |
| 10443 | 10443 |
| 10444 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 10444 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
| 10445 | 10445 |
| 10446 Object visitMethodDeclaration(MethodDeclaration node) { | 10446 Object visitMethodDeclaration(MethodDeclaration node) { |
| 10447 ExecutableElement outerFunction = _enclosingFunction; | 10447 ExecutableElement outerFunction = _enclosingFunction; |
| 10448 try { | 10448 try { |
| 10449 _enclosingFunction = node.element; | 10449 _enclosingFunction = node.element; |
| 10450 super.visitMethodDeclaration(node); | 10450 super.visitMethodDeclaration(node); |
| 10451 } finally { | 10451 } finally { |
| 10452 _enclosingFunction = outerFunction; | 10452 _enclosingFunction = outerFunction; |
| 10453 } | 10453 } |
| 10454 return null; | 10454 return null; |
| 10455 } | 10455 } |
| 10456 | 10456 |
| 10457 Object visitMethodInvocation(MethodInvocation node) { | 10457 Object visitMethodInvocation(MethodInvocation node) { |
| 10458 // | 10458 // |
| 10459 // We visit the target and argument list, but do not visit the method name b
ecause it needs to | 10459 // We visit the target and argument list, but do not visit the method name b
ecause it needs to |
| 10460 // be visited in the context of the invocation. | 10460 // be visited in the context of the invocation. |
| 10461 // | 10461 // |
| 10462 safelyVisit(node.target); | 10462 safelyVisit(node.target); |
| 10463 node.accept(_elementResolver); | 10463 node.accept(_elementResolver); |
| 10464 inferFunctionExpressionsParametersTypes(node.argumentList); | 10464 _inferFunctionExpressionsParametersTypes(node.argumentList); |
| 10465 safelyVisit(node.argumentList); | 10465 safelyVisit(node.argumentList); |
| 10466 node.accept(_typeAnalyzer); | 10466 node.accept(_typeAnalyzer); |
| 10467 return null; | 10467 return null; |
| 10468 } | 10468 } |
| 10469 | 10469 |
| 10470 Object visitNode(AstNode node) { | 10470 Object visitNode(AstNode node) { |
| 10471 node.visitChildren(this); | 10471 node.visitChildren(this); |
| 10472 node.accept(_elementResolver); | 10472 node.accept(_elementResolver); |
| 10473 node.accept(_typeAnalyzer); | 10473 node.accept(_typeAnalyzer); |
| 10474 return null; | 10474 return null; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10554 | 10554 |
| 10555 Object visitTypeName(TypeName node) => null; | 10555 Object visitTypeName(TypeName node) => null; |
| 10556 | 10556 |
| 10557 Object visitWhileStatement(WhileStatement node) { | 10557 Object visitWhileStatement(WhileStatement node) { |
| 10558 Expression condition = node.condition; | 10558 Expression condition = node.condition; |
| 10559 safelyVisit(condition); | 10559 safelyVisit(condition); |
| 10560 Statement body = node.body; | 10560 Statement body = node.body; |
| 10561 if (body != null) { | 10561 if (body != null) { |
| 10562 try { | 10562 try { |
| 10563 _overrideManager.enterScope(); | 10563 _overrideManager.enterScope(); |
| 10564 propagateTrueState(condition); | 10564 _propagateTrueState(condition); |
| 10565 visitStatementInScope(body); | 10565 visitStatementInScope(body); |
| 10566 } finally { | 10566 } finally { |
| 10567 _overrideManager.exitScope(); | 10567 _overrideManager.exitScope(); |
| 10568 } | 10568 } |
| 10569 } | 10569 } |
| 10570 // TODO(brianwilkerson) If the loop can only be exited because the condition
is false, then | 10570 // TODO(brianwilkerson) If the loop can only be exited because the condition
is false, then |
| 10571 // propagateFalseState(condition); | 10571 // propagateFalseState(condition); |
| 10572 node.accept(_elementResolver); | 10572 node.accept(_elementResolver); |
| 10573 node.accept(_typeAnalyzer); | 10573 node.accept(_typeAnalyzer); |
| 10574 return null; | 10574 return null; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10694 void overrideVariable(VariableElement element, Type2 potentialType) { | 10694 void overrideVariable(VariableElement element, Type2 potentialType) { |
| 10695 if (potentialType == null || potentialType.isBottom) { | 10695 if (potentialType == null || potentialType.isBottom) { |
| 10696 return; | 10696 return; |
| 10697 } | 10697 } |
| 10698 if (element is PropertyInducingElement) { | 10698 if (element is PropertyInducingElement) { |
| 10699 PropertyInducingElement variable = element; | 10699 PropertyInducingElement variable = element; |
| 10700 if (!variable.isConst && !variable.isFinal) { | 10700 if (!variable.isConst && !variable.isFinal) { |
| 10701 return; | 10701 return; |
| 10702 } | 10702 } |
| 10703 } | 10703 } |
| 10704 Type2 currentType = getBestType(element); | 10704 Type2 currentType = _getBestType(element); |
| 10705 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) { | 10705 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) { |
| 10706 _overrideManager.setType(element, potentialType); | 10706 _overrideManager.setType(element, potentialType); |
| 10707 } | 10707 } |
| 10708 } | 10708 } |
| 10709 | 10709 |
| 10710 /** | 10710 /** |
| 10711 * Report a conditional analysis error with the given error code and arguments
. | 10711 * Report a conditional analysis error with the given error code and arguments
. |
| 10712 * | 10712 * |
| 10713 * @param enclosingElement the enclosing element | 10713 * @param enclosingElement the enclosing element |
| 10714 * @param errorCode the error code of the error to be reported | 10714 * @param errorCode the error code of the error to be reported |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10755 SimpleIdentifier identifier = node.identifier; | 10755 SimpleIdentifier identifier = node.identifier; |
| 10756 safelyVisit(loopVariable); | 10756 safelyVisit(loopVariable); |
| 10757 safelyVisit(identifier); | 10757 safelyVisit(identifier); |
| 10758 Statement body = node.body; | 10758 Statement body = node.body; |
| 10759 if (body != null) { | 10759 if (body != null) { |
| 10760 try { | 10760 try { |
| 10761 _overrideManager.enterScope(); | 10761 _overrideManager.enterScope(); |
| 10762 if (loopVariable != null && iterator != null) { | 10762 if (loopVariable != null && iterator != null) { |
| 10763 LocalVariableElement loopElement = loopVariable.element; | 10763 LocalVariableElement loopElement = loopVariable.element; |
| 10764 if (loopElement != null) { | 10764 if (loopElement != null) { |
| 10765 Type2 iteratorElementType = getIteratorElementType(iterator); | 10765 Type2 iteratorElementType = _getIteratorElementType(iterator); |
| 10766 overrideVariable(loopElement, iteratorElementType); | 10766 overrideVariable(loopElement, iteratorElementType); |
| 10767 recordPropagatedType(loopVariable.identifier, iteratorElementType); | 10767 _recordPropagatedType(loopVariable.identifier, iteratorElementType); |
| 10768 } | 10768 } |
| 10769 } else if (identifier != null && iterator != null) { | 10769 } else if (identifier != null && iterator != null) { |
| 10770 Element identifierElement = identifier.staticElement; | 10770 Element identifierElement = identifier.staticElement; |
| 10771 if (identifierElement is VariableElement) { | 10771 if (identifierElement is VariableElement) { |
| 10772 Type2 iteratorElementType = getIteratorElementType(iterator); | 10772 Type2 iteratorElementType = _getIteratorElementType(iterator); |
| 10773 overrideVariable(identifierElement, iteratorElementType); | 10773 overrideVariable(identifierElement, iteratorElementType); |
| 10774 recordPropagatedType(identifier, iteratorElementType); | 10774 _recordPropagatedType(identifier, iteratorElementType); |
| 10775 } | 10775 } |
| 10776 } | 10776 } |
| 10777 visitStatementInScope(body); | 10777 visitStatementInScope(body); |
| 10778 } finally { | 10778 } finally { |
| 10779 _overrideManager.exitScope(); | 10779 _overrideManager.exitScope(); |
| 10780 } | 10780 } |
| 10781 } | 10781 } |
| 10782 node.accept(_elementResolver); | 10782 node.accept(_elementResolver); |
| 10783 node.accept(_typeAnalyzer); | 10783 node.accept(_typeAnalyzer); |
| 10784 } | 10784 } |
| 10785 | 10785 |
| 10786 void visitForStatementInScope(ForStatement node) { | 10786 void visitForStatementInScope(ForStatement node) { |
| 10787 safelyVisit(node.variables); | 10787 safelyVisit(node.variables); |
| 10788 safelyVisit(node.initialization); | 10788 safelyVisit(node.initialization); |
| 10789 safelyVisit(node.condition); | 10789 safelyVisit(node.condition); |
| 10790 _overrideManager.enterScope(); | 10790 _overrideManager.enterScope(); |
| 10791 try { | 10791 try { |
| 10792 propagateTrueState(node.condition); | 10792 _propagateTrueState(node.condition); |
| 10793 visitStatementInScope(node.body); | 10793 visitStatementInScope(node.body); |
| 10794 node.updaters.accept(this); | 10794 node.updaters.accept(this); |
| 10795 } finally { | 10795 } finally { |
| 10796 _overrideManager.exitScope(); | 10796 _overrideManager.exitScope(); |
| 10797 } | 10797 } |
| 10798 } | 10798 } |
| 10799 | 10799 |
| 10800 /** | 10800 /** |
| 10801 * Checks each promoted variable in the current scope for compliance with the
following | 10801 * Checks each promoted variable in the current scope for compliance with the
following |
| 10802 * specification statement: | 10802 * specification statement: |
| 10803 * | 10803 * |
| 10804 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t
hen the variable | 10804 * If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i> t
hen the variable |
| 10805 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. | 10805 * <i>v</i> is not potentially mutated anywhere in the scope of <i>v</i>. |
| 10806 */ | 10806 */ |
| 10807 void clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(AstNode targ
et) { | 10807 void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(AstNode tar
get) { |
| 10808 for (Element element in _promoteManager.promotedElements) { | 10808 for (Element element in _promoteManager.promotedElements) { |
| 10809 if ((element as VariableElementImpl).isPotentiallyMutatedInScope) { | 10809 if ((element as VariableElementImpl).isPotentiallyMutatedInScope) { |
| 10810 if (isVariableAccessedInClosure(element, target)) { | 10810 if (_isVariableAccessedInClosure(element, target)) { |
| 10811 _promoteManager.setType(element, null); | 10811 _promoteManager.setType(element, null); |
| 10812 } | 10812 } |
| 10813 } | 10813 } |
| 10814 } | 10814 } |
| 10815 } | 10815 } |
| 10816 | 10816 |
| 10817 /** | 10817 /** |
| 10818 * Checks each promoted variable in the current scope for compliance with the
following | 10818 * Checks each promoted variable in the current scope for compliance with the
following |
| 10819 * specification statement: | 10819 * specification statement: |
| 10820 * | 10820 * |
| 10821 * <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a clo
sure. | 10821 * <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a clo
sure. |
| 10822 */ | 10822 */ |
| 10823 void clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) { | 10823 void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) { |
| 10824 for (Element element in _promoteManager.promotedElements) { | 10824 for (Element element in _promoteManager.promotedElements) { |
| 10825 if (isVariablePotentiallyMutatedIn(element, target)) { | 10825 if (_isVariablePotentiallyMutatedIn(element, target)) { |
| 10826 _promoteManager.setType(element, null); | 10826 _promoteManager.setType(element, null); |
| 10827 } | 10827 } |
| 10828 } | 10828 } |
| 10829 } | 10829 } |
| 10830 | 10830 |
| 10831 /** | 10831 /** |
| 10832 * Return the best type information available for the given element. If the ty
pe of the element | 10832 * Return the best type information available for the given element. If the ty
pe of the element |
| 10833 * has been overridden, then return the overriding type. Otherwise, return the
static type. | 10833 * has been overridden, then return the overriding type. Otherwise, return the
static type. |
| 10834 * | 10834 * |
| 10835 * @param element the element for which type information is to be returned | 10835 * @param element the element for which type information is to be returned |
| 10836 * @return the best type information available for the given element | 10836 * @return the best type information available for the given element |
| 10837 */ | 10837 */ |
| 10838 Type2 getBestType(Element element) { | 10838 Type2 _getBestType(Element element) { |
| 10839 Type2 bestType = _overrideManager.getType(element); | 10839 Type2 bestType = _overrideManager.getType(element); |
| 10840 if (bestType == null) { | 10840 if (bestType == null) { |
| 10841 if (element is LocalVariableElement) { | 10841 if (element is LocalVariableElement) { |
| 10842 bestType = element.type; | 10842 bestType = element.type; |
| 10843 } else if (element is ParameterElement) { | 10843 } else if (element is ParameterElement) { |
| 10844 bestType = element.type; | 10844 bestType = element.type; |
| 10845 } | 10845 } |
| 10846 } | 10846 } |
| 10847 return bestType; | 10847 return bestType; |
| 10848 } | 10848 } |
| 10849 | 10849 |
| 10850 /** | 10850 /** |
| 10851 * The given expression is the expression used to compute the iterator for a f
or-each statement. | 10851 * The given expression is the expression used to compute the iterator for a f
or-each statement. |
| 10852 * Attempt to compute the type of objects that will be assigned to the loop va
riable and return | 10852 * Attempt to compute the type of objects that will be assigned to the loop va
riable and return |
| 10853 * that type. Return `null` if the type could not be determined. | 10853 * that type. Return `null` if the type could not be determined. |
| 10854 * | 10854 * |
| 10855 * @param iterator the iterator for a for-each statement | 10855 * @param iterator the iterator for a for-each statement |
| 10856 * @return the type of objects that will be assigned to the loop variable | 10856 * @return the type of objects that will be assigned to the loop variable |
| 10857 */ | 10857 */ |
| 10858 Type2 getIteratorElementType(Expression iteratorExpression) { | 10858 Type2 _getIteratorElementType(Expression iteratorExpression) { |
| 10859 Type2 expressionType = iteratorExpression.staticType; | 10859 Type2 expressionType = iteratorExpression.staticType; |
| 10860 if (expressionType is InterfaceType) { | 10860 if (expressionType is InterfaceType) { |
| 10861 InterfaceType interfaceType = expressionType; | 10861 InterfaceType interfaceType = expressionType; |
| 10862 FunctionType iteratorFunction = _inheritanceManager.lookupMemberType(inter
faceType, "iterator"); | 10862 FunctionType iteratorFunction = _inheritanceManager.lookupMemberType(inter
faceType, "iterator"); |
| 10863 if (iteratorFunction == null) { | 10863 if (iteratorFunction == null) { |
| 10864 // TODO(brianwilkerson) Should we report this error? | 10864 // TODO(brianwilkerson) Should we report this error? |
| 10865 return null; | 10865 return null; |
| 10866 } | 10866 } |
| 10867 Type2 iteratorType = iteratorFunction.returnType; | 10867 Type2 iteratorType = iteratorFunction.returnType; |
| 10868 if (iteratorType is InterfaceType) { | 10868 if (iteratorType is InterfaceType) { |
| 10869 InterfaceType iteratorInterfaceType = iteratorType; | 10869 InterfaceType iteratorInterfaceType = iteratorType; |
| 10870 FunctionType currentFunction = _inheritanceManager.lookupMemberType(iter
atorInterfaceType, "current"); | 10870 FunctionType currentFunction = _inheritanceManager.lookupMemberType(iter
atorInterfaceType, "current"); |
| 10871 if (currentFunction == null) { | 10871 if (currentFunction == null) { |
| 10872 // TODO(brianwilkerson) Should we report this error? | 10872 // TODO(brianwilkerson) Should we report this error? |
| 10873 return null; | 10873 return null; |
| 10874 } | 10874 } |
| 10875 return currentFunction.returnType; | 10875 return currentFunction.returnType; |
| 10876 } | 10876 } |
| 10877 } | 10877 } |
| 10878 return null; | 10878 return null; |
| 10879 } | 10879 } |
| 10880 | 10880 |
| 10881 /** | 10881 /** |
| 10882 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its | 10882 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its |
| 10883 * required type is [FunctionType], then infer parameters types from [Function
Type]. | 10883 * required type is [FunctionType], then infer parameters types from [Function
Type]. |
| 10884 */ | 10884 */ |
| 10885 void inferFunctionExpressionParametersTypes(Expression mayBeClosure, Type2 may
ByFunctionType) { | 10885 void _inferFunctionExpressionParametersTypes(Expression mayBeClosure, Type2 ma
yByFunctionType) { |
| 10886 // prepare closure | 10886 // prepare closure |
| 10887 if (mayBeClosure is! FunctionExpression) { | 10887 if (mayBeClosure is! FunctionExpression) { |
| 10888 return; | 10888 return; |
| 10889 } | 10889 } |
| 10890 FunctionExpression closure = mayBeClosure as FunctionExpression; | 10890 FunctionExpression closure = mayBeClosure as FunctionExpression; |
| 10891 // prepare expected closure type | 10891 // prepare expected closure type |
| 10892 if (mayByFunctionType is! FunctionType) { | 10892 if (mayByFunctionType is! FunctionType) { |
| 10893 return; | 10893 return; |
| 10894 } | 10894 } |
| 10895 FunctionType expectedClosureType = mayByFunctionType as FunctionType; | 10895 FunctionType expectedClosureType = mayByFunctionType as FunctionType; |
| 10896 // set propagated type for the closure | 10896 // set propagated type for the closure |
| 10897 closure.propagatedType = expectedClosureType; | 10897 closure.propagatedType = expectedClosureType; |
| 10898 // set inferred types for parameters | 10898 // set inferred types for parameters |
| 10899 NodeList<FormalParameter> parameters = closure.parameters.parameters; | 10899 NodeList<FormalParameter> parameters = closure.parameters.parameters; |
| 10900 List<ParameterElement> expectedParameters = expectedClosureType.parameters; | 10900 List<ParameterElement> expectedParameters = expectedClosureType.parameters; |
| 10901 for (int i = 0; i < parameters.length && i < expectedParameters.length; i++)
{ | 10901 for (int i = 0; i < parameters.length && i < expectedParameters.length; i++)
{ |
| 10902 FormalParameter parameter = parameters[i]; | 10902 FormalParameter parameter = parameters[i]; |
| 10903 ParameterElement element = parameter.element; | 10903 ParameterElement element = parameter.element; |
| 10904 Type2 currentType = getBestType(element); | 10904 Type2 currentType = _getBestType(element); |
| 10905 // may be override the type | 10905 // may be override the type |
| 10906 Type2 expectedType = expectedParameters[i].type; | 10906 Type2 expectedType = expectedParameters[i].type; |
| 10907 if (currentType == null || expectedType.isMoreSpecificThan(currentType)) { | 10907 if (currentType == null || expectedType.isMoreSpecificThan(currentType)) { |
| 10908 _overrideManager.setType(element, expectedType); | 10908 _overrideManager.setType(element, expectedType); |
| 10909 } | 10909 } |
| 10910 } | 10910 } |
| 10911 } | 10911 } |
| 10912 | 10912 |
| 10913 /** | 10913 /** |
| 10914 * Try to infer types of parameters of the [FunctionExpression] arguments. | 10914 * Try to infer types of parameters of the [FunctionExpression] arguments. |
| 10915 */ | 10915 */ |
| 10916 void inferFunctionExpressionsParametersTypes(ArgumentList argumentList) { | 10916 void _inferFunctionExpressionsParametersTypes(ArgumentList argumentList) { |
| 10917 for (Expression argument in argumentList.arguments) { | 10917 for (Expression argument in argumentList.arguments) { |
| 10918 ParameterElement parameter = argument.propagatedParameterElement; | 10918 ParameterElement parameter = argument.propagatedParameterElement; |
| 10919 if (parameter == null) { | 10919 if (parameter == null) { |
| 10920 parameter = argument.staticParameterElement; | 10920 parameter = argument.staticParameterElement; |
| 10921 } | 10921 } |
| 10922 if (parameter != null) { | 10922 if (parameter != null) { |
| 10923 inferFunctionExpressionParametersTypes(argument, parameter.type); | 10923 _inferFunctionExpressionParametersTypes(argument, parameter.type); |
| 10924 } | 10924 } |
| 10925 } | 10925 } |
| 10926 } | 10926 } |
| 10927 | 10927 |
| 10928 /** | 10928 /** |
| 10929 * Return `true` if the given expression terminates abruptly (that is, if any
expression | 10929 * Return `true` if the given expression terminates abruptly (that is, if any
expression |
| 10930 * following the given expression will not be reached). | 10930 * following the given expression will not be reached). |
| 10931 * | 10931 * |
| 10932 * @param expression the expression being tested | 10932 * @param expression the expression being tested |
| 10933 * @return `true` if the given expression terminates abruptly | 10933 * @return `true` if the given expression terminates abruptly |
| 10934 */ | 10934 */ |
| 10935 bool isAbruptTerminationExpression(Expression expression) { | 10935 bool _isAbruptTerminationExpression(Expression expression) { |
| 10936 // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
would eventually | 10936 // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
would eventually |
| 10937 // turn this into a method on Expression that returns a termination indicati
on (normal, abrupt | 10937 // turn this into a method on Expression that returns a termination indicati
on (normal, abrupt |
| 10938 // with no exception, abrupt with an exception). | 10938 // with no exception, abrupt with an exception). |
| 10939 while (expression is ParenthesizedExpression) { | 10939 while (expression is ParenthesizedExpression) { |
| 10940 expression = (expression as ParenthesizedExpression).expression; | 10940 expression = (expression as ParenthesizedExpression).expression; |
| 10941 } | 10941 } |
| 10942 return expression is ThrowExpression || expression is RethrowExpression; | 10942 return expression is ThrowExpression || expression is RethrowExpression; |
| 10943 } | 10943 } |
| 10944 | 10944 |
| 10945 /** | 10945 /** |
| 10946 * Return `true` if the given statement terminates abruptly (that is, if any s
tatement | 10946 * Return `true` if the given statement terminates abruptly (that is, if any s
tatement |
| 10947 * following the given statement will not be reached). | 10947 * following the given statement will not be reached). |
| 10948 * | 10948 * |
| 10949 * @param statement the statement being tested | 10949 * @param statement the statement being tested |
| 10950 * @return `true` if the given statement terminates abruptly | 10950 * @return `true` if the given statement terminates abruptly |
| 10951 */ | 10951 */ |
| 10952 bool isAbruptTerminationStatement(Statement statement) { | 10952 bool _isAbruptTerminationStatement(Statement statement) { |
| 10953 // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
would eventually | 10953 // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
would eventually |
| 10954 // turn this into a method on Statement that returns a termination indicatio
n (normal, abrupt | 10954 // turn this into a method on Statement that returns a termination indicatio
n (normal, abrupt |
| 10955 // with no exception, abrupt with an exception). | 10955 // with no exception, abrupt with an exception). |
| 10956 if (statement is ReturnStatement || statement is BreakStatement || statement
is ContinueStatement) { | 10956 if (statement is ReturnStatement || statement is BreakStatement || statement
is ContinueStatement) { |
| 10957 return true; | 10957 return true; |
| 10958 } else if (statement is ExpressionStatement) { | 10958 } else if (statement is ExpressionStatement) { |
| 10959 return isAbruptTerminationExpression(statement.expression); | 10959 return _isAbruptTerminationExpression(statement.expression); |
| 10960 } else if (statement is Block) { | 10960 } else if (statement is Block) { |
| 10961 NodeList<Statement> statements = statement.statements; | 10961 NodeList<Statement> statements = statement.statements; |
| 10962 int size = statements.length; | 10962 int size = statements.length; |
| 10963 if (size == 0) { | 10963 if (size == 0) { |
| 10964 return false; | 10964 return false; |
| 10965 } | 10965 } |
| 10966 return isAbruptTerminationStatement(statements[size - 1]); | 10966 return _isAbruptTerminationStatement(statements[size - 1]); |
| 10967 } | 10967 } |
| 10968 return false; | 10968 return false; |
| 10969 } | 10969 } |
| 10970 | 10970 |
| 10971 /** | 10971 /** |
| 10972 * Return `true` if the given variable is accessed within a closure in the giv
en | 10972 * Return `true` if the given variable is accessed within a closure in the giv
en |
| 10973 * [AstNode] and also mutated somewhere in variable scope. This information is
only | 10973 * [AstNode] and also mutated somewhere in variable scope. This information is
only |
| 10974 * available for local variables (including parameters). | 10974 * available for local variables (including parameters). |
| 10975 * | 10975 * |
| 10976 * @param variable the variable to check | 10976 * @param variable the variable to check |
| 10977 * @param target the [AstNode] to check within | 10977 * @param target the [AstNode] to check within |
| 10978 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode | 10978 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode |
| 10979 */ | 10979 */ |
| 10980 bool isVariableAccessedInClosure(Element variable, AstNode target) { | 10980 bool _isVariableAccessedInClosure(Element variable, AstNode target) { |
| 10981 List<bool> result = [false]; | 10981 List<bool> result = [false]; |
| 10982 target.accept(new RecursiveAstVisitor_ResolverVisitor_isVariableAccessedInCl
osure(result, variable)); | 10982 target.accept(new RecursiveAstVisitor_ResolverVisitor_isVariableAccessedInCl
osure(result, variable)); |
| 10983 return result[0]; | 10983 return result[0]; |
| 10984 } | 10984 } |
| 10985 | 10985 |
| 10986 /** | 10986 /** |
| 10987 * Return `true` if the given variable is potentially mutated somewhere in the
given | 10987 * Return `true` if the given variable is potentially mutated somewhere in the
given |
| 10988 * [AstNode]. This information is only available for local variables (includin
g parameters). | 10988 * [AstNode]. This information is only available for local variables (includin
g parameters). |
| 10989 * | 10989 * |
| 10990 * @param variable the variable to check | 10990 * @param variable the variable to check |
| 10991 * @param target the [AstNode] to check within | 10991 * @param target the [AstNode] to check within |
| 10992 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode | 10992 * @return `true` if this variable is potentially mutated somewhere in the giv
en ASTNode |
| 10993 */ | 10993 */ |
| 10994 bool isVariablePotentiallyMutatedIn(Element variable, AstNode target) { | 10994 bool _isVariablePotentiallyMutatedIn(Element variable, AstNode target) { |
| 10995 List<bool> result = [false]; | 10995 List<bool> result = [false]; |
| 10996 target.accept(new RecursiveAstVisitor_ResolverVisitor_isVariablePotentiallyM
utatedIn(result, variable)); | 10996 target.accept(new RecursiveAstVisitor_ResolverVisitor_isVariablePotentiallyM
utatedIn(result, variable)); |
| 10997 return result[0]; | 10997 return result[0]; |
| 10998 } | 10998 } |
| 10999 | 10999 |
| 11000 /** | 11000 /** |
| 11001 * If it is appropriate to do so, promotes the current type of the static elem
ent associated with | 11001 * If it is appropriate to do so, promotes the current type of the static elem
ent associated with |
| 11002 * the given expression with the given type. Generally speaking, it is appropr
iate if the given | 11002 * the given expression with the given type. Generally speaking, it is appropr
iate if the given |
| 11003 * type is more specific than the current type. | 11003 * type is more specific than the current type. |
| 11004 * | 11004 * |
| 11005 * @param expression the expression used to access the static element whose ty
pes might be | 11005 * @param expression the expression used to access the static element whose ty
pes might be |
| 11006 * promoted | 11006 * promoted |
| 11007 * @param potentialType the potential type of the elements | 11007 * @param potentialType the potential type of the elements |
| 11008 */ | 11008 */ |
| 11009 void promote(Expression expression, Type2 potentialType) { | 11009 void _promote(Expression expression, Type2 potentialType) { |
| 11010 VariableElement element = getPromotionStaticElement(expression); | 11010 VariableElement element = getPromotionStaticElement(expression); |
| 11011 if (element != null) { | 11011 if (element != null) { |
| 11012 // may be mutated somewhere in closure | 11012 // may be mutated somewhere in closure |
| 11013 if ((element as VariableElementImpl).isPotentiallyMutatedInClosure) { | 11013 if ((element as VariableElementImpl).isPotentiallyMutatedInClosure) { |
| 11014 return; | 11014 return; |
| 11015 } | 11015 } |
| 11016 // prepare current variable type | 11016 // prepare current variable type |
| 11017 Type2 type = _promoteManager.getType(element); | 11017 Type2 type = _promoteManager.getType(element); |
| 11018 if (type == null) { | 11018 if (type == null) { |
| 11019 type = expression.staticType; | 11019 type = expression.staticType; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 11031 return; | 11031 return; |
| 11032 } | 11032 } |
| 11033 // Do promote type of variable. | 11033 // Do promote type of variable. |
| 11034 _promoteManager.setType(element, potentialType); | 11034 _promoteManager.setType(element, potentialType); |
| 11035 } | 11035 } |
| 11036 } | 11036 } |
| 11037 | 11037 |
| 11038 /** | 11038 /** |
| 11039 * Promotes type information using given condition. | 11039 * Promotes type information using given condition. |
| 11040 */ | 11040 */ |
| 11041 void promoteTypes(Expression condition) { | 11041 void _promoteTypes(Expression condition) { |
| 11042 if (condition is BinaryExpression) { | 11042 if (condition is BinaryExpression) { |
| 11043 BinaryExpression binary = condition; | 11043 BinaryExpression binary = condition; |
| 11044 if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) { | 11044 if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) { |
| 11045 Expression left = binary.leftOperand; | 11045 Expression left = binary.leftOperand; |
| 11046 Expression right = binary.rightOperand; | 11046 Expression right = binary.rightOperand; |
| 11047 promoteTypes(left); | 11047 _promoteTypes(left); |
| 11048 promoteTypes(right); | 11048 _promoteTypes(right); |
| 11049 clearTypePromotionsIfPotentiallyMutatedIn(right); | 11049 _clearTypePromotionsIfPotentiallyMutatedIn(right); |
| 11050 } | 11050 } |
| 11051 } else if (condition is IsExpression) { | 11051 } else if (condition is IsExpression) { |
| 11052 IsExpression is2 = condition; | 11052 IsExpression is2 = condition; |
| 11053 if (is2.notOperator == null) { | 11053 if (is2.notOperator == null) { |
| 11054 promote(is2.expression, is2.type.type); | 11054 _promote(is2.expression, is2.type.type); |
| 11055 } | 11055 } |
| 11056 } else if (condition is ParenthesizedExpression) { | 11056 } else if (condition is ParenthesizedExpression) { |
| 11057 promoteTypes(condition.expression); | 11057 _promoteTypes(condition.expression); |
| 11058 } | 11058 } |
| 11059 } | 11059 } |
| 11060 | 11060 |
| 11061 /** | 11061 /** |
| 11062 * Propagate any type information that results from knowing that the given con
dition will have | 11062 * Propagate any type information that results from knowing that the given con
dition will have |
| 11063 * been evaluated to 'false'. | 11063 * been evaluated to 'false'. |
| 11064 * | 11064 * |
| 11065 * @param condition the condition that will have evaluated to 'false' | 11065 * @param condition the condition that will have evaluated to 'false' |
| 11066 */ | 11066 */ |
| 11067 void propagateFalseState(Expression condition) { | 11067 void _propagateFalseState(Expression condition) { |
| 11068 if (condition is BinaryExpression) { | 11068 if (condition is BinaryExpression) { |
| 11069 BinaryExpression binary = condition; | 11069 BinaryExpression binary = condition; |
| 11070 if (identical(binary.operator.type, sc.TokenType.BAR_BAR)) { | 11070 if (identical(binary.operator.type, sc.TokenType.BAR_BAR)) { |
| 11071 propagateFalseState(binary.leftOperand); | 11071 _propagateFalseState(binary.leftOperand); |
| 11072 propagateFalseState(binary.rightOperand); | 11072 _propagateFalseState(binary.rightOperand); |
| 11073 } | 11073 } |
| 11074 } else if (condition is IsExpression) { | 11074 } else if (condition is IsExpression) { |
| 11075 IsExpression is2 = condition; | 11075 IsExpression is2 = condition; |
| 11076 if (is2.notOperator != null) { | 11076 if (is2.notOperator != null) { |
| 11077 overrideExpression(is2.expression, is2.type.type); | 11077 overrideExpression(is2.expression, is2.type.type); |
| 11078 } | 11078 } |
| 11079 } else if (condition is PrefixExpression) { | 11079 } else if (condition is PrefixExpression) { |
| 11080 PrefixExpression prefix = condition; | 11080 PrefixExpression prefix = condition; |
| 11081 if (identical(prefix.operator.type, sc.TokenType.BANG)) { | 11081 if (identical(prefix.operator.type, sc.TokenType.BANG)) { |
| 11082 propagateTrueState(prefix.operand); | 11082 _propagateTrueState(prefix.operand); |
| 11083 } | 11083 } |
| 11084 } else if (condition is ParenthesizedExpression) { | 11084 } else if (condition is ParenthesizedExpression) { |
| 11085 propagateFalseState(condition.expression); | 11085 _propagateFalseState(condition.expression); |
| 11086 } | 11086 } |
| 11087 } | 11087 } |
| 11088 | 11088 |
| 11089 /** | 11089 /** |
| 11090 * Propagate any type information that results from knowing that the given exp
ression will have | 11090 * Propagate any type information that results from knowing that the given exp
ression will have |
| 11091 * been evaluated without altering the flow of execution. | 11091 * been evaluated without altering the flow of execution. |
| 11092 * | 11092 * |
| 11093 * @param expression the expression that will have been evaluated | 11093 * @param expression the expression that will have been evaluated |
| 11094 */ | 11094 */ |
| 11095 void propagateState(Expression expression) { | 11095 void _propagateState(Expression expression) { |
| 11096 } | 11096 } |
| 11097 | 11097 |
| 11098 /** | 11098 /** |
| 11099 * Propagate any type information that results from knowing that the given con
dition will have | 11099 * Propagate any type information that results from knowing that the given con
dition will have |
| 11100 * been evaluated to 'true'. | 11100 * been evaluated to 'true'. |
| 11101 * | 11101 * |
| 11102 * @param condition the condition that will have evaluated to 'true' | 11102 * @param condition the condition that will have evaluated to 'true' |
| 11103 */ | 11103 */ |
| 11104 void propagateTrueState(Expression condition) { | 11104 void _propagateTrueState(Expression condition) { |
| 11105 if (condition is BinaryExpression) { | 11105 if (condition is BinaryExpression) { |
| 11106 BinaryExpression binary = condition; | 11106 BinaryExpression binary = condition; |
| 11107 if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) { | 11107 if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) { |
| 11108 propagateTrueState(binary.leftOperand); | 11108 _propagateTrueState(binary.leftOperand); |
| 11109 propagateTrueState(binary.rightOperand); | 11109 _propagateTrueState(binary.rightOperand); |
| 11110 } | 11110 } |
| 11111 } else if (condition is IsExpression) { | 11111 } else if (condition is IsExpression) { |
| 11112 IsExpression is2 = condition; | 11112 IsExpression is2 = condition; |
| 11113 if (is2.notOperator == null) { | 11113 if (is2.notOperator == null) { |
| 11114 overrideExpression(is2.expression, is2.type.type); | 11114 overrideExpression(is2.expression, is2.type.type); |
| 11115 } | 11115 } |
| 11116 } else if (condition is PrefixExpression) { | 11116 } else if (condition is PrefixExpression) { |
| 11117 PrefixExpression prefix = condition; | 11117 PrefixExpression prefix = condition; |
| 11118 if (identical(prefix.operator.type, sc.TokenType.BANG)) { | 11118 if (identical(prefix.operator.type, sc.TokenType.BANG)) { |
| 11119 propagateFalseState(prefix.operand); | 11119 _propagateFalseState(prefix.operand); |
| 11120 } | 11120 } |
| 11121 } else if (condition is ParenthesizedExpression) { | 11121 } else if (condition is ParenthesizedExpression) { |
| 11122 propagateTrueState(condition.expression); | 11122 _propagateTrueState(condition.expression); |
| 11123 } | 11123 } |
| 11124 } | 11124 } |
| 11125 | 11125 |
| 11126 /** | 11126 /** |
| 11127 * Record that the propagated type of the given node is the given type. | 11127 * Record that the propagated type of the given node is the given type. |
| 11128 * | 11128 * |
| 11129 * @param expression the node whose type is to be recorded | 11129 * @param expression the node whose type is to be recorded |
| 11130 * @param type the propagated type of the node | 11130 * @param type the propagated type of the node |
| 11131 */ | 11131 */ |
| 11132 void recordPropagatedType(Expression expression, Type2 type) { | 11132 void _recordPropagatedType(Expression expression, Type2 type) { |
| 11133 if (type != null && !type.isDynamic) { | 11133 if (type != null && !type.isDynamic) { |
| 11134 expression.propagatedType = type; | 11134 expression.propagatedType = type; |
| 11135 } | 11135 } |
| 11136 } | 11136 } |
| 11137 | 11137 |
| 11138 get elementResolver_J2DAccessor => _elementResolver; | 11138 get elementResolver_J2DAccessor => _elementResolver; |
| 11139 | 11139 |
| 11140 set elementResolver_J2DAccessor(__v) => _elementResolver = __v; | 11140 set elementResolver_J2DAccessor(__v) => _elementResolver = __v; |
| 11141 | 11141 |
| 11142 get labelScope_J2DAccessor => _labelScope; | 11142 get labelScope_J2DAccessor => _labelScope; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11323 * @param errorCode analysis error | 11323 * @param errorCode analysis error |
| 11324 */ | 11324 */ |
| 11325 void reportError(AnalysisError analysisError) { | 11325 void reportError(AnalysisError analysisError) { |
| 11326 _errorListener.onError(analysisError); | 11326 _errorListener.onError(analysisError); |
| 11327 } | 11327 } |
| 11328 | 11328 |
| 11329 Object visitBlock(Block node) { | 11329 Object visitBlock(Block node) { |
| 11330 Scope outerScope = _nameScope; | 11330 Scope outerScope = _nameScope; |
| 11331 try { | 11331 try { |
| 11332 EnclosedScope enclosedScope = new EnclosedScope(_nameScope); | 11332 EnclosedScope enclosedScope = new EnclosedScope(_nameScope); |
| 11333 hideNamesDefinedInBlock(enclosedScope, node); | 11333 _hideNamesDefinedInBlock(enclosedScope, node); |
| 11334 _nameScope = enclosedScope; | 11334 _nameScope = enclosedScope; |
| 11335 super.visitBlock(node); | 11335 super.visitBlock(node); |
| 11336 } finally { | 11336 } finally { |
| 11337 _nameScope = outerScope; | 11337 _nameScope = outerScope; |
| 11338 } | 11338 } |
| 11339 return null; | 11339 return null; |
| 11340 } | 11340 } |
| 11341 | 11341 |
| 11342 Object visitCatchClause(CatchClause node) { | 11342 Object visitCatchClause(CatchClause node) { |
| 11343 SimpleIdentifier exception = node.exceptionParameter; | 11343 SimpleIdentifier exception = node.exceptionParameter; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11501 } | 11501 } |
| 11502 | 11502 |
| 11503 Object visitIfStatement(IfStatement node) { | 11503 Object visitIfStatement(IfStatement node) { |
| 11504 safelyVisit(node.condition); | 11504 safelyVisit(node.condition); |
| 11505 visitStatementInScope(node.thenStatement); | 11505 visitStatementInScope(node.thenStatement); |
| 11506 visitStatementInScope(node.elseStatement); | 11506 visitStatementInScope(node.elseStatement); |
| 11507 return null; | 11507 return null; |
| 11508 } | 11508 } |
| 11509 | 11509 |
| 11510 Object visitLabeledStatement(LabeledStatement node) { | 11510 Object visitLabeledStatement(LabeledStatement node) { |
| 11511 LabelScope outerScope = addScopesFor(node.labels); | 11511 LabelScope outerScope = _addScopesFor(node.labels); |
| 11512 try { | 11512 try { |
| 11513 super.visitLabeledStatement(node); | 11513 super.visitLabeledStatement(node); |
| 11514 } finally { | 11514 } finally { |
| 11515 _labelScope = outerScope; | 11515 _labelScope = outerScope; |
| 11516 } | 11516 } |
| 11517 return null; | 11517 return null; |
| 11518 } | 11518 } |
| 11519 | 11519 |
| 11520 Object visitMethodDeclaration(MethodDeclaration node) { | 11520 Object visitMethodDeclaration(MethodDeclaration node) { |
| 11521 Scope outerScope = _nameScope; | 11521 Scope outerScope = _nameScope; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11708 } | 11708 } |
| 11709 } | 11709 } |
| 11710 } | 11710 } |
| 11711 | 11711 |
| 11712 /** | 11712 /** |
| 11713 * Add scopes for each of the given labels. | 11713 * Add scopes for each of the given labels. |
| 11714 * | 11714 * |
| 11715 * @param labels the labels for which new scopes are to be added | 11715 * @param labels the labels for which new scopes are to be added |
| 11716 * @return the scope that was in effect before the new scopes were added | 11716 * @return the scope that was in effect before the new scopes were added |
| 11717 */ | 11717 */ |
| 11718 LabelScope addScopesFor(NodeList<Label> labels) { | 11718 LabelScope _addScopesFor(NodeList<Label> labels) { |
| 11719 LabelScope outerScope = _labelScope; | 11719 LabelScope outerScope = _labelScope; |
| 11720 for (Label label in labels) { | 11720 for (Label label in labels) { |
| 11721 SimpleIdentifier labelNameNode = label.label; | 11721 SimpleIdentifier labelNameNode = label.label; |
| 11722 String labelName = labelNameNode.name; | 11722 String labelName = labelNameNode.name; |
| 11723 LabelElement labelElement = labelNameNode.staticElement as LabelElement; | 11723 LabelElement labelElement = labelNameNode.staticElement as LabelElement; |
| 11724 _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement); | 11724 _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement); |
| 11725 } | 11725 } |
| 11726 return outerScope; | 11726 return outerScope; |
| 11727 } | 11727 } |
| 11728 | 11728 |
| 11729 /** | 11729 /** |
| 11730 * Marks the local declarations of the given [Block] hidden in the enclosing s
cope. | 11730 * Marks the local declarations of the given [Block] hidden in the enclosing s
cope. |
| 11731 * According to the scoping rules name is hidden if block defines it, but name
is defined after | 11731 * According to the scoping rules name is hidden if block defines it, but name
is defined after |
| 11732 * its declaration statement. | 11732 * its declaration statement. |
| 11733 */ | 11733 */ |
| 11734 void hideNamesDefinedInBlock(EnclosedScope scope, Block block) { | 11734 void _hideNamesDefinedInBlock(EnclosedScope scope, Block block) { |
| 11735 NodeList<Statement> statements = block.statements; | 11735 NodeList<Statement> statements = block.statements; |
| 11736 int statementCount = statements.length; | 11736 int statementCount = statements.length; |
| 11737 for (int i = 0; i < statementCount; i++) { | 11737 for (int i = 0; i < statementCount; i++) { |
| 11738 Statement statement = statements[i]; | 11738 Statement statement = statements[i]; |
| 11739 if (statement is VariableDeclarationStatement) { | 11739 if (statement is VariableDeclarationStatement) { |
| 11740 VariableDeclarationStatement vds = statement; | 11740 VariableDeclarationStatement vds = statement; |
| 11741 NodeList<VariableDeclaration> variables = vds.variables.variables; | 11741 NodeList<VariableDeclaration> variables = vds.variables.variables; |
| 11742 int variableCount = variables.length; | 11742 int variableCount = variables.length; |
| 11743 for (int j = 0; j < variableCount; j++) { | 11743 for (int j = 0; j < variableCount; j++) { |
| 11744 scope.hide(variables[j].element); | 11744 scope.hide(variables[j].element); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 11760 * * Every node representing an expression should be resolved to the Type of the
expression. | 11760 * * Every node representing an expression should be resolved to the Type of the
expression. |
| 11761 * </ol> | 11761 * </ol> |
| 11762 */ | 11762 */ |
| 11763 class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { | 11763 class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| 11764 /** | 11764 /** |
| 11765 * Create a table mapping HTML tag names to the names of the classes (in 'dart
:html') that | 11765 * Create a table mapping HTML tag names to the names of the classes (in 'dart
:html') that |
| 11766 * implement those tags. | 11766 * implement those tags. |
| 11767 * | 11767 * |
| 11768 * @return the table that was created | 11768 * @return the table that was created |
| 11769 */ | 11769 */ |
| 11770 static Map<String, String> createHtmlTagToClassMap() { | 11770 static Map<String, String> _createHtmlTagToClassMap() { |
| 11771 Map<String, String> map = new Map<String, String>(); | 11771 Map<String, String> map = new Map<String, String>(); |
| 11772 map["a"] = "AnchorElement"; | 11772 map["a"] = "AnchorElement"; |
| 11773 map["area"] = "AreaElement"; | 11773 map["area"] = "AreaElement"; |
| 11774 map["br"] = "BRElement"; | 11774 map["br"] = "BRElement"; |
| 11775 map["base"] = "BaseElement"; | 11775 map["base"] = "BaseElement"; |
| 11776 map["body"] = "BodyElement"; | 11776 map["body"] = "BodyElement"; |
| 11777 map["button"] = "ButtonElement"; | 11777 map["button"] = "ButtonElement"; |
| 11778 map["canvas"] = "CanvasElement"; | 11778 map["canvas"] = "CanvasElement"; |
| 11779 map["content"] = "ContentElement"; | 11779 map["content"] = "ContentElement"; |
| 11780 map["dl"] = "DListElement"; | 11780 map["dl"] = "DListElement"; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11863 | 11863 |
| 11864 /** | 11864 /** |
| 11865 * A table mapping [ExecutableElement]s to their propagated return types. | 11865 * A table mapping [ExecutableElement]s to their propagated return types. |
| 11866 */ | 11866 */ |
| 11867 Map<ExecutableElement, Type2> _propagatedReturnTypes = new Map<ExecutableEleme
nt, Type2>(); | 11867 Map<ExecutableElement, Type2> _propagatedReturnTypes = new Map<ExecutableEleme
nt, Type2>(); |
| 11868 | 11868 |
| 11869 /** | 11869 /** |
| 11870 * A table mapping HTML tag names to the names of the classes (in 'dart:html')
that implement | 11870 * A table mapping HTML tag names to the names of the classes (in 'dart:html')
that implement |
| 11871 * those tags. | 11871 * those tags. |
| 11872 */ | 11872 */ |
| 11873 static Map<String, String> _HTML_ELEMENT_TO_CLASS_MAP = createHtmlTagToClassMa
p(); | 11873 static Map<String, String> _HTML_ELEMENT_TO_CLASS_MAP = _createHtmlTagToClassM
ap(); |
| 11874 | 11874 |
| 11875 /** | 11875 /** |
| 11876 * Initialize a newly created type analyzer. | 11876 * Initialize a newly created type analyzer. |
| 11877 * | 11877 * |
| 11878 * @param resolver the resolver driving this participant | 11878 * @param resolver the resolver driving this participant |
| 11879 */ | 11879 */ |
| 11880 StaticTypeAnalyzer(ResolverVisitor resolver) { | 11880 StaticTypeAnalyzer(ResolverVisitor resolver) { |
| 11881 this._resolver = resolver; | 11881 this._resolver = resolver; |
| 11882 _typeProvider = resolver.typeProvider; | 11882 _typeProvider = resolver.typeProvider; |
| 11883 _dynamicType = _typeProvider.dynamicType; | 11883 _dynamicType = _typeProvider.dynamicType; |
| 11884 _overrideManager = resolver.overrideManager; | 11884 _overrideManager = resolver.overrideManager; |
| 11885 _promoteManager = resolver.promoteManager; | 11885 _promoteManager = resolver.promoteManager; |
| 11886 } | 11886 } |
| 11887 | 11887 |
| 11888 /** | 11888 /** |
| 11889 * Set the type of the class being analyzed to the given type. | 11889 * Set the type of the class being analyzed to the given type. |
| 11890 * | 11890 * |
| 11891 * @param thisType the type representing the class containing the nodes being
analyzed | 11891 * @param thisType the type representing the class containing the nodes being
analyzed |
| 11892 */ | 11892 */ |
| 11893 void set thisType(InterfaceType thisType) { | 11893 void set thisType(InterfaceType thisType) { |
| 11894 this._thisType = thisType; | 11894 this._thisType = thisType; |
| 11895 } | 11895 } |
| 11896 | 11896 |
| 11897 /** | 11897 /** |
| 11898 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is | 11898 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is |
| 11899 * `String`.</blockquote> | 11899 * `String`.</blockquote> |
| 11900 */ | 11900 */ |
| 11901 Object visitAdjacentStrings(AdjacentStrings node) { | 11901 Object visitAdjacentStrings(AdjacentStrings node) { |
| 11902 recordStaticType(node, _typeProvider.stringType); | 11902 _recordStaticType(node, _typeProvider.stringType); |
| 11903 return null; | 11903 return null; |
| 11904 } | 11904 } |
| 11905 | 11905 |
| 11906 /** | 11906 /** |
| 11907 * The Dart Language Specification, 12.33: <blockquote>The static type of an a
rgument definition | 11907 * The Dart Language Specification, 12.33: <blockquote>The static type of an a
rgument definition |
| 11908 * test is `bool`.</blockquote> | 11908 * test is `bool`.</blockquote> |
| 11909 */ | 11909 */ |
| 11910 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) { | 11910 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) { |
| 11911 recordStaticType(node, _typeProvider.boolType); | 11911 _recordStaticType(node, _typeProvider.boolType); |
| 11912 return null; | 11912 return null; |
| 11913 } | 11913 } |
| 11914 | 11914 |
| 11915 /** | 11915 /** |
| 11916 * The Dart Language Specification, 12.32: <blockquote>... the cast expression
<i>e as T</i> ... | 11916 * The Dart Language Specification, 12.32: <blockquote>... the cast expression
<i>e as T</i> ... |
| 11917 * | 11917 * |
| 11918 * It is a static warning if <i>T</i> does not denote a type available in the
current lexical | 11918 * It is a static warning if <i>T</i> does not denote a type available in the
current lexical |
| 11919 * scope. | 11919 * scope. |
| 11920 * | 11920 * |
| 11921 * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote
> | 11921 * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote
> |
| 11922 */ | 11922 */ |
| 11923 Object visitAsExpression(AsExpression node) { | 11923 Object visitAsExpression(AsExpression node) { |
| 11924 recordStaticType(node, getType(node.type)); | 11924 _recordStaticType(node, _getType(node.type)); |
| 11925 return null; | 11925 return null; |
| 11926 } | 11926 } |
| 11927 | 11927 |
| 11928 /** | 11928 /** |
| 11929 * The Dart Language Specification, 12.18: <blockquote>... an assignment <i>a<
/i> of the form <i>v | 11929 * The Dart Language Specification, 12.18: <blockquote>... an assignment <i>a<
/i> of the form <i>v |
| 11930 * = e</i> ... | 11930 * = e</i> ... |
| 11931 * | 11931 * |
| 11932 * It is a static type warning if the static type of <i>e</i> may not be assig
ned to the static | 11932 * It is a static type warning if the static type of <i>e</i> may not be assig
ned to the static |
| 11933 * type of <i>v</i>. | 11933 * type of <i>v</i>. |
| 11934 * | 11934 * |
| (...skipping 26 matching lines...) Expand all Loading... |
| 11961 * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable tha
t is not used in | 11961 * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable tha
t is not used in |
| 11962 * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e<
sub>2</sub>] op= | 11962 * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e<
sub>2</sub>] op= |
| 11963 * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</su
b>)(e<sub>1</sub>, | 11963 * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</su
b>)(e<sub>1</sub>, |
| 11964 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not
used in | 11964 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not
used in |
| 11965 * <i>e<sub>3</sub></i>.</blockquote> | 11965 * <i>e<sub>3</sub></i>.</blockquote> |
| 11966 */ | 11966 */ |
| 11967 Object visitAssignmentExpression(AssignmentExpression node) { | 11967 Object visitAssignmentExpression(AssignmentExpression node) { |
| 11968 sc.TokenType operator = node.operator.type; | 11968 sc.TokenType operator = node.operator.type; |
| 11969 if (identical(operator, sc.TokenType.EQ)) { | 11969 if (identical(operator, sc.TokenType.EQ)) { |
| 11970 Expression rightHandSide = node.rightHandSide; | 11970 Expression rightHandSide = node.rightHandSide; |
| 11971 Type2 staticType = getStaticType(rightHandSide); | 11971 Type2 staticType = _getStaticType(rightHandSide); |
| 11972 recordStaticType(node, staticType); | 11972 _recordStaticType(node, staticType); |
| 11973 Type2 overrideType = staticType; | 11973 Type2 overrideType = staticType; |
| 11974 Type2 propagatedType = rightHandSide.propagatedType; | 11974 Type2 propagatedType = rightHandSide.propagatedType; |
| 11975 if (propagatedType != null) { | 11975 if (propagatedType != null) { |
| 11976 if (propagatedType.isMoreSpecificThan(staticType)) { | 11976 if (propagatedType.isMoreSpecificThan(staticType)) { |
| 11977 recordPropagatedType(node, propagatedType); | 11977 _recordPropagatedType(node, propagatedType); |
| 11978 } | 11978 } |
| 11979 overrideType = propagatedType; | 11979 overrideType = propagatedType; |
| 11980 } | 11980 } |
| 11981 _resolver.overrideExpression(node.leftHandSide, overrideType); | 11981 _resolver.overrideExpression(node.leftHandSide, overrideType); |
| 11982 } else { | 11982 } else { |
| 11983 ExecutableElement staticMethodElement = node.staticElement; | 11983 ExecutableElement staticMethodElement = node.staticElement; |
| 11984 Type2 staticType = computeStaticReturnType(staticMethodElement); | 11984 Type2 staticType = _computeStaticReturnType(staticMethodElement); |
| 11985 recordStaticType(node, staticType); | 11985 _recordStaticType(node, staticType); |
| 11986 MethodElement propagatedMethodElement = node.propagatedElement; | 11986 MethodElement propagatedMethodElement = node.propagatedElement; |
| 11987 if (propagatedMethodElement != staticMethodElement) { | 11987 if (propagatedMethodElement != staticMethodElement) { |
| 11988 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 11988 Type2 propagatedType = _computeStaticReturnType(propagatedMethodElement)
; |
| 11989 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 11989 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 11990 recordPropagatedType(node, propagatedType); | 11990 _recordPropagatedType(node, propagatedType); |
| 11991 } | 11991 } |
| 11992 } | 11992 } |
| 11993 } | 11993 } |
| 11994 return null; | 11994 return null; |
| 11995 } | 11995 } |
| 11996 | 11996 |
| 11997 /** | 11997 /** |
| 11998 * The Dart Language Specification, 12.20: <blockquote>The static type of a lo
gical boolean | 11998 * The Dart Language Specification, 12.20: <blockquote>The static type of a lo
gical boolean |
| 11999 * expression is `bool`.</blockquote> | 11999 * expression is `bool`.</blockquote> |
| 12000 * | 12000 * |
| (...skipping 25 matching lines...) Expand all Loading... |
| 12026 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> | 12026 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> |
| 12027 * | 12027 * |
| 12028 * The Dart Language Specification, 12.26: <blockquote>A multiplicative expres
sion of the form | 12028 * The Dart Language Specification, 12.26: <blockquote>A multiplicative expres
sion of the form |
| 12029 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio
n | 12029 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio
n |
| 12030 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the
form <i>super op | 12030 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the
form <i>super op |
| 12031 * e<sub>2</sub></i> is equivalent to the method invocation | 12031 * e<sub>2</sub></i> is equivalent to the method invocation |
| 12032 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> | 12032 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> |
| 12033 */ | 12033 */ |
| 12034 Object visitBinaryExpression(BinaryExpression node) { | 12034 Object visitBinaryExpression(BinaryExpression node) { |
| 12035 ExecutableElement staticMethodElement = node.staticElement; | 12035 ExecutableElement staticMethodElement = node.staticElement; |
| 12036 Type2 staticType = computeStaticReturnType(staticMethodElement); | 12036 Type2 staticType = _computeStaticReturnType(staticMethodElement); |
| 12037 staticType = refineBinaryExpressionType(node, staticType); | 12037 staticType = _refineBinaryExpressionType(node, staticType); |
| 12038 recordStaticType(node, staticType); | 12038 _recordStaticType(node, staticType); |
| 12039 MethodElement propagatedMethodElement = node.propagatedElement; | 12039 MethodElement propagatedMethodElement = node.propagatedElement; |
| 12040 if (propagatedMethodElement != staticMethodElement) { | 12040 if (propagatedMethodElement != staticMethodElement) { |
| 12041 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 12041 Type2 propagatedType = _computeStaticReturnType(propagatedMethodElement); |
| 12042 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { | 12042 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { |
| 12043 recordPropagatedType(node, propagatedType); | 12043 _recordPropagatedType(node, propagatedType); |
| 12044 } | 12044 } |
| 12045 } | 12045 } |
| 12046 return null; | 12046 return null; |
| 12047 } | 12047 } |
| 12048 | 12048 |
| 12049 /** | 12049 /** |
| 12050 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo
lean literal is | 12050 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo
lean literal is |
| 12051 * bool.</blockquote> | 12051 * bool.</blockquote> |
| 12052 */ | 12052 */ |
| 12053 Object visitBooleanLiteral(BooleanLiteral node) { | 12053 Object visitBooleanLiteral(BooleanLiteral node) { |
| 12054 recordStaticType(node, _typeProvider.boolType); | 12054 _recordStaticType(node, _typeProvider.boolType); |
| 12055 return null; | 12055 return null; |
| 12056 } | 12056 } |
| 12057 | 12057 |
| 12058 /** | 12058 /** |
| 12059 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv
ocation expression | 12059 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv
ocation expression |
| 12060 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff
ix; return | 12060 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff
ix; return |
| 12061 * t;}(e)</i>.</blockquote> | 12061 * t;}(e)</i>.</blockquote> |
| 12062 */ | 12062 */ |
| 12063 Object visitCascadeExpression(CascadeExpression node) { | 12063 Object visitCascadeExpression(CascadeExpression node) { |
| 12064 recordStaticType(node, getStaticType(node.target)); | 12064 _recordStaticType(node, _getStaticType(node.target)); |
| 12065 recordPropagatedType(node, node.target.propagatedType); | 12065 _recordPropagatedType(node, node.target.propagatedType); |
| 12066 return null; | 12066 return null; |
| 12067 } | 12067 } |
| 12068 | 12068 |
| 12069 /** | 12069 /** |
| 12070 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr
ession <i>c</i> of | 12070 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr
ession <i>c</i> of |
| 12071 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ... | 12071 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ... |
| 12072 * | 12072 * |
| 12073 * It is a static type warning if the type of e<sub>1</sub> may not be assigne
d to `bool`. | 12073 * It is a static type warning if the type of e<sub>1</sub> may not be assigne
d to `bool`. |
| 12074 * | 12074 * |
| 12075 * The static type of <i>c</i> is the least upper bound of the static type of
<i>e<sub>2</sub></i> | 12075 * The static type of <i>c</i> is the least upper bound of the static type of
<i>e<sub>2</sub></i> |
| 12076 * and the static type of <i>e<sub>3</sub></i>.</blockquote> | 12076 * and the static type of <i>e<sub>3</sub></i>.</blockquote> |
| 12077 */ | 12077 */ |
| 12078 Object visitConditionalExpression(ConditionalExpression node) { | 12078 Object visitConditionalExpression(ConditionalExpression node) { |
| 12079 Type2 staticThenType = getStaticType(node.thenExpression); | 12079 Type2 staticThenType = _getStaticType(node.thenExpression); |
| 12080 Type2 staticElseType = getStaticType(node.elseExpression); | 12080 Type2 staticElseType = _getStaticType(node.elseExpression); |
| 12081 if (staticThenType == null) { | 12081 if (staticThenType == null) { |
| 12082 // TODO(brianwilkerson) Determine whether this can still happen. | 12082 // TODO(brianwilkerson) Determine whether this can still happen. |
| 12083 staticThenType = _dynamicType; | 12083 staticThenType = _dynamicType; |
| 12084 } | 12084 } |
| 12085 if (staticElseType == null) { | 12085 if (staticElseType == null) { |
| 12086 // TODO(brianwilkerson) Determine whether this can still happen. | 12086 // TODO(brianwilkerson) Determine whether this can still happen. |
| 12087 staticElseType = _dynamicType; | 12087 staticElseType = _dynamicType; |
| 12088 } | 12088 } |
| 12089 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType); | 12089 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType); |
| 12090 if (staticType == null) { | 12090 if (staticType == null) { |
| 12091 staticType = _dynamicType; | 12091 staticType = _dynamicType; |
| 12092 } | 12092 } |
| 12093 recordStaticType(node, staticType); | 12093 _recordStaticType(node, staticType); |
| 12094 Type2 propagatedThenType = node.thenExpression.propagatedType; | 12094 Type2 propagatedThenType = node.thenExpression.propagatedType; |
| 12095 Type2 propagatedElseType = node.elseExpression.propagatedType; | 12095 Type2 propagatedElseType = node.elseExpression.propagatedType; |
| 12096 if (propagatedThenType != null || propagatedElseType != null) { | 12096 if (propagatedThenType != null || propagatedElseType != null) { |
| 12097 if (propagatedThenType == null) { | 12097 if (propagatedThenType == null) { |
| 12098 propagatedThenType = staticThenType; | 12098 propagatedThenType = staticThenType; |
| 12099 } | 12099 } |
| 12100 if (propagatedElseType == null) { | 12100 if (propagatedElseType == null) { |
| 12101 propagatedElseType = staticElseType; | 12101 propagatedElseType = staticElseType; |
| 12102 } | 12102 } |
| 12103 Type2 propagatedType = propagatedThenType.getLeastUpperBound(propagatedEls
eType); | 12103 Type2 propagatedType = propagatedThenType.getLeastUpperBound(propagatedEls
eType); |
| 12104 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { | 12104 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { |
| 12105 recordPropagatedType(node, propagatedType); | 12105 _recordPropagatedType(node, propagatedType); |
| 12106 } | 12106 } |
| 12107 } | 12107 } |
| 12108 return null; | 12108 return null; |
| 12109 } | 12109 } |
| 12110 | 12110 |
| 12111 /** | 12111 /** |
| 12112 * The Dart Language Specification, 12.3: <blockquote>The static type of a lit
eral double is | 12112 * The Dart Language Specification, 12.3: <blockquote>The static type of a lit
eral double is |
| 12113 * double.</blockquote> | 12113 * double.</blockquote> |
| 12114 */ | 12114 */ |
| 12115 Object visitDoubleLiteral(DoubleLiteral node) { | 12115 Object visitDoubleLiteral(DoubleLiteral node) { |
| 12116 recordStaticType(node, _typeProvider.doubleType); | 12116 _recordStaticType(node, _typeProvider.doubleType); |
| 12117 return null; | 12117 return null; |
| 12118 } | 12118 } |
| 12119 | 12119 |
| 12120 Object visitFunctionDeclaration(FunctionDeclaration node) { | 12120 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 12121 FunctionExpression function = node.functionExpression; | 12121 FunctionExpression function = node.functionExpression; |
| 12122 ExecutableElementImpl functionElement = node.element as ExecutableElementImp
l; | 12122 ExecutableElementImpl functionElement = node.element as ExecutableElementImp
l; |
| 12123 functionElement.returnType = computeStaticReturnTypeOfFunctionDeclaration(no
de); | 12123 functionElement.returnType = _computeStaticReturnTypeOfFunctionDeclaration(n
ode); |
| 12124 recordPropagatedTypeOfFunction(functionElement, function.body); | 12124 _recordPropagatedTypeOfFunction(functionElement, function.body); |
| 12125 recordStaticType(function, functionElement.type); | 12125 _recordStaticType(function, functionElement.type); |
| 12126 return null; | 12126 return null; |
| 12127 } | 12127 } |
| 12128 | 12128 |
| 12129 /** | 12129 /** |
| 12130 * The Dart Language Specification, 12.9: <blockquote>The static type of a fun
ction literal of the | 12130 * The Dart Language Specification, 12.9: <blockquote>The static type of a fun
ction literal of the |
| 12131 * form <i>(T<sub>1</sub> a<sub>1</sub>, …, T<sub>n</sub> a<sub>n</sub>
, [T<sub>n+1</sub> | 12131 * form <i>(T<sub>1</sub> a<sub>1</sub>, …, T<sub>n</sub> a<sub>n</sub>
, [T<sub>n+1</sub> |
| 12132 * x<sub>n+1</sub> = d1, …, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e
</i> is | 12132 * x<sub>n+1</sub> = d1, …, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e
</i> is |
| 12133 * <i>(T<sub>1</sub>, …, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, …
, T<sub>n+k</sub> | 12133 * <i>(T<sub>1</sub>, …, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, …
, T<sub>n+k</sub> |
| 12134 * x<sub>n+k</sub>]) → T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is t
he static type of | 12134 * x<sub>n+k</sub>]) → T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is t
he static type of |
| 12135 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not
specified, it is | 12135 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not
specified, it is |
| (...skipping 19 matching lines...) Expand all Loading... |
| 12155 * x<sub>n+1</sub>, …, T<sub>n+k</sub> x<sub>n+k</sub>}) → dynamic
</i>. In any case | 12155 * x<sub>n+1</sub>, …, T<sub>n+k</sub> x<sub>n+k</sub>}) → dynamic
</i>. In any case |
| 12156 * where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not specified, it is cons
idered to have been | 12156 * where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not specified, it is cons
idered to have been |
| 12157 * specified as dynamic.</blockquote> | 12157 * specified as dynamic.</blockquote> |
| 12158 */ | 12158 */ |
| 12159 Object visitFunctionExpression(FunctionExpression node) { | 12159 Object visitFunctionExpression(FunctionExpression node) { |
| 12160 if (node.parent is FunctionDeclaration) { | 12160 if (node.parent is FunctionDeclaration) { |
| 12161 // The function type will be resolved and set when we visit the parent nod
e. | 12161 // The function type will be resolved and set when we visit the parent nod
e. |
| 12162 return null; | 12162 return null; |
| 12163 } | 12163 } |
| 12164 ExecutableElementImpl functionElement = node.element as ExecutableElementImp
l; | 12164 ExecutableElementImpl functionElement = node.element as ExecutableElementImp
l; |
| 12165 functionElement.returnType = computeStaticReturnTypeOfFunctionExpression(nod
e); | 12165 functionElement.returnType = _computeStaticReturnTypeOfFunctionExpression(no
de); |
| 12166 recordPropagatedTypeOfFunction(functionElement, node.body); | 12166 _recordPropagatedTypeOfFunction(functionElement, node.body); |
| 12167 recordStaticType(node, node.element.type); | 12167 _recordStaticType(node, node.element.type); |
| 12168 return null; | 12168 return null; |
| 12169 } | 12169 } |
| 12170 | 12170 |
| 12171 /** | 12171 /** |
| 12172 * The Dart Language Specification, 12.14.4: <blockquote>A function expression
invocation <i>i</i> | 12172 * The Dart Language Specification, 12.14.4: <blockquote>A function expression
invocation <i>i</i> |
| 12173 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub
>n+1</sub>: | 12173 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub
>n+1</sub>: |
| 12174 * a<sub>n+1</sub>, …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>
e<sub>f</sub></i> is | 12174 * a<sub>n+1</sub>, …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>
e<sub>f</sub></i> is |
| 12175 * an expression. | 12175 * an expression. |
| 12176 * | 12176 * |
| 12177 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub>
</i> may not be | 12177 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub>
</i> may not be |
| 12178 * assigned to a function type. | 12178 * assigned to a function type. |
| 12179 * | 12179 * |
| 12180 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic.
Otherwise the | 12180 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic.
Otherwise the |
| 12181 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot
e> | 12181 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot
e> |
| 12182 */ | 12182 */ |
| 12183 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 12183 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 12184 ExecutableElement staticMethodElement = node.staticElement; | 12184 ExecutableElement staticMethodElement = node.staticElement; |
| 12185 // Record static return type of the static element. | 12185 // Record static return type of the static element. |
| 12186 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); | 12186 Type2 staticStaticType = _computeStaticReturnType(staticMethodElement); |
| 12187 recordStaticType(node, staticStaticType); | 12187 _recordStaticType(node, staticStaticType); |
| 12188 // Record propagated return type of the static element. | 12188 // Record propagated return type of the static element. |
| 12189 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); | 12189 Type2 staticPropagatedType = _computePropagatedReturnType(staticMethodElemen
t); |
| 12190 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 12190 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 12191 recordPropagatedType(node, staticPropagatedType); | 12191 _recordPropagatedType(node, staticPropagatedType); |
| 12192 } | 12192 } |
| 12193 ExecutableElement propagatedMethodElement = node.propagatedElement; | 12193 ExecutableElement propagatedMethodElement = node.propagatedElement; |
| 12194 if (propagatedMethodElement != staticMethodElement) { | 12194 if (propagatedMethodElement != staticMethodElement) { |
| 12195 // Record static return type of the propagated element. | 12195 // Record static return type of the propagated element. |
| 12196 Type2 propagatedStaticType = computeStaticReturnType(propagatedMethodEleme
nt); | 12196 Type2 propagatedStaticType = _computeStaticReturnType(propagatedMethodElem
ent); |
| 12197 if (propagatedStaticType != null && (staticStaticType == null || propagate
dStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == nu
ll || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { | 12197 if (propagatedStaticType != null && (staticStaticType == null || propagate
dStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == nu
ll || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { |
| 12198 recordPropagatedType(node, propagatedStaticType); | 12198 _recordPropagatedType(node, propagatedStaticType); |
| 12199 } | 12199 } |
| 12200 // Record propagated return type of the propagated element. | 12200 // Record propagated return type of the propagated element. |
| 12201 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedMet
hodElement); | 12201 Type2 propagatedPropagatedType = _computePropagatedReturnType(propagatedMe
thodElement); |
| 12202 if (propagatedPropagatedType != null && (staticStaticType == null || propa
gatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedTy
pe == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType))
&& (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan
(propagatedStaticType))) { | 12202 if (propagatedPropagatedType != null && (staticStaticType == null || propa
gatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedTy
pe == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType))
&& (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan
(propagatedStaticType))) { |
| 12203 recordPropagatedType(node, propagatedPropagatedType); | 12203 _recordPropagatedType(node, propagatedPropagatedType); |
| 12204 } | 12204 } |
| 12205 } | 12205 } |
| 12206 return null; | 12206 return null; |
| 12207 } | 12207 } |
| 12208 | 12208 |
| 12209 /** | 12209 /** |
| 12210 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio
n of the form | 12210 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio
n of the form |
| 12211 * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of
the operator method | 12211 * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of
the operator method |
| 12212 * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bloc
kquote> | 12212 * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bloc
kquote> |
| 12213 */ | 12213 */ |
| 12214 Object visitIndexExpression(IndexExpression node) { | 12214 Object visitIndexExpression(IndexExpression node) { |
| 12215 if (node.inSetterContext()) { | 12215 if (node.inSetterContext()) { |
| 12216 ExecutableElement staticMethodElement = node.staticElement; | 12216 ExecutableElement staticMethodElement = node.staticElement; |
| 12217 Type2 staticType = computeArgumentType(staticMethodElement); | 12217 Type2 staticType = _computeArgumentType(staticMethodElement); |
| 12218 recordStaticType(node, staticType); | 12218 _recordStaticType(node, staticType); |
| 12219 MethodElement propagatedMethodElement = node.propagatedElement; | 12219 MethodElement propagatedMethodElement = node.propagatedElement; |
| 12220 if (propagatedMethodElement != staticMethodElement) { | 12220 if (propagatedMethodElement != staticMethodElement) { |
| 12221 Type2 propagatedType = computeArgumentType(propagatedMethodElement); | 12221 Type2 propagatedType = _computeArgumentType(propagatedMethodElement); |
| 12222 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 12222 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 12223 recordPropagatedType(node, propagatedType); | 12223 _recordPropagatedType(node, propagatedType); |
| 12224 } | 12224 } |
| 12225 } | 12225 } |
| 12226 } else { | 12226 } else { |
| 12227 ExecutableElement staticMethodElement = node.staticElement; | 12227 ExecutableElement staticMethodElement = node.staticElement; |
| 12228 Type2 staticType = computeStaticReturnType(staticMethodElement); | 12228 Type2 staticType = _computeStaticReturnType(staticMethodElement); |
| 12229 recordStaticType(node, staticType); | 12229 _recordStaticType(node, staticType); |
| 12230 MethodElement propagatedMethodElement = node.propagatedElement; | 12230 MethodElement propagatedMethodElement = node.propagatedElement; |
| 12231 if (propagatedMethodElement != staticMethodElement) { | 12231 if (propagatedMethodElement != staticMethodElement) { |
| 12232 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 12232 Type2 propagatedType = _computeStaticReturnType(propagatedMethodElement)
; |
| 12233 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 12233 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 12234 recordPropagatedType(node, propagatedType); | 12234 _recordPropagatedType(node, propagatedType); |
| 12235 } | 12235 } |
| 12236 } | 12236 } |
| 12237 } | 12237 } |
| 12238 return null; | 12238 return null; |
| 12239 } | 12239 } |
| 12240 | 12240 |
| 12241 /** | 12241 /** |
| 12242 * The Dart Language Specification, 12.11.1: <blockquote>The static type of a
new expression of | 12242 * The Dart Language Specification, 12.11.1: <blockquote>The static type of a
new expression of |
| 12243 * either the form <i>new T.id(a<sub>1</sub>, …, a<sub>n</sub>)</i> or
the form <i>new | 12243 * either the form <i>new T.id(a<sub>1</sub>, …, a<sub>n</sub>)</i> or
the form <i>new |
| 12244 * T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>.</blockquote> | 12244 * T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>.</blockquote> |
| 12245 * | 12245 * |
| 12246 * The Dart Language Specification, 12.11.2: <blockquote>The static type of a
constant object | 12246 * The Dart Language Specification, 12.11.2: <blockquote>The static type of a
constant object |
| 12247 * expression of either the form <i>const T.id(a<sub>1</sub>, …, a<sub>
n</sub>)</i> or the | 12247 * expression of either the form <i>const T.id(a<sub>1</sub>, …, a<sub>
n</sub>)</i> or the |
| 12248 * form <i>const T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>. </
blockquote> | 12248 * form <i>const T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>. </
blockquote> |
| 12249 */ | 12249 */ |
| 12250 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 12250 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 12251 recordStaticType(node, node.constructorName.type.type); | 12251 _recordStaticType(node, node.constructorName.type.type); |
| 12252 ConstructorElement element = node.staticElement; | 12252 ConstructorElement element = node.staticElement; |
| 12253 if (element != null && "Element" == element.enclosingElement.name) { | 12253 if (element != null && "Element" == element.enclosingElement.name) { |
| 12254 LibraryElement library = element.library; | 12254 LibraryElement library = element.library; |
| 12255 if (isHtmlLibrary(library)) { | 12255 if (_isHtmlLibrary(library)) { |
| 12256 String constructorName = element.name; | 12256 String constructorName = element.name; |
| 12257 if ("tag" == constructorName) { | 12257 if ("tag" == constructorName) { |
| 12258 Type2 returnType = getFirstArgumentAsTypeWithMap(library, node.argumen
tList, _HTML_ELEMENT_TO_CLASS_MAP); | 12258 Type2 returnType = _getFirstArgumentAsTypeWithMap(library, node.argume
ntList, _HTML_ELEMENT_TO_CLASS_MAP); |
| 12259 if (returnType != null) { | 12259 if (returnType != null) { |
| 12260 recordPropagatedType(node, returnType); | 12260 _recordPropagatedType(node, returnType); |
| 12261 } | 12261 } |
| 12262 } else { | 12262 } else { |
| 12263 Type2 returnType = getElementNameAsType(library, constructorName, _HTM
L_ELEMENT_TO_CLASS_MAP); | 12263 Type2 returnType = _getElementNameAsType(library, constructorName, _HT
ML_ELEMENT_TO_CLASS_MAP); |
| 12264 if (returnType != null) { | 12264 if (returnType != null) { |
| 12265 recordPropagatedType(node, returnType); | 12265 _recordPropagatedType(node, returnType); |
| 12266 } | 12266 } |
| 12267 } | 12267 } |
| 12268 } | 12268 } |
| 12269 } | 12269 } |
| 12270 return null; | 12270 return null; |
| 12271 } | 12271 } |
| 12272 | 12272 |
| 12273 /** | 12273 /** |
| 12274 * The Dart Language Specification, 12.3: <blockquote>The static type of an in
teger literal is | 12274 * The Dart Language Specification, 12.3: <blockquote>The static type of an in
teger literal is |
| 12275 * `int`.</blockquote> | 12275 * `int`.</blockquote> |
| 12276 */ | 12276 */ |
| 12277 Object visitIntegerLiteral(IntegerLiteral node) { | 12277 Object visitIntegerLiteral(IntegerLiteral node) { |
| 12278 recordStaticType(node, _typeProvider.intType); | 12278 _recordStaticType(node, _typeProvider.intType); |
| 12279 return null; | 12279 return null; |
| 12280 } | 12280 } |
| 12281 | 12281 |
| 12282 /** | 12282 /** |
| 12283 * The Dart Language Specification, 12.31: <blockquote>It is a static warning
if <i>T</i> does not | 12283 * The Dart Language Specification, 12.31: <blockquote>It is a static warning
if <i>T</i> does not |
| 12284 * denote a type available in the current lexical scope. | 12284 * denote a type available in the current lexical scope. |
| 12285 * | 12285 * |
| 12286 * The static type of an is-expression is `bool`.</blockquote> | 12286 * The static type of an is-expression is `bool`.</blockquote> |
| 12287 */ | 12287 */ |
| 12288 Object visitIsExpression(IsExpression node) { | 12288 Object visitIsExpression(IsExpression node) { |
| 12289 recordStaticType(node, _typeProvider.boolType); | 12289 _recordStaticType(node, _typeProvider.boolType); |
| 12290 return null; | 12290 return null; |
| 12291 } | 12291 } |
| 12292 | 12292 |
| 12293 /** | 12293 /** |
| 12294 * The Dart Language Specification, 12.6: <blockquote>The static type of a lis
t literal of the | 12294 * The Dart Language Specification, 12.6: <blockquote>The static type of a lis
t literal of the |
| 12295 * form <i><b>const</b> <E>[e<sub>1</sub>, …, e<sub>n</sub>]</i>
or the form | 12295 * form <i><b>const</b> <E>[e<sub>1</sub>, …, e<sub>n</sub>]</i>
or the form |
| 12296 * <i><E>[e<sub>1</sub>, …, e<sub>n</sub>]</i> is `List<E>`
. The static | 12296 * <i><E>[e<sub>1</sub>, …, e<sub>n</sub>]</i> is `List<E>`
. The static |
| 12297 * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, …, e
<sub>n</sub>]</i> or | 12297 * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, …, e
<sub>n</sub>]</i> or |
| 12298 * the form <i>[e<sub>1</sub>, …, e<sub>n</sub>]</i> is `List<dynami
c>` | 12298 * the form <i>[e<sub>1</sub>, …, e<sub>n</sub>]</i> is `List<dynami
c>` |
| 12299 * .</blockquote> | 12299 * .</blockquote> |
| 12300 */ | 12300 */ |
| 12301 Object visitListLiteral(ListLiteral node) { | 12301 Object visitListLiteral(ListLiteral node) { |
| 12302 Type2 staticType = _dynamicType; | 12302 Type2 staticType = _dynamicType; |
| 12303 TypeArgumentList typeArguments = node.typeArguments; | 12303 TypeArgumentList typeArguments = node.typeArguments; |
| 12304 if (typeArguments != null) { | 12304 if (typeArguments != null) { |
| 12305 NodeList<TypeName> arguments = typeArguments.arguments; | 12305 NodeList<TypeName> arguments = typeArguments.arguments; |
| 12306 if (arguments != null && arguments.length == 1) { | 12306 if (arguments != null && arguments.length == 1) { |
| 12307 TypeName argumentTypeName = arguments[0]; | 12307 TypeName argumentTypeName = arguments[0]; |
| 12308 Type2 argumentType = getType(argumentTypeName); | 12308 Type2 argumentType = _getType(argumentTypeName); |
| 12309 if (argumentType != null) { | 12309 if (argumentType != null) { |
| 12310 staticType = argumentType; | 12310 staticType = argumentType; |
| 12311 } | 12311 } |
| 12312 } | 12312 } |
| 12313 } | 12313 } |
| 12314 recordStaticType(node, _typeProvider.listType.substitute4(<Type2> [staticTyp
e])); | 12314 _recordStaticType(node, _typeProvider.listType.substitute4(<Type2> [staticTy
pe])); |
| 12315 NodeList<Expression> elements = node.elements; | 12315 NodeList<Expression> elements = node.elements; |
| 12316 int count = elements.length; | 12316 int count = elements.length; |
| 12317 if (count > 0) { | 12317 if (count > 0) { |
| 12318 Type2 propagatedType = elements[0].bestType; | 12318 Type2 propagatedType = elements[0].bestType; |
| 12319 for (int i = 1; i < count; i++) { | 12319 for (int i = 1; i < count; i++) { |
| 12320 Type2 elementType = elements[i].bestType; | 12320 Type2 elementType = elements[i].bestType; |
| 12321 if (propagatedType != elementType) { | 12321 if (propagatedType != elementType) { |
| 12322 propagatedType = _dynamicType; | 12322 propagatedType = _dynamicType; |
| 12323 } else { | 12323 } else { |
| 12324 propagatedType = propagatedType.getLeastUpperBound(elementType); | 12324 propagatedType = propagatedType.getLeastUpperBound(elementType); |
| 12325 if (propagatedType == null) { | 12325 if (propagatedType == null) { |
| 12326 propagatedType = _dynamicType; | 12326 propagatedType = _dynamicType; |
| 12327 } | 12327 } |
| 12328 } | 12328 } |
| 12329 } | 12329 } |
| 12330 if (propagatedType.isMoreSpecificThan(staticType)) { | 12330 if (propagatedType.isMoreSpecificThan(staticType)) { |
| 12331 recordPropagatedType(node, _typeProvider.listType.substitute4(<Type2> [p
ropagatedType])); | 12331 _recordPropagatedType(node, _typeProvider.listType.substitute4(<Type2> [
propagatedType])); |
| 12332 } | 12332 } |
| 12333 } | 12333 } |
| 12334 return null; | 12334 return null; |
| 12335 } | 12335 } |
| 12336 | 12336 |
| 12337 /** | 12337 /** |
| 12338 * The Dart Language Specification, 12.7: <blockquote>The static type of a map
literal of the form | 12338 * The Dart Language Specification, 12.7: <blockquote>The static type of a map
literal of the form |
| 12339 * <i><b>const</b> <String, V> {k<sub>1</sub>:e<sub>1</sub>, …, | 12339 * <i><b>const</b> <String, V> {k<sub>1</sub>:e<sub>1</sub>, …, |
| 12340 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i><String, V> {k<sub>1<
/sub>:e<sub>1</sub>, | 12340 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i><String, V> {k<sub>1<
/sub>:e<sub>1</sub>, |
| 12341 * …, k<sub>n</sub>:e<sub>n</sub>}</i> is `Map<String, V>`. The s
tatic type a | 12341 * …, k<sub>n</sub>:e<sub>n</sub>}</i> is `Map<String, V>`. The s
tatic type a |
| 12342 * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hell
ip;, | 12342 * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hell
ip;, |
| 12343 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub
>, …, | 12343 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub
>, …, |
| 12344 * k<sub>n</sub>:e<sub>n</sub>}</i> is `Map<String, dynamic>`. | 12344 * k<sub>n</sub>:e<sub>n</sub>}</i> is `Map<String, dynamic>`. |
| 12345 * | 12345 * |
| 12346 * It is a compile-time error if the first type argument to a map literal is n
ot | 12346 * It is a compile-time error if the first type argument to a map literal is n
ot |
| 12347 * <i>String</i>.</blockquote> | 12347 * <i>String</i>.</blockquote> |
| 12348 */ | 12348 */ |
| 12349 Object visitMapLiteral(MapLiteral node) { | 12349 Object visitMapLiteral(MapLiteral node) { |
| 12350 Type2 staticKeyType = _dynamicType; | 12350 Type2 staticKeyType = _dynamicType; |
| 12351 Type2 staticValueType = _dynamicType; | 12351 Type2 staticValueType = _dynamicType; |
| 12352 TypeArgumentList typeArguments = node.typeArguments; | 12352 TypeArgumentList typeArguments = node.typeArguments; |
| 12353 if (typeArguments != null) { | 12353 if (typeArguments != null) { |
| 12354 NodeList<TypeName> arguments = typeArguments.arguments; | 12354 NodeList<TypeName> arguments = typeArguments.arguments; |
| 12355 if (arguments != null && arguments.length == 2) { | 12355 if (arguments != null && arguments.length == 2) { |
| 12356 TypeName entryKeyTypeName = arguments[0]; | 12356 TypeName entryKeyTypeName = arguments[0]; |
| 12357 Type2 entryKeyType = getType(entryKeyTypeName); | 12357 Type2 entryKeyType = _getType(entryKeyTypeName); |
| 12358 if (entryKeyType != null) { | 12358 if (entryKeyType != null) { |
| 12359 staticKeyType = entryKeyType; | 12359 staticKeyType = entryKeyType; |
| 12360 } | 12360 } |
| 12361 TypeName entryValueTypeName = arguments[1]; | 12361 TypeName entryValueTypeName = arguments[1]; |
| 12362 Type2 entryValueType = getType(entryValueTypeName); | 12362 Type2 entryValueType = _getType(entryValueTypeName); |
| 12363 if (entryValueType != null) { | 12363 if (entryValueType != null) { |
| 12364 staticValueType = entryValueType; | 12364 staticValueType = entryValueType; |
| 12365 } | 12365 } |
| 12366 } | 12366 } |
| 12367 } | 12367 } |
| 12368 recordStaticType(node, _typeProvider.mapType.substitute4(<Type2> [staticKeyT
ype, staticValueType])); | 12368 _recordStaticType(node, _typeProvider.mapType.substitute4(<Type2> [staticKey
Type, staticValueType])); |
| 12369 NodeList<MapLiteralEntry> entries = node.entries; | 12369 NodeList<MapLiteralEntry> entries = node.entries; |
| 12370 int count = entries.length; | 12370 int count = entries.length; |
| 12371 if (count > 0) { | 12371 if (count > 0) { |
| 12372 MapLiteralEntry entry = entries[0]; | 12372 MapLiteralEntry entry = entries[0]; |
| 12373 Type2 propagatedKeyType = entry.key.bestType; | 12373 Type2 propagatedKeyType = entry.key.bestType; |
| 12374 Type2 propagatedValueType = entry.value.bestType; | 12374 Type2 propagatedValueType = entry.value.bestType; |
| 12375 for (int i = 1; i < count; i++) { | 12375 for (int i = 1; i < count; i++) { |
| 12376 entry = entries[i]; | 12376 entry = entries[i]; |
| 12377 Type2 elementKeyType = entry.key.bestType; | 12377 Type2 elementKeyType = entry.key.bestType; |
| 12378 if (propagatedKeyType != elementKeyType) { | 12378 if (propagatedKeyType != elementKeyType) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 12395 } | 12395 } |
| 12396 bool betterKey = propagatedKeyType != null && propagatedKeyType.isMoreSpec
ificThan(staticKeyType); | 12396 bool betterKey = propagatedKeyType != null && propagatedKeyType.isMoreSpec
ificThan(staticKeyType); |
| 12397 bool betterValue = propagatedValueType != null && propagatedValueType.isMo
reSpecificThan(staticValueType); | 12397 bool betterValue = propagatedValueType != null && propagatedValueType.isMo
reSpecificThan(staticValueType); |
| 12398 if (betterKey || betterValue) { | 12398 if (betterKey || betterValue) { |
| 12399 if (!betterKey) { | 12399 if (!betterKey) { |
| 12400 propagatedKeyType = staticKeyType; | 12400 propagatedKeyType = staticKeyType; |
| 12401 } | 12401 } |
| 12402 if (!betterValue) { | 12402 if (!betterValue) { |
| 12403 propagatedValueType = staticValueType; | 12403 propagatedValueType = staticValueType; |
| 12404 } | 12404 } |
| 12405 recordPropagatedType(node, _typeProvider.mapType.substitute4(<Type2> [pr
opagatedKeyType, propagatedValueType])); | 12405 _recordPropagatedType(node, _typeProvider.mapType.substitute4(<Type2> [p
ropagatedKeyType, propagatedValueType])); |
| 12406 } | 12406 } |
| 12407 } | 12407 } |
| 12408 return null; | 12408 return null; |
| 12409 } | 12409 } |
| 12410 | 12410 |
| 12411 /** | 12411 /** |
| 12412 * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method in
vocation <i>i</i> | 12412 * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method in
vocation <i>i</i> |
| 12413 * has the form <i>o.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>
: a<sub>n+1</sub>, | 12413 * has the form <i>o.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>
: a<sub>n+1</sub>, |
| 12414 * …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. | 12414 * …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. |
| 12415 * | 12415 * |
| (...skipping 28 matching lines...) Expand all Loading... |
| 12444 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared
return type of | 12444 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared
return type of |
| 12445 * <i>F</i>.</blockquote> | 12445 * <i>F</i>.</blockquote> |
| 12446 */ | 12446 */ |
| 12447 Object visitMethodInvocation(MethodInvocation node) { | 12447 Object visitMethodInvocation(MethodInvocation node) { |
| 12448 SimpleIdentifier methodNameNode = node.methodName; | 12448 SimpleIdentifier methodNameNode = node.methodName; |
| 12449 Element staticMethodElement = methodNameNode.staticElement; | 12449 Element staticMethodElement = methodNameNode.staticElement; |
| 12450 // Record types of the local variable invoked as a function. | 12450 // Record types of the local variable invoked as a function. |
| 12451 if (staticMethodElement is LocalVariableElement) { | 12451 if (staticMethodElement is LocalVariableElement) { |
| 12452 LocalVariableElement variable = staticMethodElement; | 12452 LocalVariableElement variable = staticMethodElement; |
| 12453 Type2 staticType = variable.type; | 12453 Type2 staticType = variable.type; |
| 12454 recordStaticType(methodNameNode, staticType); | 12454 _recordStaticType(methodNameNode, staticType); |
| 12455 Type2 propagatedType = _overrideManager.getType(variable); | 12455 Type2 propagatedType = _overrideManager.getType(variable); |
| 12456 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { | 12456 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType
)) { |
| 12457 recordPropagatedType(methodNameNode, propagatedType); | 12457 _recordPropagatedType(methodNameNode, propagatedType); |
| 12458 } | 12458 } |
| 12459 } | 12459 } |
| 12460 // Record static return type of the static element. | 12460 // Record static return type of the static element. |
| 12461 Type2 staticStaticType = computeStaticReturnType(staticMethodElement); | 12461 Type2 staticStaticType = _computeStaticReturnType(staticMethodElement); |
| 12462 recordStaticType(node, staticStaticType); | 12462 _recordStaticType(node, staticStaticType); |
| 12463 // Record propagated return type of the static element. | 12463 // Record propagated return type of the static element. |
| 12464 Type2 staticPropagatedType = computePropagatedReturnType(staticMethodElement
); | 12464 Type2 staticPropagatedType = _computePropagatedReturnType(staticMethodElemen
t); |
| 12465 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { | 12465 if (staticPropagatedType != null && (staticStaticType == null || staticPropa
gatedType.isMoreSpecificThan(staticStaticType))) { |
| 12466 recordPropagatedType(node, staticPropagatedType); | 12466 _recordPropagatedType(node, staticPropagatedType); |
| 12467 } | 12467 } |
| 12468 String methodName = methodNameNode.name; | 12468 String methodName = methodNameNode.name; |
| 12469 // Future.then(closure) return type is: | 12469 // Future.then(closure) return type is: |
| 12470 // 1) the returned Future type, if the closure returns a Future; | 12470 // 1) the returned Future type, if the closure returns a Future; |
| 12471 // 2) Future<valueType>, if the closure returns a value. | 12471 // 2) Future<valueType>, if the closure returns a value. |
| 12472 if (methodName == "then") { | 12472 if (methodName == "then") { |
| 12473 Expression target = node.realTarget; | 12473 Expression target = node.realTarget; |
| 12474 Type2 targetType = target == null ? null : target.bestType; | 12474 Type2 targetType = target == null ? null : target.bestType; |
| 12475 if (isAsyncFutureType(targetType)) { | 12475 if (_isAsyncFutureType(targetType)) { |
| 12476 NodeList<Expression> arguments = node.argumentList.arguments; | 12476 NodeList<Expression> arguments = node.argumentList.arguments; |
| 12477 if (arguments.length == 1) { | 12477 if (arguments.length == 1) { |
| 12478 // TODO(brianwilkerson) Handle the case where both arguments are provi
ded. | 12478 // TODO(brianwilkerson) Handle the case where both arguments are provi
ded. |
| 12479 Expression closureArg = arguments[0]; | 12479 Expression closureArg = arguments[0]; |
| 12480 if (closureArg is FunctionExpression) { | 12480 if (closureArg is FunctionExpression) { |
| 12481 FunctionExpression closureExpr = closureArg; | 12481 FunctionExpression closureExpr = closureArg; |
| 12482 Type2 returnType = computePropagatedReturnType(closureExpr.element); | 12482 Type2 returnType = _computePropagatedReturnType(closureExpr.element)
; |
| 12483 if (returnType != null) { | 12483 if (returnType != null) { |
| 12484 // prepare the type of the returned Future | 12484 // prepare the type of the returned Future |
| 12485 InterfaceTypeImpl newFutureType; | 12485 InterfaceTypeImpl newFutureType; |
| 12486 if (isAsyncFutureType(returnType)) { | 12486 if (_isAsyncFutureType(returnType)) { |
| 12487 newFutureType = returnType as InterfaceTypeImpl; | 12487 newFutureType = returnType as InterfaceTypeImpl; |
| 12488 } else { | 12488 } else { |
| 12489 InterfaceType futureType = targetType as InterfaceType; | 12489 InterfaceType futureType = targetType as InterfaceType; |
| 12490 newFutureType = new InterfaceTypeImpl.con1(futureType.element); | 12490 newFutureType = new InterfaceTypeImpl.con1(futureType.element); |
| 12491 newFutureType.typeArguments = <Type2> [returnType]; | 12491 newFutureType.typeArguments = <Type2> [returnType]; |
| 12492 } | 12492 } |
| 12493 // set the 'then' invocation type | 12493 // set the 'then' invocation type |
| 12494 recordPropagatedType(node, newFutureType); | 12494 _recordPropagatedType(node, newFutureType); |
| 12495 return null; | 12495 return null; |
| 12496 } | 12496 } |
| 12497 } | 12497 } |
| 12498 } | 12498 } |
| 12499 } | 12499 } |
| 12500 } | 12500 } |
| 12501 if (methodName == "\$dom_createEvent") { | 12501 if (methodName == "\$dom_createEvent") { |
| 12502 Expression target = node.realTarget; | 12502 Expression target = node.realTarget; |
| 12503 if (target != null) { | 12503 if (target != null) { |
| 12504 Type2 targetType = target.bestType; | 12504 Type2 targetType = target.bestType; |
| 12505 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { | 12505 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 12506 LibraryElement library = targetType.element.library; | 12506 LibraryElement library = targetType.element.library; |
| 12507 if (isHtmlLibrary(library)) { | 12507 if (_isHtmlLibrary(library)) { |
| 12508 Type2 returnType = getFirstArgumentAsType(library, node.argumentList
); | 12508 Type2 returnType = _getFirstArgumentAsType(library, node.argumentLis
t); |
| 12509 if (returnType != null) { | 12509 if (returnType != null) { |
| 12510 recordPropagatedType(node, returnType); | 12510 _recordPropagatedType(node, returnType); |
| 12511 } | 12511 } |
| 12512 } | 12512 } |
| 12513 } | 12513 } |
| 12514 } | 12514 } |
| 12515 } else if (methodName == "query") { | 12515 } else if (methodName == "query") { |
| 12516 Expression target = node.realTarget; | 12516 Expression target = node.realTarget; |
| 12517 if (target == null) { | 12517 if (target == null) { |
| 12518 Element methodElement = methodNameNode.bestElement; | 12518 Element methodElement = methodNameNode.bestElement; |
| 12519 if (methodElement != null) { | 12519 if (methodElement != null) { |
| 12520 LibraryElement library = methodElement.library; | 12520 LibraryElement library = methodElement.library; |
| 12521 if (isHtmlLibrary(library)) { | 12521 if (_isHtmlLibrary(library)) { |
| 12522 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentLis
t); | 12522 Type2 returnType = _getFirstArgumentAsQuery(library, node.argumentLi
st); |
| 12523 if (returnType != null) { | 12523 if (returnType != null) { |
| 12524 recordPropagatedType(node, returnType); | 12524 _recordPropagatedType(node, returnType); |
| 12525 } | 12525 } |
| 12526 } | 12526 } |
| 12527 } | 12527 } |
| 12528 } else { | 12528 } else { |
| 12529 Type2 targetType = target.bestType; | 12529 Type2 targetType = target.bestType; |
| 12530 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { | 12530 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" ||
targetType.name == "Document")) { |
| 12531 LibraryElement library = targetType.element.library; | 12531 LibraryElement library = targetType.element.library; |
| 12532 if (isHtmlLibrary(library)) { | 12532 if (_isHtmlLibrary(library)) { |
| 12533 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentLis
t); | 12533 Type2 returnType = _getFirstArgumentAsQuery(library, node.argumentLi
st); |
| 12534 if (returnType != null) { | 12534 if (returnType != null) { |
| 12535 recordPropagatedType(node, returnType); | 12535 _recordPropagatedType(node, returnType); |
| 12536 } | 12536 } |
| 12537 } | 12537 } |
| 12538 } | 12538 } |
| 12539 } | 12539 } |
| 12540 } else if (methodName == "\$dom_createElement") { | 12540 } else if (methodName == "\$dom_createElement") { |
| 12541 Expression target = node.realTarget; | 12541 Expression target = node.realTarget; |
| 12542 Type2 targetType = target.bestType; | 12542 Type2 targetType = target.bestType; |
| 12543 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || t
argetType.name == "Document")) { | 12543 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || t
argetType.name == "Document")) { |
| 12544 LibraryElement library = targetType.element.library; | 12544 LibraryElement library = targetType.element.library; |
| 12545 if (isHtmlLibrary(library)) { | 12545 if (_isHtmlLibrary(library)) { |
| 12546 Type2 returnType = getFirstArgumentAsQuery(library, node.argumentList)
; | 12546 Type2 returnType = _getFirstArgumentAsQuery(library, node.argumentList
); |
| 12547 if (returnType != null) { | 12547 if (returnType != null) { |
| 12548 recordPropagatedType(node, returnType); | 12548 _recordPropagatedType(node, returnType); |
| 12549 } | 12549 } |
| 12550 } | 12550 } |
| 12551 } | 12551 } |
| 12552 } else if (methodName == "JS") { | 12552 } else if (methodName == "JS") { |
| 12553 Type2 returnType = getFirstArgumentAsType(_typeProvider.objectType.element
.library, node.argumentList); | 12553 Type2 returnType = _getFirstArgumentAsType(_typeProvider.objectType.elemen
t.library, node.argumentList); |
| 12554 if (returnType != null) { | 12554 if (returnType != null) { |
| 12555 recordPropagatedType(node, returnType); | 12555 _recordPropagatedType(node, returnType); |
| 12556 } | 12556 } |
| 12557 } else { | 12557 } else { |
| 12558 Element propagatedElement = methodNameNode.propagatedElement; | 12558 Element propagatedElement = methodNameNode.propagatedElement; |
| 12559 if (propagatedElement != staticMethodElement) { | 12559 if (propagatedElement != staticMethodElement) { |
| 12560 // Record static return type of the propagated element. | 12560 // Record static return type of the propagated element. |
| 12561 Type2 propagatedStaticType = computeStaticReturnType(propagatedElement); | 12561 Type2 propagatedStaticType = _computeStaticReturnType(propagatedElement)
; |
| 12562 if (propagatedStaticType != null && (staticStaticType == null || propaga
tedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType ==
null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { | 12562 if (propagatedStaticType != null && (staticStaticType == null || propaga
tedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType ==
null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) { |
| 12563 recordPropagatedType(node, propagatedStaticType); | 12563 _recordPropagatedType(node, propagatedStaticType); |
| 12564 } | 12564 } |
| 12565 // Record propagated return type of the propagated element. | 12565 // Record propagated return type of the propagated element. |
| 12566 Type2 propagatedPropagatedType = computePropagatedReturnType(propagatedE
lement); | 12566 Type2 propagatedPropagatedType = _computePropagatedReturnType(propagated
Element); |
| 12567 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { | 12567 if (propagatedPropagatedType != null && (staticStaticType == null || pro
pagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagated
Type == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType
)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificTh
an(propagatedStaticType))) { |
| 12568 recordPropagatedType(node, propagatedPropagatedType); | 12568 _recordPropagatedType(node, propagatedPropagatedType); |
| 12569 } | 12569 } |
| 12570 } | 12570 } |
| 12571 } | 12571 } |
| 12572 return null; | 12572 return null; |
| 12573 } | 12573 } |
| 12574 | 12574 |
| 12575 Object visitNamedExpression(NamedExpression node) { | 12575 Object visitNamedExpression(NamedExpression node) { |
| 12576 Expression expression = node.expression; | 12576 Expression expression = node.expression; |
| 12577 recordStaticType(node, getStaticType(expression)); | 12577 _recordStaticType(node, _getStaticType(expression)); |
| 12578 recordPropagatedType(node, expression.propagatedType); | 12578 _recordPropagatedType(node, expression.propagatedType); |
| 12579 return null; | 12579 return null; |
| 12580 } | 12580 } |
| 12581 | 12581 |
| 12582 /** | 12582 /** |
| 12583 * The Dart Language Specification, 12.2: <blockquote>The static type of `null
` is bottom. | 12583 * The Dart Language Specification, 12.2: <blockquote>The static type of `null
` is bottom. |
| 12584 * </blockquote> | 12584 * </blockquote> |
| 12585 */ | 12585 */ |
| 12586 Object visitNullLiteral(NullLiteral node) { | 12586 Object visitNullLiteral(NullLiteral node) { |
| 12587 recordStaticType(node, _typeProvider.bottomType); | 12587 _recordStaticType(node, _typeProvider.bottomType); |
| 12588 return null; | 12588 return null; |
| 12589 } | 12589 } |
| 12590 | 12590 |
| 12591 Object visitParenthesizedExpression(ParenthesizedExpression node) { | 12591 Object visitParenthesizedExpression(ParenthesizedExpression node) { |
| 12592 Expression expression = node.expression; | 12592 Expression expression = node.expression; |
| 12593 recordStaticType(node, getStaticType(expression)); | 12593 _recordStaticType(node, _getStaticType(expression)); |
| 12594 recordPropagatedType(node, expression.propagatedType); | 12594 _recordPropagatedType(node, expression.propagatedType); |
| 12595 return null; | 12595 return null; |
| 12596 } | 12596 } |
| 12597 | 12597 |
| 12598 /** | 12598 /** |
| 12599 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of
the form | 12599 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of
the form |
| 12600 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r =
v; v = r + 1; | 12600 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r =
v; v = r + 1; |
| 12601 * return r}()</i>. | 12601 * return r}()</i>. |
| 12602 * | 12602 * |
| 12603 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r
= C.v; C.v = r + 1; | 12603 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r
= C.v; C.v = r + 1; |
| 12604 * return r}()</i>. | 12604 * return r}()</i>. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 12616 * return r}()</i>. | 12616 * return r}()</i>. |
| 12617 * | 12617 * |
| 12618 * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var
r = x.v; x.v = r - | 12618 * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var
r = x.v; x.v = r - |
| 12619 * 1; return r}(e1)</i>. | 12619 * 1; return r}(e1)</i>. |
| 12620 * | 12620 * |
| 12621 * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i)
{var r = a[i]; a[i] | 12621 * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i)
{var r = a[i]; a[i] |
| 12622 * = r - 1; return r}(e1, e2)</i></blockquote> | 12622 * = r - 1; return r}(e1, e2)</i></blockquote> |
| 12623 */ | 12623 */ |
| 12624 Object visitPostfixExpression(PostfixExpression node) { | 12624 Object visitPostfixExpression(PostfixExpression node) { |
| 12625 Expression operand = node.operand; | 12625 Expression operand = node.operand; |
| 12626 Type2 staticType = getStaticType(operand); | 12626 Type2 staticType = _getStaticType(operand); |
| 12627 sc.TokenType operator = node.operator.type; | 12627 sc.TokenType operator = node.operator.type; |
| 12628 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, sc.
TokenType.PLUS_PLUS)) { | 12628 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, sc.
TokenType.PLUS_PLUS)) { |
| 12629 Type2 intType = _typeProvider.intType; | 12629 Type2 intType = _typeProvider.intType; |
| 12630 if (identical(getStaticType(node.operand), intType)) { | 12630 if (identical(_getStaticType(node.operand), intType)) { |
| 12631 staticType = intType; | 12631 staticType = intType; |
| 12632 } | 12632 } |
| 12633 } | 12633 } |
| 12634 recordStaticType(node, staticType); | 12634 _recordStaticType(node, staticType); |
| 12635 recordPropagatedType(node, operand.propagatedType); | 12635 _recordPropagatedType(node, operand.propagatedType); |
| 12636 return null; | 12636 return null; |
| 12637 } | 12637 } |
| 12638 | 12638 |
| 12639 /** | 12639 /** |
| 12640 * See [visitSimpleIdentifier]. | 12640 * See [visitSimpleIdentifier]. |
| 12641 */ | 12641 */ |
| 12642 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 12642 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 12643 SimpleIdentifier prefixedIdentifier = node.identifier; | 12643 SimpleIdentifier prefixedIdentifier = node.identifier; |
| 12644 Element staticElement = prefixedIdentifier.staticElement; | 12644 Element staticElement = prefixedIdentifier.staticElement; |
| 12645 Type2 staticType = _dynamicType; | 12645 Type2 staticType = _dynamicType; |
| 12646 if (staticElement is ClassElement) { | 12646 if (staticElement is ClassElement) { |
| 12647 if (isNotTypeLiteral(node)) { | 12647 if (_isNotTypeLiteral(node)) { |
| 12648 staticType = staticElement.type; | 12648 staticType = staticElement.type; |
| 12649 } else { | 12649 } else { |
| 12650 staticType = _typeProvider.typeType; | 12650 staticType = _typeProvider.typeType; |
| 12651 } | 12651 } |
| 12652 } else if (staticElement is FunctionTypeAliasElement) { | 12652 } else if (staticElement is FunctionTypeAliasElement) { |
| 12653 if (isNotTypeLiteral(node)) { | 12653 if (_isNotTypeLiteral(node)) { |
| 12654 staticType = staticElement.type; | 12654 staticType = staticElement.type; |
| 12655 } else { | 12655 } else { |
| 12656 staticType = _typeProvider.typeType; | 12656 staticType = _typeProvider.typeType; |
| 12657 } | 12657 } |
| 12658 } else if (staticElement is MethodElement) { | 12658 } else if (staticElement is MethodElement) { |
| 12659 staticType = staticElement.type; | 12659 staticType = staticElement.type; |
| 12660 } else if (staticElement is PropertyAccessorElement) { | 12660 } else if (staticElement is PropertyAccessorElement) { |
| 12661 staticType = getTypeOfProperty(staticElement, node.prefix.staticType); | 12661 staticType = _getTypeOfProperty(staticElement, node.prefix.staticType); |
| 12662 } else if (staticElement is ExecutableElement) { | 12662 } else if (staticElement is ExecutableElement) { |
| 12663 staticType = staticElement.type; | 12663 staticType = staticElement.type; |
| 12664 } else if (staticElement is TypeParameterElement) { | 12664 } else if (staticElement is TypeParameterElement) { |
| 12665 staticType = staticElement.type; | 12665 staticType = staticElement.type; |
| 12666 } else if (staticElement is VariableElement) { | 12666 } else if (staticElement is VariableElement) { |
| 12667 staticType = staticElement.type; | 12667 staticType = staticElement.type; |
| 12668 } | 12668 } |
| 12669 recordStaticType(prefixedIdentifier, staticType); | 12669 _recordStaticType(prefixedIdentifier, staticType); |
| 12670 recordStaticType(node, staticType); | 12670 _recordStaticType(node, staticType); |
| 12671 Element propagatedElement = prefixedIdentifier.propagatedElement; | 12671 Element propagatedElement = prefixedIdentifier.propagatedElement; |
| 12672 Type2 propagatedType = null; | 12672 Type2 propagatedType = null; |
| 12673 if (propagatedElement is ClassElement) { | 12673 if (propagatedElement is ClassElement) { |
| 12674 if (isNotTypeLiteral(node)) { | 12674 if (_isNotTypeLiteral(node)) { |
| 12675 propagatedType = propagatedElement.type; | 12675 propagatedType = propagatedElement.type; |
| 12676 } else { | 12676 } else { |
| 12677 propagatedType = _typeProvider.typeType; | 12677 propagatedType = _typeProvider.typeType; |
| 12678 } | 12678 } |
| 12679 } else if (propagatedElement is FunctionTypeAliasElement) { | 12679 } else if (propagatedElement is FunctionTypeAliasElement) { |
| 12680 propagatedType = propagatedElement.type; | 12680 propagatedType = propagatedElement.type; |
| 12681 } else if (propagatedElement is MethodElement) { | 12681 } else if (propagatedElement is MethodElement) { |
| 12682 propagatedType = propagatedElement.type; | 12682 propagatedType = propagatedElement.type; |
| 12683 } else if (propagatedElement is PropertyAccessorElement) { | 12683 } else if (propagatedElement is PropertyAccessorElement) { |
| 12684 propagatedType = getTypeOfProperty(propagatedElement, node.prefix.staticTy
pe); | 12684 propagatedType = _getTypeOfProperty(propagatedElement, node.prefix.staticT
ype); |
| 12685 } else if (propagatedElement is ExecutableElement) { | 12685 } else if (propagatedElement is ExecutableElement) { |
| 12686 propagatedType = propagatedElement.type; | 12686 propagatedType = propagatedElement.type; |
| 12687 } else if (propagatedElement is TypeParameterElement) { | 12687 } else if (propagatedElement is TypeParameterElement) { |
| 12688 propagatedType = propagatedElement.type; | 12688 propagatedType = propagatedElement.type; |
| 12689 } else if (propagatedElement is VariableElement) { | 12689 } else if (propagatedElement is VariableElement) { |
| 12690 propagatedType = propagatedElement.type; | 12690 propagatedType = propagatedElement.type; |
| 12691 } | 12691 } |
| 12692 Type2 overriddenType = _overrideManager.getType(propagatedElement); | 12692 Type2 overriddenType = _overrideManager.getType(propagatedElement); |
| 12693 if (propagatedType == null || (overriddenType != null && overriddenType.isMo
reSpecificThan(propagatedType))) { | 12693 if (propagatedType == null || (overriddenType != null && overriddenType.isMo
reSpecificThan(propagatedType))) { |
| 12694 propagatedType = overriddenType; | 12694 propagatedType = overriddenType; |
| 12695 } | 12695 } |
| 12696 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ | 12696 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ |
| 12697 recordPropagatedType(prefixedIdentifier, propagatedType); | 12697 _recordPropagatedType(prefixedIdentifier, propagatedType); |
| 12698 recordPropagatedType(node, propagatedType); | 12698 _recordPropagatedType(node, propagatedType); |
| 12699 } | 12699 } |
| 12700 return null; | 12700 return null; |
| 12701 } | 12701 } |
| 12702 | 12702 |
| 12703 /** | 12703 /** |
| 12704 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u
</i> of the form | 12704 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u
</i> of the form |
| 12705 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>.
An expression of the | 12705 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>.
An expression of the |
| 12706 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i
>.</blockquote> | 12706 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i
>.</blockquote> |
| 12707 */ | 12707 */ |
| 12708 Object visitPrefixExpression(PrefixExpression node) { | 12708 Object visitPrefixExpression(PrefixExpression node) { |
| 12709 sc.TokenType operator = node.operator.type; | 12709 sc.TokenType operator = node.operator.type; |
| 12710 if (identical(operator, sc.TokenType.BANG)) { | 12710 if (identical(operator, sc.TokenType.BANG)) { |
| 12711 recordStaticType(node, _typeProvider.boolType); | 12711 _recordStaticType(node, _typeProvider.boolType); |
| 12712 } else { | 12712 } else { |
| 12713 // The other cases are equivalent to invoking a method. | 12713 // The other cases are equivalent to invoking a method. |
| 12714 ExecutableElement staticMethodElement = node.staticElement; | 12714 ExecutableElement staticMethodElement = node.staticElement; |
| 12715 Type2 staticType = computeStaticReturnType(staticMethodElement); | 12715 Type2 staticType = _computeStaticReturnType(staticMethodElement); |
| 12716 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, s
c.TokenType.PLUS_PLUS)) { | 12716 if (identical(operator, sc.TokenType.MINUS_MINUS) || identical(operator, s
c.TokenType.PLUS_PLUS)) { |
| 12717 Type2 intType = _typeProvider.intType; | 12717 Type2 intType = _typeProvider.intType; |
| 12718 if (identical(getStaticType(node.operand), intType)) { | 12718 if (identical(_getStaticType(node.operand), intType)) { |
| 12719 staticType = intType; | 12719 staticType = intType; |
| 12720 } | 12720 } |
| 12721 } | 12721 } |
| 12722 recordStaticType(node, staticType); | 12722 _recordStaticType(node, staticType); |
| 12723 MethodElement propagatedMethodElement = node.propagatedElement; | 12723 MethodElement propagatedMethodElement = node.propagatedElement; |
| 12724 if (propagatedMethodElement != staticMethodElement) { | 12724 if (propagatedMethodElement != staticMethodElement) { |
| 12725 Type2 propagatedType = computeStaticReturnType(propagatedMethodElement); | 12725 Type2 propagatedType = _computeStaticReturnType(propagatedMethodElement)
; |
| 12726 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { | 12726 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy
pe)) { |
| 12727 recordPropagatedType(node, propagatedType); | 12727 _recordPropagatedType(node, propagatedType); |
| 12728 } | 12728 } |
| 12729 } | 12729 } |
| 12730 } | 12730 } |
| 12731 return null; | 12731 return null; |
| 12732 } | 12732 } |
| 12733 | 12733 |
| 12734 /** | 12734 /** |
| 12735 * The Dart Language Specification, 12.13: <blockquote> Property extraction al
lows for a member of | 12735 * The Dart Language Specification, 12.13: <blockquote> Property extraction al
lows for a member of |
| 12736 * an object to be concisely extracted from the object. If <i>o</i> is an obje
ct, and if <i>m</i> | 12736 * an object to be concisely extracted from the object. If <i>o</i> is an obje
ct, and if <i>m</i> |
| 12737 * is the name of a method member of <i>o</i>, then | 12737 * is the name of a method member of <i>o</i>, then |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12773 * The static type of <i>i</i> is the declared return type of <i>m</i>.</block
quote> | 12773 * The static type of <i>i</i> is the declared return type of <i>m</i>.</block
quote> |
| 12774 */ | 12774 */ |
| 12775 Object visitPropertyAccess(PropertyAccess node) { | 12775 Object visitPropertyAccess(PropertyAccess node) { |
| 12776 SimpleIdentifier propertyName = node.propertyName; | 12776 SimpleIdentifier propertyName = node.propertyName; |
| 12777 Element staticElement = propertyName.staticElement; | 12777 Element staticElement = propertyName.staticElement; |
| 12778 Type2 staticType = _dynamicType; | 12778 Type2 staticType = _dynamicType; |
| 12779 if (staticElement is MethodElement) { | 12779 if (staticElement is MethodElement) { |
| 12780 staticType = staticElement.type; | 12780 staticType = staticElement.type; |
| 12781 } else if (staticElement is PropertyAccessorElement) { | 12781 } else if (staticElement is PropertyAccessorElement) { |
| 12782 Expression realTarget = node.realTarget; | 12782 Expression realTarget = node.realTarget; |
| 12783 staticType = getTypeOfProperty(staticElement, realTarget != null ? getStat
icType(realTarget) : null); | 12783 staticType = _getTypeOfProperty(staticElement, realTarget != null ? _getSt
aticType(realTarget) : null); |
| 12784 } else { | 12784 } else { |
| 12785 } | 12785 } |
| 12786 recordStaticType(propertyName, staticType); | 12786 _recordStaticType(propertyName, staticType); |
| 12787 recordStaticType(node, staticType); | 12787 _recordStaticType(node, staticType); |
| 12788 Element propagatedElement = propertyName.propagatedElement; | 12788 Element propagatedElement = propertyName.propagatedElement; |
| 12789 Type2 propagatedType = _overrideManager.getType(propagatedElement); | 12789 Type2 propagatedType = _overrideManager.getType(propagatedElement); |
| 12790 if (propagatedElement is MethodElement) { | 12790 if (propagatedElement is MethodElement) { |
| 12791 propagatedType = propagatedElement.type; | 12791 propagatedType = propagatedElement.type; |
| 12792 } else if (propagatedElement is PropertyAccessorElement) { | 12792 } else if (propagatedElement is PropertyAccessorElement) { |
| 12793 Expression realTarget = node.realTarget; | 12793 Expression realTarget = node.realTarget; |
| 12794 propagatedType = getTypeOfProperty(propagatedElement, realTarget != null ?
realTarget.bestType : null); | 12794 propagatedType = _getTypeOfProperty(propagatedElement, realTarget != null
? realTarget.bestType : null); |
| 12795 } else { | 12795 } else { |
| 12796 } | 12796 } |
| 12797 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ | 12797 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ |
| 12798 recordPropagatedType(propertyName, propagatedType); | 12798 _recordPropagatedType(propertyName, propagatedType); |
| 12799 recordPropagatedType(node, propagatedType); | 12799 _recordPropagatedType(node, propagatedType); |
| 12800 } | 12800 } |
| 12801 return null; | 12801 return null; |
| 12802 } | 12802 } |
| 12803 | 12803 |
| 12804 /** | 12804 /** |
| 12805 * The Dart Language Specification, 12.9: <blockquote>The static type of a ret
hrow expression is | 12805 * The Dart Language Specification, 12.9: <blockquote>The static type of a ret
hrow expression is |
| 12806 * bottom.</blockquote> | 12806 * bottom.</blockquote> |
| 12807 */ | 12807 */ |
| 12808 Object visitRethrowExpression(RethrowExpression node) { | 12808 Object visitRethrowExpression(RethrowExpression node) { |
| 12809 recordStaticType(node, _typeProvider.bottomType); | 12809 _recordStaticType(node, _typeProvider.bottomType); |
| 12810 return null; | 12810 return null; |
| 12811 } | 12811 } |
| 12812 | 12812 |
| 12813 /** | 12813 /** |
| 12814 * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identi
fier expression | 12814 * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identi
fier expression |
| 12815 * <i>e</i> of the form <i>id</i> proceeds as follows: | 12815 * <i>e</i> of the form <i>id</i> proceeds as follows: |
| 12816 * | 12816 * |
| 12817 * Let <i>d</i> be the innermost declaration in the enclosing lexical scope wh
ose name is | 12817 * Let <i>d</i> be the innermost declaration in the enclosing lexical scope wh
ose name is |
| 12818 * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i>
be the declaration | 12818 * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i>
be the declaration |
| 12819 * of the inherited member named <i>id</i> if it exists. | 12819 * of the inherited member named <i>id</i> if it exists. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 12845 * * Otherwise, if <i>e</i> occurs inside a top level or static function (be i
t function, | 12845 * * Otherwise, if <i>e</i> occurs inside a top level or static function (be i
t function, |
| 12846 * method, getter, or setter) or variable initializer, evaluation of e causes
a NoSuchMethodError | 12846 * method, getter, or setter) or variable initializer, evaluation of e causes
a NoSuchMethodError |
| 12847 * to be thrown. | 12847 * to be thrown. |
| 12848 * * Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i
>. | 12848 * * Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i
>. |
| 12849 * </blockquote> | 12849 * </blockquote> |
| 12850 */ | 12850 */ |
| 12851 Object visitSimpleIdentifier(SimpleIdentifier node) { | 12851 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 12852 Element element = node.staticElement; | 12852 Element element = node.staticElement; |
| 12853 Type2 staticType = _dynamicType; | 12853 Type2 staticType = _dynamicType; |
| 12854 if (element is ClassElement) { | 12854 if (element is ClassElement) { |
| 12855 if (isNotTypeLiteral(node)) { | 12855 if (_isNotTypeLiteral(node)) { |
| 12856 staticType = element.type; | 12856 staticType = element.type; |
| 12857 } else { | 12857 } else { |
| 12858 staticType = _typeProvider.typeType; | 12858 staticType = _typeProvider.typeType; |
| 12859 } | 12859 } |
| 12860 } else if (element is FunctionTypeAliasElement) { | 12860 } else if (element is FunctionTypeAliasElement) { |
| 12861 if (isNotTypeLiteral(node)) { | 12861 if (_isNotTypeLiteral(node)) { |
| 12862 staticType = element.type; | 12862 staticType = element.type; |
| 12863 } else { | 12863 } else { |
| 12864 staticType = _typeProvider.typeType; | 12864 staticType = _typeProvider.typeType; |
| 12865 } | 12865 } |
| 12866 } else if (element is MethodElement) { | 12866 } else if (element is MethodElement) { |
| 12867 staticType = element.type; | 12867 staticType = element.type; |
| 12868 } else if (element is PropertyAccessorElement) { | 12868 } else if (element is PropertyAccessorElement) { |
| 12869 staticType = getTypeOfProperty(element, null); | 12869 staticType = _getTypeOfProperty(element, null); |
| 12870 } else if (element is ExecutableElement) { | 12870 } else if (element is ExecutableElement) { |
| 12871 staticType = element.type; | 12871 staticType = element.type; |
| 12872 } else if (element is TypeParameterElement) { | 12872 } else if (element is TypeParameterElement) { |
| 12873 // if (isTypeName(node)) { | 12873 // if (isTypeName(node)) { |
| 12874 staticType = element.type; | 12874 staticType = element.type; |
| 12875 } else if (element is VariableElement) { | 12875 } else if (element is VariableElement) { |
| 12876 VariableElement variable = element; | 12876 VariableElement variable = element; |
| 12877 staticType = _promoteManager.getStaticType(variable); | 12877 staticType = _promoteManager.getStaticType(variable); |
| 12878 } else if (element is PrefixElement) { | 12878 } else if (element is PrefixElement) { |
| 12879 return null; | 12879 return null; |
| 12880 } else { | 12880 } else { |
| 12881 staticType = _dynamicType; | 12881 staticType = _dynamicType; |
| 12882 } | 12882 } |
| 12883 recordStaticType(node, staticType); | 12883 _recordStaticType(node, staticType); |
| 12884 // TODO(brianwilkerson) I think we want to repeat the logic above using the
propagated element | 12884 // TODO(brianwilkerson) I think we want to repeat the logic above using the
propagated element |
| 12885 // to get another candidate for the propagated type. | 12885 // to get another candidate for the propagated type. |
| 12886 Type2 propagatedType = _overrideManager.getType(element); | 12886 Type2 propagatedType = _overrideManager.getType(element); |
| 12887 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ | 12887 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ |
| 12888 recordPropagatedType(node, propagatedType); | 12888 _recordPropagatedType(node, propagatedType); |
| 12889 } | 12889 } |
| 12890 return null; | 12890 return null; |
| 12891 } | 12891 } |
| 12892 | 12892 |
| 12893 /** | 12893 /** |
| 12894 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is | 12894 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is |
| 12895 * `String`.</blockquote> | 12895 * `String`.</blockquote> |
| 12896 */ | 12896 */ |
| 12897 Object visitSimpleStringLiteral(SimpleStringLiteral node) { | 12897 Object visitSimpleStringLiteral(SimpleStringLiteral node) { |
| 12898 recordStaticType(node, _typeProvider.stringType); | 12898 _recordStaticType(node, _typeProvider.stringType); |
| 12899 return null; | 12899 return null; |
| 12900 } | 12900 } |
| 12901 | 12901 |
| 12902 /** | 12902 /** |
| 12903 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is | 12903 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is |
| 12904 * `String`.</blockquote> | 12904 * `String`.</blockquote> |
| 12905 */ | 12905 */ |
| 12906 Object visitStringInterpolation(StringInterpolation node) { | 12906 Object visitStringInterpolation(StringInterpolation node) { |
| 12907 recordStaticType(node, _typeProvider.stringType); | 12907 _recordStaticType(node, _typeProvider.stringType); |
| 12908 return null; | 12908 return null; |
| 12909 } | 12909 } |
| 12910 | 12910 |
| 12911 Object visitSuperExpression(SuperExpression node) { | 12911 Object visitSuperExpression(SuperExpression node) { |
| 12912 if (_thisType == null) { | 12912 if (_thisType == null) { |
| 12913 // TODO(brianwilkerson) Report this error if it hasn't already been report
ed | 12913 // TODO(brianwilkerson) Report this error if it hasn't already been report
ed |
| 12914 recordStaticType(node, _dynamicType); | 12914 _recordStaticType(node, _dynamicType); |
| 12915 } else { | 12915 } else { |
| 12916 recordStaticType(node, _thisType); | 12916 _recordStaticType(node, _thisType); |
| 12917 } | 12917 } |
| 12918 return null; | 12918 return null; |
| 12919 } | 12919 } |
| 12920 | 12920 |
| 12921 Object visitSymbolLiteral(SymbolLiteral node) { | 12921 Object visitSymbolLiteral(SymbolLiteral node) { |
| 12922 recordStaticType(node, _typeProvider.symbolType); | 12922 _recordStaticType(node, _typeProvider.symbolType); |
| 12923 return null; | 12923 return null; |
| 12924 } | 12924 } |
| 12925 | 12925 |
| 12926 /** | 12926 /** |
| 12927 * The Dart Language Specification, 12.10: <blockquote>The static type of `thi
s` is the | 12927 * The Dart Language Specification, 12.10: <blockquote>The static type of `thi
s` is the |
| 12928 * interface of the immediately enclosing class.</blockquote> | 12928 * interface of the immediately enclosing class.</blockquote> |
| 12929 */ | 12929 */ |
| 12930 Object visitThisExpression(ThisExpression node) { | 12930 Object visitThisExpression(ThisExpression node) { |
| 12931 if (_thisType == null) { | 12931 if (_thisType == null) { |
| 12932 // TODO(brianwilkerson) Report this error if it hasn't already been report
ed | 12932 // TODO(brianwilkerson) Report this error if it hasn't already been report
ed |
| 12933 recordStaticType(node, _dynamicType); | 12933 _recordStaticType(node, _dynamicType); |
| 12934 } else { | 12934 } else { |
| 12935 recordStaticType(node, _thisType); | 12935 _recordStaticType(node, _thisType); |
| 12936 } | 12936 } |
| 12937 return null; | 12937 return null; |
| 12938 } | 12938 } |
| 12939 | 12939 |
| 12940 /** | 12940 /** |
| 12941 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr
ow expression is | 12941 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr
ow expression is |
| 12942 * bottom.</blockquote> | 12942 * bottom.</blockquote> |
| 12943 */ | 12943 */ |
| 12944 Object visitThrowExpression(ThrowExpression node) { | 12944 Object visitThrowExpression(ThrowExpression node) { |
| 12945 recordStaticType(node, _typeProvider.bottomType); | 12945 _recordStaticType(node, _typeProvider.bottomType); |
| 12946 return null; | 12946 return null; |
| 12947 } | 12947 } |
| 12948 | 12948 |
| 12949 Object visitVariableDeclaration(VariableDeclaration node) { | 12949 Object visitVariableDeclaration(VariableDeclaration node) { |
| 12950 Expression initializer = node.initializer; | 12950 Expression initializer = node.initializer; |
| 12951 if (initializer != null) { | 12951 if (initializer != null) { |
| 12952 Type2 rightType = initializer.bestType; | 12952 Type2 rightType = initializer.bestType; |
| 12953 SimpleIdentifier name = node.name; | 12953 SimpleIdentifier name = node.name; |
| 12954 recordPropagatedType(name, rightType); | 12954 _recordPropagatedType(name, rightType); |
| 12955 VariableElement element = name.staticElement as VariableElement; | 12955 VariableElement element = name.staticElement as VariableElement; |
| 12956 if (element != null) { | 12956 if (element != null) { |
| 12957 _resolver.overrideVariable(element, rightType); | 12957 _resolver.overrideVariable(element, rightType); |
| 12958 } | 12958 } |
| 12959 } | 12959 } |
| 12960 return null; | 12960 return null; |
| 12961 } | 12961 } |
| 12962 | 12962 |
| 12963 /** | 12963 /** |
| 12964 * Record that the static type of the given node is the type of the second arg
ument to the method | 12964 * Record that the static type of the given node is the type of the second arg
ument to the method |
| 12965 * represented by the given element. | 12965 * represented by the given element. |
| 12966 * | 12966 * |
| 12967 * @param element the element representing the method invoked by the given nod
e | 12967 * @param element the element representing the method invoked by the given nod
e |
| 12968 */ | 12968 */ |
| 12969 Type2 computeArgumentType(ExecutableElement element) { | 12969 Type2 _computeArgumentType(ExecutableElement element) { |
| 12970 if (element != null) { | 12970 if (element != null) { |
| 12971 List<ParameterElement> parameters = element.parameters; | 12971 List<ParameterElement> parameters = element.parameters; |
| 12972 if (parameters != null && parameters.length == 2) { | 12972 if (parameters != null && parameters.length == 2) { |
| 12973 return parameters[1].type; | 12973 return parameters[1].type; |
| 12974 } | 12974 } |
| 12975 } | 12975 } |
| 12976 return _dynamicType; | 12976 return _dynamicType; |
| 12977 } | 12977 } |
| 12978 | 12978 |
| 12979 /** | 12979 /** |
| 12980 * Compute the propagated return type of the method or function represented by
the given element. | 12980 * Compute the propagated return type of the method or function represented by
the given element. |
| 12981 * | 12981 * |
| 12982 * @param element the element representing the method or function invoked by t
he given node | 12982 * @param element the element representing the method or function invoked by t
he given node |
| 12983 * @return the propagated return type that was computed | 12983 * @return the propagated return type that was computed |
| 12984 */ | 12984 */ |
| 12985 Type2 computePropagatedReturnType(Element element) { | 12985 Type2 _computePropagatedReturnType(Element element) { |
| 12986 if (element is ExecutableElement) { | 12986 if (element is ExecutableElement) { |
| 12987 return _propagatedReturnTypes[element]; | 12987 return _propagatedReturnTypes[element]; |
| 12988 } | 12988 } |
| 12989 return null; | 12989 return null; |
| 12990 } | 12990 } |
| 12991 | 12991 |
| 12992 /** | 12992 /** |
| 12993 * Given a function body, compute the propagated return type of the function.
The propagated | 12993 * Given a function body, compute the propagated return type of the function.
The propagated |
| 12994 * return type of functions with a block body is the least upper bound of all | 12994 * return type of functions with a block body is the least upper bound of all |
| 12995 * [ReturnStatement] expressions, with an expression body it is the type of th
e expression. | 12995 * [ReturnStatement] expressions, with an expression body it is the type of th
e expression. |
| 12996 * | 12996 * |
| 12997 * @param body the boy of the function whose propagated return type is to be c
omputed | 12997 * @param body the boy of the function whose propagated return type is to be c
omputed |
| 12998 * @return the propagated return type that was computed | 12998 * @return the propagated return type that was computed |
| 12999 */ | 12999 */ |
| 13000 Type2 computePropagatedReturnTypeOfFunction(FunctionBody body) { | 13000 Type2 _computePropagatedReturnTypeOfFunction(FunctionBody body) { |
| 13001 if (body is ExpressionFunctionBody) { | 13001 if (body is ExpressionFunctionBody) { |
| 13002 ExpressionFunctionBody expressionBody = body; | 13002 ExpressionFunctionBody expressionBody = body; |
| 13003 return expressionBody.expression.bestType; | 13003 return expressionBody.expression.bestType; |
| 13004 } | 13004 } |
| 13005 if (body is BlockFunctionBody) { | 13005 if (body is BlockFunctionBody) { |
| 13006 List<Type2> result = [null]; | 13006 List<Type2> result = [null]; |
| 13007 body.accept(new GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagate
dReturnTypeOfFunction(result)); | 13007 body.accept(new GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagate
dReturnTypeOfFunction(result)); |
| 13008 return result[0]; | 13008 return result[0]; |
| 13009 } | 13009 } |
| 13010 return null; | 13010 return null; |
| 13011 } | 13011 } |
| 13012 | 13012 |
| 13013 /** | 13013 /** |
| 13014 * Compute the static return type of the method or function represented by the
given element. | 13014 * Compute the static return type of the method or function represented by the
given element. |
| 13015 * | 13015 * |
| 13016 * @param element the element representing the method or function invoked by t
he given node | 13016 * @param element the element representing the method or function invoked by t
he given node |
| 13017 * @return the static return type that was computed | 13017 * @return the static return type that was computed |
| 13018 */ | 13018 */ |
| 13019 Type2 computeStaticReturnType(Element element) { | 13019 Type2 _computeStaticReturnType(Element element) { |
| 13020 if (element is PropertyAccessorElement) { | 13020 if (element is PropertyAccessorElement) { |
| 13021 // | 13021 // |
| 13022 // This is a function invocation expression disguised as something else. W
e are invoking a | 13022 // This is a function invocation expression disguised as something else. W
e are invoking a |
| 13023 // getter and then invoking the returned function. | 13023 // getter and then invoking the returned function. |
| 13024 // | 13024 // |
| 13025 FunctionType propertyType = element.type; | 13025 FunctionType propertyType = element.type; |
| 13026 if (propertyType != null) { | 13026 if (propertyType != null) { |
| 13027 Type2 returnType = propertyType.returnType; | 13027 Type2 returnType = propertyType.returnType; |
| 13028 if (returnType.isDartCoreFunction) { | 13028 if (returnType.isDartCoreFunction) { |
| 13029 return _dynamicType; | 13029 return _dynamicType; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 13059 } | 13059 } |
| 13060 | 13060 |
| 13061 /** | 13061 /** |
| 13062 * Given a function declaration, compute the return static type of the functio
n. The return type | 13062 * Given a function declaration, compute the return static type of the functio
n. The return type |
| 13063 * of functions with a block body is `dynamicType`, with an expression body it
is the type | 13063 * of functions with a block body is `dynamicType`, with an expression body it
is the type |
| 13064 * of the expression. | 13064 * of the expression. |
| 13065 * | 13065 * |
| 13066 * @param node the function expression whose static return type is to be compu
ted | 13066 * @param node the function expression whose static return type is to be compu
ted |
| 13067 * @return the static return type that was computed | 13067 * @return the static return type that was computed |
| 13068 */ | 13068 */ |
| 13069 Type2 computeStaticReturnTypeOfFunctionDeclaration(FunctionDeclaration node) { | 13069 Type2 _computeStaticReturnTypeOfFunctionDeclaration(FunctionDeclaration node)
{ |
| 13070 TypeName returnType = node.returnType; | 13070 TypeName returnType = node.returnType; |
| 13071 if (returnType == null) { | 13071 if (returnType == null) { |
| 13072 return _dynamicType; | 13072 return _dynamicType; |
| 13073 } | 13073 } |
| 13074 return returnType.type; | 13074 return returnType.type; |
| 13075 } | 13075 } |
| 13076 | 13076 |
| 13077 /** | 13077 /** |
| 13078 * Given a function expression, compute the return type of the function. The r
eturn type of | 13078 * Given a function expression, compute the return type of the function. The r
eturn type of |
| 13079 * functions with a block body is `dynamicType`, with an expression body it is
the type of | 13079 * functions with a block body is `dynamicType`, with an expression body it is
the type of |
| 13080 * the expression. | 13080 * the expression. |
| 13081 * | 13081 * |
| 13082 * @param node the function expression whose return type is to be computed | 13082 * @param node the function expression whose return type is to be computed |
| 13083 * @return the return type that was computed | 13083 * @return the return type that was computed |
| 13084 */ | 13084 */ |
| 13085 Type2 computeStaticReturnTypeOfFunctionExpression(FunctionExpression node) { | 13085 Type2 _computeStaticReturnTypeOfFunctionExpression(FunctionExpression node) { |
| 13086 FunctionBody body = node.body; | 13086 FunctionBody body = node.body; |
| 13087 if (body is ExpressionFunctionBody) { | 13087 if (body is ExpressionFunctionBody) { |
| 13088 return getStaticType(body.expression); | 13088 return _getStaticType(body.expression); |
| 13089 } | 13089 } |
| 13090 return _dynamicType; | 13090 return _dynamicType; |
| 13091 } | 13091 } |
| 13092 | 13092 |
| 13093 /** | 13093 /** |
| 13094 * If the given element name can be mapped to the name of a class defined with
in the given | 13094 * If the given element name can be mapped to the name of a class defined with
in the given |
| 13095 * library, return the type specified by the argument. | 13095 * library, return the type specified by the argument. |
| 13096 * | 13096 * |
| 13097 * @param library the library in which the specified type would be defined | 13097 * @param library the library in which the specified type would be defined |
| 13098 * @param elementName the name of the element for which a type is being sought | 13098 * @param elementName the name of the element for which a type is being sought |
| 13099 * @param nameMap an optional map used to map the element name to a type name | 13099 * @param nameMap an optional map used to map the element name to a type name |
| 13100 * @return the type specified by the first argument in the argument list | 13100 * @return the type specified by the first argument in the argument list |
| 13101 */ | 13101 */ |
| 13102 Type2 getElementNameAsType(LibraryElement library, String elementName, Map<Str
ing, String> nameMap) { | 13102 Type2 _getElementNameAsType(LibraryElement library, String elementName, Map<St
ring, String> nameMap) { |
| 13103 if (elementName != null) { | 13103 if (elementName != null) { |
| 13104 if (nameMap != null) { | 13104 if (nameMap != null) { |
| 13105 elementName = nameMap[elementName.toLowerCase()]; | 13105 elementName = nameMap[elementName.toLowerCase()]; |
| 13106 } | 13106 } |
| 13107 ClassElement returnType = library.getType(elementName); | 13107 ClassElement returnType = library.getType(elementName); |
| 13108 if (returnType != null) { | 13108 if (returnType != null) { |
| 13109 return returnType.type; | 13109 return returnType.type; |
| 13110 } | 13110 } |
| 13111 } | 13111 } |
| 13112 return null; | 13112 return null; |
| 13113 } | 13113 } |
| 13114 | 13114 |
| 13115 /** | 13115 /** |
| 13116 * If the given argument list contains at least one argument, and if the argum
ent is a simple | 13116 * If the given argument list contains at least one argument, and if the argum
ent is a simple |
| 13117 * string literal, then parse that argument as a query string and return the t
ype specified by the | 13117 * string literal, then parse that argument as a query string and return the t
ype specified by the |
| 13118 * argument. | 13118 * argument. |
| 13119 * | 13119 * |
| 13120 * @param library the library in which the specified type would be defined | 13120 * @param library the library in which the specified type would be defined |
| 13121 * @param argumentList the list of arguments from which a type is to be extrac
ted | 13121 * @param argumentList the list of arguments from which a type is to be extrac
ted |
| 13122 * @return the type specified by the first argument in the argument list | 13122 * @return the type specified by the first argument in the argument list |
| 13123 */ | 13123 */ |
| 13124 Type2 getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentLis
t) { | 13124 Type2 _getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentLi
st) { |
| 13125 String argumentValue = getFirstArgumentAsString(argumentList); | 13125 String argumentValue = _getFirstArgumentAsString(argumentList); |
| 13126 if (argumentValue != null) { | 13126 if (argumentValue != null) { |
| 13127 // | 13127 // |
| 13128 // If the query has spaces, full parsing is required because it might be: | 13128 // If the query has spaces, full parsing is required because it might be: |
| 13129 // E[text='warning text'] | 13129 // E[text='warning text'] |
| 13130 // | 13130 // |
| 13131 if (StringUtilities.indexOf1(argumentValue, 0, 0x20) >= 0) { | 13131 if (StringUtilities.indexOf1(argumentValue, 0, 0x20) >= 0) { |
| 13132 return null; | 13132 return null; |
| 13133 } | 13133 } |
| 13134 // | 13134 // |
| 13135 // Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/se
lector.html. | 13135 // Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/se
lector.html. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 13148 return null; | 13148 return null; |
| 13149 } | 13149 } |
| 13150 | 13150 |
| 13151 /** | 13151 /** |
| 13152 * If the given argument list contains at least one argument, and if the argum
ent is a simple | 13152 * If the given argument list contains at least one argument, and if the argum
ent is a simple |
| 13153 * string literal, return the String value of the argument. | 13153 * string literal, return the String value of the argument. |
| 13154 * | 13154 * |
| 13155 * @param argumentList the list of arguments from which a string value is to b
e extracted | 13155 * @param argumentList the list of arguments from which a string value is to b
e extracted |
| 13156 * @return the string specified by the first argument in the argument list | 13156 * @return the string specified by the first argument in the argument list |
| 13157 */ | 13157 */ |
| 13158 String getFirstArgumentAsString(ArgumentList argumentList) { | 13158 String _getFirstArgumentAsString(ArgumentList argumentList) { |
| 13159 NodeList<Expression> arguments = argumentList.arguments; | 13159 NodeList<Expression> arguments = argumentList.arguments; |
| 13160 if (arguments.length > 0) { | 13160 if (arguments.length > 0) { |
| 13161 Expression argument = arguments[0]; | 13161 Expression argument = arguments[0]; |
| 13162 if (argument is SimpleStringLiteral) { | 13162 if (argument is SimpleStringLiteral) { |
| 13163 return argument.value; | 13163 return argument.value; |
| 13164 } | 13164 } |
| 13165 } | 13165 } |
| 13166 return null; | 13166 return null; |
| 13167 } | 13167 } |
| 13168 | 13168 |
| 13169 /** | 13169 /** |
| 13170 * If the given argument list contains at least one argument, and if the argum
ent is a simple | 13170 * If the given argument list contains at least one argument, and if the argum
ent is a simple |
| 13171 * string literal, and if the value of the argument is the name of a class def
ined within the | 13171 * string literal, and if the value of the argument is the name of a class def
ined within the |
| 13172 * given library, return the type specified by the argument. | 13172 * given library, return the type specified by the argument. |
| 13173 * | 13173 * |
| 13174 * @param library the library in which the specified type would be defined | 13174 * @param library the library in which the specified type would be defined |
| 13175 * @param argumentList the list of arguments from which a type is to be extrac
ted | 13175 * @param argumentList the list of arguments from which a type is to be extrac
ted |
| 13176 * @return the type specified by the first argument in the argument list | 13176 * @return the type specified by the first argument in the argument list |
| 13177 */ | 13177 */ |
| 13178 Type2 getFirstArgumentAsType(LibraryElement library, ArgumentList argumentList
) => getFirstArgumentAsTypeWithMap(library, argumentList, null); | 13178 Type2 _getFirstArgumentAsType(LibraryElement library, ArgumentList argumentLis
t) => _getFirstArgumentAsTypeWithMap(library, argumentList, null); |
| 13179 | 13179 |
| 13180 /** | 13180 /** |
| 13181 * If the given argument list contains at least one argument, and if the argum
ent is a simple | 13181 * If the given argument list contains at least one argument, and if the argum
ent is a simple |
| 13182 * string literal, and if the value of the argument is the name of a class def
ined within the | 13182 * string literal, and if the value of the argument is the name of a class def
ined within the |
| 13183 * given library, return the type specified by the argument. | 13183 * given library, return the type specified by the argument. |
| 13184 * | 13184 * |
| 13185 * @param library the library in which the specified type would be defined | 13185 * @param library the library in which the specified type would be defined |
| 13186 * @param argumentList the list of arguments from which a type is to be extrac
ted | 13186 * @param argumentList the list of arguments from which a type is to be extrac
ted |
| 13187 * @param nameMap an optional map used to map the element name to a type name | 13187 * @param nameMap an optional map used to map the element name to a type name |
| 13188 * @return the type specified by the first argument in the argument list | 13188 * @return the type specified by the first argument in the argument list |
| 13189 */ | 13189 */ |
| 13190 Type2 getFirstArgumentAsTypeWithMap(LibraryElement library, ArgumentList argum
entList, Map<String, String> nameMap) => getElementNameAsType(library, getFirstA
rgumentAsString(argumentList), nameMap); | 13190 Type2 _getFirstArgumentAsTypeWithMap(LibraryElement library, ArgumentList argu
mentList, Map<String, String> nameMap) => _getElementNameAsType(library, _getFir
stArgumentAsString(argumentList), nameMap); |
| 13191 | 13191 |
| 13192 /** | 13192 /** |
| 13193 * Return the static type of the given expression. | 13193 * Return the static type of the given expression. |
| 13194 * | 13194 * |
| 13195 * @param expression the expression whose type is to be returned | 13195 * @param expression the expression whose type is to be returned |
| 13196 * @return the static type of the given expression | 13196 * @return the static type of the given expression |
| 13197 */ | 13197 */ |
| 13198 Type2 getStaticType(Expression expression) { | 13198 Type2 _getStaticType(Expression expression) { |
| 13199 Type2 type = expression.staticType; | 13199 Type2 type = expression.staticType; |
| 13200 if (type == null) { | 13200 if (type == null) { |
| 13201 // TODO(brianwilkerson) Determine the conditions for which the static type
is null. | 13201 // TODO(brianwilkerson) Determine the conditions for which the static type
is null. |
| 13202 return _dynamicType; | 13202 return _dynamicType; |
| 13203 } | 13203 } |
| 13204 return type; | 13204 return type; |
| 13205 } | 13205 } |
| 13206 | 13206 |
| 13207 /** | 13207 /** |
| 13208 * Return the type represented by the given type name. | 13208 * Return the type represented by the given type name. |
| 13209 * | 13209 * |
| 13210 * @param typeName the type name representing the type to be returned | 13210 * @param typeName the type name representing the type to be returned |
| 13211 * @return the type represented by the type name | 13211 * @return the type represented by the type name |
| 13212 */ | 13212 */ |
| 13213 Type2 getType(TypeName typeName) { | 13213 Type2 _getType(TypeName typeName) { |
| 13214 Type2 type = typeName.type; | 13214 Type2 type = typeName.type; |
| 13215 if (type == null) { | 13215 if (type == null) { |
| 13216 //TODO(brianwilkerson) Determine the conditions for which the type is null
. | 13216 //TODO(brianwilkerson) Determine the conditions for which the type is null
. |
| 13217 return _dynamicType; | 13217 return _dynamicType; |
| 13218 } | 13218 } |
| 13219 return type; | 13219 return type; |
| 13220 } | 13220 } |
| 13221 | 13221 |
| 13222 /** | 13222 /** |
| 13223 * Return the type that should be recorded for a node that resolved to the giv
en accessor. | 13223 * Return the type that should be recorded for a node that resolved to the giv
en accessor. |
| 13224 * | 13224 * |
| 13225 * @param accessor the accessor that the node resolved to | 13225 * @param accessor the accessor that the node resolved to |
| 13226 * @param context if the accessor element has context [by being the RHS of a | 13226 * @param context if the accessor element has context [by being the RHS of a |
| 13227 * [PrefixedIdentifier] or [PropertyAccess]], and the return type of
the | 13227 * [PrefixedIdentifier] or [PropertyAccess]], and the return type of
the |
| 13228 * accessor is a parameter type, then the type of the LHS can be used
to get more | 13228 * accessor is a parameter type, then the type of the LHS can be used
to get more |
| 13229 * specific type information | 13229 * specific type information |
| 13230 * @return the type that should be recorded for a node that resolved to the gi
ven accessor | 13230 * @return the type that should be recorded for a node that resolved to the gi
ven accessor |
| 13231 */ | 13231 */ |
| 13232 Type2 getTypeOfProperty(PropertyAccessorElement accessor, Type2 context) { | 13232 Type2 _getTypeOfProperty(PropertyAccessorElement accessor, Type2 context) { |
| 13233 FunctionType functionType = accessor.type; | 13233 FunctionType functionType = accessor.type; |
| 13234 if (functionType == null) { | 13234 if (functionType == null) { |
| 13235 // TODO(brianwilkerson) Report this internal error. This happens when we a
re analyzing a | 13235 // TODO(brianwilkerson) Report this internal error. This happens when we a
re analyzing a |
| 13236 // reference to a property before we have analyzed the declaration of the
property or when | 13236 // reference to a property before we have analyzed the declaration of the
property or when |
| 13237 // the property does not have a defined type. | 13237 // the property does not have a defined type. |
| 13238 return _dynamicType; | 13238 return _dynamicType; |
| 13239 } | 13239 } |
| 13240 if (accessor.isSetter) { | 13240 if (accessor.isSetter) { |
| 13241 List<Type2> parameterTypes = functionType.normalParameterTypes; | 13241 List<Type2> parameterTypes = functionType.normalParameterTypes; |
| 13242 if (parameterTypes != null && parameterTypes.length > 0) { | 13242 if (parameterTypes != null && parameterTypes.length > 0) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 13267 } | 13267 } |
| 13268 } | 13268 } |
| 13269 } | 13269 } |
| 13270 return returnType; | 13270 return returnType; |
| 13271 } | 13271 } |
| 13272 | 13272 |
| 13273 /** | 13273 /** |
| 13274 * Return `true` if the given [Type] is the `Future` form the 'dart:async' | 13274 * Return `true` if the given [Type] is the `Future` form the 'dart:async' |
| 13275 * library. | 13275 * library. |
| 13276 */ | 13276 */ |
| 13277 bool isAsyncFutureType(Type2 type) => type is InterfaceType && type.name == "F
uture" && isAsyncLibrary(type.element.library); | 13277 bool _isAsyncFutureType(Type2 type) => type is InterfaceType && type.name == "
Future" && _isAsyncLibrary(type.element.library); |
| 13278 | 13278 |
| 13279 /** | 13279 /** |
| 13280 * Return `true` if the given library is the 'dart:async' library. | 13280 * Return `true` if the given library is the 'dart:async' library. |
| 13281 * | 13281 * |
| 13282 * @param library the library being tested | 13282 * @param library the library being tested |
| 13283 * @return `true` if the library is 'dart:async' | 13283 * @return `true` if the library is 'dart:async' |
| 13284 */ | 13284 */ |
| 13285 bool isAsyncLibrary(LibraryElement library) => library.name == "dart.async"; | 13285 bool _isAsyncLibrary(LibraryElement library) => library.name == "dart.async"; |
| 13286 | 13286 |
| 13287 /** | 13287 /** |
| 13288 * Return `true` if the given library is the 'dart:html' library. | 13288 * Return `true` if the given library is the 'dart:html' library. |
| 13289 * | 13289 * |
| 13290 * @param library the library being tested | 13290 * @param library the library being tested |
| 13291 * @return `true` if the library is 'dart:html' | 13291 * @return `true` if the library is 'dart:html' |
| 13292 */ | 13292 */ |
| 13293 bool isHtmlLibrary(LibraryElement library) => library != null && "dart.dom.htm
l" == library.name; | 13293 bool _isHtmlLibrary(LibraryElement library) => library != null && "dart.dom.ht
ml" == library.name; |
| 13294 | 13294 |
| 13295 /** | 13295 /** |
| 13296 * Return `true` if the given node is not a type literal. | 13296 * Return `true` if the given node is not a type literal. |
| 13297 * | 13297 * |
| 13298 * @param node the node being tested | 13298 * @param node the node being tested |
| 13299 * @return `true` if the given node is not a type literal | 13299 * @return `true` if the given node is not a type literal |
| 13300 */ | 13300 */ |
| 13301 bool isNotTypeLiteral(Identifier node) { | 13301 bool _isNotTypeLiteral(Identifier node) { |
| 13302 AstNode parent = node.parent; | 13302 AstNode parent = node.parent; |
| 13303 return parent is TypeName || (parent is PrefixedIdentifier && (parent.parent
is TypeName || identical(parent.prefix, node))) || (parent is PropertyAccess &&
identical(parent.target, node)) || (parent is MethodInvocation && identical(nod
e, parent.target)); | 13303 return parent is TypeName || (parent is PrefixedIdentifier && (parent.parent
is TypeName || identical(parent.prefix, node))) || (parent is PropertyAccess &&
identical(parent.target, node)) || (parent is MethodInvocation && identical(nod
e, parent.target)); |
| 13304 } | 13304 } |
| 13305 | 13305 |
| 13306 /** | 13306 /** |
| 13307 * Record that the propagated type of the given node is the given type. | 13307 * Record that the propagated type of the given node is the given type. |
| 13308 * | 13308 * |
| 13309 * @param expression the node whose type is to be recorded | 13309 * @param expression the node whose type is to be recorded |
| 13310 * @param type the propagated type of the node | 13310 * @param type the propagated type of the node |
| 13311 */ | 13311 */ |
| 13312 void recordPropagatedType(Expression expression, Type2 type) { | 13312 void _recordPropagatedType(Expression expression, Type2 type) { |
| 13313 if (type != null && !type.isDynamic) { | 13313 if (type != null && !type.isDynamic) { |
| 13314 expression.propagatedType = type; | 13314 expression.propagatedType = type; |
| 13315 } | 13315 } |
| 13316 } | 13316 } |
| 13317 | 13317 |
| 13318 /** | 13318 /** |
| 13319 * Given a function element and its body, compute and record the propagated re
turn type of the | 13319 * Given a function element and its body, compute and record the propagated re
turn type of the |
| 13320 * function. | 13320 * function. |
| 13321 * | 13321 * |
| 13322 * @param functionElement the function element to record propagated return typ
e for | 13322 * @param functionElement the function element to record propagated return typ
e for |
| 13323 * @param body the boy of the function whose propagated return type is to be c
omputed | 13323 * @param body the boy of the function whose propagated return type is to be c
omputed |
| 13324 * @return the propagated return type that was computed, may be `null` if it i
s not more | 13324 * @return the propagated return type that was computed, may be `null` if it i
s not more |
| 13325 * specific than the static return type. | 13325 * specific than the static return type. |
| 13326 */ | 13326 */ |
| 13327 void recordPropagatedTypeOfFunction(ExecutableElement functionElement, Functio
nBody body) { | 13327 void _recordPropagatedTypeOfFunction(ExecutableElement functionElement, Functi
onBody body) { |
| 13328 Type2 propagatedReturnType = computePropagatedReturnTypeOfFunction(body); | 13328 Type2 propagatedReturnType = _computePropagatedReturnTypeOfFunction(body); |
| 13329 if (propagatedReturnType == null) { | 13329 if (propagatedReturnType == null) { |
| 13330 return; | 13330 return; |
| 13331 } | 13331 } |
| 13332 // Ignore 'bottom' type. | 13332 // Ignore 'bottom' type. |
| 13333 if (propagatedReturnType.isBottom) { | 13333 if (propagatedReturnType.isBottom) { |
| 13334 return; | 13334 return; |
| 13335 } | 13335 } |
| 13336 // Record only if we inferred more specific type. | 13336 // Record only if we inferred more specific type. |
| 13337 Type2 staticReturnType = functionElement.returnType; | 13337 Type2 staticReturnType = functionElement.returnType; |
| 13338 if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) { | 13338 if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) { |
| 13339 return; | 13339 return; |
| 13340 } | 13340 } |
| 13341 // OK, do record. | 13341 // OK, do record. |
| 13342 _propagatedReturnTypes[functionElement] = propagatedReturnType; | 13342 _propagatedReturnTypes[functionElement] = propagatedReturnType; |
| 13343 } | 13343 } |
| 13344 | 13344 |
| 13345 /** | 13345 /** |
| 13346 * Record that the static type of the given node is the given type. | 13346 * Record that the static type of the given node is the given type. |
| 13347 * | 13347 * |
| 13348 * @param expression the node whose type is to be recorded | 13348 * @param expression the node whose type is to be recorded |
| 13349 * @param type the static type of the node | 13349 * @param type the static type of the node |
| 13350 */ | 13350 */ |
| 13351 void recordStaticType(Expression expression, Type2 type) { | 13351 void _recordStaticType(Expression expression, Type2 type) { |
| 13352 if (type == null) { | 13352 if (type == null) { |
| 13353 expression.staticType = _dynamicType; | 13353 expression.staticType = _dynamicType; |
| 13354 } else { | 13354 } else { |
| 13355 expression.staticType = type; | 13355 expression.staticType = type; |
| 13356 } | 13356 } |
| 13357 } | 13357 } |
| 13358 | 13358 |
| 13359 /** | 13359 /** |
| 13360 * Attempts to make a better guess for the static type of the given binary exp
ression. | 13360 * Attempts to make a better guess for the static type of the given binary exp
ression. |
| 13361 * | 13361 * |
| 13362 * @param node the binary expression to analyze | 13362 * @param node the binary expression to analyze |
| 13363 * @param staticType the static type of the expression as resolved | 13363 * @param staticType the static type of the expression as resolved |
| 13364 * @return the better type guess, or the same static type as given | 13364 * @return the better type guess, or the same static type as given |
| 13365 */ | 13365 */ |
| 13366 Type2 refineBinaryExpressionType(BinaryExpression node, Type2 staticType) { | 13366 Type2 _refineBinaryExpressionType(BinaryExpression node, Type2 staticType) { |
| 13367 sc.TokenType operator = node.operator.type; | 13367 sc.TokenType operator = node.operator.type; |
| 13368 // bool | 13368 // bool |
| 13369 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)) { | 13369 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)) { |
| 13370 return _typeProvider.boolType; | 13370 return _typeProvider.boolType; |
| 13371 } | 13371 } |
| 13372 Type2 intType = _typeProvider.intType; | 13372 Type2 intType = _typeProvider.intType; |
| 13373 if (getStaticType(node.leftOperand) == intType) { | 13373 if (_getStaticType(node.leftOperand) == intType) { |
| 13374 // int op double | 13374 // int op double |
| 13375 if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.Toke
nType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator,
sc.TokenType.STAR)) { | 13375 if (identical(operator, sc.TokenType.MINUS) || identical(operator, sc.Toke
nType.PERCENT) || identical(operator, sc.TokenType.PLUS) || identical(operator,
sc.TokenType.STAR)) { |
| 13376 Type2 doubleType = _typeProvider.doubleType; | 13376 Type2 doubleType = _typeProvider.doubleType; |
| 13377 if (getStaticType(node.rightOperand) == doubleType) { | 13377 if (_getStaticType(node.rightOperand) == doubleType) { |
| 13378 return doubleType; | 13378 return doubleType; |
| 13379 } | 13379 } |
| 13380 } | 13380 } |
| 13381 // int op int | 13381 // int op int |
| 13382 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)) { | 13382 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)) { |
| 13383 if (getStaticType(node.rightOperand) == intType) { | 13383 if (_getStaticType(node.rightOperand) == intType) { |
| 13384 staticType = intType; | 13384 staticType = intType; |
| 13385 } | 13385 } |
| 13386 } | 13386 } |
| 13387 } | 13387 } |
| 13388 // default | 13388 // default |
| 13389 return staticType; | 13389 return staticType; |
| 13390 } | 13390 } |
| 13391 | 13391 |
| 13392 get thisType_J2DAccessor => _thisType; | 13392 get thisType_J2DAccessor => _thisType; |
| 13393 | 13393 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13437 */ | 13437 */ |
| 13438 Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>(); | 13438 Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>(); |
| 13439 | 13439 |
| 13440 /** | 13440 /** |
| 13441 * Given some [ClassElement], return the set of all subtypes, and subtypes of
subtypes. | 13441 * Given some [ClassElement], return the set of all subtypes, and subtypes of
subtypes. |
| 13442 * | 13442 * |
| 13443 * @param classElement the class to recursively return the set of subtypes of | 13443 * @param classElement the class to recursively return the set of subtypes of |
| 13444 */ | 13444 */ |
| 13445 Set<ClassElement> computeAllSubtypes(ClassElement classElement) { | 13445 Set<ClassElement> computeAllSubtypes(ClassElement classElement) { |
| 13446 // Ensure that we have generated the subtype map for the library | 13446 // Ensure that we have generated the subtype map for the library |
| 13447 computeSubtypesInLibrary(classElement.library); | 13447 _computeSubtypesInLibrary(classElement.library); |
| 13448 // use the subtypeMap to compute the set of all subtypes and subtype's subty
pes | 13448 // use the subtypeMap to compute the set of all subtypes and subtype's subty
pes |
| 13449 Set<ClassElement> allSubtypes = new Set<ClassElement>(); | 13449 Set<ClassElement> allSubtypes = new Set<ClassElement>(); |
| 13450 safelyComputeAllSubtypes(classElement, new Set<ClassElement>(), allSubtypes)
; | 13450 _safelyComputeAllSubtypes(classElement, new Set<ClassElement>(), allSubtypes
); |
| 13451 return allSubtypes; | 13451 return allSubtypes; |
| 13452 } | 13452 } |
| 13453 | 13453 |
| 13454 /** | 13454 /** |
| 13455 * Given some [LibraryElement], visit all of the types in the library, the pas
sed library, | 13455 * Given some [LibraryElement], visit all of the types in the library, the pas
sed library, |
| 13456 * and any imported libraries, will be in the [visitedLibraries] set. | 13456 * and any imported libraries, will be in the [visitedLibraries] set. |
| 13457 * | 13457 * |
| 13458 * @param libraryElement the library to visit, it it hasn't been visited alrea
dy | 13458 * @param libraryElement the library to visit, it it hasn't been visited alrea
dy |
| 13459 */ | 13459 */ |
| 13460 void ensureLibraryVisited(LibraryElement libraryElement) { | 13460 void ensureLibraryVisited(LibraryElement libraryElement) { |
| 13461 computeSubtypesInLibrary(libraryElement); | 13461 _computeSubtypesInLibrary(libraryElement); |
| 13462 } | 13462 } |
| 13463 | 13463 |
| 13464 /** | 13464 /** |
| 13465 * Given some [ClassElement], this method adds all of the pairs combinations o
f itself and | 13465 * Given some [ClassElement], this method adds all of the pairs combinations o
f itself and |
| 13466 * all of its supertypes to the [subtypeMap] map. | 13466 * all of its supertypes to the [subtypeMap] map. |
| 13467 * | 13467 * |
| 13468 * @param classElement the class element | 13468 * @param classElement the class element |
| 13469 */ | 13469 */ |
| 13470 void computeSubtypesInClass(ClassElement classElement) { | 13470 void _computeSubtypesInClass(ClassElement classElement) { |
| 13471 InterfaceType supertypeType = classElement.supertype; | 13471 InterfaceType supertypeType = classElement.supertype; |
| 13472 if (supertypeType != null) { | 13472 if (supertypeType != null) { |
| 13473 ClassElement supertypeElement = supertypeType.element; | 13473 ClassElement supertypeElement = supertypeType.element; |
| 13474 if (supertypeElement != null) { | 13474 if (supertypeElement != null) { |
| 13475 putInSubtypeMap(supertypeElement, classElement); | 13475 _putInSubtypeMap(supertypeElement, classElement); |
| 13476 } | 13476 } |
| 13477 } | 13477 } |
| 13478 List<InterfaceType> interfaceTypes = classElement.interfaces; | 13478 List<InterfaceType> interfaceTypes = classElement.interfaces; |
| 13479 for (InterfaceType interfaceType in interfaceTypes) { | 13479 for (InterfaceType interfaceType in interfaceTypes) { |
| 13480 ClassElement interfaceElement = interfaceType.element; | 13480 ClassElement interfaceElement = interfaceType.element; |
| 13481 if (interfaceElement != null) { | 13481 if (interfaceElement != null) { |
| 13482 putInSubtypeMap(interfaceElement, classElement); | 13482 _putInSubtypeMap(interfaceElement, classElement); |
| 13483 } | 13483 } |
| 13484 } | 13484 } |
| 13485 List<InterfaceType> mixinTypes = classElement.mixins; | 13485 List<InterfaceType> mixinTypes = classElement.mixins; |
| 13486 for (InterfaceType mixinType in mixinTypes) { | 13486 for (InterfaceType mixinType in mixinTypes) { |
| 13487 ClassElement mixinElement = mixinType.element; | 13487 ClassElement mixinElement = mixinType.element; |
| 13488 if (mixinElement != null) { | 13488 if (mixinElement != null) { |
| 13489 putInSubtypeMap(mixinElement, classElement); | 13489 _putInSubtypeMap(mixinElement, classElement); |
| 13490 } | 13490 } |
| 13491 } | 13491 } |
| 13492 } | 13492 } |
| 13493 | 13493 |
| 13494 /** | 13494 /** |
| 13495 * Given some [CompilationUnitElement], this method calls | 13495 * Given some [CompilationUnitElement], this method calls |
| 13496 * [computeAllSubtypes] on all of the [ClassElement]s in the | 13496 * [computeAllSubtypes] on all of the [ClassElement]s in the |
| 13497 * compilation unit. | 13497 * compilation unit. |
| 13498 * | 13498 * |
| 13499 * @param unitElement the compilation unit element | 13499 * @param unitElement the compilation unit element |
| 13500 */ | 13500 */ |
| 13501 void computeSubtypesInCompilationUnit(CompilationUnitElement unitElement) { | 13501 void _computeSubtypesInCompilationUnit(CompilationUnitElement unitElement) { |
| 13502 List<ClassElement> classElements = unitElement.types; | 13502 List<ClassElement> classElements = unitElement.types; |
| 13503 for (ClassElement classElement in classElements) { | 13503 for (ClassElement classElement in classElements) { |
| 13504 computeSubtypesInClass(classElement); | 13504 _computeSubtypesInClass(classElement); |
| 13505 } | 13505 } |
| 13506 } | 13506 } |
| 13507 | 13507 |
| 13508 /** | 13508 /** |
| 13509 * Given some [LibraryElement], this method calls | 13509 * Given some [LibraryElement], this method calls |
| 13510 * [computeAllSubtypes] on all of the [ClassElement]s in the | 13510 * [computeAllSubtypes] on all of the [ClassElement]s in the |
| 13511 * compilation unit, and itself for all imported and exported libraries. All v
isited libraries are | 13511 * compilation unit, and itself for all imported and exported libraries. All v
isited libraries are |
| 13512 * added to the [visitedLibraries] set. | 13512 * added to the [visitedLibraries] set. |
| 13513 * | 13513 * |
| 13514 * @param libraryElement the library element | 13514 * @param libraryElement the library element |
| 13515 */ | 13515 */ |
| 13516 void computeSubtypesInLibrary(LibraryElement libraryElement) { | 13516 void _computeSubtypesInLibrary(LibraryElement libraryElement) { |
| 13517 if (libraryElement == null || _visitedLibraries.contains(libraryElement)) { | 13517 if (libraryElement == null || _visitedLibraries.contains(libraryElement)) { |
| 13518 return; | 13518 return; |
| 13519 } | 13519 } |
| 13520 _visitedLibraries.add(libraryElement); | 13520 _visitedLibraries.add(libraryElement); |
| 13521 computeSubtypesInCompilationUnit(libraryElement.definingCompilationUnit); | 13521 _computeSubtypesInCompilationUnit(libraryElement.definingCompilationUnit); |
| 13522 List<CompilationUnitElement> parts = libraryElement.parts; | 13522 List<CompilationUnitElement> parts = libraryElement.parts; |
| 13523 for (CompilationUnitElement part in parts) { | 13523 for (CompilationUnitElement part in parts) { |
| 13524 computeSubtypesInCompilationUnit(part); | 13524 _computeSubtypesInCompilationUnit(part); |
| 13525 } | 13525 } |
| 13526 List<LibraryElement> imports = libraryElement.importedLibraries; | 13526 List<LibraryElement> imports = libraryElement.importedLibraries; |
| 13527 for (LibraryElement importElt in imports) { | 13527 for (LibraryElement importElt in imports) { |
| 13528 computeSubtypesInLibrary(importElt.library); | 13528 _computeSubtypesInLibrary(importElt.library); |
| 13529 } | 13529 } |
| 13530 List<LibraryElement> exports = libraryElement.exportedLibraries; | 13530 List<LibraryElement> exports = libraryElement.exportedLibraries; |
| 13531 for (LibraryElement exportElt in exports) { | 13531 for (LibraryElement exportElt in exports) { |
| 13532 computeSubtypesInLibrary(exportElt.library); | 13532 _computeSubtypesInLibrary(exportElt.library); |
| 13533 } | 13533 } |
| 13534 } | 13534 } |
| 13535 | 13535 |
| 13536 /** | 13536 /** |
| 13537 * Add some key/ value pair into the [subtypeMap] map. | 13537 * Add some key/ value pair into the [subtypeMap] map. |
| 13538 * | 13538 * |
| 13539 * @param supertypeElement the key for the [subtypeMap] map | 13539 * @param supertypeElement the key for the [subtypeMap] map |
| 13540 * @param subtypeElement the value for the [subtypeMap] map | 13540 * @param subtypeElement the value for the [subtypeMap] map |
| 13541 */ | 13541 */ |
| 13542 void putInSubtypeMap(ClassElement supertypeElement, ClassElement subtypeElemen
t) { | 13542 void _putInSubtypeMap(ClassElement supertypeElement, ClassElement subtypeEleme
nt) { |
| 13543 Set<ClassElement> subtypes = _subtypeMap[supertypeElement]; | 13543 Set<ClassElement> subtypes = _subtypeMap[supertypeElement]; |
| 13544 if (subtypes == null) { | 13544 if (subtypes == null) { |
| 13545 subtypes = new Set<ClassElement>(); | 13545 subtypes = new Set<ClassElement>(); |
| 13546 _subtypeMap[supertypeElement] = subtypes; | 13546 _subtypeMap[supertypeElement] = subtypes; |
| 13547 } | 13547 } |
| 13548 subtypes.add(subtypeElement); | 13548 subtypes.add(subtypeElement); |
| 13549 } | 13549 } |
| 13550 | 13550 |
| 13551 /** | 13551 /** |
| 13552 * Given some [ClassElement] and a [HashSet<ClassElement>], this method recurs
ively | 13552 * Given some [ClassElement] and a [HashSet<ClassElement>], this method recurs
ively |
| 13553 * adds all of the subtypes of the [ClassElement] to the passed array. | 13553 * adds all of the subtypes of the [ClassElement] to the passed array. |
| 13554 * | 13554 * |
| 13555 * @param classElement the type to compute the set of subtypes of | 13555 * @param classElement the type to compute the set of subtypes of |
| 13556 * @param visitedClasses the set of class elements that this method has alread
y recursively seen | 13556 * @param visitedClasses the set of class elements that this method has alread
y recursively seen |
| 13557 * @param allSubtypes the computed set of subtypes of the passed class element | 13557 * @param allSubtypes the computed set of subtypes of the passed class element |
| 13558 */ | 13558 */ |
| 13559 void safelyComputeAllSubtypes(ClassElement classElement, Set<ClassElement> vis
itedClasses, Set<ClassElement> allSubtypes) { | 13559 void _safelyComputeAllSubtypes(ClassElement classElement, Set<ClassElement> vi
sitedClasses, Set<ClassElement> allSubtypes) { |
| 13560 if (!visitedClasses.add(classElement)) { | 13560 if (!visitedClasses.add(classElement)) { |
| 13561 // if this class has already been called on this class element | 13561 // if this class has already been called on this class element |
| 13562 return; | 13562 return; |
| 13563 } | 13563 } |
| 13564 Set<ClassElement> subtypes = _subtypeMap[classElement]; | 13564 Set<ClassElement> subtypes = _subtypeMap[classElement]; |
| 13565 if (subtypes == null) { | 13565 if (subtypes == null) { |
| 13566 return; | 13566 return; |
| 13567 } | 13567 } |
| 13568 for (ClassElement subtype in subtypes) { | 13568 for (ClassElement subtype in subtypes) { |
| 13569 safelyComputeAllSubtypes(subtype, visitedClasses, allSubtypes); | 13569 _safelyComputeAllSubtypes(subtype, visitedClasses, allSubtypes); |
| 13570 } | 13570 } |
| 13571 allSubtypes.addAll(subtypes); | 13571 allSubtypes.addAll(subtypes); |
| 13572 } | 13572 } |
| 13573 } | 13573 } |
| 13574 | 13574 |
| 13575 /** | 13575 /** |
| 13576 * Instances of the class `TypeOverrideManager` manage the ability to override t
he type of an | 13576 * Instances of the class `TypeOverrideManager` manage the ability to override t
he type of an |
| 13577 * element within a given context. | 13577 * element within a given context. |
| 13578 */ | 13578 */ |
| 13579 class TypeOverrideManager { | 13579 class TypeOverrideManager { |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14098 * The type representing the built-in type 'Type'. | 14098 * The type representing the built-in type 'Type'. |
| 14099 */ | 14099 */ |
| 14100 InterfaceType _typeType; | 14100 InterfaceType _typeType; |
| 14101 | 14101 |
| 14102 /** | 14102 /** |
| 14103 * Initialize a newly created type provider to provide the types defined in th
e given library. | 14103 * Initialize a newly created type provider to provide the types defined in th
e given library. |
| 14104 * | 14104 * |
| 14105 * @param coreLibrary the element representing the core library (dart:core). | 14105 * @param coreLibrary the element representing the core library (dart:core). |
| 14106 */ | 14106 */ |
| 14107 TypeProviderImpl(LibraryElement coreLibrary) { | 14107 TypeProviderImpl(LibraryElement coreLibrary) { |
| 14108 initializeFrom(coreLibrary); | 14108 _initializeFrom(coreLibrary); |
| 14109 } | 14109 } |
| 14110 | 14110 |
| 14111 InterfaceType get boolType => _boolType; | 14111 InterfaceType get boolType => _boolType; |
| 14112 | 14112 |
| 14113 Type2 get bottomType => _bottomType; | 14113 Type2 get bottomType => _bottomType; |
| 14114 | 14114 |
| 14115 InterfaceType get deprecatedType => _deprecatedType; | 14115 InterfaceType get deprecatedType => _deprecatedType; |
| 14116 | 14116 |
| 14117 InterfaceType get doubleType => _doubleType; | 14117 InterfaceType get doubleType => _doubleType; |
| 14118 | 14118 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 14141 InterfaceType get typeType => _typeType; | 14141 InterfaceType get typeType => _typeType; |
| 14142 | 14142 |
| 14143 /** | 14143 /** |
| 14144 * Return the type with the given name from the given namespace, or `null` if
there is no | 14144 * Return the type with the given name from the given namespace, or `null` if
there is no |
| 14145 * class with the given name. | 14145 * class with the given name. |
| 14146 * | 14146 * |
| 14147 * @param namespace the namespace in which to search for the given name | 14147 * @param namespace the namespace in which to search for the given name |
| 14148 * @param typeName the name of the type being searched for | 14148 * @param typeName the name of the type being searched for |
| 14149 * @return the type that was found | 14149 * @return the type that was found |
| 14150 */ | 14150 */ |
| 14151 InterfaceType getType(Namespace namespace, String typeName) { | 14151 InterfaceType _getType(Namespace namespace, String typeName) { |
| 14152 Element element = namespace.get(typeName); | 14152 Element element = namespace.get(typeName); |
| 14153 if (element == null) { | 14153 if (element == null) { |
| 14154 AnalysisEngine.instance.logger.logInformation("No definition of type ${typ
eName}"); | 14154 AnalysisEngine.instance.logger.logInformation("No definition of type ${typ
eName}"); |
| 14155 return null; | 14155 return null; |
| 14156 } | 14156 } |
| 14157 return (element as ClassElement).type; | 14157 return (element as ClassElement).type; |
| 14158 } | 14158 } |
| 14159 | 14159 |
| 14160 /** | 14160 /** |
| 14161 * Initialize the types provided by this type provider from the given library. | 14161 * Initialize the types provided by this type provider from the given library. |
| 14162 * | 14162 * |
| 14163 * @param library the library containing the definitions of the core types | 14163 * @param library the library containing the definitions of the core types |
| 14164 */ | 14164 */ |
| 14165 void initializeFrom(LibraryElement library) { | 14165 void _initializeFrom(LibraryElement library) { |
| 14166 Namespace namespace = new NamespaceBuilder().createPublicNamespaceForLibrary
(library); | 14166 Namespace namespace = new NamespaceBuilder().createPublicNamespaceForLibrary
(library); |
| 14167 _boolType = getType(namespace, "bool"); | 14167 _boolType = _getType(namespace, "bool"); |
| 14168 _bottomType = BottomTypeImpl.instance; | 14168 _bottomType = BottomTypeImpl.instance; |
| 14169 _deprecatedType = getType(namespace, "Deprecated"); | 14169 _deprecatedType = _getType(namespace, "Deprecated"); |
| 14170 _doubleType = getType(namespace, "double"); | 14170 _doubleType = _getType(namespace, "double"); |
| 14171 _dynamicType = DynamicTypeImpl.instance; | 14171 _dynamicType = DynamicTypeImpl.instance; |
| 14172 _functionType = getType(namespace, "Function"); | 14172 _functionType = _getType(namespace, "Function"); |
| 14173 _intType = getType(namespace, "int"); | 14173 _intType = _getType(namespace, "int"); |
| 14174 _listType = getType(namespace, "List"); | 14174 _listType = _getType(namespace, "List"); |
| 14175 _mapType = getType(namespace, "Map"); | 14175 _mapType = _getType(namespace, "Map"); |
| 14176 _nullType = getType(namespace, "Null"); | 14176 _nullType = _getType(namespace, "Null"); |
| 14177 _numType = getType(namespace, "num"); | 14177 _numType = _getType(namespace, "num"); |
| 14178 _objectType = getType(namespace, "Object"); | 14178 _objectType = _getType(namespace, "Object"); |
| 14179 _stackTraceType = getType(namespace, "StackTrace"); | 14179 _stackTraceType = _getType(namespace, "StackTrace"); |
| 14180 _stringType = getType(namespace, "String"); | 14180 _stringType = _getType(namespace, "String"); |
| 14181 _symbolType = getType(namespace, "Symbol"); | 14181 _symbolType = _getType(namespace, "Symbol"); |
| 14182 _typeType = getType(namespace, "Type"); | 14182 _typeType = _getType(namespace, "Type"); |
| 14183 } | 14183 } |
| 14184 } | 14184 } |
| 14185 | 14185 |
| 14186 /** | 14186 /** |
| 14187 * Instances of the class `TypeResolverVisitor` are used to resolve the types as
sociated with | 14187 * Instances of the class `TypeResolverVisitor` are used to resolve the types as
sociated with |
| 14188 * the elements in the element model. This includes the types of superclasses, m
ixins, interfaces, | 14188 * the elements in the element model. This includes the types of superclasses, m
ixins, interfaces, |
| 14189 * fields, methods, parameters, and local variables. As a side-effect, this also
finishes building | 14189 * fields, methods, parameters, and local variables. As a side-effect, this also
finishes building |
| 14190 * the type hierarchy. | 14190 * the type hierarchy. |
| 14191 */ | 14191 */ |
| 14192 class TypeResolverVisitor extends ScopedVisitor { | 14192 class TypeResolverVisitor extends ScopedVisitor { |
| 14193 /** | 14193 /** |
| 14194 * @return `true` if the name of the given [TypeName] is an built-in identifie
r. | 14194 * @return `true` if the name of the given [TypeName] is an built-in identifie
r. |
| 14195 */ | 14195 */ |
| 14196 static bool isBuiltInIdentifier(TypeName node) { | 14196 static bool _isBuiltInIdentifier(TypeName node) { |
| 14197 sc.Token token = node.name.beginToken; | 14197 sc.Token token = node.name.beginToken; |
| 14198 return identical(token.type, sc.TokenType.KEYWORD); | 14198 return identical(token.type, sc.TokenType.KEYWORD); |
| 14199 } | 14199 } |
| 14200 | 14200 |
| 14201 /** | 14201 /** |
| 14202 * @return `true` if given [TypeName] is used as a type annotation. | 14202 * @return `true` if given [TypeName] is used as a type annotation. |
| 14203 */ | 14203 */ |
| 14204 static bool isTypeAnnotation(TypeName node) { | 14204 static bool _isTypeAnnotation(TypeName node) { |
| 14205 AstNode parent = node.parent; | 14205 AstNode parent = node.parent; |
| 14206 if (parent is VariableDeclarationList) { | 14206 if (parent is VariableDeclarationList) { |
| 14207 return identical(parent.type, node); | 14207 return identical(parent.type, node); |
| 14208 } | 14208 } |
| 14209 if (parent is FieldFormalParameter) { | 14209 if (parent is FieldFormalParameter) { |
| 14210 return identical(parent.type, node); | 14210 return identical(parent.type, node); |
| 14211 } | 14211 } |
| 14212 if (parent is SimpleFormalParameter) { | 14212 if (parent is SimpleFormalParameter) { |
| 14213 return identical(parent.type, node); | 14213 return identical(parent.type, node); |
| 14214 } | 14214 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14268 super.visitCatchClause(node); | 14268 super.visitCatchClause(node); |
| 14269 SimpleIdentifier exception = node.exceptionParameter; | 14269 SimpleIdentifier exception = node.exceptionParameter; |
| 14270 if (exception != null) { | 14270 if (exception != null) { |
| 14271 // If an 'on' clause is provided the type of the exception parameter is th
e type in the 'on' | 14271 // If an 'on' clause is provided the type of the exception parameter is th
e type in the 'on' |
| 14272 // clause. Otherwise, the type of the exception parameter is 'Object'. | 14272 // clause. Otherwise, the type of the exception parameter is 'Object'. |
| 14273 TypeName exceptionTypeName = node.exceptionType; | 14273 TypeName exceptionTypeName = node.exceptionType; |
| 14274 Type2 exceptionType; | 14274 Type2 exceptionType; |
| 14275 if (exceptionTypeName == null) { | 14275 if (exceptionTypeName == null) { |
| 14276 exceptionType = typeProvider.dynamicType; | 14276 exceptionType = typeProvider.dynamicType; |
| 14277 } else { | 14277 } else { |
| 14278 exceptionType = getType(exceptionTypeName); | 14278 exceptionType = _getType(exceptionTypeName); |
| 14279 } | 14279 } |
| 14280 recordType(exception, exceptionType); | 14280 _recordType(exception, exceptionType); |
| 14281 Element element = exception.staticElement; | 14281 Element element = exception.staticElement; |
| 14282 if (element is VariableElementImpl) { | 14282 if (element is VariableElementImpl) { |
| 14283 element.type = exceptionType; | 14283 element.type = exceptionType; |
| 14284 } else { | 14284 } else { |
| 14285 } | 14285 } |
| 14286 } | 14286 } |
| 14287 SimpleIdentifier stackTrace = node.stackTraceParameter; | 14287 SimpleIdentifier stackTrace = node.stackTraceParameter; |
| 14288 if (stackTrace != null) { | 14288 if (stackTrace != null) { |
| 14289 recordType(stackTrace, typeProvider.stackTraceType); | 14289 _recordType(stackTrace, typeProvider.stackTraceType); |
| 14290 } | 14290 } |
| 14291 return null; | 14291 return null; |
| 14292 } | 14292 } |
| 14293 | 14293 |
| 14294 Object visitClassDeclaration(ClassDeclaration node) { | 14294 Object visitClassDeclaration(ClassDeclaration node) { |
| 14295 _hasReferenceToSuper = false; | 14295 _hasReferenceToSuper = false; |
| 14296 super.visitClassDeclaration(node); | 14296 super.visitClassDeclaration(node); |
| 14297 ClassElementImpl classElement = getClassElement(node.name); | 14297 ClassElementImpl classElement = _getClassElement(node.name); |
| 14298 InterfaceType superclassType = null; | 14298 InterfaceType superclassType = null; |
| 14299 ExtendsClause extendsClause = node.extendsClause; | 14299 ExtendsClause extendsClause = node.extendsClause; |
| 14300 if (extendsClause != null) { | 14300 if (extendsClause != null) { |
| 14301 ErrorCode errorCode = (node.withClause == null ? CompileTimeErrorCode.EXTE
NDS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS); | 14301 ErrorCode errorCode = (node.withClause == null ? CompileTimeErrorCode.EXTE
NDS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS); |
| 14302 superclassType = resolveType(extendsClause.superclass, errorCode, errorCod
e); | 14302 superclassType = _resolveType(extendsClause.superclass, errorCode, errorCo
de); |
| 14303 if (superclassType != typeProvider.objectType) { | 14303 if (superclassType != typeProvider.objectType) { |
| 14304 classElement.validMixin = false; | 14304 classElement.validMixin = false; |
| 14305 } | 14305 } |
| 14306 } | 14306 } |
| 14307 if (classElement != null) { | 14307 if (classElement != null) { |
| 14308 if (superclassType == null) { | 14308 if (superclassType == null) { |
| 14309 InterfaceType objectType = typeProvider.objectType; | 14309 InterfaceType objectType = typeProvider.objectType; |
| 14310 if (classElement.type != objectType) { | 14310 if (classElement.type != objectType) { |
| 14311 superclassType = objectType; | 14311 superclassType = objectType; |
| 14312 } | 14312 } |
| 14313 } | 14313 } |
| 14314 classElement.supertype = superclassType; | 14314 classElement.supertype = superclassType; |
| 14315 classElement.hasReferenceToSuper = _hasReferenceToSuper; | 14315 classElement.hasReferenceToSuper = _hasReferenceToSuper; |
| 14316 } | 14316 } |
| 14317 resolve(classElement, node.withClause, node.implementsClause); | 14317 _resolve(classElement, node.withClause, node.implementsClause); |
| 14318 return null; | 14318 return null; |
| 14319 } | 14319 } |
| 14320 | 14320 |
| 14321 Object visitClassTypeAlias(ClassTypeAlias node) { | 14321 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 14322 super.visitClassTypeAlias(node); | 14322 super.visitClassTypeAlias(node); |
| 14323 ClassElementImpl classElement = getClassElement(node.name); | 14323 ClassElementImpl classElement = _getClassElement(node.name); |
| 14324 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS; | 14324 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS; |
| 14325 InterfaceType superclassType = resolveType(node.superclass, errorCode, error
Code); | 14325 InterfaceType superclassType = _resolveType(node.superclass, errorCode, erro
rCode); |
| 14326 if (superclassType == null) { | 14326 if (superclassType == null) { |
| 14327 superclassType = typeProvider.objectType; | 14327 superclassType = typeProvider.objectType; |
| 14328 } | 14328 } |
| 14329 if (classElement != null && superclassType != null) { | 14329 if (classElement != null && superclassType != null) { |
| 14330 classElement.supertype = superclassType; | 14330 classElement.supertype = superclassType; |
| 14331 ClassElement superclassElement = superclassType.element; | 14331 ClassElement superclassElement = superclassType.element; |
| 14332 if (superclassElement != null) { | 14332 if (superclassElement != null) { |
| 14333 List<ConstructorElement> constructors = superclassElement.constructors; | 14333 List<ConstructorElement> constructors = superclassElement.constructors; |
| 14334 int count = constructors.length; | 14334 int count = constructors.length; |
| 14335 if (count > 0) { | 14335 if (count > 0) { |
| 14336 List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(superclass
Type.typeParameters); | 14336 List<Type2> parameterTypes = TypeParameterTypeImpl.getTypes(superclass
Type.typeParameters); |
| 14337 List<Type2> argumentTypes = getArgumentTypes(node.superclass.typeArgum
ents, parameterTypes); | 14337 List<Type2> argumentTypes = _getArgumentTypes(node.superclass.typeArgu
ments, parameterTypes); |
| 14338 InterfaceType classType = classElement.type; | 14338 InterfaceType classType = classElement.type; |
| 14339 List<ConstructorElement> implicitConstructors = new List<ConstructorEl
ement>(); | 14339 List<ConstructorElement> implicitConstructors = new List<ConstructorEl
ement>(); |
| 14340 for (int i = 0; i < count; i++) { | 14340 for (int i = 0; i < count; i++) { |
| 14341 ConstructorElement explicitConstructor = constructors[i]; | 14341 ConstructorElement explicitConstructor = constructors[i]; |
| 14342 if (!explicitConstructor.isFactory) { | 14342 if (!explicitConstructor.isFactory) { |
| 14343 implicitConstructors.add(createImplicitContructor(classType, expli
citConstructor, parameterTypes, argumentTypes)); | 14343 implicitConstructors.add(_createImplicitContructor(classType, expl
icitConstructor, parameterTypes, argumentTypes)); |
| 14344 } | 14344 } |
| 14345 } | 14345 } |
| 14346 classElement.constructors = new List.from(implicitConstructors); | 14346 classElement.constructors = new List.from(implicitConstructors); |
| 14347 } | 14347 } |
| 14348 } | 14348 } |
| 14349 } | 14349 } |
| 14350 resolve(classElement, node.withClause, node.implementsClause); | 14350 _resolve(classElement, node.withClause, node.implementsClause); |
| 14351 return null; | 14351 return null; |
| 14352 } | 14352 } |
| 14353 | 14353 |
| 14354 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 14354 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 14355 super.visitConstructorDeclaration(node); | 14355 super.visitConstructorDeclaration(node); |
| 14356 ExecutableElementImpl element = node.element as ExecutableElementImpl; | 14356 ExecutableElementImpl element = node.element as ExecutableElementImpl; |
| 14357 ClassElement definingClass = element.enclosingElement as ClassElement; | 14357 ClassElement definingClass = element.enclosingElement as ClassElement; |
| 14358 element.returnType = definingClass.type; | 14358 element.returnType = definingClass.type; |
| 14359 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); | 14359 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); |
| 14360 type.typeArguments = definingClass.type.typeArguments; | 14360 type.typeArguments = definingClass.type.typeArguments; |
| 14361 element.type = type; | 14361 element.type = type; |
| 14362 return null; | 14362 return null; |
| 14363 } | 14363 } |
| 14364 | 14364 |
| 14365 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 14365 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 14366 super.visitDeclaredIdentifier(node); | 14366 super.visitDeclaredIdentifier(node); |
| 14367 Type2 declaredType; | 14367 Type2 declaredType; |
| 14368 TypeName typeName = node.type; | 14368 TypeName typeName = node.type; |
| 14369 if (typeName == null) { | 14369 if (typeName == null) { |
| 14370 declaredType = _dynamicType; | 14370 declaredType = _dynamicType; |
| 14371 } else { | 14371 } else { |
| 14372 declaredType = getType(typeName); | 14372 declaredType = _getType(typeName); |
| 14373 } | 14373 } |
| 14374 LocalVariableElementImpl element = node.element as LocalVariableElementImpl; | 14374 LocalVariableElementImpl element = node.element as LocalVariableElementImpl; |
| 14375 element.type = declaredType; | 14375 element.type = declaredType; |
| 14376 return null; | 14376 return null; |
| 14377 } | 14377 } |
| 14378 | 14378 |
| 14379 Object visitFieldFormalParameter(FieldFormalParameter node) { | 14379 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 14380 super.visitFieldFormalParameter(node); | 14380 super.visitFieldFormalParameter(node); |
| 14381 Element element = node.identifier.staticElement; | 14381 Element element = node.identifier.staticElement; |
| 14382 if (element is ParameterElementImpl) { | 14382 if (element is ParameterElementImpl) { |
| 14383 ParameterElementImpl parameter = element; | 14383 ParameterElementImpl parameter = element; |
| 14384 FormalParameterList parameterList = node.parameters; | 14384 FormalParameterList parameterList = node.parameters; |
| 14385 if (parameterList == null) { | 14385 if (parameterList == null) { |
| 14386 Type2 type; | 14386 Type2 type; |
| 14387 TypeName typeName = node.type; | 14387 TypeName typeName = node.type; |
| 14388 if (typeName == null) { | 14388 if (typeName == null) { |
| 14389 type = _dynamicType; | 14389 type = _dynamicType; |
| 14390 if (parameter is FieldFormalParameterElement) { | 14390 if (parameter is FieldFormalParameterElement) { |
| 14391 FieldElement fieldElement = (parameter as FieldFormalParameterElemen
t).field; | 14391 FieldElement fieldElement = (parameter as FieldFormalParameterElemen
t).field; |
| 14392 if (fieldElement != null) { | 14392 if (fieldElement != null) { |
| 14393 type = fieldElement.type; | 14393 type = fieldElement.type; |
| 14394 } | 14394 } |
| 14395 } | 14395 } |
| 14396 } else { | 14396 } else { |
| 14397 type = getType(typeName); | 14397 type = _getType(typeName); |
| 14398 } | 14398 } |
| 14399 parameter.type = type; | 14399 parameter.type = type; |
| 14400 } else { | 14400 } else { |
| 14401 setFunctionTypedParameterType(parameter, node.type, node.parameters); | 14401 _setFunctionTypedParameterType(parameter, node.type, node.parameters); |
| 14402 } | 14402 } |
| 14403 } else { | 14403 } else { |
| 14404 } | 14404 } |
| 14405 return null; | 14405 return null; |
| 14406 } | 14406 } |
| 14407 | 14407 |
| 14408 Object visitFunctionDeclaration(FunctionDeclaration node) { | 14408 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 14409 super.visitFunctionDeclaration(node); | 14409 super.visitFunctionDeclaration(node); |
| 14410 ExecutableElementImpl element = node.element as ExecutableElementImpl; | 14410 ExecutableElementImpl element = node.element as ExecutableElementImpl; |
| 14411 element.returnType = computeReturnType(node.returnType); | 14411 element.returnType = _computeReturnType(node.returnType); |
| 14412 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); | 14412 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); |
| 14413 ClassElement definingClass = element.getAncestor((element) => element is Cla
ssElement); | 14413 ClassElement definingClass = element.getAncestor((element) => element is Cla
ssElement); |
| 14414 if (definingClass != null) { | 14414 if (definingClass != null) { |
| 14415 type.typeArguments = definingClass.type.typeArguments; | 14415 type.typeArguments = definingClass.type.typeArguments; |
| 14416 } | 14416 } |
| 14417 element.type = type; | 14417 element.type = type; |
| 14418 return null; | 14418 return null; |
| 14419 } | 14419 } |
| 14420 | 14420 |
| 14421 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 14421 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 14422 super.visitFunctionTypeAlias(node); | 14422 super.visitFunctionTypeAlias(node); |
| 14423 FunctionTypeAliasElementImpl element = node.element as FunctionTypeAliasElem
entImpl; | 14423 FunctionTypeAliasElementImpl element = node.element as FunctionTypeAliasElem
entImpl; |
| 14424 element.returnType = computeReturnType(node.returnType); | 14424 element.returnType = _computeReturnType(node.returnType); |
| 14425 return null; | 14425 return null; |
| 14426 } | 14426 } |
| 14427 | 14427 |
| 14428 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 14428 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 14429 super.visitFunctionTypedFormalParameter(node); | 14429 super.visitFunctionTypedFormalParameter(node); |
| 14430 Element element = node.identifier.staticElement; | 14430 Element element = node.identifier.staticElement; |
| 14431 if (element is ParameterElementImpl) { | 14431 if (element is ParameterElementImpl) { |
| 14432 setFunctionTypedParameterType(element, node.returnType, node.parameters); | 14432 _setFunctionTypedParameterType(element, node.returnType, node.parameters); |
| 14433 } else { | 14433 } else { |
| 14434 } | 14434 } |
| 14435 return null; | 14435 return null; |
| 14436 } | 14436 } |
| 14437 | 14437 |
| 14438 Object visitMethodDeclaration(MethodDeclaration node) { | 14438 Object visitMethodDeclaration(MethodDeclaration node) { |
| 14439 super.visitMethodDeclaration(node); | 14439 super.visitMethodDeclaration(node); |
| 14440 ExecutableElementImpl element = node.element as ExecutableElementImpl; | 14440 ExecutableElementImpl element = node.element as ExecutableElementImpl; |
| 14441 element.returnType = computeReturnType(node.returnType); | 14441 element.returnType = _computeReturnType(node.returnType); |
| 14442 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); | 14442 FunctionTypeImpl type = new FunctionTypeImpl.con1(element); |
| 14443 ClassElement definingClass = element.getAncestor((element) => element is Cla
ssElement); | 14443 ClassElement definingClass = element.getAncestor((element) => element is Cla
ssElement); |
| 14444 if (definingClass != null) { | 14444 if (definingClass != null) { |
| 14445 type.typeArguments = definingClass.type.typeArguments; | 14445 type.typeArguments = definingClass.type.typeArguments; |
| 14446 } | 14446 } |
| 14447 element.type = type; | 14447 element.type = type; |
| 14448 if (element is PropertyAccessorElement) { | 14448 if (element is PropertyAccessorElement) { |
| 14449 PropertyAccessorElement accessor = element as PropertyAccessorElement; | 14449 PropertyAccessorElement accessor = element as PropertyAccessorElement; |
| 14450 PropertyInducingElementImpl variable = accessor.variable as PropertyInduci
ngElementImpl; | 14450 PropertyInducingElementImpl variable = accessor.variable as PropertyInduci
ngElementImpl; |
| 14451 if (accessor.isGetter) { | 14451 if (accessor.isGetter) { |
| 14452 variable.type = type.returnType; | 14452 variable.type = type.returnType; |
| 14453 } else if (variable.type == null) { | 14453 } else if (variable.type == null) { |
| 14454 List<Type2> parameterTypes = type.normalParameterTypes; | 14454 List<Type2> parameterTypes = type.normalParameterTypes; |
| 14455 if (parameterTypes != null && parameterTypes.length > 0) { | 14455 if (parameterTypes != null && parameterTypes.length > 0) { |
| 14456 variable.type = parameterTypes[0]; | 14456 variable.type = parameterTypes[0]; |
| 14457 } | 14457 } |
| 14458 } | 14458 } |
| 14459 } | 14459 } |
| 14460 return null; | 14460 return null; |
| 14461 } | 14461 } |
| 14462 | 14462 |
| 14463 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 14463 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 14464 super.visitSimpleFormalParameter(node); | 14464 super.visitSimpleFormalParameter(node); |
| 14465 Type2 declaredType; | 14465 Type2 declaredType; |
| 14466 TypeName typeName = node.type; | 14466 TypeName typeName = node.type; |
| 14467 if (typeName == null) { | 14467 if (typeName == null) { |
| 14468 declaredType = _dynamicType; | 14468 declaredType = _dynamicType; |
| 14469 } else { | 14469 } else { |
| 14470 declaredType = getType(typeName); | 14470 declaredType = _getType(typeName); |
| 14471 } | 14471 } |
| 14472 Element element = node.identifier.staticElement; | 14472 Element element = node.identifier.staticElement; |
| 14473 if (element is ParameterElement) { | 14473 if (element is ParameterElement) { |
| 14474 (element as ParameterElementImpl).type = declaredType; | 14474 (element as ParameterElementImpl).type = declaredType; |
| 14475 } else { | 14475 } else { |
| 14476 } | 14476 } |
| 14477 return null; | 14477 return null; |
| 14478 } | 14478 } |
| 14479 | 14479 |
| 14480 Object visitSuperExpression(SuperExpression node) { | 14480 Object visitSuperExpression(SuperExpression node) { |
| 14481 _hasReferenceToSuper = true; | 14481 _hasReferenceToSuper = true; |
| 14482 return super.visitSuperExpression(node); | 14482 return super.visitSuperExpression(node); |
| 14483 } | 14483 } |
| 14484 | 14484 |
| 14485 Object visitTypeName(TypeName node) { | 14485 Object visitTypeName(TypeName node) { |
| 14486 super.visitTypeName(node); | 14486 super.visitTypeName(node); |
| 14487 Identifier typeName = node.name; | 14487 Identifier typeName = node.name; |
| 14488 TypeArgumentList argumentList = node.typeArguments; | 14488 TypeArgumentList argumentList = node.typeArguments; |
| 14489 Element element = nameScope.lookup(typeName, definingLibrary); | 14489 Element element = nameScope.lookup(typeName, definingLibrary); |
| 14490 if (element == null) { | 14490 if (element == null) { |
| 14491 // | 14491 // |
| 14492 // Check to see whether the type name is either 'dynamic' or 'void', neith
er of which are in | 14492 // Check to see whether the type name is either 'dynamic' or 'void', neith
er of which are in |
| 14493 // the name scope and hence will not be found by normal means. | 14493 // the name scope and hence will not be found by normal means. |
| 14494 // | 14494 // |
| 14495 if (typeName.name == this._dynamicType.name) { | 14495 if (typeName.name == _dynamicType.name) { |
| 14496 setElement(typeName, this._dynamicType.element); | 14496 _setElement(typeName, _dynamicType.element); |
| 14497 if (argumentList != null) { | 14497 if (argumentList != null) { |
| 14498 } | 14498 } |
| 14499 typeName.staticType = this._dynamicType; | 14499 typeName.staticType = _dynamicType; |
| 14500 node.type = this._dynamicType; | 14500 node.type = _dynamicType; |
| 14501 return null; | 14501 return null; |
| 14502 } | 14502 } |
| 14503 VoidTypeImpl voidType = VoidTypeImpl.instance; | 14503 VoidTypeImpl voidType = VoidTypeImpl.instance; |
| 14504 if (typeName.name == voidType.name) { | 14504 if (typeName.name == voidType.name) { |
| 14505 // There is no element for 'void'. | 14505 // There is no element for 'void'. |
| 14506 if (argumentList != null) { | 14506 if (argumentList != null) { |
| 14507 } | 14507 } |
| 14508 typeName.staticType = voidType; | 14508 typeName.staticType = voidType; |
| 14509 node.type = voidType; | 14509 node.type = voidType; |
| 14510 return null; | 14510 return null; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 14522 element = nameScope.lookup(prefix, definingLibrary); | 14522 element = nameScope.lookup(prefix, definingLibrary); |
| 14523 if (element is PrefixElement) { | 14523 if (element is PrefixElement) { |
| 14524 if (parent.parent is InstanceCreationExpression && (parent.parent as
InstanceCreationExpression).isConst) { | 14524 if (parent.parent is InstanceCreationExpression && (parent.parent as
InstanceCreationExpression).isConst) { |
| 14525 // If, if this is a const expression, then generate a | 14525 // If, if this is a const expression, then generate a |
| 14526 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. | 14526 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. |
| 14527 reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefi
xedIdentifier.identifier, [prefixedIdentifier.identifier.name]); | 14527 reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, prefi
xedIdentifier.identifier, [prefixedIdentifier.identifier.name]); |
| 14528 } else { | 14528 } else { |
| 14529 // Else, if this expression is a new expression, report a NEW_WITH
_NON_TYPE warning. | 14529 // Else, if this expression is a new expression, report a NEW_WITH
_NON_TYPE warning. |
| 14530 reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedId
entifier.identifier, [prefixedIdentifier.identifier.name]); | 14530 reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE, prefixedId
entifier.identifier, [prefixedIdentifier.identifier.name]); |
| 14531 } | 14531 } |
| 14532 setElement(prefix, element); | 14532 _setElement(prefix, element); |
| 14533 return null; | 14533 return null; |
| 14534 } else if (element != null) { | 14534 } else if (element != null) { |
| 14535 // | 14535 // |
| 14536 // Rewrite the constructor name. The parser, when it sees a construc
tor named "a.b", | 14536 // Rewrite the constructor name. The parser, when it sees a construc
tor named "a.b", |
| 14537 // cannot tell whether "a" is a prefix and "b" is a class name, or w
hether "a" is a | 14537 // cannot tell whether "a" is a prefix and "b" is a class name, or w
hether "a" is a |
| 14538 // class name and "b" is a constructor name. It arbitrarily chooses
the former, but | 14538 // class name and "b" is a constructor name. It arbitrarily chooses
the former, but |
| 14539 // in this case was wrong. | 14539 // in this case was wrong. |
| 14540 // | 14540 // |
| 14541 name.name = prefixedIdentifier.identifier; | 14541 name.name = prefixedIdentifier.identifier; |
| 14542 name.period = prefixedIdentifier.period; | 14542 name.period = prefixedIdentifier.period; |
| 14543 node.name = prefix; | 14543 node.name = prefix; |
| 14544 typeName = prefix; | 14544 typeName = prefix; |
| 14545 } | 14545 } |
| 14546 } | 14546 } |
| 14547 } | 14547 } |
| 14548 } | 14548 } |
| 14549 // check element | 14549 // check element |
| 14550 bool elementValid = element is! MultiplyDefinedElement; | 14550 bool elementValid = element is! MultiplyDefinedElement; |
| 14551 if (elementValid && element is! ClassElement && isTypeNameInInstanceCreation
Expression(node)) { | 14551 if (elementValid && element is! ClassElement && _isTypeNameInInstanceCreatio
nExpression(node)) { |
| 14552 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName); | 14552 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); |
| 14553 InstanceCreationExpression creation = node.parent.parent as InstanceCreati
onExpression; | 14553 InstanceCreationExpression creation = node.parent.parent as InstanceCreati
onExpression; |
| 14554 if (creation.isConst) { | 14554 if (creation.isConst) { |
| 14555 if (element == null) { | 14555 if (element == null) { |
| 14556 reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimpl
e, [typeName]); | 14556 reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimpl
e, [typeName]); |
| 14557 } else { | 14557 } else { |
| 14558 reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameS
imple, [typeName]); | 14558 reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameS
imple, [typeName]); |
| 14559 } | 14559 } |
| 14560 elementValid = false; | 14560 elementValid = false; |
| 14561 } else { | 14561 } else { |
| 14562 if (element != null) { | 14562 if (element != null) { |
| 14563 reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple
, [typeName]); | 14563 reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple
, [typeName]); |
| 14564 elementValid = false; | 14564 elementValid = false; |
| 14565 } | 14565 } |
| 14566 } | 14566 } |
| 14567 } | 14567 } |
| 14568 if (elementValid && element == null) { | 14568 if (elementValid && element == null) { |
| 14569 // We couldn't resolve the type name. | 14569 // We couldn't resolve the type name. |
| 14570 // TODO(jwren) Consider moving the check for CompileTimeErrorCode.BUILT_IN
_IDENTIFIER_AS_TYPE | 14570 // TODO(jwren) Consider moving the check for CompileTimeErrorCode.BUILT_IN
_IDENTIFIER_AS_TYPE |
| 14571 // from the ErrorVerifier, so that we don't have two errors on a built in
identifier being | 14571 // from the ErrorVerifier, so that we don't have two errors on a built in
identifier being |
| 14572 // used as a class name. See CompileTimeErrorCodeTest.test_builtInIdentifi
erAsType(). | 14572 // used as a class name. See CompileTimeErrorCodeTest.test_builtInIdentifi
erAsType(). |
| 14573 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName); | 14573 SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName); |
| 14574 RedirectingConstructorKind redirectingConstructorKind; | 14574 RedirectingConstructorKind redirectingConstructorKind; |
| 14575 if (isBuiltInIdentifier(node) && isTypeAnnotation(node)) { | 14575 if (_isBuiltInIdentifier(node) && _isTypeAnnotation(node)) { |
| 14576 reportErrorForNode(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typ
eName, [typeName.name]); | 14576 reportErrorForNode(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, typ
eName, [typeName.name]); |
| 14577 } else if (typeNameSimple.name == "boolean") { | 14577 } else if (typeNameSimple.name == "boolean") { |
| 14578 reportErrorForNode(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSi
mple, []); | 14578 reportErrorForNode(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSi
mple, []); |
| 14579 } else if (isTypeNameInCatchClause(node)) { | 14579 } else if (_isTypeNameInCatchClause(node)) { |
| 14580 reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
[typeName.name]); | 14580 reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
[typeName.name]); |
| 14581 } else if (isTypeNameInAsExpression(node)) { | 14581 } else if (_isTypeNameInAsExpression(node)) { |
| 14582 reportErrorForNode(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeNa
me.name]); | 14582 reportErrorForNode(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeNa
me.name]); |
| 14583 } else if (isTypeNameInIsExpression(node)) { | 14583 } else if (_isTypeNameInIsExpression(node)) { |
| 14584 reportErrorForNode(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [type
Name.name]); | 14584 reportErrorForNode(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [type
Name.name]); |
| 14585 } else if ((redirectingConstructorKind = getRedirectingConstructorKind(nod
e)) != null) { | 14585 } else if ((redirectingConstructorKind = _getRedirectingConstructorKind(no
de)) != null) { |
| 14586 ErrorCode errorCode = (identical(redirectingConstructorKind, Redirecting
ConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarn
ingCode.REDIRECT_TO_NON_CLASS) as ErrorCode; | 14586 ErrorCode errorCode = (identical(redirectingConstructorKind, Redirecting
ConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarn
ingCode.REDIRECT_TO_NON_CLASS) as ErrorCode; |
| 14587 reportErrorForNode(errorCode, typeName, [typeName.name]); | 14587 reportErrorForNode(errorCode, typeName, [typeName.name]); |
| 14588 } else if (isTypeNameInTypeArgumentList(node)) { | 14588 } else if (_isTypeNameInTypeArgumentList(node)) { |
| 14589 reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, type
Name, [typeName.name]); | 14589 reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, type
Name, [typeName.name]); |
| 14590 } else { | 14590 } else { |
| 14591 reportErrorForNode(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeNam
e.name]); | 14591 reportErrorForNode(StaticWarningCode.UNDEFINED_CLASS, typeName, [typeNam
e.name]); |
| 14592 } | 14592 } |
| 14593 elementValid = false; | 14593 elementValid = false; |
| 14594 } | 14594 } |
| 14595 if (!elementValid) { | 14595 if (!elementValid) { |
| 14596 if (element is MultiplyDefinedElement) { | 14596 if (element is MultiplyDefinedElement) { |
| 14597 setElement(typeName, element); | 14597 _setElement(typeName, element); |
| 14598 } else { | 14598 } else { |
| 14599 setElement(typeName, this._dynamicType.element); | 14599 _setElement(typeName, _dynamicType.element); |
| 14600 } | 14600 } |
| 14601 typeName.staticType = this._dynamicType; | 14601 typeName.staticType = _dynamicType; |
| 14602 node.type = this._dynamicType; | 14602 node.type = _dynamicType; |
| 14603 return null; | 14603 return null; |
| 14604 } | 14604 } |
| 14605 Type2 type = null; | 14605 Type2 type = null; |
| 14606 if (element is ClassElement) { | 14606 if (element is ClassElement) { |
| 14607 setElement(typeName, element); | 14607 _setElement(typeName, element); |
| 14608 type = (element as ClassElement).type; | 14608 type = (element as ClassElement).type; |
| 14609 } else if (element is FunctionTypeAliasElement) { | 14609 } else if (element is FunctionTypeAliasElement) { |
| 14610 setElement(typeName, element); | 14610 _setElement(typeName, element); |
| 14611 type = (element as FunctionTypeAliasElement).type; | 14611 type = (element as FunctionTypeAliasElement).type; |
| 14612 } else if (element is TypeParameterElement) { | 14612 } else if (element is TypeParameterElement) { |
| 14613 setElement(typeName, element); | 14613 _setElement(typeName, element); |
| 14614 type = (element as TypeParameterElement).type; | 14614 type = (element as TypeParameterElement).type; |
| 14615 if (argumentList != null) { | 14615 if (argumentList != null) { |
| 14616 } | 14616 } |
| 14617 } else if (element is MultiplyDefinedElement) { | 14617 } else if (element is MultiplyDefinedElement) { |
| 14618 List<Element> elements = (element as MultiplyDefinedElement).conflictingEl
ements; | 14618 List<Element> elements = (element as MultiplyDefinedElement).conflictingEl
ements; |
| 14619 type = getTypeWhenMultiplyDefined(elements); | 14619 type = _getTypeWhenMultiplyDefined(elements); |
| 14620 if (type != null) { | 14620 if (type != null) { |
| 14621 node.type = type; | 14621 node.type = type; |
| 14622 } | 14622 } |
| 14623 } else { | 14623 } else { |
| 14624 // The name does not represent a type. | 14624 // The name does not represent a type. |
| 14625 RedirectingConstructorKind redirectingConstructorKind; | 14625 RedirectingConstructorKind redirectingConstructorKind; |
| 14626 if (isTypeNameInCatchClause(node)) { | 14626 if (_isTypeNameInCatchClause(node)) { |
| 14627 reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
[typeName.name]); | 14627 reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
[typeName.name]); |
| 14628 } else if (isTypeNameInAsExpression(node)) { | 14628 } else if (_isTypeNameInAsExpression(node)) { |
| 14629 reportErrorForNode(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeNa
me.name]); | 14629 reportErrorForNode(StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeNa
me.name]); |
| 14630 } else if (isTypeNameInIsExpression(node)) { | 14630 } else if (_isTypeNameInIsExpression(node)) { |
| 14631 reportErrorForNode(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [type
Name.name]); | 14631 reportErrorForNode(StaticWarningCode.TYPE_TEST_NON_TYPE, typeName, [type
Name.name]); |
| 14632 } else if ((redirectingConstructorKind = getRedirectingConstructorKind(nod
e)) != null) { | 14632 } else if ((redirectingConstructorKind = _getRedirectingConstructorKind(no
de)) != null) { |
| 14633 ErrorCode errorCode = (identical(redirectingConstructorKind, Redirecting
ConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarn
ingCode.REDIRECT_TO_NON_CLASS) as ErrorCode; | 14633 ErrorCode errorCode = (identical(redirectingConstructorKind, Redirecting
ConstructorKind.CONST) ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS : StaticWarn
ingCode.REDIRECT_TO_NON_CLASS) as ErrorCode; |
| 14634 reportErrorForNode(errorCode, typeName, [typeName.name]); | 14634 reportErrorForNode(errorCode, typeName, [typeName.name]); |
| 14635 } else if (isTypeNameInTypeArgumentList(node)) { | 14635 } else if (_isTypeNameInTypeArgumentList(node)) { |
| 14636 reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, type
Name, [typeName.name]); | 14636 reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT, type
Name, [typeName.name]); |
| 14637 } else { | 14637 } else { |
| 14638 AstNode parent = typeName.parent; | 14638 AstNode parent = typeName.parent; |
| 14639 while (parent is TypeName) { | 14639 while (parent is TypeName) { |
| 14640 parent = parent.parent; | 14640 parent = parent.parent; |
| 14641 } | 14641 } |
| 14642 if (parent is ExtendsClause || parent is ImplementsClause || parent is W
ithClause || parent is ClassTypeAlias) { | 14642 if (parent is ExtendsClause || parent is ImplementsClause || parent is W
ithClause || parent is ClassTypeAlias) { |
| 14643 } else { | 14643 } else { |
| 14644 reportErrorForNode(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.n
ame]); | 14644 reportErrorForNode(StaticWarningCode.NOT_A_TYPE, typeName, [typeName.n
ame]); |
| 14645 } | 14645 } |
| 14646 } | 14646 } |
| 14647 setElement(typeName, this._dynamicType.element); | 14647 _setElement(typeName, _dynamicType.element); |
| 14648 typeName.staticType = this._dynamicType; | 14648 typeName.staticType = _dynamicType; |
| 14649 node.type = this._dynamicType; | 14649 node.type = _dynamicType; |
| 14650 return null; | 14650 return null; |
| 14651 } | 14651 } |
| 14652 if (argumentList != null) { | 14652 if (argumentList != null) { |
| 14653 NodeList<TypeName> arguments = argumentList.arguments; | 14653 NodeList<TypeName> arguments = argumentList.arguments; |
| 14654 int argumentCount = arguments.length; | 14654 int argumentCount = arguments.length; |
| 14655 List<Type2> parameters = getTypeArguments(type); | 14655 List<Type2> parameters = _getTypeArguments(type); |
| 14656 int parameterCount = parameters.length; | 14656 int parameterCount = parameters.length; |
| 14657 int count = Math.min(argumentCount, parameterCount); | 14657 int count = Math.min(argumentCount, parameterCount); |
| 14658 List<Type2> typeArguments = new List<Type2>(); | 14658 List<Type2> typeArguments = new List<Type2>(); |
| 14659 for (int i = 0; i < count; i++) { | 14659 for (int i = 0; i < count; i++) { |
| 14660 Type2 argumentType = getType(arguments[i]); | 14660 Type2 argumentType = _getType(arguments[i]); |
| 14661 if (argumentType != null) { | 14661 if (argumentType != null) { |
| 14662 typeArguments.add(argumentType); | 14662 typeArguments.add(argumentType); |
| 14663 } | 14663 } |
| 14664 } | 14664 } |
| 14665 if (argumentCount != parameterCount) { | 14665 if (argumentCount != parameterCount) { |
| 14666 reportErrorForNode(getInvalidTypeParametersErrorCode(node), node, [typeN
ame.name, parameterCount, argumentCount]); | 14666 reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node, [type
Name.name, parameterCount, argumentCount]); |
| 14667 } | 14667 } |
| 14668 argumentCount = typeArguments.length; | 14668 argumentCount = typeArguments.length; |
| 14669 if (argumentCount < parameterCount) { | 14669 if (argumentCount < parameterCount) { |
| 14670 // | 14670 // |
| 14671 // If there were too many arguments, we already handled it by not adding
the values of the | 14671 // If there were too many arguments, we already handled it by not adding
the values of the |
| 14672 // extra arguments to the list. If there are too few, we handle it by ad
ding 'dynamic' | 14672 // extra arguments to the list. If there are too few, we handle it by ad
ding 'dynamic' |
| 14673 // enough times to make the count equal. | 14673 // enough times to make the count equal. |
| 14674 // | 14674 // |
| 14675 for (int i = argumentCount; i < parameterCount; i++) { | 14675 for (int i = argumentCount; i < parameterCount; i++) { |
| 14676 typeArguments.add(this._dynamicType); | 14676 typeArguments.add(_dynamicType); |
| 14677 } | 14677 } |
| 14678 } | 14678 } |
| 14679 if (type is InterfaceTypeImpl) { | 14679 if (type is InterfaceTypeImpl) { |
| 14680 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl; | 14680 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl; |
| 14681 type = interfaceType.substitute4(new List.from(typeArguments)); | 14681 type = interfaceType.substitute4(new List.from(typeArguments)); |
| 14682 } else if (type is FunctionTypeImpl) { | 14682 } else if (type is FunctionTypeImpl) { |
| 14683 FunctionTypeImpl functionType = type as FunctionTypeImpl; | 14683 FunctionTypeImpl functionType = type as FunctionTypeImpl; |
| 14684 type = functionType.substitute3(new List.from(typeArguments)); | 14684 type = functionType.substitute3(new List.from(typeArguments)); |
| 14685 } else { | 14685 } else { |
| 14686 } | 14686 } |
| 14687 } else { | 14687 } else { |
| 14688 // | 14688 // |
| 14689 // Check for the case where there are no type arguments given for a parame
terized type. | 14689 // Check for the case where there are no type arguments given for a parame
terized type. |
| 14690 // | 14690 // |
| 14691 List<Type2> parameters = getTypeArguments(type); | 14691 List<Type2> parameters = _getTypeArguments(type); |
| 14692 int parameterCount = parameters.length; | 14692 int parameterCount = parameters.length; |
| 14693 if (parameterCount > 0) { | 14693 if (parameterCount > 0) { |
| 14694 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; | 14694 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; |
| 14695 List<Type2> arguments = new List<Type2>(parameterCount); | 14695 List<Type2> arguments = new List<Type2>(parameterCount); |
| 14696 for (int i = 0; i < parameterCount; i++) { | 14696 for (int i = 0; i < parameterCount; i++) { |
| 14697 arguments[i] = dynamicType; | 14697 arguments[i] = dynamicType; |
| 14698 } | 14698 } |
| 14699 type = type.substitute2(arguments, parameters); | 14699 type = type.substitute2(arguments, parameters); |
| 14700 } | 14700 } |
| 14701 } | 14701 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 14716 return null; | 14716 return null; |
| 14717 } | 14717 } |
| 14718 | 14718 |
| 14719 Object visitVariableDeclaration(VariableDeclaration node) { | 14719 Object visitVariableDeclaration(VariableDeclaration node) { |
| 14720 super.visitVariableDeclaration(node); | 14720 super.visitVariableDeclaration(node); |
| 14721 Type2 declaredType; | 14721 Type2 declaredType; |
| 14722 TypeName typeName = (node.parent as VariableDeclarationList).type; | 14722 TypeName typeName = (node.parent as VariableDeclarationList).type; |
| 14723 if (typeName == null) { | 14723 if (typeName == null) { |
| 14724 declaredType = _dynamicType; | 14724 declaredType = _dynamicType; |
| 14725 } else { | 14725 } else { |
| 14726 declaredType = getType(typeName); | 14726 declaredType = _getType(typeName); |
| 14727 } | 14727 } |
| 14728 Element element = node.name.staticElement; | 14728 Element element = node.name.staticElement; |
| 14729 if (element is VariableElement) { | 14729 if (element is VariableElement) { |
| 14730 (element as VariableElementImpl).type = declaredType; | 14730 (element as VariableElementImpl).type = declaredType; |
| 14731 if (element is PropertyInducingElement) { | 14731 if (element is PropertyInducingElement) { |
| 14732 PropertyInducingElement variableElement = element; | 14732 PropertyInducingElement variableElement = element; |
| 14733 PropertyAccessorElementImpl getter = variableElement.getter as PropertyA
ccessorElementImpl; | 14733 PropertyAccessorElementImpl getter = variableElement.getter as PropertyA
ccessorElementImpl; |
| 14734 getter.returnType = declaredType; | 14734 getter.returnType = declaredType; |
| 14735 FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter); | 14735 FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter); |
| 14736 ClassElement definingClass = element.getAncestor((element) => element is
ClassElement); | 14736 ClassElement definingClass = element.getAncestor((element) => element is
ClassElement); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14770 } | 14770 } |
| 14771 } | 14771 } |
| 14772 | 14772 |
| 14773 /** | 14773 /** |
| 14774 * Given a type name representing the return type of a function, compute the r
eturn type of the | 14774 * Given a type name representing the return type of a function, compute the r
eturn type of the |
| 14775 * function. | 14775 * function. |
| 14776 * | 14776 * |
| 14777 * @param returnType the type name representing the return type of the functio
n | 14777 * @param returnType the type name representing the return type of the functio
n |
| 14778 * @return the return type that was computed | 14778 * @return the return type that was computed |
| 14779 */ | 14779 */ |
| 14780 Type2 computeReturnType(TypeName returnType) { | 14780 Type2 _computeReturnType(TypeName returnType) { |
| 14781 if (returnType == null) { | 14781 if (returnType == null) { |
| 14782 return _dynamicType; | 14782 return _dynamicType; |
| 14783 } else { | 14783 } else { |
| 14784 return returnType.type; | 14784 return returnType.type; |
| 14785 } | 14785 } |
| 14786 } | 14786 } |
| 14787 | 14787 |
| 14788 /** | 14788 /** |
| 14789 * Create an implicit constructor that is copied from the given constructor, b
ut that is in the | 14789 * Create an implicit constructor that is copied from the given constructor, b
ut that is in the |
| 14790 * given class. | 14790 * given class. |
| 14791 * | 14791 * |
| 14792 * @param classType the class in which the implicit constructor is defined | 14792 * @param classType the class in which the implicit constructor is defined |
| 14793 * @param explicitConstructor the constructor on which the implicit constructo
r is modeled | 14793 * @param explicitConstructor the constructor on which the implicit constructo
r is modeled |
| 14794 * @param parameterTypes the types to be replaced when creating parameters | 14794 * @param parameterTypes the types to be replaced when creating parameters |
| 14795 * @param argumentTypes the types with which the parameters are to be replaced | 14795 * @param argumentTypes the types with which the parameters are to be replaced |
| 14796 * @return the implicit constructor that was created | 14796 * @return the implicit constructor that was created |
| 14797 */ | 14797 */ |
| 14798 ConstructorElement createImplicitContructor(InterfaceType classType, Construct
orElement explicitConstructor, List<Type2> parameterTypes, List<Type2> argumentT
ypes) { | 14798 ConstructorElement _createImplicitContructor(InterfaceType classType, Construc
torElement explicitConstructor, List<Type2> parameterTypes, List<Type2> argument
Types) { |
| 14799 ConstructorElementImpl implicitConstructor = new ConstructorElementImpl.con2
(explicitConstructor.name, -1); | 14799 ConstructorElementImpl implicitConstructor = new ConstructorElementImpl.con2
(explicitConstructor.name, -1); |
| 14800 implicitConstructor.synthetic = true; | 14800 implicitConstructor.synthetic = true; |
| 14801 implicitConstructor.redirectedConstructor = explicitConstructor; | 14801 implicitConstructor.redirectedConstructor = explicitConstructor; |
| 14802 implicitConstructor.const2 = explicitConstructor.isConst; | 14802 implicitConstructor.const2 = explicitConstructor.isConst; |
| 14803 implicitConstructor.returnType = classType; | 14803 implicitConstructor.returnType = classType; |
| 14804 List<ParameterElement> explicitParameters = explicitConstructor.parameters; | 14804 List<ParameterElement> explicitParameters = explicitConstructor.parameters; |
| 14805 int count = explicitParameters.length; | 14805 int count = explicitParameters.length; |
| 14806 if (count > 0) { | 14806 if (count > 0) { |
| 14807 List<ParameterElement> implicitParameters = new List<ParameterElement>(cou
nt); | 14807 List<ParameterElement> implicitParameters = new List<ParameterElement>(cou
nt); |
| 14808 for (int i = 0; i < count; i++) { | 14808 for (int i = 0; i < count; i++) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 14824 } | 14824 } |
| 14825 | 14825 |
| 14826 /** | 14826 /** |
| 14827 * Return an array of argument types that corresponds to the array of paramete
r types and that are | 14827 * Return an array of argument types that corresponds to the array of paramete
r types and that are |
| 14828 * derived from the given list of type arguments. | 14828 * derived from the given list of type arguments. |
| 14829 * | 14829 * |
| 14830 * @param typeArguments the type arguments from which the types will be taken | 14830 * @param typeArguments the type arguments from which the types will be taken |
| 14831 * @param parameterTypes the parameter types that must be matched by the type
arguments | 14831 * @param parameterTypes the parameter types that must be matched by the type
arguments |
| 14832 * @return the argument types that correspond to the parameter types | 14832 * @return the argument types that correspond to the parameter types |
| 14833 */ | 14833 */ |
| 14834 List<Type2> getArgumentTypes(TypeArgumentList typeArguments, List<Type2> param
eterTypes) { | 14834 List<Type2> _getArgumentTypes(TypeArgumentList typeArguments, List<Type2> para
meterTypes) { |
| 14835 DynamicTypeImpl dynamic = DynamicTypeImpl.instance; | 14835 DynamicTypeImpl dynamic = DynamicTypeImpl.instance; |
| 14836 int parameterCount = parameterTypes.length; | 14836 int parameterCount = parameterTypes.length; |
| 14837 List<Type2> types = new List<Type2>(parameterCount); | 14837 List<Type2> types = new List<Type2>(parameterCount); |
| 14838 if (typeArguments == null) { | 14838 if (typeArguments == null) { |
| 14839 for (int i = 0; i < parameterCount; i++) { | 14839 for (int i = 0; i < parameterCount; i++) { |
| 14840 types[i] = dynamic; | 14840 types[i] = dynamic; |
| 14841 } | 14841 } |
| 14842 } else { | 14842 } else { |
| 14843 NodeList<TypeName> arguments = typeArguments.arguments; | 14843 NodeList<TypeName> arguments = typeArguments.arguments; |
| 14844 int argumentCount = Math.min(arguments.length, parameterCount); | 14844 int argumentCount = Math.min(arguments.length, parameterCount); |
| 14845 for (int i = 0; i < argumentCount; i++) { | 14845 for (int i = 0; i < argumentCount; i++) { |
| 14846 types[i] = arguments[i].type; | 14846 types[i] = arguments[i].type; |
| 14847 } | 14847 } |
| 14848 for (int i = argumentCount; i < parameterCount; i++) { | 14848 for (int i = argumentCount; i < parameterCount; i++) { |
| 14849 types[i] = dynamic; | 14849 types[i] = dynamic; |
| 14850 } | 14850 } |
| 14851 } | 14851 } |
| 14852 return types; | 14852 return types; |
| 14853 } | 14853 } |
| 14854 | 14854 |
| 14855 /** | 14855 /** |
| 14856 * Return the class element that represents the class whose name was provided. | 14856 * Return the class element that represents the class whose name was provided. |
| 14857 * | 14857 * |
| 14858 * @param identifier the name from the declaration of a class | 14858 * @param identifier the name from the declaration of a class |
| 14859 * @return the class element that represents the class | 14859 * @return the class element that represents the class |
| 14860 */ | 14860 */ |
| 14861 ClassElementImpl getClassElement(SimpleIdentifier identifier) { | 14861 ClassElementImpl _getClassElement(SimpleIdentifier identifier) { |
| 14862 // TODO(brianwilkerson) Seems like we should be using ClassDeclaration.getEl
ement(). | 14862 // TODO(brianwilkerson) Seems like we should be using ClassDeclaration.getEl
ement(). |
| 14863 if (identifier == null) { | 14863 if (identifier == null) { |
| 14864 // TODO(brianwilkerson) Report this | 14864 // TODO(brianwilkerson) Report this |
| 14865 // Internal error: We should never build a class declaration without a nam
e. | 14865 // Internal error: We should never build a class declaration without a nam
e. |
| 14866 return null; | 14866 return null; |
| 14867 } | 14867 } |
| 14868 Element element = identifier.staticElement; | 14868 Element element = identifier.staticElement; |
| 14869 if (element is! ClassElementImpl) { | 14869 if (element is! ClassElementImpl) { |
| 14870 // TODO(brianwilkerson) Report this | 14870 // TODO(brianwilkerson) Report this |
| 14871 // Internal error: Failed to create an element for a class declaration. | 14871 // Internal error: Failed to create an element for a class declaration. |
| 14872 return null; | 14872 return null; |
| 14873 } | 14873 } |
| 14874 return element as ClassElementImpl; | 14874 return element as ClassElementImpl; |
| 14875 } | 14875 } |
| 14876 | 14876 |
| 14877 /** | 14877 /** |
| 14878 * Return an array containing all of the elements associated with the paramete
rs in the given | 14878 * Return an array containing all of the elements associated with the paramete
rs in the given |
| 14879 * list. | 14879 * list. |
| 14880 * | 14880 * |
| 14881 * @param parameterList the list of parameters whose elements are to be return
ed | 14881 * @param parameterList the list of parameters whose elements are to be return
ed |
| 14882 * @return the elements associated with the parameters | 14882 * @return the elements associated with the parameters |
| 14883 */ | 14883 */ |
| 14884 List<ParameterElement> getElements(FormalParameterList parameterList) { | 14884 List<ParameterElement> _getElements(FormalParameterList parameterList) { |
| 14885 List<ParameterElement> elements = new List<ParameterElement>(); | 14885 List<ParameterElement> elements = new List<ParameterElement>(); |
| 14886 for (FormalParameter parameter in parameterList.parameters) { | 14886 for (FormalParameter parameter in parameterList.parameters) { |
| 14887 ParameterElement element = parameter.identifier.staticElement as Parameter
Element; | 14887 ParameterElement element = parameter.identifier.staticElement as Parameter
Element; |
| 14888 // TODO(brianwilkerson) Understand why the element would be null. | 14888 // TODO(brianwilkerson) Understand why the element would be null. |
| 14889 if (element != null) { | 14889 if (element != null) { |
| 14890 elements.add(element); | 14890 elements.add(element); |
| 14891 } | 14891 } |
| 14892 } | 14892 } |
| 14893 return new List.from(elements); | 14893 return new List.from(elements); |
| 14894 } | 14894 } |
| 14895 | 14895 |
| 14896 /** | 14896 /** |
| 14897 * The number of type arguments in the given type name does not match the numb
er of parameters in | 14897 * The number of type arguments in the given type name does not match the numb
er of parameters in |
| 14898 * the corresponding class element. Return the error code that should be used
to report this | 14898 * the corresponding class element. Return the error code that should be used
to report this |
| 14899 * error. | 14899 * error. |
| 14900 * | 14900 * |
| 14901 * @param node the type name with the wrong number of type arguments | 14901 * @param node the type name with the wrong number of type arguments |
| 14902 * @return the error code that should be used to report that the wrong number
of type arguments | 14902 * @return the error code that should be used to report that the wrong number
of type arguments |
| 14903 * were provided | 14903 * were provided |
| 14904 */ | 14904 */ |
| 14905 ErrorCode getInvalidTypeParametersErrorCode(TypeName node) { | 14905 ErrorCode _getInvalidTypeParametersErrorCode(TypeName node) { |
| 14906 AstNode parent = node.parent; | 14906 AstNode parent = node.parent; |
| 14907 if (parent is ConstructorName) { | 14907 if (parent is ConstructorName) { |
| 14908 parent = parent.parent; | 14908 parent = parent.parent; |
| 14909 if (parent is InstanceCreationExpression) { | 14909 if (parent is InstanceCreationExpression) { |
| 14910 if ((parent as InstanceCreationExpression).isConst) { | 14910 if ((parent as InstanceCreationExpression).isConst) { |
| 14911 return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS; | 14911 return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS; |
| 14912 } else { | 14912 } else { |
| 14913 return StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS; | 14913 return StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS; |
| 14914 } | 14914 } |
| 14915 } | 14915 } |
| 14916 } | 14916 } |
| 14917 return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS; | 14917 return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS; |
| 14918 } | 14918 } |
| 14919 | 14919 |
| 14920 /** | 14920 /** |
| 14921 * Checks if the given type name is the target in a redirected constructor. | 14921 * Checks if the given type name is the target in a redirected constructor. |
| 14922 * | 14922 * |
| 14923 * @param typeName the type name to analyze | 14923 * @param typeName the type name to analyze |
| 14924 * @return some [RedirectingConstructorKind] if the given type name is used as
the type in a | 14924 * @return some [RedirectingConstructorKind] if the given type name is used as
the type in a |
| 14925 * redirected constructor, or `null` otherwise | 14925 * redirected constructor, or `null` otherwise |
| 14926 */ | 14926 */ |
| 14927 RedirectingConstructorKind getRedirectingConstructorKind(TypeName typeName) { | 14927 RedirectingConstructorKind _getRedirectingConstructorKind(TypeName typeName) { |
| 14928 AstNode parent = typeName.parent; | 14928 AstNode parent = typeName.parent; |
| 14929 if (parent is ConstructorName) { | 14929 if (parent is ConstructorName) { |
| 14930 ConstructorName constructorName = parent as ConstructorName; | 14930 ConstructorName constructorName = parent as ConstructorName; |
| 14931 parent = constructorName.parent; | 14931 parent = constructorName.parent; |
| 14932 if (parent is ConstructorDeclaration) { | 14932 if (parent is ConstructorDeclaration) { |
| 14933 ConstructorDeclaration constructorDeclaration = parent as ConstructorDec
laration; | 14933 ConstructorDeclaration constructorDeclaration = parent as ConstructorDec
laration; |
| 14934 if (identical(constructorDeclaration.redirectedConstructor, constructorN
ame)) { | 14934 if (identical(constructorDeclaration.redirectedConstructor, constructorN
ame)) { |
| 14935 if (constructorDeclaration.constKeyword != null) { | 14935 if (constructorDeclaration.constKeyword != null) { |
| 14936 return RedirectingConstructorKind.CONST; | 14936 return RedirectingConstructorKind.CONST; |
| 14937 } | 14937 } |
| 14938 return RedirectingConstructorKind.NORMAL; | 14938 return RedirectingConstructorKind.NORMAL; |
| 14939 } | 14939 } |
| 14940 } | 14940 } |
| 14941 } | 14941 } |
| 14942 return null; | 14942 return null; |
| 14943 } | 14943 } |
| 14944 | 14944 |
| 14945 /** | 14945 /** |
| 14946 * Return the type represented by the given type name. | 14946 * Return the type represented by the given type name. |
| 14947 * | 14947 * |
| 14948 * @param typeName the type name representing the type to be returned | 14948 * @param typeName the type name representing the type to be returned |
| 14949 * @return the type represented by the type name | 14949 * @return the type represented by the type name |
| 14950 */ | 14950 */ |
| 14951 Type2 getType(TypeName typeName) { | 14951 Type2 _getType(TypeName typeName) { |
| 14952 Type2 type = typeName.type; | 14952 Type2 type = typeName.type; |
| 14953 if (type == null) { | 14953 if (type == null) { |
| 14954 return _dynamicType; | 14954 return _dynamicType; |
| 14955 } | 14955 } |
| 14956 return type; | 14956 return type; |
| 14957 } | 14957 } |
| 14958 | 14958 |
| 14959 /** | 14959 /** |
| 14960 * Return the type arguments associated with the given type. | 14960 * Return the type arguments associated with the given type. |
| 14961 * | 14961 * |
| 14962 * @param type the type whole type arguments are to be returned | 14962 * @param type the type whole type arguments are to be returned |
| 14963 * @return the type arguments associated with the given type | 14963 * @return the type arguments associated with the given type |
| 14964 */ | 14964 */ |
| 14965 List<Type2> getTypeArguments(Type2 type) { | 14965 List<Type2> _getTypeArguments(Type2 type) { |
| 14966 if (type is InterfaceType) { | 14966 if (type is InterfaceType) { |
| 14967 return type.typeArguments; | 14967 return type.typeArguments; |
| 14968 } else if (type is FunctionType) { | 14968 } else if (type is FunctionType) { |
| 14969 return type.typeArguments; | 14969 return type.typeArguments; |
| 14970 } | 14970 } |
| 14971 return TypeImpl.EMPTY_ARRAY; | 14971 return TypeImpl.EMPTY_ARRAY; |
| 14972 } | 14972 } |
| 14973 | 14973 |
| 14974 /** | 14974 /** |
| 14975 * Returns the simple identifier of the given (may be qualified) type name. | 14975 * Returns the simple identifier of the given (may be qualified) type name. |
| 14976 * | 14976 * |
| 14977 * @param typeName the (may be qualified) qualified type name | 14977 * @param typeName the (may be qualified) qualified type name |
| 14978 * @return the simple identifier of the given (may be qualified) type name. | 14978 * @return the simple identifier of the given (may be qualified) type name. |
| 14979 */ | 14979 */ |
| 14980 SimpleIdentifier getTypeSimpleIdentifier(Identifier typeName) { | 14980 SimpleIdentifier _getTypeSimpleIdentifier(Identifier typeName) { |
| 14981 if (typeName is SimpleIdentifier) { | 14981 if (typeName is SimpleIdentifier) { |
| 14982 return typeName; | 14982 return typeName; |
| 14983 } else { | 14983 } else { |
| 14984 return (typeName as PrefixedIdentifier).identifier; | 14984 return (typeName as PrefixedIdentifier).identifier; |
| 14985 } | 14985 } |
| 14986 } | 14986 } |
| 14987 | 14987 |
| 14988 /** | 14988 /** |
| 14989 * Given the multiple elements to which a single name could potentially be res
olved, return the | 14989 * Given the multiple elements to which a single name could potentially be res
olved, return the |
| 14990 * single interface type that should be used, or `null` if there is no clear c
hoice. | 14990 * single interface type that should be used, or `null` if there is no clear c
hoice. |
| 14991 * | 14991 * |
| 14992 * @param elements the elements to which a single name could potentially be re
solved | 14992 * @param elements the elements to which a single name could potentially be re
solved |
| 14993 * @return the single interface type that should be used for the type name | 14993 * @return the single interface type that should be used for the type name |
| 14994 */ | 14994 */ |
| 14995 InterfaceType getTypeWhenMultiplyDefined(List<Element> elements) { | 14995 InterfaceType _getTypeWhenMultiplyDefined(List<Element> elements) { |
| 14996 InterfaceType type = null; | 14996 InterfaceType type = null; |
| 14997 for (Element element in elements) { | 14997 for (Element element in elements) { |
| 14998 if (element is ClassElement) { | 14998 if (element is ClassElement) { |
| 14999 if (type != null) { | 14999 if (type != null) { |
| 15000 return null; | 15000 return null; |
| 15001 } | 15001 } |
| 15002 type = element.type; | 15002 type = element.type; |
| 15003 } | 15003 } |
| 15004 } | 15004 } |
| 15005 return type; | 15005 return type; |
| 15006 } | 15006 } |
| 15007 | 15007 |
| 15008 /** | 15008 /** |
| 15009 * Checks if the given type name is used as the type in an as expression. | 15009 * Checks if the given type name is used as the type in an as expression. |
| 15010 * | 15010 * |
| 15011 * @param typeName the type name to analyzer | 15011 * @param typeName the type name to analyzer |
| 15012 * @return `true` if the given type name is used as the type in an as expressi
on | 15012 * @return `true` if the given type name is used as the type in an as expressi
on |
| 15013 */ | 15013 */ |
| 15014 bool isTypeNameInAsExpression(TypeName typeName) { | 15014 bool _isTypeNameInAsExpression(TypeName typeName) { |
| 15015 AstNode parent = typeName.parent; | 15015 AstNode parent = typeName.parent; |
| 15016 if (parent is AsExpression) { | 15016 if (parent is AsExpression) { |
| 15017 AsExpression asExpression = parent; | 15017 AsExpression asExpression = parent; |
| 15018 return identical(asExpression.type, typeName); | 15018 return identical(asExpression.type, typeName); |
| 15019 } | 15019 } |
| 15020 return false; | 15020 return false; |
| 15021 } | 15021 } |
| 15022 | 15022 |
| 15023 /** | 15023 /** |
| 15024 * Checks if the given type name is used as the exception type in a catch clau
se. | 15024 * Checks if the given type name is used as the exception type in a catch clau
se. |
| 15025 * | 15025 * |
| 15026 * @param typeName the type name to analyzer | 15026 * @param typeName the type name to analyzer |
| 15027 * @return `true` if the given type name is used as the exception type in a ca
tch clause | 15027 * @return `true` if the given type name is used as the exception type in a ca
tch clause |
| 15028 */ | 15028 */ |
| 15029 bool isTypeNameInCatchClause(TypeName typeName) { | 15029 bool _isTypeNameInCatchClause(TypeName typeName) { |
| 15030 AstNode parent = typeName.parent; | 15030 AstNode parent = typeName.parent; |
| 15031 if (parent is CatchClause) { | 15031 if (parent is CatchClause) { |
| 15032 CatchClause catchClause = parent; | 15032 CatchClause catchClause = parent; |
| 15033 return identical(catchClause.exceptionType, typeName); | 15033 return identical(catchClause.exceptionType, typeName); |
| 15034 } | 15034 } |
| 15035 return false; | 15035 return false; |
| 15036 } | 15036 } |
| 15037 | 15037 |
| 15038 /** | 15038 /** |
| 15039 * Checks if the given type name is used as the type in an instance creation e
xpression. | 15039 * Checks if the given type name is used as the type in an instance creation e
xpression. |
| 15040 * | 15040 * |
| 15041 * @param typeName the type name to analyzer | 15041 * @param typeName the type name to analyzer |
| 15042 * @return `true` if the given type name is used as the type in an instance cr
eation | 15042 * @return `true` if the given type name is used as the type in an instance cr
eation |
| 15043 * expression | 15043 * expression |
| 15044 */ | 15044 */ |
| 15045 bool isTypeNameInInstanceCreationExpression(TypeName typeName) { | 15045 bool _isTypeNameInInstanceCreationExpression(TypeName typeName) { |
| 15046 AstNode parent = typeName.parent; | 15046 AstNode parent = typeName.parent; |
| 15047 if (parent is ConstructorName && parent.parent is InstanceCreationExpression
) { | 15047 if (parent is ConstructorName && parent.parent is InstanceCreationExpression
) { |
| 15048 ConstructorName constructorName = parent; | 15048 ConstructorName constructorName = parent; |
| 15049 return constructorName != null && identical(constructorName.type, typeName
); | 15049 return constructorName != null && identical(constructorName.type, typeName
); |
| 15050 } | 15050 } |
| 15051 return false; | 15051 return false; |
| 15052 } | 15052 } |
| 15053 | 15053 |
| 15054 /** | 15054 /** |
| 15055 * Checks if the given type name is used as the type in an is expression. | 15055 * Checks if the given type name is used as the type in an is expression. |
| 15056 * | 15056 * |
| 15057 * @param typeName the type name to analyzer | 15057 * @param typeName the type name to analyzer |
| 15058 * @return `true` if the given type name is used as the type in an is expressi
on | 15058 * @return `true` if the given type name is used as the type in an is expressi
on |
| 15059 */ | 15059 */ |
| 15060 bool isTypeNameInIsExpression(TypeName typeName) { | 15060 bool _isTypeNameInIsExpression(TypeName typeName) { |
| 15061 AstNode parent = typeName.parent; | 15061 AstNode parent = typeName.parent; |
| 15062 if (parent is IsExpression) { | 15062 if (parent is IsExpression) { |
| 15063 IsExpression isExpression = parent; | 15063 IsExpression isExpression = parent; |
| 15064 return identical(isExpression.type, typeName); | 15064 return identical(isExpression.type, typeName); |
| 15065 } | 15065 } |
| 15066 return false; | 15066 return false; |
| 15067 } | 15067 } |
| 15068 | 15068 |
| 15069 /** | 15069 /** |
| 15070 * Checks if the given type name used in a type argument list. | 15070 * Checks if the given type name used in a type argument list. |
| 15071 * | 15071 * |
| 15072 * @param typeName the type name to analyzer | 15072 * @param typeName the type name to analyzer |
| 15073 * @return `true` if the given type name is in a type argument list | 15073 * @return `true` if the given type name is in a type argument list |
| 15074 */ | 15074 */ |
| 15075 bool isTypeNameInTypeArgumentList(TypeName typeName) => typeName.parent is Typ
eArgumentList; | 15075 bool _isTypeNameInTypeArgumentList(TypeName typeName) => typeName.parent is Ty
peArgumentList; |
| 15076 | 15076 |
| 15077 /** | 15077 /** |
| 15078 * Record that the static type of the given node is the given type. | 15078 * Record that the static type of the given node is the given type. |
| 15079 * | 15079 * |
| 15080 * @param expression the node whose type is to be recorded | 15080 * @param expression the node whose type is to be recorded |
| 15081 * @param type the static type of the node | 15081 * @param type the static type of the node |
| 15082 */ | 15082 */ |
| 15083 Object recordType(Expression expression, Type2 type) { | 15083 Object _recordType(Expression expression, Type2 type) { |
| 15084 if (type == null) { | 15084 if (type == null) { |
| 15085 expression.staticType = _dynamicType; | 15085 expression.staticType = _dynamicType; |
| 15086 } else { | 15086 } else { |
| 15087 expression.staticType = type; | 15087 expression.staticType = type; |
| 15088 } | 15088 } |
| 15089 return null; | 15089 return null; |
| 15090 } | 15090 } |
| 15091 | 15091 |
| 15092 /** | 15092 /** |
| 15093 * Resolve the types in the given with and implements clauses and associate th
ose types with the | 15093 * Resolve the types in the given with and implements clauses and associate th
ose types with the |
| 15094 * given class element. | 15094 * given class element. |
| 15095 * | 15095 * |
| 15096 * @param classElement the class element with which the mixin and interface ty
pes are to be | 15096 * @param classElement the class element with which the mixin and interface ty
pes are to be |
| 15097 * associated | 15097 * associated |
| 15098 * @param withClause the with clause to be resolved | 15098 * @param withClause the with clause to be resolved |
| 15099 * @param implementsClause the implements clause to be resolved | 15099 * @param implementsClause the implements clause to be resolved |
| 15100 */ | 15100 */ |
| 15101 void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsC
lause implementsClause) { | 15101 void _resolve(ClassElementImpl classElement, WithClause withClause, Implements
Clause implementsClause) { |
| 15102 if (withClause != null) { | 15102 if (withClause != null) { |
| 15103 List<InterfaceType> mixinTypes = resolveTypes(withClause.mixinTypes, Compi
leTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_NON_CLASS); | 15103 List<InterfaceType> mixinTypes = _resolveTypes(withClause.mixinTypes, Comp
ileTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_NON_CLASS); |
| 15104 if (classElement != null) { | 15104 if (classElement != null) { |
| 15105 classElement.mixins = mixinTypes; | 15105 classElement.mixins = mixinTypes; |
| 15106 } | 15106 } |
| 15107 } | 15107 } |
| 15108 if (implementsClause != null) { | 15108 if (implementsClause != null) { |
| 15109 NodeList<TypeName> interfaces = implementsClause.interfaces; | 15109 NodeList<TypeName> interfaces = implementsClause.interfaces; |
| 15110 List<InterfaceType> interfaceTypes = resolveTypes(interfaces, CompileTimeE
rrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_DYNAMIC); | 15110 List<InterfaceType> interfaceTypes = _resolveTypes(interfaces, CompileTime
ErrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_DYNAMIC); |
| 15111 if (classElement != null) { | 15111 if (classElement != null) { |
| 15112 classElement.interfaces = interfaceTypes; | 15112 classElement.interfaces = interfaceTypes; |
| 15113 } | 15113 } |
| 15114 // TODO(brianwilkerson) Move the following checks to ErrorVerifier. | 15114 // TODO(brianwilkerson) Move the following checks to ErrorVerifier. |
| 15115 List<TypeName> typeNames = new List.from(interfaces); | 15115 List<TypeName> typeNames = new List.from(interfaces); |
| 15116 List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length,
false); | 15116 List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length,
false); |
| 15117 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { | 15117 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { |
| 15118 detectedRepeatOnIndex[i] = false; | 15118 detectedRepeatOnIndex[i] = false; |
| 15119 } | 15119 } |
| 15120 for (int i = 0; i < typeNames.length; i++) { | 15120 for (int i = 0; i < typeNames.length; i++) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 15138 | 15138 |
| 15139 /** | 15139 /** |
| 15140 * Return the type specified by the given name. | 15140 * Return the type specified by the given name. |
| 15141 * | 15141 * |
| 15142 * @param typeName the type name specifying the type to be returned | 15142 * @param typeName the type name specifying the type to be returned |
| 15143 * @param nonTypeError the error to produce if the type name is defined to be
something other than | 15143 * @param nonTypeError the error to produce if the type name is defined to be
something other than |
| 15144 * a type | 15144 * a type |
| 15145 * @param dynamicTypeError the error to produce if the type name is "dynamic" | 15145 * @param dynamicTypeError the error to produce if the type name is "dynamic" |
| 15146 * @return the type specified by the type name | 15146 * @return the type specified by the type name |
| 15147 */ | 15147 */ |
| 15148 InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCode
dynamicTypeError) { | 15148 InterfaceType _resolveType(TypeName typeName, ErrorCode nonTypeError, ErrorCod
e dynamicTypeError) { |
| 15149 Type2 type = typeName.type; | 15149 Type2 type = typeName.type; |
| 15150 if (type is InterfaceType) { | 15150 if (type is InterfaceType) { |
| 15151 return type; | 15151 return type; |
| 15152 } | 15152 } |
| 15153 // If the type is not an InterfaceType, then visitTypeName() sets the type t
o be a DynamicTypeImpl | 15153 // If the type is not an InterfaceType, then visitTypeName() sets the type t
o be a DynamicTypeImpl |
| 15154 Identifier name = typeName.name; | 15154 Identifier name = typeName.name; |
| 15155 if (name.name == sc.Keyword.DYNAMIC.syntax) { | 15155 if (name.name == sc.Keyword.DYNAMIC.syntax) { |
| 15156 reportErrorForNode(dynamicTypeError, name, [name.name]); | 15156 reportErrorForNode(dynamicTypeError, name, [name.name]); |
| 15157 } else { | 15157 } else { |
| 15158 reportErrorForNode(nonTypeError, name, [name.name]); | 15158 reportErrorForNode(nonTypeError, name, [name.name]); |
| 15159 } | 15159 } |
| 15160 return null; | 15160 return null; |
| 15161 } | 15161 } |
| 15162 | 15162 |
| 15163 /** | 15163 /** |
| 15164 * Resolve the types in the given list of type names. | 15164 * Resolve the types in the given list of type names. |
| 15165 * | 15165 * |
| 15166 * @param typeNames the type names to be resolved | 15166 * @param typeNames the type names to be resolved |
| 15167 * @param nonTypeError the error to produce if the type name is defined to be
something other than | 15167 * @param nonTypeError the error to produce if the type name is defined to be
something other than |
| 15168 * a type | 15168 * a type |
| 15169 * @param dynamicTypeError the error to produce if the type name is "dynamic" | 15169 * @param dynamicTypeError the error to produce if the type name is "dynamic" |
| 15170 * @return an array containing all of the types that were resolved. | 15170 * @return an array containing all of the types that were resolved. |
| 15171 */ | 15171 */ |
| 15172 List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonTy
peError, ErrorCode dynamicTypeError) { | 15172 List<InterfaceType> _resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonT
ypeError, ErrorCode dynamicTypeError) { |
| 15173 List<InterfaceType> types = new List<InterfaceType>(); | 15173 List<InterfaceType> types = new List<InterfaceType>(); |
| 15174 for (TypeName typeName in typeNames) { | 15174 for (TypeName typeName in typeNames) { |
| 15175 InterfaceType type = resolveType(typeName, nonTypeError, dynamicTypeError)
; | 15175 InterfaceType type = _resolveType(typeName, nonTypeError, dynamicTypeError
); |
| 15176 if (type != null) { | 15176 if (type != null) { |
| 15177 types.add(type); | 15177 types.add(type); |
| 15178 } | 15178 } |
| 15179 } | 15179 } |
| 15180 return new List.from(types); | 15180 return new List.from(types); |
| 15181 } | 15181 } |
| 15182 | 15182 |
| 15183 void setElement(Identifier typeName, Element element) { | 15183 void _setElement(Identifier typeName, Element element) { |
| 15184 if (element != null) { | 15184 if (element != null) { |
| 15185 if (typeName is SimpleIdentifier) { | 15185 if (typeName is SimpleIdentifier) { |
| 15186 typeName.staticElement = element; | 15186 typeName.staticElement = element; |
| 15187 } else if (typeName is PrefixedIdentifier) { | 15187 } else if (typeName is PrefixedIdentifier) { |
| 15188 PrefixedIdentifier identifier = typeName; | 15188 PrefixedIdentifier identifier = typeName; |
| 15189 identifier.identifier.staticElement = element; | 15189 identifier.identifier.staticElement = element; |
| 15190 SimpleIdentifier prefix = identifier.prefix; | 15190 SimpleIdentifier prefix = identifier.prefix; |
| 15191 Element prefixElement = nameScope.lookup(prefix, definingLibrary); | 15191 Element prefixElement = nameScope.lookup(prefix, definingLibrary); |
| 15192 if (prefixElement != null) { | 15192 if (prefixElement != null) { |
| 15193 prefix.staticElement = prefixElement; | 15193 prefix.staticElement = prefixElement; |
| 15194 } | 15194 } |
| 15195 } | 15195 } |
| 15196 } | 15196 } |
| 15197 } | 15197 } |
| 15198 | 15198 |
| 15199 /** | 15199 /** |
| 15200 * Given a parameter element, create a function type based on the given return
type and parameter | 15200 * Given a parameter element, create a function type based on the given return
type and parameter |
| 15201 * list and associate the created type with the element. | 15201 * list and associate the created type with the element. |
| 15202 * | 15202 * |
| 15203 * @param element the parameter element whose type is to be set | 15203 * @param element the parameter element whose type is to be set |
| 15204 * @param returnType the (possibly `null`) return type of the function | 15204 * @param returnType the (possibly `null`) return type of the function |
| 15205 * @param parameterList the list of parameters to the function | 15205 * @param parameterList the list of parameters to the function |
| 15206 */ | 15206 */ |
| 15207 void setFunctionTypedParameterType(ParameterElementImpl element, TypeName retu
rnType, FormalParameterList parameterList) { | 15207 void _setFunctionTypedParameterType(ParameterElementImpl element, TypeName ret
urnType, FormalParameterList parameterList) { |
| 15208 List<ParameterElement> parameters = getElements(parameterList); | 15208 List<ParameterElement> parameters = _getElements(parameterList); |
| 15209 FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl
(null); | 15209 FunctionTypeAliasElementImpl aliasElement = new FunctionTypeAliasElementImpl
(null); |
| 15210 aliasElement.synthetic = true; | 15210 aliasElement.synthetic = true; |
| 15211 aliasElement.shareParameters(parameters); | 15211 aliasElement.shareParameters(parameters); |
| 15212 aliasElement.returnType = computeReturnType(returnType); | 15212 aliasElement.returnType = _computeReturnType(returnType); |
| 15213 FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement); | 15213 FunctionTypeImpl type = new FunctionTypeImpl.con2(aliasElement); |
| 15214 ClassElement definingClass = element.getAncestor((element) => element is Cla
ssElement); | 15214 ClassElement definingClass = element.getAncestor((element) => element is Cla
ssElement); |
| 15215 if (definingClass != null) { | 15215 if (definingClass != null) { |
| 15216 aliasElement.shareTypeParameters(definingClass.typeParameters); | 15216 aliasElement.shareTypeParameters(definingClass.typeParameters); |
| 15217 type.typeArguments = definingClass.type.typeArguments; | 15217 type.typeArguments = definingClass.type.typeArguments; |
| 15218 } else { | 15218 } else { |
| 15219 FunctionTypeAliasElement alias = element.getAncestor((element) => element
is FunctionTypeAliasElement); | 15219 FunctionTypeAliasElement alias = element.getAncestor((element) => element
is FunctionTypeAliasElement); |
| 15220 while (alias != null && alias.isSynthetic) { | 15220 while (alias != null && alias.isSynthetic) { |
| 15221 alias = alias.getAncestor((element) => element is FunctionTypeAliasEleme
nt); | 15221 alias = alias.getAncestor((element) => element is FunctionTypeAliasEleme
nt); |
| 15222 } | 15222 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15377 * Instances of the class `ClassScope` implement the scope defined by a class. | 15377 * Instances of the class `ClassScope` implement the scope defined by a class. |
| 15378 */ | 15378 */ |
| 15379 class ClassScope extends EnclosedScope { | 15379 class ClassScope extends EnclosedScope { |
| 15380 /** | 15380 /** |
| 15381 * Initialize a newly created scope enclosed within another scope. | 15381 * Initialize a newly created scope enclosed within another scope. |
| 15382 * | 15382 * |
| 15383 * @param enclosingScope the scope in which this scope is lexically enclosed | 15383 * @param enclosingScope the scope in which this scope is lexically enclosed |
| 15384 * @param typeElement the element representing the type represented by this sc
ope | 15384 * @param typeElement the element representing the type represented by this sc
ope |
| 15385 */ | 15385 */ |
| 15386 ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new Enclose
dScope(enclosingScope)) { | 15386 ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new Enclose
dScope(enclosingScope)) { |
| 15387 defineTypeParameters(typeElement); | 15387 _defineTypeParameters(typeElement); |
| 15388 defineMembers(typeElement); | 15388 _defineMembers(typeElement); |
| 15389 } | 15389 } |
| 15390 | 15390 |
| 15391 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 15391 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
| 15392 if (existing is PropertyAccessorElement && duplicate is MethodElement) { | 15392 if (existing is PropertyAccessorElement && duplicate is MethodElement) { |
| 15393 if (existing.nameOffset < duplicate.nameOffset) { | 15393 if (existing.nameOffset < duplicate.nameOffset) { |
| 15394 return new AnalysisError.con2(duplicate.source, duplicate.nameOffset, du
plicate.displayName.length, CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAM
E, [existing.displayName]); | 15394 return new AnalysisError.con2(duplicate.source, duplicate.nameOffset, du
plicate.displayName.length, CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAM
E, [existing.displayName]); |
| 15395 } else { | 15395 } else { |
| 15396 return new AnalysisError.con2(existing.source, existing.nameOffset, exis
ting.displayName.length, CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
[existing.displayName]); | 15396 return new AnalysisError.con2(existing.source, existing.nameOffset, exis
ting.displayName.length, CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
[existing.displayName]); |
| 15397 } | 15397 } |
| 15398 } | 15398 } |
| 15399 return super.getErrorForDuplicate(existing, duplicate); | 15399 return super.getErrorForDuplicate(existing, duplicate); |
| 15400 } | 15400 } |
| 15401 | 15401 |
| 15402 /** | 15402 /** |
| 15403 * Define the instance members defined by the class. | 15403 * Define the instance members defined by the class. |
| 15404 * | 15404 * |
| 15405 * @param typeElement the element representing the type represented by this sc
ope | 15405 * @param typeElement the element representing the type represented by this sc
ope |
| 15406 */ | 15406 */ |
| 15407 void defineMembers(ClassElement typeElement) { | 15407 void _defineMembers(ClassElement typeElement) { |
| 15408 for (PropertyAccessorElement accessor in typeElement.accessors) { | 15408 for (PropertyAccessorElement accessor in typeElement.accessors) { |
| 15409 define(accessor); | 15409 define(accessor); |
| 15410 } | 15410 } |
| 15411 for (MethodElement method in typeElement.methods) { | 15411 for (MethodElement method in typeElement.methods) { |
| 15412 define(method); | 15412 define(method); |
| 15413 } | 15413 } |
| 15414 } | 15414 } |
| 15415 | 15415 |
| 15416 /** | 15416 /** |
| 15417 * Define the type parameters for the class. | 15417 * Define the type parameters for the class. |
| 15418 * | 15418 * |
| 15419 * @param typeElement the element representing the type represented by this sc
ope | 15419 * @param typeElement the element representing the type represented by this sc
ope |
| 15420 */ | 15420 */ |
| 15421 void defineTypeParameters(ClassElement typeElement) { | 15421 void _defineTypeParameters(ClassElement typeElement) { |
| 15422 Scope parameterScope = enclosingScope; | 15422 Scope parameterScope = enclosingScope; |
| 15423 for (TypeParameterElement typeParameter in typeElement.typeParameters) { | 15423 for (TypeParameterElement typeParameter in typeElement.typeParameters) { |
| 15424 parameterScope.define(typeParameter); | 15424 parameterScope.define(typeParameter); |
| 15425 } | 15425 } |
| 15426 } | 15426 } |
| 15427 } | 15427 } |
| 15428 | 15428 |
| 15429 /** | 15429 /** |
| 15430 * Instances of the class `EnclosedScope` implement a scope that is lexically en
closed in | 15430 * Instances of the class `EnclosedScope` implement a scope that is lexically en
closed in |
| 15431 * another scope. | 15431 * another scope. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15543 bool _parametersDefined = false; | 15543 bool _parametersDefined = false; |
| 15544 | 15544 |
| 15545 /** | 15545 /** |
| 15546 * Initialize a newly created scope enclosed within another scope. | 15546 * Initialize a newly created scope enclosed within another scope. |
| 15547 * | 15547 * |
| 15548 * @param enclosingScope the scope in which this scope is lexically enclosed | 15548 * @param enclosingScope the scope in which this scope is lexically enclosed |
| 15549 * @param typeElement the element representing the type alias represented by t
his scope | 15549 * @param typeElement the element representing the type alias represented by t
his scope |
| 15550 */ | 15550 */ |
| 15551 FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement)
: super(new EnclosedScope(enclosingScope)) { | 15551 FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement)
: super(new EnclosedScope(enclosingScope)) { |
| 15552 this._typeElement = typeElement; | 15552 this._typeElement = typeElement; |
| 15553 defineTypeParameters(); | 15553 _defineTypeParameters(); |
| 15554 } | 15554 } |
| 15555 | 15555 |
| 15556 /** | 15556 /** |
| 15557 * Define the parameters for the function type alias. | 15557 * Define the parameters for the function type alias. |
| 15558 * | 15558 * |
| 15559 * @param typeElement the element representing the type represented by this sc
ope | 15559 * @param typeElement the element representing the type represented by this sc
ope |
| 15560 */ | 15560 */ |
| 15561 void defineParameters() { | 15561 void defineParameters() { |
| 15562 if (_parametersDefined) { | 15562 if (_parametersDefined) { |
| 15563 return; | 15563 return; |
| 15564 } | 15564 } |
| 15565 _parametersDefined = true; | 15565 _parametersDefined = true; |
| 15566 for (ParameterElement parameter in _typeElement.parameters) { | 15566 for (ParameterElement parameter in _typeElement.parameters) { |
| 15567 define(parameter); | 15567 define(parameter); |
| 15568 } | 15568 } |
| 15569 } | 15569 } |
| 15570 | 15570 |
| 15571 /** | 15571 /** |
| 15572 * Define the type parameters for the function type alias. | 15572 * Define the type parameters for the function type alias. |
| 15573 * | 15573 * |
| 15574 * @param typeElement the element representing the type represented by this sc
ope | 15574 * @param typeElement the element representing the type represented by this sc
ope |
| 15575 */ | 15575 */ |
| 15576 void defineTypeParameters() { | 15576 void _defineTypeParameters() { |
| 15577 Scope typeParameterScope = enclosingScope; | 15577 Scope typeParameterScope = enclosingScope; |
| 15578 for (TypeParameterElement typeParameter in _typeElement.typeParameters) { | 15578 for (TypeParameterElement typeParameter in _typeElement.typeParameters) { |
| 15579 typeParameterScope.define(typeParameter); | 15579 typeParameterScope.define(typeParameter); |
| 15580 } | 15580 } |
| 15581 } | 15581 } |
| 15582 } | 15582 } |
| 15583 | 15583 |
| 15584 /** | 15584 /** |
| 15585 * Instances of the class `LabelScope` represent a scope in which a single label
is defined. | 15585 * Instances of the class `LabelScope` represent a scope in which a single label
is defined. |
| 15586 */ | 15586 */ |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15676 | 15676 |
| 15677 /** | 15677 /** |
| 15678 * Initialize a newly created scope representing the names imported into the g
iven library. | 15678 * Initialize a newly created scope representing the names imported into the g
iven library. |
| 15679 * | 15679 * |
| 15680 * @param definingLibrary the element representing the library that imports th
e names defined in | 15680 * @param definingLibrary the element representing the library that imports th
e names defined in |
| 15681 * this scope | 15681 * this scope |
| 15682 * @param errorListener the listener that is to be informed when an error is e
ncountered | 15682 * @param errorListener the listener that is to be informed when an error is e
ncountered |
| 15683 */ | 15683 */ |
| 15684 LibraryImportScope(LibraryElement definingLibrary, this.errorListener) { | 15684 LibraryImportScope(LibraryElement definingLibrary, this.errorListener) { |
| 15685 this._definingLibrary = definingLibrary; | 15685 this._definingLibrary = definingLibrary; |
| 15686 createImportedNamespaces(definingLibrary); | 15686 _createImportedNamespaces(definingLibrary); |
| 15687 } | 15687 } |
| 15688 | 15688 |
| 15689 void define(Element element) { | 15689 void define(Element element) { |
| 15690 if (!Scope.isPrivateName(element.displayName)) { | 15690 if (!Scope.isPrivateName(element.displayName)) { |
| 15691 super.define(element); | 15691 super.define(element); |
| 15692 } | 15692 } |
| 15693 } | 15693 } |
| 15694 | 15694 |
| 15695 Element internalLookup(Identifier identifier, String name, LibraryElement refe
rencingLibrary) { | 15695 Element internalLookup(Identifier identifier, String name, LibraryElement refe
rencingLibrary) { |
| 15696 Element foundElement = localLookup(name, referencingLibrary); | 15696 Element foundElement = localLookup(name, referencingLibrary); |
| 15697 if (foundElement != null) { | 15697 if (foundElement != null) { |
| 15698 return foundElement; | 15698 return foundElement; |
| 15699 } | 15699 } |
| 15700 for (Namespace nameSpace in _importedNamespaces) { | 15700 for (Namespace nameSpace in _importedNamespaces) { |
| 15701 Element element = nameSpace.get(name); | 15701 Element element = nameSpace.get(name); |
| 15702 if (element != null) { | 15702 if (element != null) { |
| 15703 if (foundElement == null) { | 15703 if (foundElement == null) { |
| 15704 foundElement = element; | 15704 foundElement = element; |
| 15705 } else if (foundElement != element) { | 15705 } else if (foundElement != element) { |
| 15706 foundElement = MultiplyDefinedElementImpl.fromElements(_definingLibrar
y.context, foundElement, element); | 15706 foundElement = MultiplyDefinedElementImpl.fromElements(_definingLibrar
y.context, foundElement, element); |
| 15707 } | 15707 } |
| 15708 } | 15708 } |
| 15709 } | 15709 } |
| 15710 if (foundElement is MultiplyDefinedElementImpl) { | 15710 if (foundElement is MultiplyDefinedElementImpl) { |
| 15711 foundElement = removeSdkElements(identifier, name, foundElement as Multipl
yDefinedElementImpl); | 15711 foundElement = _removeSdkElements(identifier, name, foundElement as Multip
lyDefinedElementImpl); |
| 15712 } | 15712 } |
| 15713 if (foundElement is MultiplyDefinedElementImpl) { | 15713 if (foundElement is MultiplyDefinedElementImpl) { |
| 15714 String foundEltName = foundElement.displayName; | 15714 String foundEltName = foundElement.displayName; |
| 15715 List<Element> conflictingMembers = (foundElement as MultiplyDefinedElement
Impl).conflictingElements; | 15715 List<Element> conflictingMembers = (foundElement as MultiplyDefinedElement
Impl).conflictingElements; |
| 15716 String libName1 = getLibraryName(conflictingMembers[0], ""); | 15716 String libName1 = _getLibraryName(conflictingMembers[0], ""); |
| 15717 String libName2 = getLibraryName(conflictingMembers[1], ""); | 15717 String libName2 = _getLibraryName(conflictingMembers[1], ""); |
| 15718 // TODO (jwren) Change the error message to include a list of all library
names instead of | 15718 // TODO (jwren) Change the error message to include a list of all library
names instead of |
| 15719 // just the first two | 15719 // just the first two |
| 15720 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltNam
e, libName1, libName2])); | 15720 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.AMBIGUOUS_IMPORT, [foundEltNam
e, libName1, libName2])); |
| 15721 return foundElement; | 15721 return foundElement; |
| 15722 } | 15722 } |
| 15723 if (foundElement != null) { | 15723 if (foundElement != null) { |
| 15724 defineNameWithoutChecking(name, foundElement); | 15724 defineNameWithoutChecking(name, foundElement); |
| 15725 } | 15725 } |
| 15726 return foundElement; | 15726 return foundElement; |
| 15727 } | 15727 } |
| 15728 | 15728 |
| 15729 /** | 15729 /** |
| 15730 * Create all of the namespaces associated with the libraries imported into th
is library. The | 15730 * Create all of the namespaces associated with the libraries imported into th
is library. The |
| 15731 * names are not added to this scope, but are stored for later reference. | 15731 * names are not added to this scope, but are stored for later reference. |
| 15732 * | 15732 * |
| 15733 * @param definingLibrary the element representing the library that imports th
e libraries for | 15733 * @param definingLibrary the element representing the library that imports th
e libraries for |
| 15734 * which namespaces will be created | 15734 * which namespaces will be created |
| 15735 */ | 15735 */ |
| 15736 void createImportedNamespaces(LibraryElement definingLibrary) { | 15736 void _createImportedNamespaces(LibraryElement definingLibrary) { |
| 15737 NamespaceBuilder builder = new NamespaceBuilder(); | 15737 NamespaceBuilder builder = new NamespaceBuilder(); |
| 15738 List<ImportElement> imports = definingLibrary.imports; | 15738 List<ImportElement> imports = definingLibrary.imports; |
| 15739 int count = imports.length; | 15739 int count = imports.length; |
| 15740 _importedNamespaces = new List<Namespace>(count); | 15740 _importedNamespaces = new List<Namespace>(count); |
| 15741 for (int i = 0; i < count; i++) { | 15741 for (int i = 0; i < count; i++) { |
| 15742 _importedNamespaces[i] = builder.createImportNamespaceForDirective(imports
[i]); | 15742 _importedNamespaces[i] = builder.createImportNamespaceForDirective(imports
[i]); |
| 15743 } | 15743 } |
| 15744 } | 15744 } |
| 15745 | 15745 |
| 15746 /** | 15746 /** |
| 15747 * Returns the name of the library that defines given element. | 15747 * Returns the name of the library that defines given element. |
| 15748 * | 15748 * |
| 15749 * @param element the element to get library name | 15749 * @param element the element to get library name |
| 15750 * @param def the default name to use | 15750 * @param def the default name to use |
| 15751 * @return the name of the library that defines given element | 15751 * @return the name of the library that defines given element |
| 15752 */ | 15752 */ |
| 15753 String getLibraryName(Element element, String def) { | 15753 String _getLibraryName(Element element, String def) { |
| 15754 if (element == null) { | 15754 if (element == null) { |
| 15755 return def; | 15755 return def; |
| 15756 } | 15756 } |
| 15757 LibraryElement library = element.library; | 15757 LibraryElement library = element.library; |
| 15758 if (library == null) { | 15758 if (library == null) { |
| 15759 return def; | 15759 return def; |
| 15760 } | 15760 } |
| 15761 return library.definingCompilationUnit.displayName; | 15761 return library.definingCompilationUnit.displayName; |
| 15762 } | 15762 } |
| 15763 | 15763 |
| 15764 /** | 15764 /** |
| 15765 * Given a collection of elements that a single name could all be mapped to, r
emove from the list | 15765 * Given a collection of elements that a single name could all be mapped to, r
emove from the list |
| 15766 * all of the names defined in the SDK. Return the element(s) that remain. | 15766 * all of the names defined in the SDK. Return the element(s) that remain. |
| 15767 * | 15767 * |
| 15768 * @param identifier the identifier node to lookup element for, used to report
correct kind of a | 15768 * @param identifier the identifier node to lookup element for, used to report
correct kind of a |
| 15769 * problem and associate problem with | 15769 * problem and associate problem with |
| 15770 * @param name the name associated with the element | 15770 * @param name the name associated with the element |
| 15771 * @param foundElement the element encapsulating the collection of elements | 15771 * @param foundElement the element encapsulating the collection of elements |
| 15772 * @return all of the elements that are not defined in the SDK | 15772 * @return all of the elements that are not defined in the SDK |
| 15773 */ | 15773 */ |
| 15774 Element removeSdkElements(Identifier identifier, String name, MultiplyDefinedE
lementImpl foundElement) { | 15774 Element _removeSdkElements(Identifier identifier, String name, MultiplyDefined
ElementImpl foundElement) { |
| 15775 List<Element> conflictingMembers = foundElement.conflictingElements; | 15775 List<Element> conflictingMembers = foundElement.conflictingElements; |
| 15776 int length = conflictingMembers.length; | 15776 int length = conflictingMembers.length; |
| 15777 int to = 0; | 15777 int to = 0; |
| 15778 Element sdkElement = null; | 15778 Element sdkElement = null; |
| 15779 for (Element member in conflictingMembers) { | 15779 for (Element member in conflictingMembers) { |
| 15780 if (member.library.isInSdk) { | 15780 if (member.library.isInSdk) { |
| 15781 sdkElement = member; | 15781 sdkElement = member; |
| 15782 } else { | 15782 } else { |
| 15783 conflictingMembers[to++] = member; | 15783 conflictingMembers[to++] = member; |
| 15784 } | 15784 } |
| 15785 } | 15785 } |
| 15786 if (sdkElement != null && to > 0) { | 15786 if (sdkElement != null && to > 0) { |
| 15787 String sdkLibName = getLibraryName(sdkElement, ""); | 15787 String sdkLibName = _getLibraryName(sdkElement, ""); |
| 15788 String otherLibName = getLibraryName(conflictingMembers[0], ""); | 15788 String otherLibName = _getLibraryName(conflictingMembers[0], ""); |
| 15789 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.CONFLICTING_DART_IMPORT, [name
, sdkLibName, otherLibName])); | 15789 errorListener.onError(new AnalysisError.con2(getSource(identifier), identi
fier.offset, identifier.length, StaticWarningCode.CONFLICTING_DART_IMPORT, [name
, sdkLibName, otherLibName])); |
| 15790 } | 15790 } |
| 15791 if (to == length) { | 15791 if (to == length) { |
| 15792 // None of the members were removed | 15792 // None of the members were removed |
| 15793 return foundElement; | 15793 return foundElement; |
| 15794 } else if (to == 1) { | 15794 } else if (to == 1) { |
| 15795 // All but one member was removed | 15795 // All but one member was removed |
| 15796 return conflictingMembers[0]; | 15796 return conflictingMembers[0]; |
| 15797 } else if (to == 0) { | 15797 } else if (to == 0) { |
| 15798 // All members were removed | 15798 // All members were removed |
| (...skipping 11 matching lines...) Expand all Loading... |
| 15810 * in a given library. | 15810 * in a given library. |
| 15811 */ | 15811 */ |
| 15812 class LibraryScope extends EnclosedScope { | 15812 class LibraryScope extends EnclosedScope { |
| 15813 /** | 15813 /** |
| 15814 * Initialize a newly created scope representing the names defined in the give
n library. | 15814 * Initialize a newly created scope representing the names defined in the give
n library. |
| 15815 * | 15815 * |
| 15816 * @param definingLibrary the element representing the library represented by
this scope | 15816 * @param definingLibrary the element representing the library represented by
this scope |
| 15817 * @param errorListener the listener that is to be informed when an error is e
ncountered | 15817 * @param errorListener the listener that is to be informed when an error is e
ncountered |
| 15818 */ | 15818 */ |
| 15819 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen
er) : super(new LibraryImportScope(definingLibrary, errorListener)) { | 15819 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen
er) : super(new LibraryImportScope(definingLibrary, errorListener)) { |
| 15820 defineTopLevelNames(definingLibrary); | 15820 _defineTopLevelNames(definingLibrary); |
| 15821 } | 15821 } |
| 15822 | 15822 |
| 15823 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 15823 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
| 15824 if (existing is PrefixElement) { | 15824 if (existing is PrefixElement) { |
| 15825 // TODO(scheglov) consider providing actual 'nameOffset' from the syntheti
c accessor | 15825 // TODO(scheglov) consider providing actual 'nameOffset' from the syntheti
c accessor |
| 15826 int offset = duplicate.nameOffset; | 15826 int offset = duplicate.nameOffset; |
| 15827 if (duplicate is PropertyAccessorElement) { | 15827 if (duplicate is PropertyAccessorElement) { |
| 15828 PropertyAccessorElement accessor = duplicate; | 15828 PropertyAccessorElement accessor = duplicate; |
| 15829 if (accessor.isSynthetic) { | 15829 if (accessor.isSynthetic) { |
| 15830 offset = accessor.variable.nameOffset; | 15830 offset = accessor.variable.nameOffset; |
| 15831 } | 15831 } |
| 15832 } | 15832 } |
| 15833 return new AnalysisError.con2(duplicate.source, offset, duplicate.displayN
ame.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existin
g.displayName]); | 15833 return new AnalysisError.con2(duplicate.source, offset, duplicate.displayN
ame.length, CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existin
g.displayName]); |
| 15834 } | 15834 } |
| 15835 return super.getErrorForDuplicate(existing, duplicate); | 15835 return super.getErrorForDuplicate(existing, duplicate); |
| 15836 } | 15836 } |
| 15837 | 15837 |
| 15838 /** | 15838 /** |
| 15839 * Add to this scope all of the public top-level names that are defined in the
given compilation | 15839 * Add to this scope all of the public top-level names that are defined in the
given compilation |
| 15840 * unit. | 15840 * unit. |
| 15841 * | 15841 * |
| 15842 * @param compilationUnit the compilation unit defining the top-level names to
be added to this | 15842 * @param compilationUnit the compilation unit defining the top-level names to
be added to this |
| 15843 * scope | 15843 * scope |
| 15844 */ | 15844 */ |
| 15845 void defineLocalNames(CompilationUnitElement compilationUnit) { | 15845 void _defineLocalNames(CompilationUnitElement compilationUnit) { |
| 15846 for (PropertyAccessorElement element in compilationUnit.accessors) { | 15846 for (PropertyAccessorElement element in compilationUnit.accessors) { |
| 15847 define(element); | 15847 define(element); |
| 15848 } | 15848 } |
| 15849 for (FunctionElement element in compilationUnit.functions) { | 15849 for (FunctionElement element in compilationUnit.functions) { |
| 15850 define(element); | 15850 define(element); |
| 15851 } | 15851 } |
| 15852 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases
) { | 15852 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases
) { |
| 15853 define(element); | 15853 define(element); |
| 15854 } | 15854 } |
| 15855 for (ClassElement element in compilationUnit.types) { | 15855 for (ClassElement element in compilationUnit.types) { |
| 15856 define(element); | 15856 define(element); |
| 15857 } | 15857 } |
| 15858 } | 15858 } |
| 15859 | 15859 |
| 15860 /** | 15860 /** |
| 15861 * Add to this scope all of the names that are explicitly defined in the given
library. | 15861 * Add to this scope all of the names that are explicitly defined in the given
library. |
| 15862 * | 15862 * |
| 15863 * @param definingLibrary the element representing the library that defines th
e names in this | 15863 * @param definingLibrary the element representing the library that defines th
e names in this |
| 15864 * scope | 15864 * scope |
| 15865 */ | 15865 */ |
| 15866 void defineTopLevelNames(LibraryElement definingLibrary) { | 15866 void _defineTopLevelNames(LibraryElement definingLibrary) { |
| 15867 for (PrefixElement prefix in definingLibrary.prefixes) { | 15867 for (PrefixElement prefix in definingLibrary.prefixes) { |
| 15868 define(prefix); | 15868 define(prefix); |
| 15869 } | 15869 } |
| 15870 defineLocalNames(definingLibrary.definingCompilationUnit); | 15870 _defineLocalNames(definingLibrary.definingCompilationUnit); |
| 15871 for (CompilationUnitElement compilationUnit in definingLibrary.parts) { | 15871 for (CompilationUnitElement compilationUnit in definingLibrary.parts) { |
| 15872 defineLocalNames(compilationUnit); | 15872 _defineLocalNames(compilationUnit); |
| 15873 } | 15873 } |
| 15874 } | 15874 } |
| 15875 } | 15875 } |
| 15876 | 15876 |
| 15877 /** | 15877 /** |
| 15878 * Instances of the class `Namespace` implement a mapping of identifiers to the
elements | 15878 * Instances of the class `Namespace` implement a mapping of identifiers to the
elements |
| 15879 * represented by those identifiers. Namespaces are the building blocks for scop
es. | 15879 * represented by those identifiers. Namespaces are the building blocks for scop
es. |
| 15880 */ | 15880 */ |
| 15881 class Namespace { | 15881 class Namespace { |
| 15882 /** | 15882 /** |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15929 * @return the export namespace that was created | 15929 * @return the export namespace that was created |
| 15930 */ | 15930 */ |
| 15931 Namespace createExportNamespaceForDirective(ExportElement element) { | 15931 Namespace createExportNamespaceForDirective(ExportElement element) { |
| 15932 LibraryElement exportedLibrary = element.exportedLibrary; | 15932 LibraryElement exportedLibrary = element.exportedLibrary; |
| 15933 if (exportedLibrary == null) { | 15933 if (exportedLibrary == null) { |
| 15934 // | 15934 // |
| 15935 // The exported library will be null if the URI does not reference a valid
library. | 15935 // The exported library will be null if the URI does not reference a valid
library. |
| 15936 // | 15936 // |
| 15937 return Namespace.EMPTY; | 15937 return Namespace.EMPTY; |
| 15938 } | 15938 } |
| 15939 Map<String, Element> definedNames = createExportMapping(exportedLibrary, new
Set<LibraryElement>()); | 15939 Map<String, Element> definedNames = _createExportMapping(exportedLibrary, ne
w Set<LibraryElement>()); |
| 15940 definedNames = applyCombinators(definedNames, element.combinators); | 15940 definedNames = _applyCombinators(definedNames, element.combinators); |
| 15941 return new Namespace(definedNames); | 15941 return new Namespace(definedNames); |
| 15942 } | 15942 } |
| 15943 | 15943 |
| 15944 /** | 15944 /** |
| 15945 * Create a namespace representing the export namespace of the given library. | 15945 * Create a namespace representing the export namespace of the given library. |
| 15946 * | 15946 * |
| 15947 * @param library the library whose export namespace is to be created | 15947 * @param library the library whose export namespace is to be created |
| 15948 * @return the export namespace that was created | 15948 * @return the export namespace that was created |
| 15949 */ | 15949 */ |
| 15950 Namespace createExportNamespaceForLibrary(LibraryElement library) => new Names
pace(createExportMapping(library, new Set<LibraryElement>())); | 15950 Namespace createExportNamespaceForLibrary(LibraryElement library) => new Names
pace(_createExportMapping(library, new Set<LibraryElement>())); |
| 15951 | 15951 |
| 15952 /** | 15952 /** |
| 15953 * Create a namespace representing the import namespace of the given library. | 15953 * Create a namespace representing the import namespace of the given library. |
| 15954 * | 15954 * |
| 15955 * @param library the library whose import namespace is to be created | 15955 * @param library the library whose import namespace is to be created |
| 15956 * @return the import namespace that was created | 15956 * @return the import namespace that was created |
| 15957 */ | 15957 */ |
| 15958 Namespace createImportNamespaceForDirective(ImportElement element) { | 15958 Namespace createImportNamespaceForDirective(ImportElement element) { |
| 15959 LibraryElement importedLibrary = element.importedLibrary; | 15959 LibraryElement importedLibrary = element.importedLibrary; |
| 15960 if (importedLibrary == null) { | 15960 if (importedLibrary == null) { |
| 15961 // | 15961 // |
| 15962 // The imported library will be null if the URI does not reference a valid
library. | 15962 // The imported library will be null if the URI does not reference a valid
library. |
| 15963 // | 15963 // |
| 15964 return Namespace.EMPTY; | 15964 return Namespace.EMPTY; |
| 15965 } | 15965 } |
| 15966 Map<String, Element> definedNames = createExportMapping(importedLibrary, new
Set<LibraryElement>()); | 15966 Map<String, Element> definedNames = _createExportMapping(importedLibrary, ne
w Set<LibraryElement>()); |
| 15967 definedNames = applyCombinators(definedNames, element.combinators); | 15967 definedNames = _applyCombinators(definedNames, element.combinators); |
| 15968 definedNames = applyPrefix(definedNames, element.prefix); | 15968 definedNames = _applyPrefix(definedNames, element.prefix); |
| 15969 return new Namespace(definedNames); | 15969 return new Namespace(definedNames); |
| 15970 } | 15970 } |
| 15971 | 15971 |
| 15972 /** | 15972 /** |
| 15973 * Create a namespace representing the public namespace of the given library. | 15973 * Create a namespace representing the public namespace of the given library. |
| 15974 * | 15974 * |
| 15975 * @param library the library whose public namespace is to be created | 15975 * @param library the library whose public namespace is to be created |
| 15976 * @return the public namespace that was created | 15976 * @return the public namespace that was created |
| 15977 */ | 15977 */ |
| 15978 Namespace createPublicNamespaceForLibrary(LibraryElement library) { | 15978 Namespace createPublicNamespaceForLibrary(LibraryElement library) { |
| 15979 Map<String, Element> definedNames = new Map<String, Element>(); | 15979 Map<String, Element> definedNames = new Map<String, Element>(); |
| 15980 addPublicNames(definedNames, library.definingCompilationUnit); | 15980 _addPublicNames(definedNames, library.definingCompilationUnit); |
| 15981 for (CompilationUnitElement compilationUnit in library.parts) { | 15981 for (CompilationUnitElement compilationUnit in library.parts) { |
| 15982 addPublicNames(definedNames, compilationUnit); | 15982 _addPublicNames(definedNames, compilationUnit); |
| 15983 } | 15983 } |
| 15984 return new Namespace(definedNames); | 15984 return new Namespace(definedNames); |
| 15985 } | 15985 } |
| 15986 | 15986 |
| 15987 /** | 15987 /** |
| 15988 * Add all of the names in the given namespace to the given mapping table. | 15988 * Add all of the names in the given namespace to the given mapping table. |
| 15989 * | 15989 * |
| 15990 * @param definedNames the mapping table to which the names in the given names
pace are to be added | 15990 * @param definedNames the mapping table to which the names in the given names
pace are to be added |
| 15991 * @param namespace the namespace containing the names to be added to this nam
espace | 15991 * @param namespace the namespace containing the names to be added to this nam
espace |
| 15992 */ | 15992 */ |
| 15993 void addAllFromMap(Map<String, Element> definedNames, Map<String, Element> new
Names) { | 15993 void _addAllFromMap(Map<String, Element> definedNames, Map<String, Element> ne
wNames) { |
| 15994 for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) { | 15994 for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) { |
| 15995 definedNames[entry.getKey()] = entry.getValue(); | 15995 definedNames[entry.getKey()] = entry.getValue(); |
| 15996 } | 15996 } |
| 15997 } | 15997 } |
| 15998 | 15998 |
| 15999 /** | 15999 /** |
| 16000 * Add all of the names in the given namespace to the given mapping table. | 16000 * Add all of the names in the given namespace to the given mapping table. |
| 16001 * | 16001 * |
| 16002 * @param definedNames the mapping table to which the names in the given names
pace are to be added | 16002 * @param definedNames the mapping table to which the names in the given names
pace are to be added |
| 16003 * @param namespace the namespace containing the names to be added to this nam
espace | 16003 * @param namespace the namespace containing the names to be added to this nam
espace |
| 16004 */ | 16004 */ |
| 16005 void addAllFromNamespace(Map<String, Element> definedNames, Namespace namespac
e) { | 16005 void _addAllFromNamespace(Map<String, Element> definedNames, Namespace namespa
ce) { |
| 16006 if (namespace != null) { | 16006 if (namespace != null) { |
| 16007 addAllFromMap(definedNames, namespace.definedNames); | 16007 _addAllFromMap(definedNames, namespace.definedNames); |
| 16008 } | 16008 } |
| 16009 } | 16009 } |
| 16010 | 16010 |
| 16011 /** | 16011 /** |
| 16012 * Add the given element to the given mapping table if it has a publicly visib
le name. | 16012 * Add the given element to the given mapping table if it has a publicly visib
le name. |
| 16013 * | 16013 * |
| 16014 * @param definedNames the mapping table to which the public name is to be add
ed | 16014 * @param definedNames the mapping table to which the public name is to be add
ed |
| 16015 * @param element the element to be added | 16015 * @param element the element to be added |
| 16016 */ | 16016 */ |
| 16017 void addIfPublic(Map<String, Element> definedNames, Element element) { | 16017 void _addIfPublic(Map<String, Element> definedNames, Element element) { |
| 16018 String name = element.name; | 16018 String name = element.name; |
| 16019 if (name != null && !Scope.isPrivateName(name)) { | 16019 if (name != null && !Scope.isPrivateName(name)) { |
| 16020 definedNames[name] = element; | 16020 definedNames[name] = element; |
| 16021 } | 16021 } |
| 16022 } | 16022 } |
| 16023 | 16023 |
| 16024 /** | 16024 /** |
| 16025 * Add to the given mapping table all of the public top-level names that are d
efined in the given | 16025 * Add to the given mapping table all of the public top-level names that are d
efined in the given |
| 16026 * compilation unit. | 16026 * compilation unit. |
| 16027 * | 16027 * |
| 16028 * @param definedNames the mapping table to which the public names are to be a
dded | 16028 * @param definedNames the mapping table to which the public names are to be a
dded |
| 16029 * @param compilationUnit the compilation unit defining the top-level names to
be added to this | 16029 * @param compilationUnit the compilation unit defining the top-level names to
be added to this |
| 16030 * namespace | 16030 * namespace |
| 16031 */ | 16031 */ |
| 16032 void addPublicNames(Map<String, Element> definedNames, CompilationUnitElement
compilationUnit) { | 16032 void _addPublicNames(Map<String, Element> definedNames, CompilationUnitElement
compilationUnit) { |
| 16033 for (PropertyAccessorElement element in compilationUnit.accessors) { | 16033 for (PropertyAccessorElement element in compilationUnit.accessors) { |
| 16034 addIfPublic(definedNames, element); | 16034 _addIfPublic(definedNames, element); |
| 16035 } | 16035 } |
| 16036 for (FunctionElement element in compilationUnit.functions) { | 16036 for (FunctionElement element in compilationUnit.functions) { |
| 16037 addIfPublic(definedNames, element); | 16037 _addIfPublic(definedNames, element); |
| 16038 } | 16038 } |
| 16039 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases
) { | 16039 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases
) { |
| 16040 addIfPublic(definedNames, element); | 16040 _addIfPublic(definedNames, element); |
| 16041 } | 16041 } |
| 16042 for (ClassElement element in compilationUnit.types) { | 16042 for (ClassElement element in compilationUnit.types) { |
| 16043 addIfPublic(definedNames, element); | 16043 _addIfPublic(definedNames, element); |
| 16044 } | 16044 } |
| 16045 } | 16045 } |
| 16046 | 16046 |
| 16047 /** | 16047 /** |
| 16048 * Apply the given combinators to all of the names in the given mapping table. | 16048 * Apply the given combinators to all of the names in the given mapping table. |
| 16049 * | 16049 * |
| 16050 * @param definedNames the mapping table to which the namespace operations are
to be applied | 16050 * @param definedNames the mapping table to which the namespace operations are
to be applied |
| 16051 * @param combinators the combinators to be applied | 16051 * @param combinators the combinators to be applied |
| 16052 */ | 16052 */ |
| 16053 Map<String, Element> applyCombinators(Map<String, Element> definedNames, List<
NamespaceCombinator> combinators) { | 16053 Map<String, Element> _applyCombinators(Map<String, Element> definedNames, List
<NamespaceCombinator> combinators) { |
| 16054 for (NamespaceCombinator combinator in combinators) { | 16054 for (NamespaceCombinator combinator in combinators) { |
| 16055 if (combinator is HideElementCombinator) { | 16055 if (combinator is HideElementCombinator) { |
| 16056 hide(definedNames, combinator.hiddenNames); | 16056 _hide(definedNames, combinator.hiddenNames); |
| 16057 } else if (combinator is ShowElementCombinator) { | 16057 } else if (combinator is ShowElementCombinator) { |
| 16058 definedNames = show(definedNames, combinator.shownNames); | 16058 definedNames = _show(definedNames, combinator.shownNames); |
| 16059 } else { | 16059 } else { |
| 16060 // Internal error. | 16060 // Internal error. |
| 16061 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c
ombinator.runtimeType.toString()}"); | 16061 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c
ombinator.runtimeType.toString()}"); |
| 16062 } | 16062 } |
| 16063 } | 16063 } |
| 16064 return definedNames; | 16064 return definedNames; |
| 16065 } | 16065 } |
| 16066 | 16066 |
| 16067 /** | 16067 /** |
| 16068 * Apply the given prefix to all of the names in the table of defined names. | 16068 * Apply the given prefix to all of the names in the table of defined names. |
| 16069 * | 16069 * |
| 16070 * @param definedNames the names that were defined before this operation | 16070 * @param definedNames the names that were defined before this operation |
| 16071 * @param prefixElement the element defining the prefix to be added to the nam
es | 16071 * @param prefixElement the element defining the prefix to be added to the nam
es |
| 16072 */ | 16072 */ |
| 16073 Map<String, Element> applyPrefix(Map<String, Element> definedNames, PrefixElem
ent prefixElement) { | 16073 Map<String, Element> _applyPrefix(Map<String, Element> definedNames, PrefixEle
ment prefixElement) { |
| 16074 if (prefixElement != null) { | 16074 if (prefixElement != null) { |
| 16075 String prefix = prefixElement.name; | 16075 String prefix = prefixElement.name; |
| 16076 Map<String, Element> newNames = new Map<String, Element>(); | 16076 Map<String, Element> newNames = new Map<String, Element>(); |
| 16077 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) { | 16077 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) { |
| 16078 newNames["${prefix}.${entry.getKey()}"] = entry.getValue(); | 16078 newNames["${prefix}.${entry.getKey()}"] = entry.getValue(); |
| 16079 } | 16079 } |
| 16080 return newNames; | 16080 return newNames; |
| 16081 } else { | 16081 } else { |
| 16082 return definedNames; | 16082 return definedNames; |
| 16083 } | 16083 } |
| 16084 } | 16084 } |
| 16085 | 16085 |
| 16086 /** | 16086 /** |
| 16087 * Create a mapping table representing the export namespace of the given libra
ry. | 16087 * Create a mapping table representing the export namespace of the given libra
ry. |
| 16088 * | 16088 * |
| 16089 * @param library the library whose public namespace is to be created | 16089 * @param library the library whose public namespace is to be created |
| 16090 * @param visitedElements a set of libraries that do not need to be visited wh
en processing the | 16090 * @param visitedElements a set of libraries that do not need to be visited wh
en processing the |
| 16091 * export directives of the given library because all of the names de
fined by them will | 16091 * export directives of the given library because all of the names de
fined by them will |
| 16092 * be added by another library | 16092 * be added by another library |
| 16093 * @return the mapping table that was created | 16093 * @return the mapping table that was created |
| 16094 */ | 16094 */ |
| 16095 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl
ement> visitedElements) { | 16095 Map<String, Element> _createExportMapping(LibraryElement library, Set<LibraryE
lement> visitedElements) { |
| 16096 visitedElements.add(library); | 16096 visitedElements.add(library); |
| 16097 try { | 16097 try { |
| 16098 Map<String, Element> definedNames = new Map<String, Element>(); | 16098 Map<String, Element> definedNames = new Map<String, Element>(); |
| 16099 for (ExportElement element in library.exports) { | 16099 for (ExportElement element in library.exports) { |
| 16100 LibraryElement exportedLibrary = element.exportedLibrary; | 16100 LibraryElement exportedLibrary = element.exportedLibrary; |
| 16101 if (exportedLibrary != null && !visitedElements.contains(exportedLibrary
)) { | 16101 if (exportedLibrary != null && !visitedElements.contains(exportedLibrary
)) { |
| 16102 // | 16102 // |
| 16103 // The exported library will be null if the URI does not reference a v
alid library. | 16103 // The exported library will be null if the URI does not reference a v
alid library. |
| 16104 // | 16104 // |
| 16105 Map<String, Element> exportedNames = createExportMapping(exportedLibra
ry, visitedElements); | 16105 Map<String, Element> exportedNames = _createExportMapping(exportedLibr
ary, visitedElements); |
| 16106 exportedNames = applyCombinators(exportedNames, element.combinators); | 16106 exportedNames = _applyCombinators(exportedNames, element.combinators); |
| 16107 addAllFromMap(definedNames, exportedNames); | 16107 _addAllFromMap(definedNames, exportedNames); |
| 16108 } | 16108 } |
| 16109 } | 16109 } |
| 16110 addAllFromNamespace(definedNames, (library.context as InternalAnalysisCont
ext).getPublicNamespace(library)); | 16110 _addAllFromNamespace(definedNames, (library.context as InternalAnalysisCon
text).getPublicNamespace(library)); |
| 16111 return definedNames; | 16111 return definedNames; |
| 16112 } finally { | 16112 } finally { |
| 16113 visitedElements.remove(library); | 16113 visitedElements.remove(library); |
| 16114 } | 16114 } |
| 16115 } | 16115 } |
| 16116 | 16116 |
| 16117 /** | 16117 /** |
| 16118 * Hide all of the given names by removing them from the given collection of d
efined names. | 16118 * Hide all of the given names by removing them from the given collection of d
efined names. |
| 16119 * | 16119 * |
| 16120 * @param definedNames the names that were defined before this operation | 16120 * @param definedNames the names that were defined before this operation |
| 16121 * @param hiddenNames the names to be hidden | 16121 * @param hiddenNames the names to be hidden |
| 16122 */ | 16122 */ |
| 16123 void hide(Map<String, Element> definedNames, List<String> hiddenNames) { | 16123 void _hide(Map<String, Element> definedNames, List<String> hiddenNames) { |
| 16124 for (String name in hiddenNames) { | 16124 for (String name in hiddenNames) { |
| 16125 definedNames.remove(name); | 16125 definedNames.remove(name); |
| 16126 definedNames.remove("${name}="); | 16126 definedNames.remove("${name}="); |
| 16127 } | 16127 } |
| 16128 } | 16128 } |
| 16129 | 16129 |
| 16130 /** | 16130 /** |
| 16131 * Show only the given names by removing all other names from the given collec
tion of defined | 16131 * Show only the given names by removing all other names from the given collec
tion of defined |
| 16132 * names. | 16132 * names. |
| 16133 * | 16133 * |
| 16134 * @param definedNames the names that were defined before this operation | 16134 * @param definedNames the names that were defined before this operation |
| 16135 * @param shownNames the names to be shown | 16135 * @param shownNames the names to be shown |
| 16136 */ | 16136 */ |
| 16137 Map<String, Element> show(Map<String, Element> definedNames, List<String> show
nNames) { | 16137 Map<String, Element> _show(Map<String, Element> definedNames, List<String> sho
wnNames) { |
| 16138 Map<String, Element> newNames = new Map<String, Element>(); | 16138 Map<String, Element> newNames = new Map<String, Element>(); |
| 16139 for (String name in shownNames) { | 16139 for (String name in shownNames) { |
| 16140 Element element = definedNames[name]; | 16140 Element element = definedNames[name]; |
| 16141 if (element != null) { | 16141 if (element != null) { |
| 16142 newNames[name] = element; | 16142 newNames[name] = element; |
| 16143 } | 16143 } |
| 16144 String setterName = "${name}="; | 16144 String setterName = "${name}="; |
| 16145 element = definedNames[setterName]; | 16145 element = definedNames[setterName]; |
| 16146 if (element != null) { | 16146 if (element != null) { |
| 16147 newNames[setterName] = element; | 16147 newNames[setterName] = element; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16194 | 16194 |
| 16195 /** | 16195 /** |
| 16196 * Add the given element to this scope. If there is already an element with th
e given name defined | 16196 * Add the given element to this scope. If there is already an element with th
e given name defined |
| 16197 * in this scope, then an error will be generated and the original element wil
l continue to be | 16197 * in this scope, then an error will be generated and the original element wil
l continue to be |
| 16198 * mapped to the name. If there is an element with the given name in an enclos
ing scope, then a | 16198 * mapped to the name. If there is an element with the given name in an enclos
ing scope, then a |
| 16199 * warning will be generated but the given element will hide the inherited ele
ment. | 16199 * warning will be generated but the given element will hide the inherited ele
ment. |
| 16200 * | 16200 * |
| 16201 * @param element the element to be added to this scope | 16201 * @param element the element to be added to this scope |
| 16202 */ | 16202 */ |
| 16203 void define(Element element) { | 16203 void define(Element element) { |
| 16204 String name = getName(element); | 16204 String name = _getName(element); |
| 16205 if (name != null && !name.isEmpty) { | 16205 if (name != null && !name.isEmpty) { |
| 16206 if (_definedNames.containsKey(name)) { | 16206 if (_definedNames.containsKey(name)) { |
| 16207 errorListener.onError(getErrorForDuplicate(_definedNames[name], element)
); | 16207 errorListener.onError(getErrorForDuplicate(_definedNames[name], element)
); |
| 16208 } else { | 16208 } else { |
| 16209 _definedNames[name] = element; | 16209 _definedNames[name] = element; |
| 16210 _hasName = true; | 16210 _hasName = true; |
| 16211 } | 16211 } |
| 16212 } | 16212 } |
| 16213 } | 16213 } |
| 16214 | 16214 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 16240 _definedNames[name] = element; | 16240 _definedNames[name] = element; |
| 16241 _hasName = true; | 16241 _hasName = true; |
| 16242 } | 16242 } |
| 16243 | 16243 |
| 16244 /** | 16244 /** |
| 16245 * Add the given element to this scope without checking for duplication or hid
ing. | 16245 * Add the given element to this scope without checking for duplication or hid
ing. |
| 16246 * | 16246 * |
| 16247 * @param element the element to be added to this scope | 16247 * @param element the element to be added to this scope |
| 16248 */ | 16248 */ |
| 16249 void defineWithoutChecking(Element element) { | 16249 void defineWithoutChecking(Element element) { |
| 16250 _definedNames[getName(element)] = element; | 16250 _definedNames[_getName(element)] = element; |
| 16251 _hasName = true; | 16251 _hasName = true; |
| 16252 } | 16252 } |
| 16253 | 16253 |
| 16254 /** | 16254 /** |
| 16255 * Return the error code to be used when reporting that a name being defined l
ocally conflicts | 16255 * Return the error code to be used when reporting that a name being defined l
ocally conflicts |
| 16256 * with another element of the same name in the local scope. | 16256 * with another element of the same name in the local scope. |
| 16257 * | 16257 * |
| 16258 * @param existing the first element to be declared with the conflicting name | 16258 * @param existing the first element to be declared with the conflicting name |
| 16259 * @param duplicate another element declared with the conflicting name | 16259 * @param duplicate another element declared with the conflicting name |
| 16260 * @return the error code used to report duplicate names within a scope | 16260 * @return the error code used to report duplicate names within a scope |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16321 } | 16321 } |
| 16322 return null; | 16322 return null; |
| 16323 } | 16323 } |
| 16324 | 16324 |
| 16325 /** | 16325 /** |
| 16326 * Return the name that will be used to look up the given element. | 16326 * Return the name that will be used to look up the given element. |
| 16327 * | 16327 * |
| 16328 * @param element the element whose look-up name is to be returned | 16328 * @param element the element whose look-up name is to be returned |
| 16329 * @return the name that will be used to look up the given element | 16329 * @return the name that will be used to look up the given element |
| 16330 */ | 16330 */ |
| 16331 String getName(Element element) { | 16331 String _getName(Element element) { |
| 16332 if (element is MethodElement) { | 16332 if (element is MethodElement) { |
| 16333 MethodElement method = element; | 16333 MethodElement method = element; |
| 16334 if (method.name == "-" && method.parameters.length == 0) { | 16334 if (method.name == "-" && method.parameters.length == 0) { |
| 16335 return UNARY_MINUS; | 16335 return UNARY_MINUS; |
| 16336 } | 16336 } |
| 16337 } | 16337 } |
| 16338 return element.name; | 16338 return element.name; |
| 16339 } | 16339 } |
| 16340 } | 16340 } |
| 16341 | 16341 |
| 16342 /** | 16342 /** |
| 16343 * Instances of the class `ScopeBuilder` build the scope for a given node in an
AST structure. | 16343 * Instances of the class `ScopeBuilder` build the scope for a given node in an
AST structure. |
| 16344 * At the moment, this class only handles top-level and class-level declarations
. | 16344 * At the moment, this class only handles top-level and class-level declarations
. |
| 16345 */ | 16345 */ |
| 16346 class ScopeBuilder { | 16346 class ScopeBuilder { |
| 16347 /** | 16347 /** |
| 16348 * Return the scope in which the given AST structure should be resolved. | 16348 * Return the scope in which the given AST structure should be resolved. |
| 16349 * | 16349 * |
| 16350 * @param node the root of the AST structure to be resolved | 16350 * @param node the root of the AST structure to be resolved |
| 16351 * @param errorListener the listener to which analysis errors will be reported | 16351 * @param errorListener the listener to which analysis errors will be reported |
| 16352 * @return the scope in which the given AST structure should be resolved | 16352 * @return the scope in which the given AST structure should be resolved |
| 16353 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a | 16353 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a |
| 16354 * [CompilationUnit] | 16354 * [CompilationUnit] |
| 16355 */ | 16355 */ |
| 16356 static Scope scopeFor(AstNode node, AnalysisErrorListener errorListener) { | 16356 static Scope scopeFor(AstNode node, AnalysisErrorListener errorListener) { |
| 16357 if (node == null) { | 16357 if (node == null) { |
| 16358 throw new AnalysisException.con1("Cannot create scope: node is null"); | 16358 throw new AnalysisException.con1("Cannot create scope: node is null"); |
| 16359 } else if (node is CompilationUnit) { | 16359 } else if (node is CompilationUnit) { |
| 16360 ScopeBuilder builder = new ScopeBuilder(errorListener); | 16360 ScopeBuilder builder = new ScopeBuilder(errorListener); |
| 16361 return builder.scopeForAstNode(node); | 16361 return builder._scopeForAstNode(node); |
| 16362 } | 16362 } |
| 16363 AstNode parent = node.parent; | 16363 AstNode parent = node.parent; |
| 16364 if (parent == null) { | 16364 if (parent == null) { |
| 16365 throw new AnalysisException.con1("Cannot create scope: node is not part of
a CompilationUnit"); | 16365 throw new AnalysisException.con1("Cannot create scope: node is not part of
a CompilationUnit"); |
| 16366 } | 16366 } |
| 16367 ScopeBuilder builder = new ScopeBuilder(errorListener); | 16367 ScopeBuilder builder = new ScopeBuilder(errorListener); |
| 16368 return builder.scopeForAstNode(parent); | 16368 return builder._scopeForAstNode(parent); |
| 16369 } | 16369 } |
| 16370 | 16370 |
| 16371 /** | 16371 /** |
| 16372 * The listener to which analysis errors will be reported. | 16372 * The listener to which analysis errors will be reported. |
| 16373 */ | 16373 */ |
| 16374 AnalysisErrorListener _errorListener; | 16374 AnalysisErrorListener _errorListener; |
| 16375 | 16375 |
| 16376 /** | 16376 /** |
| 16377 * Initialize a newly created scope builder to generate a scope that will repo
rt errors to the | 16377 * Initialize a newly created scope builder to generate a scope that will repo
rt errors to the |
| 16378 * given listener. | 16378 * given listener. |
| 16379 * | 16379 * |
| 16380 * @param errorListener the listener to which analysis errors will be reported | 16380 * @param errorListener the listener to which analysis errors will be reported |
| 16381 */ | 16381 */ |
| 16382 ScopeBuilder(AnalysisErrorListener errorListener) { | 16382 ScopeBuilder(AnalysisErrorListener errorListener) { |
| 16383 this._errorListener = errorListener; | 16383 this._errorListener = errorListener; |
| 16384 } | 16384 } |
| 16385 | 16385 |
| 16386 /** | 16386 /** |
| 16387 * Return the scope in which the given AST structure should be resolved. | 16387 * Return the scope in which the given AST structure should be resolved. |
| 16388 * | 16388 * |
| 16389 * <b>Note:</b> This method needs to be kept in sync with | 16389 * <b>Note:</b> This method needs to be kept in sync with |
| 16390 * [IncrementalResolver#canBeResolved]. | 16390 * [IncrementalResolver#canBeResolved]. |
| 16391 * | 16391 * |
| 16392 * @param node the root of the AST structure to be resolved | 16392 * @param node the root of the AST structure to be resolved |
| 16393 * @return the scope in which the given AST structure should be resolved | 16393 * @return the scope in which the given AST structure should be resolved |
| 16394 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a | 16394 * @throws AnalysisException if the AST structure has not been resolved or is
not part of a |
| 16395 * [CompilationUnit] | 16395 * [CompilationUnit] |
| 16396 */ | 16396 */ |
| 16397 Scope scopeForAstNode(AstNode node) { | 16397 Scope _scopeForAstNode(AstNode node) { |
| 16398 if (node is CompilationUnit) { | 16398 if (node is CompilationUnit) { |
| 16399 return scopeForCompilationUnit(node); | 16399 return _scopeForCompilationUnit(node); |
| 16400 } | 16400 } |
| 16401 AstNode parent = node.parent; | 16401 AstNode parent = node.parent; |
| 16402 if (parent == null) { | 16402 if (parent == null) { |
| 16403 throw new AnalysisException.con1("Cannot create scope: node is not part of
a CompilationUnit"); | 16403 throw new AnalysisException.con1("Cannot create scope: node is not part of
a CompilationUnit"); |
| 16404 } | 16404 } |
| 16405 Scope scope = scopeForAstNode(parent); | 16405 Scope scope = _scopeForAstNode(parent); |
| 16406 if (node is ClassDeclaration) { | 16406 if (node is ClassDeclaration) { |
| 16407 scope = new ClassScope(scope, node.element); | 16407 scope = new ClassScope(scope, node.element); |
| 16408 } else if (node is ClassTypeAlias) { | 16408 } else if (node is ClassTypeAlias) { |
| 16409 scope = new ClassScope(scope, node.element); | 16409 scope = new ClassScope(scope, node.element); |
| 16410 } else if (node is ConstructorDeclaration) { | 16410 } else if (node is ConstructorDeclaration) { |
| 16411 FunctionScope functionScope = new FunctionScope(scope, node.element); | 16411 FunctionScope functionScope = new FunctionScope(scope, node.element); |
| 16412 functionScope.defineParameters(); | 16412 functionScope.defineParameters(); |
| 16413 scope = functionScope; | 16413 scope = functionScope; |
| 16414 } else if (node is FunctionDeclaration) { | 16414 } else if (node is FunctionDeclaration) { |
| 16415 FunctionScope functionScope = new FunctionScope(scope, node.element); | 16415 FunctionScope functionScope = new FunctionScope(scope, node.element); |
| 16416 functionScope.defineParameters(); | 16416 functionScope.defineParameters(); |
| 16417 scope = functionScope; | 16417 scope = functionScope; |
| 16418 } else if (node is FunctionTypeAlias) { | 16418 } else if (node is FunctionTypeAlias) { |
| 16419 scope = new FunctionTypeScope(scope, node.element); | 16419 scope = new FunctionTypeScope(scope, node.element); |
| 16420 } else if (node is MethodDeclaration) { | 16420 } else if (node is MethodDeclaration) { |
| 16421 FunctionScope functionScope = new FunctionScope(scope, node.element); | 16421 FunctionScope functionScope = new FunctionScope(scope, node.element); |
| 16422 functionScope.defineParameters(); | 16422 functionScope.defineParameters(); |
| 16423 scope = functionScope; | 16423 scope = functionScope; |
| 16424 } | 16424 } |
| 16425 return scope; | 16425 return scope; |
| 16426 } | 16426 } |
| 16427 | 16427 |
| 16428 Scope scopeForCompilationUnit(CompilationUnit node) { | 16428 Scope _scopeForCompilationUnit(CompilationUnit node) { |
| 16429 CompilationUnitElement unitElement = node.element; | 16429 CompilationUnitElement unitElement = node.element; |
| 16430 if (unitElement == null) { | 16430 if (unitElement == null) { |
| 16431 throw new AnalysisException.con1("Cannot create scope: compilation unit is
not resolved"); | 16431 throw new AnalysisException.con1("Cannot create scope: compilation unit is
not resolved"); |
| 16432 } | 16432 } |
| 16433 LibraryElement libraryElement = unitElement.library; | 16433 LibraryElement libraryElement = unitElement.library; |
| 16434 if (libraryElement == null) { | 16434 if (libraryElement == null) { |
| 16435 throw new AnalysisException.con1("Cannot create scope: compilation unit is
not part of a library"); | 16435 throw new AnalysisException.con1("Cannot create scope: compilation unit is
not part of a library"); |
| 16436 } | 16436 } |
| 16437 return new LibraryScope(libraryElement, _errorListener); | 16437 return new LibraryScope(libraryElement, _errorListener); |
| 16438 } | 16438 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16499 _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_CONSTANT_ANNO
TATION_CONSTRUCTOR, node, []); | 16499 _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_CONSTANT_ANNO
TATION_CONSTRUCTOR, node, []); |
| 16500 return null; | 16500 return null; |
| 16501 } | 16501 } |
| 16502 // should have arguments | 16502 // should have arguments |
| 16503 ArgumentList argumentList = node.arguments; | 16503 ArgumentList argumentList = node.arguments; |
| 16504 if (argumentList == null) { | 16504 if (argumentList == null) { |
| 16505 _errorReporter.reportErrorForNode(CompileTimeErrorCode.NO_ANNOTATION_CON
STRUCTOR_ARGUMENTS, node, []); | 16505 _errorReporter.reportErrorForNode(CompileTimeErrorCode.NO_ANNOTATION_CON
STRUCTOR_ARGUMENTS, node, []); |
| 16506 return null; | 16506 return null; |
| 16507 } | 16507 } |
| 16508 // arguments should be constants | 16508 // arguments should be constants |
| 16509 validateConstantArguments(argumentList); | 16509 _validateConstantArguments(argumentList); |
| 16510 } | 16510 } |
| 16511 return null; | 16511 return null; |
| 16512 } | 16512 } |
| 16513 | 16513 |
| 16514 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 16514 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 16515 if (node.constKeyword != null) { | 16515 if (node.constKeyword != null) { |
| 16516 validateInitializers(node); | 16516 _validateInitializers(node); |
| 16517 } | 16517 } |
| 16518 validateDefaultValues(node.parameters); | 16518 _validateDefaultValues(node.parameters); |
| 16519 return super.visitConstructorDeclaration(node); | 16519 return super.visitConstructorDeclaration(node); |
| 16520 } | 16520 } |
| 16521 | 16521 |
| 16522 Object visitFunctionExpression(FunctionExpression node) { | 16522 Object visitFunctionExpression(FunctionExpression node) { |
| 16523 super.visitFunctionExpression(node); | 16523 super.visitFunctionExpression(node); |
| 16524 validateDefaultValues(node.parameters); | 16524 _validateDefaultValues(node.parameters); |
| 16525 return null; | 16525 return null; |
| 16526 } | 16526 } |
| 16527 | 16527 |
| 16528 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 16528 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 16529 validateInstanceCreationArguments(node); | 16529 _validateInstanceCreationArguments(node); |
| 16530 return super.visitInstanceCreationExpression(node); | 16530 return super.visitInstanceCreationExpression(node); |
| 16531 } | 16531 } |
| 16532 | 16532 |
| 16533 Object visitListLiteral(ListLiteral node) { | 16533 Object visitListLiteral(ListLiteral node) { |
| 16534 super.visitListLiteral(node); | 16534 super.visitListLiteral(node); |
| 16535 if (node.constKeyword != null) { | 16535 if (node.constKeyword != null) { |
| 16536 for (Expression element in node.elements) { | 16536 for (Expression element in node.elements) { |
| 16537 validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT); | 16537 _validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT); |
| 16538 } | 16538 } |
| 16539 } | 16539 } |
| 16540 return null; | 16540 return null; |
| 16541 } | 16541 } |
| 16542 | 16542 |
| 16543 Object visitMapLiteral(MapLiteral node) { | 16543 Object visitMapLiteral(MapLiteral node) { |
| 16544 super.visitMapLiteral(node); | 16544 super.visitMapLiteral(node); |
| 16545 bool isConst = node.constKeyword != null; | 16545 bool isConst = node.constKeyword != null; |
| 16546 bool reportEqualKeys = true; | 16546 bool reportEqualKeys = true; |
| 16547 Set<DartObject> keys = new Set<DartObject>(); | 16547 Set<DartObject> keys = new Set<DartObject>(); |
| 16548 List<Expression> invalidKeys = new List<Expression>(); | 16548 List<Expression> invalidKeys = new List<Expression>(); |
| 16549 for (MapLiteralEntry entry in node.entries) { | 16549 for (MapLiteralEntry entry in node.entries) { |
| 16550 Expression key = entry.key; | 16550 Expression key = entry.key; |
| 16551 if (isConst) { | 16551 if (isConst) { |
| 16552 EvaluationResultImpl result = validate(key, CompileTimeErrorCode.NON_CON
STANT_MAP_KEY); | 16552 EvaluationResultImpl result = _validate(key, CompileTimeErrorCode.NON_CO
NSTANT_MAP_KEY); |
| 16553 validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE); | 16553 _validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE); |
| 16554 if (result is ValidResult) { | 16554 if (result is ValidResult) { |
| 16555 DartObject value = result.value; | 16555 DartObject value = result.value; |
| 16556 if (keys.contains(value)) { | 16556 if (keys.contains(value)) { |
| 16557 invalidKeys.add(key); | 16557 invalidKeys.add(key); |
| 16558 } else { | 16558 } else { |
| 16559 keys.add(value); | 16559 keys.add(value); |
| 16560 } | 16560 } |
| 16561 } | 16561 } |
| 16562 } else { | 16562 } else { |
| 16563 EvaluationResultImpl result = key.accept(new ConstantVisitor(_typeProvid
er)); | 16563 EvaluationResultImpl result = key.accept(new ConstantVisitor(_typeProvid
er)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 16576 if (reportEqualKeys) { | 16576 if (reportEqualKeys) { |
| 16577 for (Expression key in invalidKeys) { | 16577 for (Expression key in invalidKeys) { |
| 16578 _errorReporter.reportErrorForNode(StaticWarningCode.EQUAL_KEYS_IN_MAP, k
ey, []); | 16578 _errorReporter.reportErrorForNode(StaticWarningCode.EQUAL_KEYS_IN_MAP, k
ey, []); |
| 16579 } | 16579 } |
| 16580 } | 16580 } |
| 16581 return null; | 16581 return null; |
| 16582 } | 16582 } |
| 16583 | 16583 |
| 16584 Object visitMethodDeclaration(MethodDeclaration node) { | 16584 Object visitMethodDeclaration(MethodDeclaration node) { |
| 16585 super.visitMethodDeclaration(node); | 16585 super.visitMethodDeclaration(node); |
| 16586 validateDefaultValues(node.parameters); | 16586 _validateDefaultValues(node.parameters); |
| 16587 return null; | 16587 return null; |
| 16588 } | 16588 } |
| 16589 | 16589 |
| 16590 Object visitSwitchCase(SwitchCase node) { | 16590 Object visitSwitchCase(SwitchCase node) { |
| 16591 super.visitSwitchCase(node); | 16591 super.visitSwitchCase(node); |
| 16592 validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION)
; | 16592 _validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION
); |
| 16593 return null; | 16593 return null; |
| 16594 } | 16594 } |
| 16595 | 16595 |
| 16596 Object visitVariableDeclaration(VariableDeclaration node) { | 16596 Object visitVariableDeclaration(VariableDeclaration node) { |
| 16597 super.visitVariableDeclaration(node); | 16597 super.visitVariableDeclaration(node); |
| 16598 Expression initializer = node.initializer; | 16598 Expression initializer = node.initializer; |
| 16599 if (initializer != null && node.isConst) { | 16599 if (initializer != null && node.isConst) { |
| 16600 VariableElementImpl element = node.element as VariableElementImpl; | 16600 VariableElementImpl element = node.element as VariableElementImpl; |
| 16601 EvaluationResultImpl result = element.evaluationResult; | 16601 EvaluationResultImpl result = element.evaluationResult; |
| 16602 if (result == null) { | 16602 if (result == null) { |
| 16603 // | 16603 // |
| 16604 // Normally we don't need to visit const variable declarations because w
e have already | 16604 // Normally we don't need to visit const variable declarations because w
e have already |
| 16605 // computed their values. But if we missed it for some reason, this give
s us a second | 16605 // computed their values. But if we missed it for some reason, this give
s us a second |
| 16606 // chance. | 16606 // chance. |
| 16607 // | 16607 // |
| 16608 result = validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_WI
TH_NON_CONSTANT_VALUE); | 16608 result = _validate(initializer, CompileTimeErrorCode.CONST_INITIALIZED_W
ITH_NON_CONSTANT_VALUE); |
| 16609 element.evaluationResult = result; | 16609 element.evaluationResult = result; |
| 16610 } else if (result is ErrorResult) { | 16610 } else if (result is ErrorResult) { |
| 16611 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON
STANT_VALUE); | 16611 _reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CO
NSTANT_VALUE); |
| 16612 } | 16612 } |
| 16613 } | 16613 } |
| 16614 return null; | 16614 return null; |
| 16615 } | 16615 } |
| 16616 | 16616 |
| 16617 /** | 16617 /** |
| 16618 * If the given result represents one or more errors, report those errors. Exc
ept for special | 16618 * If the given result represents one or more errors, report those errors. Exc
ept for special |
| 16619 * cases, use the given error code rather than the one reported in the error. | 16619 * cases, use the given error code rather than the one reported in the error. |
| 16620 * | 16620 * |
| 16621 * @param result the result containing any errors that need to be reported | 16621 * @param result the result containing any errors that need to be reported |
| 16622 * @param errorCode the error code to be used if the result represents an erro
r | 16622 * @param errorCode the error code to be used if the result represents an erro
r |
| 16623 */ | 16623 */ |
| 16624 void reportErrors(EvaluationResultImpl result, ErrorCode errorCode) { | 16624 void _reportErrors(EvaluationResultImpl result, ErrorCode errorCode) { |
| 16625 if (result is ErrorResult) { | 16625 if (result is ErrorResult) { |
| 16626 for (ErrorResult_ErrorData data in result.errorData) { | 16626 for (ErrorResult_ErrorData data in result.errorData) { |
| 16627 ErrorCode dataErrorCode = data.errorCode; | 16627 ErrorCode dataErrorCode = data.errorCode; |
| 16628 if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCE
PTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE)
|| identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRIN
G) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || ide
ntical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dat
aErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) { | 16628 if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCE
PTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE)
|| identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRIN
G) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || ide
ntical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dat
aErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) { |
| 16629 _errorReporter.reportErrorForNode(dataErrorCode, data.node, []); | 16629 _errorReporter.reportErrorForNode(dataErrorCode, data.node, []); |
| 16630 } else { | 16630 } else { |
| 16631 _errorReporter.reportErrorForNode(errorCode, data.node, []); | 16631 _errorReporter.reportErrorForNode(errorCode, data.node, []); |
| 16632 } | 16632 } |
| 16633 } | 16633 } |
| 16634 } | 16634 } |
| 16635 } | 16635 } |
| 16636 | 16636 |
| 16637 ValidResult valid(InterfaceType type, InstanceState state) => new ValidResult(
new DartObjectImpl(type, state)); | 16637 ValidResult _valid(InterfaceType type, InstanceState state) => new ValidResult
(new DartObjectImpl(type, state)); |
| 16638 | 16638 |
| 16639 /** | 16639 /** |
| 16640 * Validate that the given expression is a compile time constant. Return the v
alue of the compile | 16640 * Validate that the given expression is a compile time constant. Return the v
alue of the compile |
| 16641 * time constant, or `null` if the expression is not a compile time constant. | 16641 * time constant, or `null` if the expression is not a compile time constant. |
| 16642 * | 16642 * |
| 16643 * @param expression the expression to be validated | 16643 * @param expression the expression to be validated |
| 16644 * @param errorCode the error code to be used if the expression is not a compi
le time constant | 16644 * @param errorCode the error code to be used if the expression is not a compi
le time constant |
| 16645 * @return the value of the compile time constant | 16645 * @return the value of the compile time constant |
| 16646 */ | 16646 */ |
| 16647 EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) { | 16647 EvaluationResultImpl _validate(Expression expression, ErrorCode errorCode) { |
| 16648 EvaluationResultImpl result = expression.accept(new ConstantVisitor(_typePro
vider)); | 16648 EvaluationResultImpl result = expression.accept(new ConstantVisitor(_typePro
vider)); |
| 16649 reportErrors(result, errorCode); | 16649 _reportErrors(result, errorCode); |
| 16650 return result; | 16650 return result; |
| 16651 } | 16651 } |
| 16652 | 16652 |
| 16653 /** | 16653 /** |
| 16654 * Validate that if the passed arguments are constant expressions. | 16654 * Validate that if the passed arguments are constant expressions. |
| 16655 * | 16655 * |
| 16656 * @param argumentList the argument list to evaluate | 16656 * @param argumentList the argument list to evaluate |
| 16657 */ | 16657 */ |
| 16658 void validateConstantArguments(ArgumentList argumentList) { | 16658 void _validateConstantArguments(ArgumentList argumentList) { |
| 16659 for (Expression argument in argumentList.arguments) { | 16659 for (Expression argument in argumentList.arguments) { |
| 16660 if (argument is NamedExpression) { | 16660 if (argument is NamedExpression) { |
| 16661 argument = (argument as NamedExpression).expression; | 16661 argument = (argument as NamedExpression).expression; |
| 16662 } | 16662 } |
| 16663 validate(argument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT); | 16663 _validate(argument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT)
; |
| 16664 } | 16664 } |
| 16665 } | 16665 } |
| 16666 | 16666 |
| 16667 /** | 16667 /** |
| 16668 * Validate that the default value associated with each of the parameters in t
he given list is a | 16668 * Validate that the default value associated with each of the parameters in t
he given list is a |
| 16669 * compile time constant. | 16669 * compile time constant. |
| 16670 * | 16670 * |
| 16671 * @param parameters the list of parameters to be validated | 16671 * @param parameters the list of parameters to be validated |
| 16672 */ | 16672 */ |
| 16673 void validateDefaultValues(FormalParameterList parameters) { | 16673 void _validateDefaultValues(FormalParameterList parameters) { |
| 16674 if (parameters == null) { | 16674 if (parameters == null) { |
| 16675 return; | 16675 return; |
| 16676 } | 16676 } |
| 16677 for (FormalParameter parameter in parameters.parameters) { | 16677 for (FormalParameter parameter in parameters.parameters) { |
| 16678 if (parameter is DefaultFormalParameter) { | 16678 if (parameter is DefaultFormalParameter) { |
| 16679 DefaultFormalParameter defaultParameter = parameter; | 16679 DefaultFormalParameter defaultParameter = parameter; |
| 16680 Expression defaultValue = defaultParameter.defaultValue; | 16680 Expression defaultValue = defaultParameter.defaultValue; |
| 16681 if (defaultValue != null) { | 16681 if (defaultValue != null) { |
| 16682 EvaluationResultImpl result = validate(defaultValue, CompileTimeErrorC
ode.NON_CONSTANT_DEFAULT_VALUE); | 16682 EvaluationResultImpl result = _validate(defaultValue, CompileTimeError
Code.NON_CONSTANT_DEFAULT_VALUE); |
| 16683 VariableElementImpl element = parameter.element as VariableElementImpl
; | 16683 VariableElementImpl element = parameter.element as VariableElementImpl
; |
| 16684 element.evaluationResult = result; | 16684 element.evaluationResult = result; |
| 16685 } | 16685 } |
| 16686 } | 16686 } |
| 16687 } | 16687 } |
| 16688 } | 16688 } |
| 16689 | 16689 |
| 16690 /** | 16690 /** |
| 16691 * Validates that the given expression is a compile time constant. | 16691 * Validates that the given expression is a compile time constant. |
| 16692 * | 16692 * |
| 16693 * @param parameterElements the elements of parameters of constant constructor
, they are | 16693 * @param parameterElements the elements of parameters of constant constructor
, they are |
| 16694 * considered as a valid potentially constant expressions | 16694 * considered as a valid potentially constant expressions |
| 16695 * @param expression the expression to validate | 16695 * @param expression the expression to validate |
| 16696 */ | 16696 */ |
| 16697 void validateInitializerExpression(List<ParameterElement> parameterElements, E
xpression expression) { | 16697 void _validateInitializerExpression(List<ParameterElement> parameterElements,
Expression expression) { |
| 16698 EvaluationResultImpl result = expression.accept(new ConstantVisitor_Constant
Verifier_validateInitializerExpression(_typeProvider, this, parameterElements)); | 16698 EvaluationResultImpl result = expression.accept(new ConstantVisitor_Constant
Verifier_validateInitializerExpression(_typeProvider, this, parameterElements)); |
| 16699 reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER)
; | 16699 _reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER
); |
| 16700 } | 16700 } |
| 16701 | 16701 |
| 16702 /** | 16702 /** |
| 16703 * Validates that all of the arguments of a constructor initializer are compil
e time constants. | 16703 * Validates that all of the arguments of a constructor initializer are compil
e time constants. |
| 16704 * | 16704 * |
| 16705 * @param parameterElements the elements of parameters of constant constructor
, they are | 16705 * @param parameterElements the elements of parameters of constant constructor
, they are |
| 16706 * considered as a valid potentially constant expressions | 16706 * considered as a valid potentially constant expressions |
| 16707 * @param argumentList the argument list to validate | 16707 * @param argumentList the argument list to validate |
| 16708 */ | 16708 */ |
| 16709 void validateInitializerInvocationArguments(List<ParameterElement> parameterEl
ements, ArgumentList argumentList) { | 16709 void _validateInitializerInvocationArguments(List<ParameterElement> parameterE
lements, ArgumentList argumentList) { |
| 16710 if (argumentList == null) { | 16710 if (argumentList == null) { |
| 16711 return; | 16711 return; |
| 16712 } | 16712 } |
| 16713 for (Expression argument in argumentList.arguments) { | 16713 for (Expression argument in argumentList.arguments) { |
| 16714 validateInitializerExpression(parameterElements, argument); | 16714 _validateInitializerExpression(parameterElements, argument); |
| 16715 } | 16715 } |
| 16716 } | 16716 } |
| 16717 | 16717 |
| 16718 /** | 16718 /** |
| 16719 * Validates that the expressions of the given initializers (of a constant con
structor) are all | 16719 * Validates that the expressions of the given initializers (of a constant con
structor) are all |
| 16720 * compile time constants. | 16720 * compile time constants. |
| 16721 * | 16721 * |
| 16722 * @param constructor the constant constructor declaration to validate | 16722 * @param constructor the constant constructor declaration to validate |
| 16723 */ | 16723 */ |
| 16724 void validateInitializers(ConstructorDeclaration constructor) { | 16724 void _validateInitializers(ConstructorDeclaration constructor) { |
| 16725 List<ParameterElement> parameterElements = constructor.parameters.parameterE
lements; | 16725 List<ParameterElement> parameterElements = constructor.parameters.parameterE
lements; |
| 16726 NodeList<ConstructorInitializer> initializers = constructor.initializers; | 16726 NodeList<ConstructorInitializer> initializers = constructor.initializers; |
| 16727 for (ConstructorInitializer initializer in initializers) { | 16727 for (ConstructorInitializer initializer in initializers) { |
| 16728 if (initializer is ConstructorFieldInitializer) { | 16728 if (initializer is ConstructorFieldInitializer) { |
| 16729 ConstructorFieldInitializer fieldInitializer = initializer; | 16729 ConstructorFieldInitializer fieldInitializer = initializer; |
| 16730 validateInitializerExpression(parameterElements, fieldInitializer.expres
sion); | 16730 _validateInitializerExpression(parameterElements, fieldInitializer.expre
ssion); |
| 16731 } | 16731 } |
| 16732 if (initializer is RedirectingConstructorInvocation) { | 16732 if (initializer is RedirectingConstructorInvocation) { |
| 16733 RedirectingConstructorInvocation invocation = initializer; | 16733 RedirectingConstructorInvocation invocation = initializer; |
| 16734 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); | 16734 _validateInitializerInvocationArguments(parameterElements, invocation.ar
gumentList); |
| 16735 } | 16735 } |
| 16736 if (initializer is SuperConstructorInvocation) { | 16736 if (initializer is SuperConstructorInvocation) { |
| 16737 SuperConstructorInvocation invocation = initializer; | 16737 SuperConstructorInvocation invocation = initializer; |
| 16738 validateInitializerInvocationArguments(parameterElements, invocation.arg
umentList); | 16738 _validateInitializerInvocationArguments(parameterElements, invocation.ar
gumentList); |
| 16739 } | 16739 } |
| 16740 } | 16740 } |
| 16741 } | 16741 } |
| 16742 | 16742 |
| 16743 /** | 16743 /** |
| 16744 * Validate that if the passed instance creation is 'const' then all its argum
ents are constant | 16744 * Validate that if the passed instance creation is 'const' then all its argum
ents are constant |
| 16745 * expressions. | 16745 * expressions. |
| 16746 * | 16746 * |
| 16747 * @param node the instance creation evaluate | 16747 * @param node the instance creation evaluate |
| 16748 */ | 16748 */ |
| 16749 void validateInstanceCreationArguments(InstanceCreationExpression node) { | 16749 void _validateInstanceCreationArguments(InstanceCreationExpression node) { |
| 16750 if (!node.isConst) { | 16750 if (!node.isConst) { |
| 16751 return; | 16751 return; |
| 16752 } | 16752 } |
| 16753 ArgumentList argumentList = node.argumentList; | 16753 ArgumentList argumentList = node.argumentList; |
| 16754 if (argumentList == null) { | 16754 if (argumentList == null) { |
| 16755 return; | 16755 return; |
| 16756 } | 16756 } |
| 16757 validateConstantArguments(argumentList); | 16757 _validateConstantArguments(argumentList); |
| 16758 } | 16758 } |
| 16759 } | 16759 } |
| 16760 | 16760 |
| 16761 class ConstantVisitor_ConstantVerifier_validateInitializerExpression extends Con
stantVisitor { | 16761 class ConstantVisitor_ConstantVerifier_validateInitializerExpression extends Con
stantVisitor { |
| 16762 final ConstantVerifier ConstantVerifier_this; | 16762 final ConstantVerifier ConstantVerifier_this; |
| 16763 | 16763 |
| 16764 List<ParameterElement> parameterElements; | 16764 List<ParameterElement> parameterElements; |
| 16765 | 16765 |
| 16766 ConstantVisitor_ConstantVerifier_validateInitializerExpression(TypeProvider ar
g0, this.ConstantVerifier_this, this.parameterElements) : super(arg0); | 16766 ConstantVisitor_ConstantVerifier_validateInitializerExpression(TypeProvider ar
g0, this.ConstantVerifier_this, this.parameterElements) : super(arg0); |
| 16767 | 16767 |
| 16768 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) { | 16768 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) { |
| 16769 Element element = node.staticElement; | 16769 Element element = node.staticElement; |
| 16770 for (ParameterElement parameterElement in parameterElements) { | 16770 for (ParameterElement parameterElement in parameterElements) { |
| 16771 if (identical(parameterElement, element) && parameterElement != null) { | 16771 if (identical(parameterElement, element) && parameterElement != null) { |
| 16772 Type2 type = parameterElement.type; | 16772 Type2 type = parameterElement.type; |
| 16773 if (type != null) { | 16773 if (type != null) { |
| 16774 if (type.isDynamic) { | 16774 if (type.isDynamic) { |
| 16775 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.objectType, DynamicState.DYNAMIC_STATE); | 16775 return ConstantVerifier_this._valid(ConstantVerifier_this._typeProvi
der.objectType, DynamicState.DYNAMIC_STATE); |
| 16776 } else if (type.isSubtypeOf(ConstantVerifier_this._boolType)) { | 16776 } else if (type.isSubtypeOf(ConstantVerifier_this._boolType)) { |
| 16777 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.boolType, BoolState.UNKNOWN_VALUE); | 16777 return ConstantVerifier_this._valid(ConstantVerifier_this._typeProvi
der.boolType, BoolState.UNKNOWN_VALUE); |
| 16778 } else if (type.isSubtypeOf(ConstantVerifier_this._typeProvider.double
Type)) { | 16778 } else if (type.isSubtypeOf(ConstantVerifier_this._typeProvider.double
Type)) { |
| 16779 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.doubleType, DoubleState.UNKNOWN_VALUE); | 16779 return ConstantVerifier_this._valid(ConstantVerifier_this._typeProvi
der.doubleType, DoubleState.UNKNOWN_VALUE); |
| 16780 } else if (type.isSubtypeOf(ConstantVerifier_this._intType)) { | 16780 } else if (type.isSubtypeOf(ConstantVerifier_this._intType)) { |
| 16781 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.intType, IntState.UNKNOWN_VALUE); | 16781 return ConstantVerifier_this._valid(ConstantVerifier_this._typeProvi
der.intType, IntState.UNKNOWN_VALUE); |
| 16782 } else if (type.isSubtypeOf(ConstantVerifier_this._numType)) { | 16782 } else if (type.isSubtypeOf(ConstantVerifier_this._numType)) { |
| 16783 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.numType, NumState.UNKNOWN_VALUE); | 16783 return ConstantVerifier_this._valid(ConstantVerifier_this._typeProvi
der.numType, NumState.UNKNOWN_VALUE); |
| 16784 } else if (type.isSubtypeOf(ConstantVerifier_this._stringType)) { | 16784 } else if (type.isSubtypeOf(ConstantVerifier_this._stringType)) { |
| 16785 return ConstantVerifier_this.valid(ConstantVerifier_this._typeProvid
er.stringType, StringState.UNKNOWN_VALUE); | 16785 return ConstantVerifier_this._valid(ConstantVerifier_this._typeProvi
der.stringType, StringState.UNKNOWN_VALUE); |
| 16786 } | 16786 } |
| 16787 } | 16787 } |
| 16788 return ConstantVerifier_this.valid(type is InterfaceType ? type : Consta
ntVerifier_this._typeProvider.objectType, GenericState.UNKNOWN_VALUE); | 16788 return ConstantVerifier_this._valid(type is InterfaceType ? type : Const
antVerifier_this._typeProvider.objectType, GenericState.UNKNOWN_VALUE); |
| 16789 } | 16789 } |
| 16790 } | 16790 } |
| 16791 return super.visitSimpleIdentifier(node); | 16791 return super.visitSimpleIdentifier(node); |
| 16792 } | 16792 } |
| 16793 } | 16793 } |
| 16794 | 16794 |
| 16795 /** | 16795 /** |
| 16796 * Instances of the class `ErrorVerifier` traverse an AST structure looking for
additional | 16796 * Instances of the class `ErrorVerifier` traverse an AST structure looking for
additional |
| 16797 * errors and warnings not covered by the parser and resolver. | 16797 * errors and warnings not covered by the parser and resolver. |
| 16798 */ | 16798 */ |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17000 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [ | 17000 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [ |
| 17001 typeProvider.nullType, | 17001 typeProvider.nullType, |
| 17002 typeProvider.numType, | 17002 typeProvider.numType, |
| 17003 _intType, | 17003 _intType, |
| 17004 typeProvider.doubleType, | 17004 typeProvider.doubleType, |
| 17005 _boolType, | 17005 _boolType, |
| 17006 typeProvider.stringType]; | 17006 typeProvider.stringType]; |
| 17007 } | 17007 } |
| 17008 | 17008 |
| 17009 Object visitArgumentList(ArgumentList node) { | 17009 Object visitArgumentList(ArgumentList node) { |
| 17010 checkForArgumentTypesNotAssignableInList(node); | 17010 _checkForArgumentTypesNotAssignableInList(node); |
| 17011 return super.visitArgumentList(node); | 17011 return super.visitArgumentList(node); |
| 17012 } | 17012 } |
| 17013 | 17013 |
| 17014 Object visitAssertStatement(AssertStatement node) { | 17014 Object visitAssertStatement(AssertStatement node) { |
| 17015 checkForNonBoolExpression(node); | 17015 _checkForNonBoolExpression(node); |
| 17016 return super.visitAssertStatement(node); | 17016 return super.visitAssertStatement(node); |
| 17017 } | 17017 } |
| 17018 | 17018 |
| 17019 Object visitAssignmentExpression(AssignmentExpression node) { | 17019 Object visitAssignmentExpression(AssignmentExpression node) { |
| 17020 sc.Token operator = node.operator; | 17020 sc.Token operator = node.operator; |
| 17021 sc.TokenType operatorType = operator.type; | 17021 sc.TokenType operatorType = operator.type; |
| 17022 if (identical(operatorType, sc.TokenType.EQ)) { | 17022 if (identical(operatorType, sc.TokenType.EQ)) { |
| 17023 checkForInvalidAssignment(node.leftHandSide, node.rightHandSide); | 17023 _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide); |
| 17024 } else { | 17024 } else { |
| 17025 checkForInvalidCompoundAssignment(node); | 17025 _checkForInvalidCompoundAssignment(node); |
| 17026 } | 17026 } |
| 17027 checkForAssignmentToFinal(node.leftHandSide); | 17027 _checkForAssignmentToFinal(node.leftHandSide); |
| 17028 checkForArgumentTypeNotAssignableForArgument(node.rightHandSide); | 17028 _checkForArgumentTypeNotAssignableForArgument(node.rightHandSide); |
| 17029 return super.visitAssignmentExpression(node); | 17029 return super.visitAssignmentExpression(node); |
| 17030 } | 17030 } |
| 17031 | 17031 |
| 17032 Object visitBinaryExpression(BinaryExpression node) { | 17032 Object visitBinaryExpression(BinaryExpression node) { |
| 17033 checkForArgumentTypeNotAssignableForArgument(node.rightOperand); | 17033 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand); |
| 17034 return super.visitBinaryExpression(node); | 17034 return super.visitBinaryExpression(node); |
| 17035 } | 17035 } |
| 17036 | 17036 |
| 17037 Object visitBlockFunctionBody(BlockFunctionBody node) { | 17037 Object visitBlockFunctionBody(BlockFunctionBody node) { |
| 17038 List<ReturnStatement> previousReturnsWith = _returnsWith; | 17038 List<ReturnStatement> previousReturnsWith = _returnsWith; |
| 17039 List<ReturnStatement> previousReturnsWithout = _returnsWithout; | 17039 List<ReturnStatement> previousReturnsWithout = _returnsWithout; |
| 17040 try { | 17040 try { |
| 17041 _returnsWith = new List<ReturnStatement>(); | 17041 _returnsWith = new List<ReturnStatement>(); |
| 17042 _returnsWithout = new List<ReturnStatement>(); | 17042 _returnsWithout = new List<ReturnStatement>(); |
| 17043 super.visitBlockFunctionBody(node); | 17043 super.visitBlockFunctionBody(node); |
| 17044 checkForMixedReturns(node); | 17044 _checkForMixedReturns(node); |
| 17045 } finally { | 17045 } finally { |
| 17046 _returnsWith = previousReturnsWith; | 17046 _returnsWith = previousReturnsWith; |
| 17047 _returnsWithout = previousReturnsWithout; | 17047 _returnsWithout = previousReturnsWithout; |
| 17048 } | 17048 } |
| 17049 return null; | 17049 return null; |
| 17050 } | 17050 } |
| 17051 | 17051 |
| 17052 Object visitBreakStatement(BreakStatement node) { | 17052 Object visitBreakStatement(BreakStatement node) { |
| 17053 SimpleIdentifier labelNode = node.label; | 17053 SimpleIdentifier labelNode = node.label; |
| 17054 if (labelNode != null) { | 17054 if (labelNode != null) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 17071 } | 17071 } |
| 17072 | 17072 |
| 17073 Object visitClassDeclaration(ClassDeclaration node) { | 17073 Object visitClassDeclaration(ClassDeclaration node) { |
| 17074 ClassElement outerClass = _enclosingClass; | 17074 ClassElement outerClass = _enclosingClass; |
| 17075 try { | 17075 try { |
| 17076 _isInNativeClass = node.nativeClause != null; | 17076 _isInNativeClass = node.nativeClause != null; |
| 17077 _enclosingClass = node.element; | 17077 _enclosingClass = node.element; |
| 17078 WithClause withClause = node.withClause; | 17078 WithClause withClause = node.withClause; |
| 17079 ImplementsClause implementsClause = node.implementsClause; | 17079 ImplementsClause implementsClause = node.implementsClause; |
| 17080 ExtendsClause extendsClause = node.extendsClause; | 17080 ExtendsClause extendsClause = node.extendsClause; |
| 17081 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_I
DENTIFIER_AS_TYPE_NAME); | 17081 _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_
IDENTIFIER_AS_TYPE_NAME); |
| 17082 checkForMemberWithClassName(); | 17082 _checkForMemberWithClassName(); |
| 17083 checkForNoDefaultSuperConstructorImplicit(node); | 17083 _checkForNoDefaultSuperConstructorImplicit(node); |
| 17084 checkForConflictingTypeVariableErrorCodes(node); | 17084 _checkForConflictingTypeVariableErrorCodes(node); |
| 17085 // Only do error checks on the clause nodes if there is a non-null clause | 17085 // Only do error checks on the clause nodes if there is a non-null clause |
| 17086 if (implementsClause != null || extendsClause != null || withClause != nul
l) { | 17086 if (implementsClause != null || extendsClause != null || withClause != nul
l) { |
| 17087 // Only check for all of the inheritance logic around clauses if there i
sn't an error code | 17087 // Only check for all of the inheritance logic around clauses if there i
sn't an error code |
| 17088 // such as "Cannot extend double" already on the class. | 17088 // such as "Cannot extend double" already on the class. |
| 17089 if (!checkForImplementsDisallowedClass(implementsClause) && !checkForExt
endsDisallowedClass(extendsClause) && !checkForAllMixinErrorCodes(withClause)) { | 17089 if (!_checkForImplementsDisallowedClass(implementsClause) && !_checkForE
xtendsDisallowedClass(extendsClause) && !_checkForAllMixinErrorCodes(withClause)
) { |
| 17090 checkForNonAbstractClassInheritsAbstractMember(node); | 17090 _checkForNonAbstractClassInheritsAbstractMember(node); |
| 17091 checkForInconsistentMethodInheritance(); | 17091 _checkForInconsistentMethodInheritance(); |
| 17092 checkForRecursiveInterfaceInheritance(_enclosingClass); | 17092 _checkForRecursiveInterfaceInheritance(_enclosingClass); |
| 17093 checkForConflictingGetterAndMethod(); | 17093 _checkForConflictingGetterAndMethod(); |
| 17094 checkForConflictingInstanceGetterAndSuperclassMember(); | 17094 _checkForConflictingInstanceGetterAndSuperclassMember(); |
| 17095 checkImplementsSuperClass(node); | 17095 _checkImplementsSuperClass(node); |
| 17096 checkImplementsFunctionWithoutCall(node); | 17096 _checkImplementsFunctionWithoutCall(node); |
| 17097 } | 17097 } |
| 17098 } | 17098 } |
| 17099 // initialize initialFieldElementsMap | 17099 // initialize initialFieldElementsMap |
| 17100 ClassElement classElement = node.element; | 17100 ClassElement classElement = node.element; |
| 17101 if (classElement != null) { | 17101 if (classElement != null) { |
| 17102 List<FieldElement> fieldElements = classElement.fields; | 17102 List<FieldElement> fieldElements = classElement.fields; |
| 17103 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>(); | 17103 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>(); |
| 17104 for (FieldElement fieldElement in fieldElements) { | 17104 for (FieldElement fieldElement in fieldElements) { |
| 17105 if (!fieldElement.isSynthetic) { | 17105 if (!fieldElement.isSynthetic) { |
| 17106 _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; | 17106 _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; |
| 17107 } | 17107 } |
| 17108 } | 17108 } |
| 17109 } | 17109 } |
| 17110 checkForFinalNotInitializedInClass(node); | 17110 _checkForFinalNotInitializedInClass(node); |
| 17111 checkForDuplicateDefinitionInheritance(); | 17111 _checkForDuplicateDefinitionInheritance(); |
| 17112 checkForConflictingInstanceMethodSetter(node); | 17112 _checkForConflictingInstanceMethodSetter(node); |
| 17113 return super.visitClassDeclaration(node); | 17113 return super.visitClassDeclaration(node); |
| 17114 } finally { | 17114 } finally { |
| 17115 _isInNativeClass = false; | 17115 _isInNativeClass = false; |
| 17116 _initialFieldElementsMap = null; | 17116 _initialFieldElementsMap = null; |
| 17117 _enclosingClass = outerClass; | 17117 _enclosingClass = outerClass; |
| 17118 } | 17118 } |
| 17119 } | 17119 } |
| 17120 | 17120 |
| 17121 Object visitClassTypeAlias(ClassTypeAlias node) { | 17121 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 17122 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE
NTIFIER_AS_TYPEDEF_NAME); | 17122 _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_ID
ENTIFIER_AS_TYPEDEF_NAME); |
| 17123 checkForAllMixinErrorCodes(node.withClause); | 17123 _checkForAllMixinErrorCodes(node.withClause); |
| 17124 ClassElement outerClassElement = _enclosingClass; | 17124 ClassElement outerClassElement = _enclosingClass; |
| 17125 try { | 17125 try { |
| 17126 _enclosingClass = node.element; | 17126 _enclosingClass = node.element; |
| 17127 checkForRecursiveInterfaceInheritance(node.element); | 17127 _checkForRecursiveInterfaceInheritance(node.element); |
| 17128 checkForTypeAliasCannotReferenceItself_mixin(node); | 17128 _checkForTypeAliasCannotReferenceItself_mixin(node); |
| 17129 } finally { | 17129 } finally { |
| 17130 _enclosingClass = outerClassElement; | 17130 _enclosingClass = outerClassElement; |
| 17131 } | 17131 } |
| 17132 return super.visitClassTypeAlias(node); | 17132 return super.visitClassTypeAlias(node); |
| 17133 } | 17133 } |
| 17134 | 17134 |
| 17135 Object visitComment(Comment node) { | 17135 Object visitComment(Comment node) { |
| 17136 _isInComment = true; | 17136 _isInComment = true; |
| 17137 try { | 17137 try { |
| 17138 return super.visitComment(node); | 17138 return super.visitComment(node); |
| 17139 } finally { | 17139 } finally { |
| 17140 _isInComment = false; | 17140 _isInComment = false; |
| 17141 } | 17141 } |
| 17142 } | 17142 } |
| 17143 | 17143 |
| 17144 Object visitConditionalExpression(ConditionalExpression node) { | 17144 Object visitConditionalExpression(ConditionalExpression node) { |
| 17145 checkForNonBoolCondition(node.condition); | 17145 _checkForNonBoolCondition(node.condition); |
| 17146 return super.visitConditionalExpression(node); | 17146 return super.visitConditionalExpression(node); |
| 17147 } | 17147 } |
| 17148 | 17148 |
| 17149 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 17149 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 17150 ExecutableElement outerFunction = _enclosingFunction; | 17150 ExecutableElement outerFunction = _enclosingFunction; |
| 17151 try { | 17151 try { |
| 17152 _enclosingFunction = node.element; | 17152 _enclosingFunction = node.element; |
| 17153 _isEnclosingConstructorConst = node.constKeyword != null; | 17153 _isEnclosingConstructorConst = node.constKeyword != null; |
| 17154 checkForConstConstructorWithNonFinalField(node); | 17154 _checkForConstConstructorWithNonFinalField(node); |
| 17155 checkForConstConstructorWithNonConstSuper(node); | 17155 _checkForConstConstructorWithNonConstSuper(node); |
| 17156 checkForConflictingConstructorNameAndMember(node); | 17156 _checkForConflictingConstructorNameAndMember(node); |
| 17157 checkForAllFinalInitializedErrorCodes(node); | 17157 _checkForAllFinalInitializedErrorCodes(node); |
| 17158 checkForRedirectingConstructorErrorCodes(node); | 17158 _checkForRedirectingConstructorErrorCodes(node); |
| 17159 checkForMultipleSuperInitializers(node); | 17159 _checkForMultipleSuperInitializers(node); |
| 17160 checkForRecursiveConstructorRedirect(node); | 17160 _checkForRecursiveConstructorRedirect(node); |
| 17161 if (!checkForRecursiveFactoryRedirect(node)) { | 17161 if (!_checkForRecursiveFactoryRedirect(node)) { |
| 17162 checkForAllRedirectConstructorErrorCodes(node); | 17162 _checkForAllRedirectConstructorErrorCodes(node); |
| 17163 } | 17163 } |
| 17164 checkForUndefinedConstructorInInitializerImplicit(node); | 17164 _checkForUndefinedConstructorInInitializerImplicit(node); |
| 17165 checkForRedirectToNonConstConstructor(node); | 17165 _checkForRedirectToNonConstConstructor(node); |
| 17166 checkForReturnInGenerativeConstructor(node); | 17166 _checkForReturnInGenerativeConstructor(node); |
| 17167 return super.visitConstructorDeclaration(node); | 17167 return super.visitConstructorDeclaration(node); |
| 17168 } finally { | 17168 } finally { |
| 17169 _isEnclosingConstructorConst = false; | 17169 _isEnclosingConstructorConst = false; |
| 17170 _enclosingFunction = outerFunction; | 17170 _enclosingFunction = outerFunction; |
| 17171 } | 17171 } |
| 17172 } | 17172 } |
| 17173 | 17173 |
| 17174 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 17174 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 17175 _isInConstructorInitializer = true; | 17175 _isInConstructorInitializer = true; |
| 17176 try { | 17176 try { |
| 17177 checkForInvalidField(node); | 17177 _checkForInvalidField(node); |
| 17178 checkForFieldInitializerNotAssignable(node); | 17178 _checkForFieldInitializerNotAssignable(node); |
| 17179 return super.visitConstructorFieldInitializer(node); | 17179 return super.visitConstructorFieldInitializer(node); |
| 17180 } finally { | 17180 } finally { |
| 17181 _isInConstructorInitializer = false; | 17181 _isInConstructorInitializer = false; |
| 17182 } | 17182 } |
| 17183 } | 17183 } |
| 17184 | 17184 |
| 17185 Object visitContinueStatement(ContinueStatement node) { | 17185 Object visitContinueStatement(ContinueStatement node) { |
| 17186 SimpleIdentifier labelNode = node.label; | 17186 SimpleIdentifier labelNode = node.label; |
| 17187 if (labelNode != null) { | 17187 if (labelNode != null) { |
| 17188 Element labelElement = labelNode.staticElement; | 17188 Element labelElement = labelNode.staticElement; |
| 17189 if (labelElement is LabelElementImpl && labelElement.isOnSwitchStatement)
{ | 17189 if (labelElement is LabelElementImpl && labelElement.isOnSwitchStatement)
{ |
| 17190 _errorReporter.reportErrorForNode(ResolverErrorCode.CONTINUE_LABEL_ON_SW
ITCH, labelNode, []); | 17190 _errorReporter.reportErrorForNode(ResolverErrorCode.CONTINUE_LABEL_ON_SW
ITCH, labelNode, []); |
| 17191 } | 17191 } |
| 17192 } | 17192 } |
| 17193 return null; | 17193 return null; |
| 17194 } | 17194 } |
| 17195 | 17195 |
| 17196 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 17196 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 17197 checkForInvalidAssignment(node.identifier, node.defaultValue); | 17197 _checkForInvalidAssignment(node.identifier, node.defaultValue); |
| 17198 checkForDefaultValueInFunctionTypedParameter(node); | 17198 _checkForDefaultValueInFunctionTypedParameter(node); |
| 17199 return super.visitDefaultFormalParameter(node); | 17199 return super.visitDefaultFormalParameter(node); |
| 17200 } | 17200 } |
| 17201 | 17201 |
| 17202 Object visitDoStatement(DoStatement node) { | 17202 Object visitDoStatement(DoStatement node) { |
| 17203 checkForNonBoolCondition(node.condition); | 17203 _checkForNonBoolCondition(node.condition); |
| 17204 return super.visitDoStatement(node); | 17204 return super.visitDoStatement(node); |
| 17205 } | 17205 } |
| 17206 | 17206 |
| 17207 Object visitExportDirective(ExportDirective node) { | 17207 Object visitExportDirective(ExportDirective node) { |
| 17208 ExportElement exportElement = node.element; | 17208 ExportElement exportElement = node.element; |
| 17209 if (exportElement != null) { | 17209 if (exportElement != null) { |
| 17210 checkForAmbiguousExport(node, exportElement); | 17210 _checkForAmbiguousExport(node, exportElement); |
| 17211 checkForExportDuplicateLibraryName(node, exportElement); | 17211 _checkForExportDuplicateLibraryName(node, exportElement); |
| 17212 checkForExportInternalLibrary(node, exportElement); | 17212 _checkForExportInternalLibrary(node, exportElement); |
| 17213 } | 17213 } |
| 17214 return super.visitExportDirective(node); | 17214 return super.visitExportDirective(node); |
| 17215 } | 17215 } |
| 17216 | 17216 |
| 17217 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | 17217 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 17218 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu
nction.type; | 17218 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu
nction.type; |
| 17219 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance :
functionType.returnType; | 17219 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance :
functionType.returnType; |
| 17220 checkForReturnOfInvalidType(node.expression, expectedReturnType); | 17220 _checkForReturnOfInvalidType(node.expression, expectedReturnType); |
| 17221 return super.visitExpressionFunctionBody(node); | 17221 return super.visitExpressionFunctionBody(node); |
| 17222 } | 17222 } |
| 17223 | 17223 |
| 17224 Object visitFieldDeclaration(FieldDeclaration node) { | 17224 Object visitFieldDeclaration(FieldDeclaration node) { |
| 17225 _isInStaticVariableDeclaration = node.isStatic; | 17225 _isInStaticVariableDeclaration = node.isStatic; |
| 17226 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; | 17226 _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration; |
| 17227 if (_isInInstanceVariableDeclaration) { | 17227 if (_isInInstanceVariableDeclaration) { |
| 17228 VariableDeclarationList variables = node.fields; | 17228 VariableDeclarationList variables = node.fields; |
| 17229 if (variables.isConst) { | 17229 if (variables.isConst) { |
| 17230 _errorReporter.reportErrorForToken(CompileTimeErrorCode.CONST_INSTANCE_F
IELD, variables.keyword, []); | 17230 _errorReporter.reportErrorForToken(CompileTimeErrorCode.CONST_INSTANCE_F
IELD, variables.keyword, []); |
| 17231 } | 17231 } |
| 17232 } | 17232 } |
| 17233 try { | 17233 try { |
| 17234 checkForAllInvalidOverrideErrorCodesForField(node); | 17234 _checkForAllInvalidOverrideErrorCodesForField(node); |
| 17235 return super.visitFieldDeclaration(node); | 17235 return super.visitFieldDeclaration(node); |
| 17236 } finally { | 17236 } finally { |
| 17237 _isInStaticVariableDeclaration = false; | 17237 _isInStaticVariableDeclaration = false; |
| 17238 _isInInstanceVariableDeclaration = false; | 17238 _isInInstanceVariableDeclaration = false; |
| 17239 } | 17239 } |
| 17240 } | 17240 } |
| 17241 | 17241 |
| 17242 Object visitFieldFormalParameter(FieldFormalParameter node) { | 17242 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 17243 checkForValidField(node); | 17243 _checkForValidField(node); |
| 17244 checkForConstFormalParameter(node); | 17244 _checkForConstFormalParameter(node); |
| 17245 checkForPrivateOptionalParameter(node); | 17245 _checkForPrivateOptionalParameter(node); |
| 17246 checkForFieldInitializingFormalRedirectingConstructor(node); | 17246 _checkForFieldInitializingFormalRedirectingConstructor(node); |
| 17247 return super.visitFieldFormalParameter(node); | 17247 return super.visitFieldFormalParameter(node); |
| 17248 } | 17248 } |
| 17249 | 17249 |
| 17250 Object visitFunctionDeclaration(FunctionDeclaration node) { | 17250 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 17251 ExecutableElement outerFunction = _enclosingFunction; | 17251 ExecutableElement outerFunction = _enclosingFunction; |
| 17252 try { | 17252 try { |
| 17253 SimpleIdentifier identifier = node.name; | 17253 SimpleIdentifier identifier = node.name; |
| 17254 String methodName = ""; | 17254 String methodName = ""; |
| 17255 if (identifier != null) { | 17255 if (identifier != null) { |
| 17256 methodName = identifier.name; | 17256 methodName = identifier.name; |
| 17257 } | 17257 } |
| 17258 _enclosingFunction = node.element; | 17258 _enclosingFunction = node.element; |
| 17259 if (node.isSetter || node.isGetter) { | 17259 if (node.isSetter || node.isGetter) { |
| 17260 checkForMismatchedAccessorTypes(node, methodName); | 17260 _checkForMismatchedAccessorTypes(node, methodName); |
| 17261 if (node.isSetter) { | 17261 if (node.isSetter) { |
| 17262 FunctionExpression functionExpression = node.functionExpression; | 17262 FunctionExpression functionExpression = node.functionExpression; |
| 17263 if (functionExpression != null) { | 17263 if (functionExpression != null) { |
| 17264 checkForWrongNumberOfParametersForSetter(node.name, functionExpressi
on.parameters); | 17264 _checkForWrongNumberOfParametersForSetter(node.name, functionExpress
ion.parameters); |
| 17265 } | 17265 } |
| 17266 TypeName returnType = node.returnType; | 17266 TypeName returnType = node.returnType; |
| 17267 checkForNonVoidReturnTypeForSetter(returnType); | 17267 _checkForNonVoidReturnTypeForSetter(returnType); |
| 17268 } | 17268 } |
| 17269 } | 17269 } |
| 17270 return super.visitFunctionDeclaration(node); | 17270 return super.visitFunctionDeclaration(node); |
| 17271 } finally { | 17271 } finally { |
| 17272 _enclosingFunction = outerFunction; | 17272 _enclosingFunction = outerFunction; |
| 17273 } | 17273 } |
| 17274 } | 17274 } |
| 17275 | 17275 |
| 17276 Object visitFunctionExpression(FunctionExpression node) { | 17276 Object visitFunctionExpression(FunctionExpression node) { |
| 17277 // If this function expression is wrapped in a function declaration, don't c
hange the | 17277 // If this function expression is wrapped in a function declaration, don't c
hange the |
| 17278 // enclosingFunction field. | 17278 // enclosingFunction field. |
| 17279 if (node.parent is! FunctionDeclaration) { | 17279 if (node.parent is! FunctionDeclaration) { |
| 17280 ExecutableElement outerFunction = _enclosingFunction; | 17280 ExecutableElement outerFunction = _enclosingFunction; |
| 17281 try { | 17281 try { |
| 17282 _enclosingFunction = node.element; | 17282 _enclosingFunction = node.element; |
| 17283 return super.visitFunctionExpression(node); | 17283 return super.visitFunctionExpression(node); |
| 17284 } finally { | 17284 } finally { |
| 17285 _enclosingFunction = outerFunction; | 17285 _enclosingFunction = outerFunction; |
| 17286 } | 17286 } |
| 17287 } else { | 17287 } else { |
| 17288 return super.visitFunctionExpression(node); | 17288 return super.visitFunctionExpression(node); |
| 17289 } | 17289 } |
| 17290 } | 17290 } |
| 17291 | 17291 |
| 17292 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 17292 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| 17293 Expression functionExpression = node.function; | 17293 Expression functionExpression = node.function; |
| 17294 Type2 expressionType = functionExpression.staticType; | 17294 Type2 expressionType = functionExpression.staticType; |
| 17295 if (!isFunctionType(expressionType)) { | 17295 if (!_isFunctionType(expressionType)) { |
| 17296 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVOCATION_OF_NON_
FUNCTION_EXPRESSION, functionExpression, []); | 17296 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVOCATION_OF_NON_
FUNCTION_EXPRESSION, functionExpression, []); |
| 17297 } | 17297 } |
| 17298 return super.visitFunctionExpressionInvocation(node); | 17298 return super.visitFunctionExpressionInvocation(node); |
| 17299 } | 17299 } |
| 17300 | 17300 |
| 17301 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 17301 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 17302 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE
NTIFIER_AS_TYPEDEF_NAME); | 17302 _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_ID
ENTIFIER_AS_TYPEDEF_NAME); |
| 17303 checkForDefaultValueInFunctionTypeAlias(node); | 17303 _checkForDefaultValueInFunctionTypeAlias(node); |
| 17304 checkForTypeAliasCannotReferenceItself_function(node); | 17304 _checkForTypeAliasCannotReferenceItself_function(node); |
| 17305 return super.visitFunctionTypeAlias(node); | 17305 return super.visitFunctionTypeAlias(node); |
| 17306 } | 17306 } |
| 17307 | 17307 |
| 17308 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { | 17308 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 17309 bool old = _isInFunctionTypedFormalParameter; | 17309 bool old = _isInFunctionTypedFormalParameter; |
| 17310 _isInFunctionTypedFormalParameter = true; | 17310 _isInFunctionTypedFormalParameter = true; |
| 17311 try { | 17311 try { |
| 17312 return super.visitFunctionTypedFormalParameter(node); | 17312 return super.visitFunctionTypedFormalParameter(node); |
| 17313 } finally { | 17313 } finally { |
| 17314 _isInFunctionTypedFormalParameter = old; | 17314 _isInFunctionTypedFormalParameter = old; |
| 17315 } | 17315 } |
| 17316 } | 17316 } |
| 17317 | 17317 |
| 17318 Object visitIfStatement(IfStatement node) { | 17318 Object visitIfStatement(IfStatement node) { |
| 17319 checkForNonBoolCondition(node.condition); | 17319 _checkForNonBoolCondition(node.condition); |
| 17320 return super.visitIfStatement(node); | 17320 return super.visitIfStatement(node); |
| 17321 } | 17321 } |
| 17322 | 17322 |
| 17323 Object visitImportDirective(ImportDirective node) { | 17323 Object visitImportDirective(ImportDirective node) { |
| 17324 ImportElement importElement = node.element; | 17324 ImportElement importElement = node.element; |
| 17325 if (importElement != null) { | 17325 if (importElement != null) { |
| 17326 checkForImportDuplicateLibraryName(node, importElement); | 17326 _checkForImportDuplicateLibraryName(node, importElement); |
| 17327 checkForImportInternalLibrary(node, importElement); | 17327 _checkForImportInternalLibrary(node, importElement); |
| 17328 } | 17328 } |
| 17329 return super.visitImportDirective(node); | 17329 return super.visitImportDirective(node); |
| 17330 } | 17330 } |
| 17331 | 17331 |
| 17332 Object visitIndexExpression(IndexExpression node) { | 17332 Object visitIndexExpression(IndexExpression node) { |
| 17333 checkForArgumentTypeNotAssignableForArgument(node.index); | 17333 _checkForArgumentTypeNotAssignableForArgument(node.index); |
| 17334 return super.visitIndexExpression(node); | 17334 return super.visitIndexExpression(node); |
| 17335 } | 17335 } |
| 17336 | 17336 |
| 17337 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 17337 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 17338 _isInConstInstanceCreation = node.isConst; | 17338 _isInConstInstanceCreation = node.isConst; |
| 17339 try { | 17339 try { |
| 17340 ConstructorName constructorName = node.constructorName; | 17340 ConstructorName constructorName = node.constructorName; |
| 17341 TypeName typeName = constructorName.type; | 17341 TypeName typeName = constructorName.type; |
| 17342 Type2 type = typeName.type; | 17342 Type2 type = typeName.type; |
| 17343 if (type is InterfaceType) { | 17343 if (type is InterfaceType) { |
| 17344 InterfaceType interfaceType = type; | 17344 InterfaceType interfaceType = type; |
| 17345 checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); | 17345 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); |
| 17346 if (_isInConstInstanceCreation) { | 17346 if (_isInConstInstanceCreation) { |
| 17347 checkForConstWithNonConst(node); | 17347 _checkForConstWithNonConst(node); |
| 17348 checkForConstWithUndefinedConstructor(node); | 17348 _checkForConstWithUndefinedConstructor(node); |
| 17349 checkForConstWithTypeParametersInCreation(node); | 17349 _checkForConstWithTypeParametersInCreation(node); |
| 17350 } else { | 17350 } else { |
| 17351 checkForNewWithUndefinedConstructor(node); | 17351 _checkForNewWithUndefinedConstructor(node); |
| 17352 } | 17352 } |
| 17353 } | 17353 } |
| 17354 return super.visitInstanceCreationExpression(node); | 17354 return super.visitInstanceCreationExpression(node); |
| 17355 } finally { | 17355 } finally { |
| 17356 _isInConstInstanceCreation = false; | 17356 _isInConstInstanceCreation = false; |
| 17357 } | 17357 } |
| 17358 } | 17358 } |
| 17359 | 17359 |
| 17360 Object visitListLiteral(ListLiteral node) { | 17360 Object visitListLiteral(ListLiteral node) { |
| 17361 if (node.constKeyword != null) { | 17361 if (node.constKeyword != null) { |
| 17362 TypeArgumentList typeArguments = node.typeArguments; | 17362 TypeArgumentList typeArguments = node.typeArguments; |
| 17363 if (typeArguments != null) { | 17363 if (typeArguments != null) { |
| 17364 NodeList<TypeName> arguments = typeArguments.arguments; | 17364 NodeList<TypeName> arguments = typeArguments.arguments; |
| 17365 if (arguments.length != 0) { | 17365 if (arguments.length != 0) { |
| 17366 checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeE
rrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); | 17366 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTime
ErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); |
| 17367 } | 17367 } |
| 17368 } | 17368 } |
| 17369 } | 17369 } |
| 17370 checkForExpectedOneListTypeArgument(node); | 17370 _checkForExpectedOneListTypeArgument(node); |
| 17371 checkForListElementTypeNotAssignable(node); | 17371 _checkForListElementTypeNotAssignable(node); |
| 17372 return super.visitListLiteral(node); | 17372 return super.visitListLiteral(node); |
| 17373 } | 17373 } |
| 17374 | 17374 |
| 17375 Object visitMapLiteral(MapLiteral node) { | 17375 Object visitMapLiteral(MapLiteral node) { |
| 17376 TypeArgumentList typeArguments = node.typeArguments; | 17376 TypeArgumentList typeArguments = node.typeArguments; |
| 17377 if (typeArguments != null) { | 17377 if (typeArguments != null) { |
| 17378 NodeList<TypeName> arguments = typeArguments.arguments; | 17378 NodeList<TypeName> arguments = typeArguments.arguments; |
| 17379 if (arguments.length != 0) { | 17379 if (arguments.length != 0) { |
| 17380 if (node.constKeyword != null) { | 17380 if (node.constKeyword != null) { |
| 17381 checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeE
rrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); | 17381 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTime
ErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); |
| 17382 } | 17382 } |
| 17383 } | 17383 } |
| 17384 } | 17384 } |
| 17385 checkExpectedTwoMapTypeArguments(typeArguments); | 17385 _checkExpectedTwoMapTypeArguments(typeArguments); |
| 17386 checkForNonConstMapAsExpressionStatement(node); | 17386 _checkForNonConstMapAsExpressionStatement(node); |
| 17387 checkForMapTypeNotAssignable(node); | 17387 _checkForMapTypeNotAssignable(node); |
| 17388 checkForConstMapKeyExpressionTypeImplementsEquals(node); | 17388 _checkForConstMapKeyExpressionTypeImplementsEquals(node); |
| 17389 return super.visitMapLiteral(node); | 17389 return super.visitMapLiteral(node); |
| 17390 } | 17390 } |
| 17391 | 17391 |
| 17392 Object visitMethodDeclaration(MethodDeclaration node) { | 17392 Object visitMethodDeclaration(MethodDeclaration node) { |
| 17393 ExecutableElement previousFunction = _enclosingFunction; | 17393 ExecutableElement previousFunction = _enclosingFunction; |
| 17394 try { | 17394 try { |
| 17395 _isInStaticMethod = node.isStatic; | 17395 _isInStaticMethod = node.isStatic; |
| 17396 _enclosingFunction = node.element; | 17396 _enclosingFunction = node.element; |
| 17397 SimpleIdentifier identifier = node.name; | 17397 SimpleIdentifier identifier = node.name; |
| 17398 String methodName = ""; | 17398 String methodName = ""; |
| 17399 if (identifier != null) { | 17399 if (identifier != null) { |
| 17400 methodName = identifier.name; | 17400 methodName = identifier.name; |
| 17401 } | 17401 } |
| 17402 if (node.isSetter || node.isGetter) { | 17402 if (node.isSetter || node.isGetter) { |
| 17403 checkForMismatchedAccessorTypes(node, methodName); | 17403 _checkForMismatchedAccessorTypes(node, methodName); |
| 17404 } | 17404 } |
| 17405 if (node.isGetter) { | 17405 if (node.isGetter) { |
| 17406 checkForConflictingStaticGetterAndInstanceSetter(node); | 17406 _checkForConflictingStaticGetterAndInstanceSetter(node); |
| 17407 } else if (node.isSetter) { | 17407 } else if (node.isSetter) { |
| 17408 checkForWrongNumberOfParametersForSetter(node.name, node.parameters); | 17408 _checkForWrongNumberOfParametersForSetter(node.name, node.parameters); |
| 17409 checkForNonVoidReturnTypeForSetter(node.returnType); | 17409 _checkForNonVoidReturnTypeForSetter(node.returnType); |
| 17410 checkForConflictingStaticSetterAndInstanceMember(node); | 17410 _checkForConflictingStaticSetterAndInstanceMember(node); |
| 17411 } else if (node.isOperator) { | 17411 } else if (node.isOperator) { |
| 17412 checkForOptionalParameterInOperator(node); | 17412 _checkForOptionalParameterInOperator(node); |
| 17413 checkForWrongNumberOfParametersForOperator(node); | 17413 _checkForWrongNumberOfParametersForOperator(node); |
| 17414 checkForNonVoidReturnTypeForOperator(node); | 17414 _checkForNonVoidReturnTypeForOperator(node); |
| 17415 } | 17415 } |
| 17416 checkForConcreteClassWithAbstractMember(node); | 17416 _checkForConcreteClassWithAbstractMember(node); |
| 17417 checkForAllInvalidOverrideErrorCodesForMethod(node); | 17417 _checkForAllInvalidOverrideErrorCodesForMethod(node); |
| 17418 return super.visitMethodDeclaration(node); | 17418 return super.visitMethodDeclaration(node); |
| 17419 } finally { | 17419 } finally { |
| 17420 _enclosingFunction = previousFunction; | 17420 _enclosingFunction = previousFunction; |
| 17421 _isInStaticMethod = false; | 17421 _isInStaticMethod = false; |
| 17422 } | 17422 } |
| 17423 } | 17423 } |
| 17424 | 17424 |
| 17425 Object visitMethodInvocation(MethodInvocation node) { | 17425 Object visitMethodInvocation(MethodInvocation node) { |
| 17426 Expression target = node.realTarget; | 17426 Expression target = node.realTarget; |
| 17427 SimpleIdentifier methodName = node.methodName; | 17427 SimpleIdentifier methodName = node.methodName; |
| 17428 if (target != null) { | 17428 if (target != null) { |
| 17429 ClassElement typeReference = ElementResolver.getTypeReference(target); | 17429 ClassElement typeReference = ElementResolver.getTypeReference(target); |
| 17430 checkForStaticAccessToInstanceMember(typeReference, methodName); | 17430 _checkForStaticAccessToInstanceMember(typeReference, methodName); |
| 17431 checkForInstanceAccessToStaticMember(typeReference, methodName); | 17431 _checkForInstanceAccessToStaticMember(typeReference, methodName); |
| 17432 } else { | 17432 } else { |
| 17433 checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 17433 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); |
| 17434 } | 17434 } |
| 17435 return super.visitMethodInvocation(node); | 17435 return super.visitMethodInvocation(node); |
| 17436 } | 17436 } |
| 17437 | 17437 |
| 17438 Object visitNativeClause(NativeClause node) { | 17438 Object visitNativeClause(NativeClause node) { |
| 17439 // TODO(brianwilkerson) Figure out the right rule for when 'native' is allow
ed. | 17439 // TODO(brianwilkerson) Figure out the right rule for when 'native' is allow
ed. |
| 17440 if (!_isInSystemLibrary) { | 17440 if (!_isInSystemLibrary) { |
| 17441 _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK
_CODE, node, []); | 17441 _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK
_CODE, node, []); |
| 17442 } | 17442 } |
| 17443 return super.visitNativeClause(node); | 17443 return super.visitNativeClause(node); |
| 17444 } | 17444 } |
| 17445 | 17445 |
| 17446 Object visitNativeFunctionBody(NativeFunctionBody node) { | 17446 Object visitNativeFunctionBody(NativeFunctionBody node) { |
| 17447 checkForNativeFunctionBodyInNonSDKCode(node); | 17447 _checkForNativeFunctionBodyInNonSDKCode(node); |
| 17448 return super.visitNativeFunctionBody(node); | 17448 return super.visitNativeFunctionBody(node); |
| 17449 } | 17449 } |
| 17450 | 17450 |
| 17451 Object visitPostfixExpression(PostfixExpression node) { | 17451 Object visitPostfixExpression(PostfixExpression node) { |
| 17452 checkForAssignmentToFinal(node.operand); | 17452 _checkForAssignmentToFinal(node.operand); |
| 17453 checkForIntNotAssignable(node.operand); | 17453 _checkForIntNotAssignable(node.operand); |
| 17454 return super.visitPostfixExpression(node); | 17454 return super.visitPostfixExpression(node); |
| 17455 } | 17455 } |
| 17456 | 17456 |
| 17457 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 17457 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 17458 if (node.parent is! Annotation) { | 17458 if (node.parent is! Annotation) { |
| 17459 ClassElement typeReference = ElementResolver.getTypeReference(node.prefix)
; | 17459 ClassElement typeReference = ElementResolver.getTypeReference(node.prefix)
; |
| 17460 SimpleIdentifier name = node.identifier; | 17460 SimpleIdentifier name = node.identifier; |
| 17461 checkForStaticAccessToInstanceMember(typeReference, name); | 17461 _checkForStaticAccessToInstanceMember(typeReference, name); |
| 17462 checkForInstanceAccessToStaticMember(typeReference, name); | 17462 _checkForInstanceAccessToStaticMember(typeReference, name); |
| 17463 } | 17463 } |
| 17464 return super.visitPrefixedIdentifier(node); | 17464 return super.visitPrefixedIdentifier(node); |
| 17465 } | 17465 } |
| 17466 | 17466 |
| 17467 Object visitPrefixExpression(PrefixExpression node) { | 17467 Object visitPrefixExpression(PrefixExpression node) { |
| 17468 sc.TokenType operatorType = node.operator.type; | 17468 sc.TokenType operatorType = node.operator.type; |
| 17469 Expression operand = node.operand; | 17469 Expression operand = node.operand; |
| 17470 if (identical(operatorType, sc.TokenType.BANG)) { | 17470 if (identical(operatorType, sc.TokenType.BANG)) { |
| 17471 checkForNonBoolNegationExpression(operand); | 17471 _checkForNonBoolNegationExpression(operand); |
| 17472 } else if (operatorType.isIncrementOperator) { | 17472 } else if (operatorType.isIncrementOperator) { |
| 17473 checkForAssignmentToFinal(operand); | 17473 _checkForAssignmentToFinal(operand); |
| 17474 } | 17474 } |
| 17475 checkForIntNotAssignable(operand); | 17475 _checkForIntNotAssignable(operand); |
| 17476 return super.visitPrefixExpression(node); | 17476 return super.visitPrefixExpression(node); |
| 17477 } | 17477 } |
| 17478 | 17478 |
| 17479 Object visitPropertyAccess(PropertyAccess node) { | 17479 Object visitPropertyAccess(PropertyAccess node) { |
| 17480 ClassElement typeReference = ElementResolver.getTypeReference(node.realTarge
t); | 17480 ClassElement typeReference = ElementResolver.getTypeReference(node.realTarge
t); |
| 17481 SimpleIdentifier propertyName = node.propertyName; | 17481 SimpleIdentifier propertyName = node.propertyName; |
| 17482 checkForStaticAccessToInstanceMember(typeReference, propertyName); | 17482 _checkForStaticAccessToInstanceMember(typeReference, propertyName); |
| 17483 checkForInstanceAccessToStaticMember(typeReference, propertyName); | 17483 _checkForInstanceAccessToStaticMember(typeReference, propertyName); |
| 17484 return super.visitPropertyAccess(node); | 17484 return super.visitPropertyAccess(node); |
| 17485 } | 17485 } |
| 17486 | 17486 |
| 17487 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { | 17487 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation
node) { |
| 17488 _isInConstructorInitializer = true; | 17488 _isInConstructorInitializer = true; |
| 17489 try { | 17489 try { |
| 17490 return super.visitRedirectingConstructorInvocation(node); | 17490 return super.visitRedirectingConstructorInvocation(node); |
| 17491 } finally { | 17491 } finally { |
| 17492 _isInConstructorInitializer = false; | 17492 _isInConstructorInitializer = false; |
| 17493 } | 17493 } |
| 17494 } | 17494 } |
| 17495 | 17495 |
| 17496 Object visitRethrowExpression(RethrowExpression node) { | 17496 Object visitRethrowExpression(RethrowExpression node) { |
| 17497 checkForRethrowOutsideCatch(node); | 17497 _checkForRethrowOutsideCatch(node); |
| 17498 return super.visitRethrowExpression(node); | 17498 return super.visitRethrowExpression(node); |
| 17499 } | 17499 } |
| 17500 | 17500 |
| 17501 Object visitReturnStatement(ReturnStatement node) { | 17501 Object visitReturnStatement(ReturnStatement node) { |
| 17502 if (node.expression == null) { | 17502 if (node.expression == null) { |
| 17503 _returnsWithout.add(node); | 17503 _returnsWithout.add(node); |
| 17504 } else { | 17504 } else { |
| 17505 _returnsWith.add(node); | 17505 _returnsWith.add(node); |
| 17506 } | 17506 } |
| 17507 checkForAllReturnStatementErrorCodes(node); | 17507 _checkForAllReturnStatementErrorCodes(node); |
| 17508 return super.visitReturnStatement(node); | 17508 return super.visitReturnStatement(node); |
| 17509 } | 17509 } |
| 17510 | 17510 |
| 17511 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 17511 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 17512 checkForConstFormalParameter(node); | 17512 _checkForConstFormalParameter(node); |
| 17513 checkForPrivateOptionalParameter(node); | 17513 _checkForPrivateOptionalParameter(node); |
| 17514 return super.visitSimpleFormalParameter(node); | 17514 return super.visitSimpleFormalParameter(node); |
| 17515 } | 17515 } |
| 17516 | 17516 |
| 17517 Object visitSimpleIdentifier(SimpleIdentifier node) { | 17517 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 17518 checkForImplicitThisReferenceInInitializer(node); | 17518 _checkForImplicitThisReferenceInInitializer(node); |
| 17519 if (!isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) { | 17519 if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) { |
| 17520 checkForUnqualifiedReferenceToNonLocalStaticMember(node); | 17520 _checkForUnqualifiedReferenceToNonLocalStaticMember(node); |
| 17521 } | 17521 } |
| 17522 return super.visitSimpleIdentifier(node); | 17522 return super.visitSimpleIdentifier(node); |
| 17523 } | 17523 } |
| 17524 | 17524 |
| 17525 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 17525 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 17526 _isInConstructorInitializer = true; | 17526 _isInConstructorInitializer = true; |
| 17527 try { | 17527 try { |
| 17528 return super.visitSuperConstructorInvocation(node); | 17528 return super.visitSuperConstructorInvocation(node); |
| 17529 } finally { | 17529 } finally { |
| 17530 _isInConstructorInitializer = false; | 17530 _isInConstructorInitializer = false; |
| 17531 } | 17531 } |
| 17532 } | 17532 } |
| 17533 | 17533 |
| 17534 Object visitSwitchStatement(SwitchStatement node) { | 17534 Object visitSwitchStatement(SwitchStatement node) { |
| 17535 checkForInconsistentCaseExpressionTypes(node); | 17535 _checkForInconsistentCaseExpressionTypes(node); |
| 17536 checkForSwitchExpressionNotAssignable(node); | 17536 _checkForSwitchExpressionNotAssignable(node); |
| 17537 checkForCaseBlocksNotTerminated(node); | 17537 _checkForCaseBlocksNotTerminated(node); |
| 17538 return super.visitSwitchStatement(node); | 17538 return super.visitSwitchStatement(node); |
| 17539 } | 17539 } |
| 17540 | 17540 |
| 17541 Object visitThisExpression(ThisExpression node) { | 17541 Object visitThisExpression(ThisExpression node) { |
| 17542 checkForInvalidReferenceToThis(node); | 17542 _checkForInvalidReferenceToThis(node); |
| 17543 return super.visitThisExpression(node); | 17543 return super.visitThisExpression(node); |
| 17544 } | 17544 } |
| 17545 | 17545 |
| 17546 Object visitThrowExpression(ThrowExpression node) { | 17546 Object visitThrowExpression(ThrowExpression node) { |
| 17547 checkForConstEvalThrowsException(node); | 17547 _checkForConstEvalThrowsException(node); |
| 17548 return super.visitThrowExpression(node); | 17548 return super.visitThrowExpression(node); |
| 17549 } | 17549 } |
| 17550 | 17550 |
| 17551 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 17551 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 17552 checkForFinalNotInitialized(node.variables); | 17552 _checkForFinalNotInitialized(node.variables); |
| 17553 return super.visitTopLevelVariableDeclaration(node); | 17553 return super.visitTopLevelVariableDeclaration(node); |
| 17554 } | 17554 } |
| 17555 | 17555 |
| 17556 Object visitTypeName(TypeName node) { | 17556 Object visitTypeName(TypeName node) { |
| 17557 checkForTypeArgumentNotMatchingBounds(node); | 17557 _checkForTypeArgumentNotMatchingBounds(node); |
| 17558 checkForTypeParameterReferencedByStatic(node); | 17558 _checkForTypeParameterReferencedByStatic(node); |
| 17559 return super.visitTypeName(node); | 17559 return super.visitTypeName(node); |
| 17560 } | 17560 } |
| 17561 | 17561 |
| 17562 Object visitTypeParameter(TypeParameter node) { | 17562 Object visitTypeParameter(TypeParameter node) { |
| 17563 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE
NTIFIER_AS_TYPE_PARAMETER_NAME); | 17563 _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_ID
ENTIFIER_AS_TYPE_PARAMETER_NAME); |
| 17564 checkForTypeParameterSupertypeOfItsBound(node); | 17564 _checkForTypeParameterSupertypeOfItsBound(node); |
| 17565 return super.visitTypeParameter(node); | 17565 return super.visitTypeParameter(node); |
| 17566 } | 17566 } |
| 17567 | 17567 |
| 17568 Object visitVariableDeclaration(VariableDeclaration node) { | 17568 Object visitVariableDeclaration(VariableDeclaration node) { |
| 17569 SimpleIdentifier nameNode = node.name; | 17569 SimpleIdentifier nameNode = node.name; |
| 17570 Expression initializerNode = node.initializer; | 17570 Expression initializerNode = node.initializer; |
| 17571 // do checks | 17571 // do checks |
| 17572 checkForInvalidAssignment(nameNode, initializerNode); | 17572 _checkForInvalidAssignment(nameNode, initializerNode); |
| 17573 // visit name | 17573 // visit name |
| 17574 nameNode.accept(this); | 17574 nameNode.accept(this); |
| 17575 // visit initializer | 17575 // visit initializer |
| 17576 String name = nameNode.name; | 17576 String name = nameNode.name; |
| 17577 _namesForReferenceToDeclaredVariableInInitializer.add(name); | 17577 _namesForReferenceToDeclaredVariableInInitializer.add(name); |
| 17578 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; | 17578 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; |
| 17579 try { | 17579 try { |
| 17580 if (initializerNode != null) { | 17580 if (initializerNode != null) { |
| 17581 initializerNode.accept(this); | 17581 initializerNode.accept(this); |
| 17582 } | 17582 } |
| 17583 } finally { | 17583 } finally { |
| 17584 _isInInstanceVariableInitializer = false; | 17584 _isInInstanceVariableInitializer = false; |
| 17585 _namesForReferenceToDeclaredVariableInInitializer.remove(name); | 17585 _namesForReferenceToDeclaredVariableInInitializer.remove(name); |
| 17586 } | 17586 } |
| 17587 // done | 17587 // done |
| 17588 return null; | 17588 return null; |
| 17589 } | 17589 } |
| 17590 | 17590 |
| 17591 Object visitVariableDeclarationList(VariableDeclarationList node) => super.vis
itVariableDeclarationList(node); | 17591 Object visitVariableDeclarationList(VariableDeclarationList node) => super.vis
itVariableDeclarationList(node); |
| 17592 | 17592 |
| 17593 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { | 17593 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { |
| 17594 checkForFinalNotInitialized(node.variables); | 17594 _checkForFinalNotInitialized(node.variables); |
| 17595 return super.visitVariableDeclarationStatement(node); | 17595 return super.visitVariableDeclarationStatement(node); |
| 17596 } | 17596 } |
| 17597 | 17597 |
| 17598 Object visitWhileStatement(WhileStatement node) { | 17598 Object visitWhileStatement(WhileStatement node) { |
| 17599 checkForNonBoolCondition(node.condition); | 17599 _checkForNonBoolCondition(node.condition); |
| 17600 return super.visitWhileStatement(node); | 17600 return super.visitWhileStatement(node); |
| 17601 } | 17601 } |
| 17602 | 17602 |
| 17603 /** | 17603 /** |
| 17604 * This verifies if the passed map literal has type arguments then there is ex
actly two. | 17604 * This verifies if the passed map literal has type arguments then there is ex
actly two. |
| 17605 * | 17605 * |
| 17606 * @param node the map literal to evaluate | 17606 * @param node the map literal to evaluate |
| 17607 * @return `true` if and only if an error code is generated on the passed node | 17607 * @return `true` if and only if an error code is generated on the passed node |
| 17608 * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS | 17608 * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS |
| 17609 */ | 17609 */ |
| 17610 bool checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { | 17610 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { |
| 17611 // has type arguments | 17611 // has type arguments |
| 17612 if (typeArguments == null) { | 17612 if (typeArguments == null) { |
| 17613 return false; | 17613 return false; |
| 17614 } | 17614 } |
| 17615 // check number of type arguments | 17615 // check number of type arguments |
| 17616 int num = typeArguments.arguments.length; | 17616 int num = typeArguments.arguments.length; |
| 17617 if (num == 2) { | 17617 if (num == 2) { |
| 17618 return false; | 17618 return false; |
| 17619 } | 17619 } |
| 17620 // report problem | 17620 // report problem |
| 17621 _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYP
E_ARGUMENTS, typeArguments, [num]); | 17621 _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYP
E_ARGUMENTS, typeArguments, [num]); |
| 17622 return true; | 17622 return true; |
| 17623 } | 17623 } |
| 17624 | 17624 |
| 17625 /** | 17625 /** |
| 17626 * This verifies that the passed constructor declaration does not violate any
of the error codes | 17626 * This verifies that the passed constructor declaration does not violate any
of the error codes |
| 17627 * relating to the initialization of fields in the enclosing class. | 17627 * relating to the initialization of fields in the enclosing class. |
| 17628 * | 17628 * |
| 17629 * @param node the [ConstructorDeclaration] to evaluate | 17629 * @param node the [ConstructorDeclaration] to evaluate |
| 17630 * @return `true` if and only if an error code is generated on the passed node | 17630 * @return `true` if and only if an error code is generated on the passed node |
| 17631 * @see #initialFieldElementsMap | 17631 * @see #initialFieldElementsMap |
| 17632 * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR | 17632 * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR |
| 17633 * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES | 17633 * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES |
| 17634 */ | 17634 */ |
| 17635 bool checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { | 17635 bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { |
| 17636 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod
e.externalKeyword != null) { | 17636 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod
e.externalKeyword != null) { |
| 17637 return false; | 17637 return false; |
| 17638 } | 17638 } |
| 17639 // Ignore if native class. | 17639 // Ignore if native class. |
| 17640 if (_isInNativeClass) { | 17640 if (_isInNativeClass) { |
| 17641 return false; | 17641 return false; |
| 17642 } | 17642 } |
| 17643 bool foundError = false; | 17643 bool foundError = false; |
| 17644 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_
STATE>.from(_initialFieldElementsMap); | 17644 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_
STATE>.from(_initialFieldElementsMap); |
| 17645 // Visit all of the field formal parameters | 17645 // Visit all of the field formal parameters |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17726 * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL | 17726 * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL |
| 17727 * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED | 17727 * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED |
| 17728 * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE | 17728 * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE |
| 17729 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE | 17729 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE |
| 17730 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE | 17730 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE |
| 17731 * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE | 17731 * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE |
| 17732 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE | 17732 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE |
| 17733 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE | 17733 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE |
| 17734 * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES | 17734 * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES |
| 17735 */ | 17735 */ |
| 17736 bool checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement,
ExecutableElement overriddenExecutable, List<ParameterElement> parameters, List
<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { | 17736 bool _checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement
, ExecutableElement overriddenExecutable, List<ParameterElement> parameters, Lis
t<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { |
| 17737 bool isGetter = false; | 17737 bool isGetter = false; |
| 17738 bool isSetter = false; | 17738 bool isSetter = false; |
| 17739 if (executableElement is PropertyAccessorElement) { | 17739 if (executableElement is PropertyAccessorElement) { |
| 17740 PropertyAccessorElement accessorElement = executableElement; | 17740 PropertyAccessorElement accessorElement = executableElement; |
| 17741 isGetter = accessorElement.isGetter; | 17741 isGetter = accessorElement.isGetter; |
| 17742 isSetter = accessorElement.isSetter; | 17742 isSetter = accessorElement.isSetter; |
| 17743 } | 17743 } |
| 17744 String executableElementName = executableElement.name; | 17744 String executableElementName = executableElement.name; |
| 17745 // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC | 17745 // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC |
| 17746 if (overriddenExecutable == null) { | 17746 if (overriddenExecutable == null) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17933 // Next compare the list of optional parameter elements to the list of overr
idden optional | 17933 // Next compare the list of optional parameter elements to the list of overr
idden optional |
| 17934 // parameter elements. | 17934 // parameter elements. |
| 17935 // | 17935 // |
| 17936 if (parameterElts.length > 0) { | 17936 if (parameterElts.length > 0) { |
| 17937 if (identical(parameterElts[0].parameterKind, ParameterKind.NAMED)) { | 17937 if (identical(parameterElts[0].parameterKind, ParameterKind.NAMED)) { |
| 17938 // Named parameters, consider the names when matching the parameterElts
to the overriddenParameterElts | 17938 // Named parameters, consider the names when matching the parameterElts
to the overriddenParameterElts |
| 17939 for (int i = 0; i < parameterElts.length; i++) { | 17939 for (int i = 0; i < parameterElts.length; i++) { |
| 17940 ParameterElementImpl parameterElt = parameterElts[i]; | 17940 ParameterElementImpl parameterElt = parameterElts[i]; |
| 17941 EvaluationResultImpl result = parameterElt.evaluationResult; | 17941 EvaluationResultImpl result = parameterElt.evaluationResult; |
| 17942 // TODO (jwren) Ignore Object types, see Dart bug 11287 | 17942 // TODO (jwren) Ignore Object types, see Dart bug 11287 |
| 17943 if (isUserDefinedObject(result)) { | 17943 if (_isUserDefinedObject(result)) { |
| 17944 continue; | 17944 continue; |
| 17945 } | 17945 } |
| 17946 String parameterName = parameterElt.name; | 17946 String parameterName = parameterElt.name; |
| 17947 for (int j = 0; j < overriddenParameterElts.length; j++) { | 17947 for (int j = 0; j < overriddenParameterElts.length; j++) { |
| 17948 ParameterElementImpl overriddenParameterElt = overriddenParameterElt
s[j]; | 17948 ParameterElementImpl overriddenParameterElt = overriddenParameterElt
s[j]; |
| 17949 String overriddenParameterName = overriddenParameterElt.name; | 17949 String overriddenParameterName = overriddenParameterElt.name; |
| 17950 if (parameterName != null && parameterName == overriddenParameterNam
e) { | 17950 if (parameterName != null && parameterName == overriddenParameterNam
e) { |
| 17951 EvaluationResultImpl overriddenResult = overriddenParameterElt.eva
luationResult; | 17951 EvaluationResultImpl overriddenResult = overriddenParameterElt.eva
luationResult; |
| 17952 if (isUserDefinedObject(overriddenResult)) { | 17952 if (_isUserDefinedObject(overriddenResult)) { |
| 17953 break; | 17953 break; |
| 17954 } | 17954 } |
| 17955 if (!result.equalValues(_typeProvider, overriddenResult)) { | 17955 if (!result.equalValues(_typeProvider, overriddenResult)) { |
| 17956 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVER
RIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [ | 17956 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVER
RIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [ |
| 17957 overriddenExecutable.enclosingElement.displayName, | 17957 overriddenExecutable.enclosingElement.displayName, |
| 17958 overriddenExecutable.displayName, | 17958 overriddenExecutable.displayName, |
| 17959 parameterName]); | 17959 parameterName]); |
| 17960 foundError = true; | 17960 foundError = true; |
| 17961 } | 17961 } |
| 17962 } | 17962 } |
| 17963 } | 17963 } |
| 17964 } | 17964 } |
| 17965 } else { | 17965 } else { |
| 17966 // Positional parameters, consider the positions when matching the param
eterElts to the overriddenParameterElts | 17966 // Positional parameters, consider the positions when matching the param
eterElts to the overriddenParameterElts |
| 17967 for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.
length; i++) { | 17967 for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.
length; i++) { |
| 17968 ParameterElementImpl parameterElt = parameterElts[i]; | 17968 ParameterElementImpl parameterElt = parameterElts[i]; |
| 17969 EvaluationResultImpl result = parameterElt.evaluationResult; | 17969 EvaluationResultImpl result = parameterElt.evaluationResult; |
| 17970 // TODO (jwren) Ignore Object types, see Dart bug 11287 | 17970 // TODO (jwren) Ignore Object types, see Dart bug 11287 |
| 17971 if (isUserDefinedObject(result)) { | 17971 if (_isUserDefinedObject(result)) { |
| 17972 continue; | 17972 continue; |
| 17973 } | 17973 } |
| 17974 ParameterElementImpl overriddenParameterElt = overriddenParameterElts[
i]; | 17974 ParameterElementImpl overriddenParameterElt = overriddenParameterElts[
i]; |
| 17975 EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluat
ionResult; | 17975 EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluat
ionResult; |
| 17976 if (isUserDefinedObject(overriddenResult)) { | 17976 if (_isUserDefinedObject(overriddenResult)) { |
| 17977 continue; | 17977 continue; |
| 17978 } | 17978 } |
| 17979 if (!result.equalValues(_typeProvider, overriddenResult)) { | 17979 if (!result.equalValues(_typeProvider, overriddenResult)) { |
| 17980 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE
_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [ | 17980 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE
_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [ |
| 17981 overriddenExecutable.enclosingElement.displayName, | 17981 overriddenExecutable.enclosingElement.displayName, |
| 17982 overriddenExecutable.displayName]); | 17982 overriddenExecutable.displayName]); |
| 17983 foundError = true; | 17983 foundError = true; |
| 17984 } | 17984 } |
| 17985 } | 17985 } |
| 17986 } | 17986 } |
| 17987 } | 17987 } |
| 17988 return foundError; | 17988 return foundError; |
| 17989 } | 17989 } |
| 17990 | 17990 |
| 17991 /** | 17991 /** |
| 17992 * This checks the passed executable element against override-error codes. Thi
s method computes | 17992 * This checks the passed executable element against override-error codes. Thi
s method computes |
| 17993 * the passed executableElement is overriding and calls | 17993 * the passed executableElement is overriding and calls |
| 17994 * [checkForAllInvalidOverrideErrorCodes] | 17994 * [checkForAllInvalidOverrideErrorCodes] |
| 17995 * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement
], this | 17995 * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement
], this |
| 17996 * method loops through the array in the [MultiplyInheritedExecutableElement]. | 17996 * method loops through the array in the [MultiplyInheritedExecutableElement]. |
| 17997 * | 17997 * |
| 17998 * @param executableElement a non-null [ExecutableElement] to evaluate | 17998 * @param executableElement a non-null [ExecutableElement] to evaluate |
| 17999 * @param parameters the parameters of the executable element | 17999 * @param parameters the parameters of the executable element |
| 18000 * @param errorNameTarget the node to report problems on | 18000 * @param errorNameTarget the node to report problems on |
| 18001 * @return `true` if and only if an error code is generated on the passed node | 18001 * @return `true` if and only if an error code is generated on the passed node |
| 18002 */ | 18002 */ |
| 18003 bool checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement execu
tableElement, List<ParameterElement> parameters, List<AstNode> parameterLocation
s, SimpleIdentifier errorNameTarget) { | 18003 bool _checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement exec
utableElement, List<ParameterElement> parameters, List<AstNode> parameterLocatio
ns, SimpleIdentifier errorNameTarget) { |
| 18004 // | 18004 // |
| 18005 // Compute the overridden executable from the InheritanceManager | 18005 // Compute the overridden executable from the InheritanceManager |
| 18006 // | 18006 // |
| 18007 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan
ce(_enclosingClass, executableElement.name); | 18007 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan
ce(_enclosingClass, executableElement.name); |
| 18008 // | 18008 // |
| 18009 // If the result is a MultiplyInheritedExecutableElement call | 18009 // If the result is a MultiplyInheritedExecutableElement call |
| 18010 // checkForAllInvalidOverrideErrorCodes on all of the elements, until an err
or is found. | 18010 // checkForAllInvalidOverrideErrorCodes on all of the elements, until an err
or is found. |
| 18011 // | 18011 // |
| 18012 if (overriddenExecutable is MultiplyInheritedExecutableElement) { | 18012 if (overriddenExecutable is MultiplyInheritedExecutableElement) { |
| 18013 MultiplyInheritedExecutableElement multiplyInheritedElement = overriddenEx
ecutable; | 18013 MultiplyInheritedExecutableElement multiplyInheritedElement = overriddenEx
ecutable; |
| 18014 List<ExecutableElement> overriddenElement = multiplyInheritedElement.inher
itedElements; | 18014 List<ExecutableElement> overriddenElement = multiplyInheritedElement.inher
itedElements; |
| 18015 for (int i = 0; i < overriddenElement.length; i++) { | 18015 for (int i = 0; i < overriddenElement.length; i++) { |
| 18016 if (checkForAllInvalidOverrideErrorCodes(executableElement, overriddenEl
ement[i], parameters, parameterLocations, errorNameTarget)) { | 18016 if (_checkForAllInvalidOverrideErrorCodes(executableElement, overriddenE
lement[i], parameters, parameterLocations, errorNameTarget)) { |
| 18017 return true; | 18017 return true; |
| 18018 } | 18018 } |
| 18019 } | 18019 } |
| 18020 return false; | 18020 return false; |
| 18021 } | 18021 } |
| 18022 // | 18022 // |
| 18023 // Otherwise, just call checkForAllInvalidOverrideErrorCodes. | 18023 // Otherwise, just call checkForAllInvalidOverrideErrorCodes. |
| 18024 // | 18024 // |
| 18025 return checkForAllInvalidOverrideErrorCodes(executableElement, overriddenExe
cutable, parameters, parameterLocations, errorNameTarget); | 18025 return _checkForAllInvalidOverrideErrorCodes(executableElement, overriddenEx
ecutable, parameters, parameterLocations, errorNameTarget); |
| 18026 } | 18026 } |
| 18027 | 18027 |
| 18028 /** | 18028 /** |
| 18029 * This checks the passed field declaration against override-error codes. | 18029 * This checks the passed field declaration against override-error codes. |
| 18030 * | 18030 * |
| 18031 * @param node the [MethodDeclaration] to evaluate | 18031 * @param node the [MethodDeclaration] to evaluate |
| 18032 * @return `true` if and only if an error code is generated on the passed node | 18032 * @return `true` if and only if an error code is generated on the passed node |
| 18033 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) | 18033 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) |
| 18034 */ | 18034 */ |
| 18035 bool checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { | 18035 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { |
| 18036 if (_enclosingClass == null || node.isStatic) { | 18036 if (_enclosingClass == null || node.isStatic) { |
| 18037 return false; | 18037 return false; |
| 18038 } | 18038 } |
| 18039 bool hasProblems = false; | 18039 bool hasProblems = false; |
| 18040 VariableDeclarationList fields = node.fields; | 18040 VariableDeclarationList fields = node.fields; |
| 18041 for (VariableDeclaration field in fields.variables) { | 18041 for (VariableDeclaration field in fields.variables) { |
| 18042 FieldElement element = field.element as FieldElement; | 18042 FieldElement element = field.element as FieldElement; |
| 18043 if (element == null) { | 18043 if (element == null) { |
| 18044 continue; | 18044 continue; |
| 18045 } | 18045 } |
| 18046 PropertyAccessorElement getter = element.getter; | 18046 PropertyAccessorElement getter = element.getter; |
| 18047 PropertyAccessorElement setter = element.setter; | 18047 PropertyAccessorElement setter = element.setter; |
| 18048 SimpleIdentifier fieldName = field.name; | 18048 SimpleIdentifier fieldName = field.name; |
| 18049 if (getter != null) { | 18049 if (getter != null) { |
| 18050 hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideError
CodesForExecutable(getter, ParameterElementImpl.EMPTY_ARRAY, AstNode.EMPTY_ARRAY
, fieldName)); | 18050 hasProblems = javaBooleanOr(hasProblems, _checkForAllInvalidOverrideErro
rCodesForExecutable(getter, ParameterElementImpl.EMPTY_ARRAY, AstNode.EMPTY_ARRA
Y, fieldName)); |
| 18051 } | 18051 } |
| 18052 if (setter != null) { | 18052 if (setter != null) { |
| 18053 hasProblems = javaBooleanOr(hasProblems, checkForAllInvalidOverrideError
CodesForExecutable(setter, setter.parameters, <AstNode> [fieldName], fieldName))
; | 18053 hasProblems = javaBooleanOr(hasProblems, _checkForAllInvalidOverrideErro
rCodesForExecutable(setter, setter.parameters, <AstNode> [fieldName], fieldName)
); |
| 18054 } | 18054 } |
| 18055 } | 18055 } |
| 18056 return hasProblems; | 18056 return hasProblems; |
| 18057 } | 18057 } |
| 18058 | 18058 |
| 18059 /** | 18059 /** |
| 18060 * This checks the passed method declaration against override-error codes. | 18060 * This checks the passed method declaration against override-error codes. |
| 18061 * | 18061 * |
| 18062 * @param node the [MethodDeclaration] to evaluate | 18062 * @param node the [MethodDeclaration] to evaluate |
| 18063 * @return `true` if and only if an error code is generated on the passed node | 18063 * @return `true` if and only if an error code is generated on the passed node |
| 18064 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) | 18064 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) |
| 18065 */ | 18065 */ |
| 18066 bool checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) { | 18066 bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) { |
| 18067 if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionB
ody) { | 18067 if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionB
ody) { |
| 18068 return false; | 18068 return false; |
| 18069 } | 18069 } |
| 18070 ExecutableElement executableElement = node.element; | 18070 ExecutableElement executableElement = node.element; |
| 18071 if (executableElement == null) { | 18071 if (executableElement == null) { |
| 18072 return false; | 18072 return false; |
| 18073 } | 18073 } |
| 18074 SimpleIdentifier methodName = node.name; | 18074 SimpleIdentifier methodName = node.name; |
| 18075 if (methodName.isSynthetic) { | 18075 if (methodName.isSynthetic) { |
| 18076 return false; | 18076 return false; |
| 18077 } | 18077 } |
| 18078 FormalParameterList formalParameterList = node.parameters; | 18078 FormalParameterList formalParameterList = node.parameters; |
| 18079 NodeList<FormalParameter> parameterList = formalParameterList != null ? form
alParameterList.parameters : null; | 18079 NodeList<FormalParameter> parameterList = formalParameterList != null ? form
alParameterList.parameters : null; |
| 18080 List<AstNode> parameters = parameterList != null ? new List.from(parameterLi
st) : null; | 18080 List<AstNode> parameters = parameterList != null ? new List.from(parameterLi
st) : null; |
| 18081 return checkForAllInvalidOverrideErrorCodesForExecutable(executableElement,
executableElement.parameters, parameters, methodName); | 18081 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement,
executableElement.parameters, parameters, methodName); |
| 18082 } | 18082 } |
| 18083 | 18083 |
| 18084 /** | 18084 /** |
| 18085 * This verifies that all classes of the passed 'with' clause are valid. | 18085 * This verifies that all classes of the passed 'with' clause are valid. |
| 18086 * | 18086 * |
| 18087 * @param node the 'with' clause to evaluate | 18087 * @param node the 'with' clause to evaluate |
| 18088 * @return `true` if and only if an error code is generated on the passed node | 18088 * @return `true` if and only if an error code is generated on the passed node |
| 18089 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR | 18089 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR |
| 18090 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT | 18090 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT |
| 18091 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER | 18091 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER |
| 18092 */ | 18092 */ |
| 18093 bool checkForAllMixinErrorCodes(WithClause withClause) { | 18093 bool _checkForAllMixinErrorCodes(WithClause withClause) { |
| 18094 if (withClause == null) { | 18094 if (withClause == null) { |
| 18095 return false; | 18095 return false; |
| 18096 } | 18096 } |
| 18097 bool problemReported = false; | 18097 bool problemReported = false; |
| 18098 for (TypeName mixinName in withClause.mixinTypes) { | 18098 for (TypeName mixinName in withClause.mixinTypes) { |
| 18099 Type2 mixinType = mixinName.type; | 18099 Type2 mixinType = mixinName.type; |
| 18100 if (mixinType is! InterfaceType) { | 18100 if (mixinType is! InterfaceType) { |
| 18101 continue; | 18101 continue; |
| 18102 } | 18102 } |
| 18103 if (checkForExtendsOrImplementsDisallowedClass(mixinName, CompileTimeError
Code.MIXIN_OF_DISALLOWED_CLASS)) { | 18103 if (_checkForExtendsOrImplementsDisallowedClass(mixinName, CompileTimeErro
rCode.MIXIN_OF_DISALLOWED_CLASS)) { |
| 18104 problemReported = true; | 18104 problemReported = true; |
| 18105 } else { | 18105 } else { |
| 18106 ClassElement mixinElement = (mixinType as InterfaceType).element; | 18106 ClassElement mixinElement = (mixinType as InterfaceType).element; |
| 18107 problemReported = javaBooleanOr(problemReported, checkForMixinDeclaresCo
nstructor(mixinName, mixinElement)); | 18107 problemReported = javaBooleanOr(problemReported, _checkForMixinDeclaresC
onstructor(mixinName, mixinElement)); |
| 18108 problemReported = javaBooleanOr(problemReported, checkForMixinInheritsNo
tFromObject(mixinName, mixinElement)); | 18108 problemReported = javaBooleanOr(problemReported, _checkForMixinInheritsN
otFromObject(mixinName, mixinElement)); |
| 18109 problemReported = javaBooleanOr(problemReported, checkForMixinReferences
Super(mixinName, mixinElement)); | 18109 problemReported = javaBooleanOr(problemReported, _checkForMixinReference
sSuper(mixinName, mixinElement)); |
| 18110 } | 18110 } |
| 18111 } | 18111 } |
| 18112 return problemReported; | 18112 return problemReported; |
| 18113 } | 18113 } |
| 18114 | 18114 |
| 18115 /** | 18115 /** |
| 18116 * This checks error related to the redirected constructors. | 18116 * This checks error related to the redirected constructors. |
| 18117 * | 18117 * |
| 18118 * @param node the constructor declaration to evaluate | 18118 * @param node the constructor declaration to evaluate |
| 18119 * @return `true` if and only if an error code is generated on the passed node | 18119 * @return `true` if and only if an error code is generated on the passed node |
| 18120 * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE | 18120 * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE |
| 18121 * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE | 18121 * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE |
| 18122 * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR | 18122 * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR |
| 18123 */ | 18123 */ |
| 18124 bool checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { | 18124 bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { |
| 18125 // | 18125 // |
| 18126 // Prepare redirected constructor node | 18126 // Prepare redirected constructor node |
| 18127 // | 18127 // |
| 18128 ConstructorName redirectedConstructor = node.redirectedConstructor; | 18128 ConstructorName redirectedConstructor = node.redirectedConstructor; |
| 18129 if (redirectedConstructor == null) { | 18129 if (redirectedConstructor == null) { |
| 18130 return false; | 18130 return false; |
| 18131 } | 18131 } |
| 18132 // | 18132 // |
| 18133 // Prepare redirected constructor type | 18133 // Prepare redirected constructor type |
| 18134 // | 18134 // |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18184 * | 18184 * |
| 18185 * This checks that the return type matches the type of the declared return ty
pe in the enclosing | 18185 * This checks that the return type matches the type of the declared return ty
pe in the enclosing |
| 18186 * method or function. | 18186 * method or function. |
| 18187 * | 18187 * |
| 18188 * @param node the return statement to evaluate | 18188 * @param node the return statement to evaluate |
| 18189 * @return `true` if and only if an error code is generated on the passed node | 18189 * @return `true` if and only if an error code is generated on the passed node |
| 18190 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR | 18190 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 18191 * @see StaticWarningCode#RETURN_WITHOUT_VALUE | 18191 * @see StaticWarningCode#RETURN_WITHOUT_VALUE |
| 18192 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE | 18192 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE |
| 18193 */ | 18193 */ |
| 18194 bool checkForAllReturnStatementErrorCodes(ReturnStatement node) { | 18194 bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) { |
| 18195 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu
nction.type; | 18195 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu
nction.type; |
| 18196 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance :
functionType.returnType; | 18196 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance :
functionType.returnType; |
| 18197 Expression returnExpression = node.expression; | 18197 Expression returnExpression = node.expression; |
| 18198 // RETURN_IN_GENERATIVE_CONSTRUCTOR | 18198 // RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 18199 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !
(_enclosingFunction as ConstructorElement).isFactory; | 18199 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !
(_enclosingFunction as ConstructorElement).isFactory; |
| 18200 if (isGenerativeConstructor) { | 18200 if (isGenerativeConstructor) { |
| 18201 if (returnExpression == null) { | 18201 if (returnExpression == null) { |
| 18202 return false; | 18202 return false; |
| 18203 } | 18203 } |
| 18204 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIV
E_CONSTRUCTOR, returnExpression, []); | 18204 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIV
E_CONSTRUCTOR, returnExpression, []); |
| 18205 return true; | 18205 return true; |
| 18206 } | 18206 } |
| 18207 // RETURN_WITHOUT_VALUE | 18207 // RETURN_WITHOUT_VALUE |
| 18208 if (returnExpression == null) { | 18208 if (returnExpression == null) { |
| 18209 if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) { | 18209 if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) { |
| 18210 return false; | 18210 return false; |
| 18211 } | 18211 } |
| 18212 _errorReporter.reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE,
node, []); | 18212 _errorReporter.reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE,
node, []); |
| 18213 return true; | 18213 return true; |
| 18214 } | 18214 } |
| 18215 // RETURN_OF_INVALID_TYPE | 18215 // RETURN_OF_INVALID_TYPE |
| 18216 return checkForReturnOfInvalidType(returnExpression, expectedReturnType); | 18216 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); |
| 18217 } | 18217 } |
| 18218 | 18218 |
| 18219 /** | 18219 /** |
| 18220 * This verifies that the export namespace of the passed export directive does
not export any name | 18220 * This verifies that the export namespace of the passed export directive does
not export any name |
| 18221 * already exported by other export directive. | 18221 * already exported by other export directive. |
| 18222 * | 18222 * |
| 18223 * @param node the export directive node to report problem on | 18223 * @param node the export directive node to report problem on |
| 18224 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 18224 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
| 18225 * node was `null`, then this method is not called | 18225 * node was `null`, then this method is not called |
| 18226 * @return `true` if and only if an error code is generated on the passed node | 18226 * @return `true` if and only if an error code is generated on the passed node |
| 18227 * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT | 18227 * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT |
| 18228 */ | 18228 */ |
| 18229 bool checkForAmbiguousExport(ExportDirective node, ExportElement exportElement
) { | 18229 bool _checkForAmbiguousExport(ExportDirective node, ExportElement exportElemen
t) { |
| 18230 // prepare exported library | 18230 // prepare exported library |
| 18231 LibraryElement exportedLibrary = exportElement.exportedLibrary; | 18231 LibraryElement exportedLibrary = exportElement.exportedLibrary; |
| 18232 if (exportedLibrary == null) { | 18232 if (exportedLibrary == null) { |
| 18233 return false; | 18233 return false; |
| 18234 } | 18234 } |
| 18235 // check exported names | 18235 // check exported names |
| 18236 Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirecti
ve(exportElement); | 18236 Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirecti
ve(exportElement); |
| 18237 Map<String, Element> definedNames = namespace.definedNames; | 18237 Map<String, Element> definedNames = namespace.definedNames; |
| 18238 for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames))
{ | 18238 for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames))
{ |
| 18239 String name = definedEntry.getKey(); | 18239 String name = definedEntry.getKey(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 18257 * | 18257 * |
| 18258 * @param expression the expression to evaluate | 18258 * @param expression the expression to evaluate |
| 18259 * @param expectedStaticType the expected static type of the parameter | 18259 * @param expectedStaticType the expected static type of the parameter |
| 18260 * @param actualStaticType the actual static type of the argument | 18260 * @param actualStaticType the actual static type of the argument |
| 18261 * @param expectedPropagatedType the expected propagated type of the parameter
, may be | 18261 * @param expectedPropagatedType the expected propagated type of the parameter
, may be |
| 18262 * `null` | 18262 * `null` |
| 18263 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` | 18263 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` |
| 18264 * @return `true` if and only if an error code is generated on the passed node | 18264 * @return `true` if and only if an error code is generated on the passed node |
| 18265 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 18265 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 18266 */ | 18266 */ |
| 18267 bool checkForArgumentTypeNotAssignable(Expression expression, Type2 expectedSt
aticType, Type2 actualStaticType, Type2 expectedPropagatedType, Type2 actualProp
agatedType, ErrorCode errorCode) { | 18267 bool _checkForArgumentTypeNotAssignable(Expression expression, Type2 expectedS
taticType, Type2 actualStaticType, Type2 expectedPropagatedType, Type2 actualPro
pagatedType, ErrorCode errorCode) { |
| 18268 // | 18268 // |
| 18269 // Test static type information | 18269 // Test static type information |
| 18270 // | 18270 // |
| 18271 if (actualStaticType == null || expectedStaticType == null) { | 18271 if (actualStaticType == null || expectedStaticType == null) { |
| 18272 return false; | 18272 return false; |
| 18273 } | 18273 } |
| 18274 if (actualStaticType.isAssignableTo(expectedStaticType)) { | 18274 if (actualStaticType.isAssignableTo(expectedStaticType)) { |
| 18275 return false; | 18275 return false; |
| 18276 } | 18276 } |
| 18277 _errorReporter.reportErrorForNode(errorCode, expression, [ | 18277 _errorReporter.reportErrorForNode(errorCode, expression, [ |
| 18278 actualStaticType.displayName, | 18278 actualStaticType.displayName, |
| 18279 expectedStaticType.displayName]); | 18279 expectedStaticType.displayName]); |
| 18280 return true; | 18280 return true; |
| 18281 } | 18281 } |
| 18282 | 18282 |
| 18283 /** | 18283 /** |
| 18284 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 18284 * This verifies that the passed argument can be assigned to its corresponding
parameter. |
| 18285 * | 18285 * |
| 18286 * @param argument the argument to evaluate | 18286 * @param argument the argument to evaluate |
| 18287 * @return `true` if and only if an error code is generated on the passed node | 18287 * @return `true` if and only if an error code is generated on the passed node |
| 18288 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 18288 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 18289 */ | 18289 */ |
| 18290 bool checkForArgumentTypeNotAssignableForArgument(Expression argument) { | 18290 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { |
| 18291 if (argument == null) { | 18291 if (argument == null) { |
| 18292 return false; | 18292 return false; |
| 18293 } | 18293 } |
| 18294 ParameterElement staticParameterElement = argument.staticParameterElement; | 18294 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 18295 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; | 18295 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; |
| 18296 ParameterElement propagatedParameterElement = argument.propagatedParameterEl
ement; | 18296 ParameterElement propagatedParameterElement = argument.propagatedParameterEl
ement; |
| 18297 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; | 18297 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; |
| 18298 return checkForArgumentTypeNotAssignableWithExpectedTypes(argument, staticPa
rameterType, propagatedParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGN
ABLE); | 18298 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, staticP
arameterType, propagatedParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIG
NABLE); |
| 18299 } | 18299 } |
| 18300 | 18300 |
| 18301 /** | 18301 /** |
| 18302 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 18302 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
| 18303 * | 18303 * |
| 18304 * @param expression the expression to evaluate | 18304 * @param expression the expression to evaluate |
| 18305 * @param expectedStaticType the expected static type | 18305 * @param expectedStaticType the expected static type |
| 18306 * @param expectedPropagatedType the expected propagated type, may be `null` | 18306 * @param expectedPropagatedType the expected propagated type, may be `null` |
| 18307 * @return `true` if and only if an error code is generated on the passed node | 18307 * @return `true` if and only if an error code is generated on the passed node |
| 18308 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 18308 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 18309 */ | 18309 */ |
| 18310 bool checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression,
Type2 expectedStaticType, Type2 expectedPropagatedType, ErrorCode errorCode) =>
checkForArgumentTypeNotAssignable(expression, expectedStaticType, getStaticType
(expression), expectedPropagatedType, expression.propagatedType, errorCode); | 18310 bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression
, Type2 expectedStaticType, Type2 expectedPropagatedType, ErrorCode errorCode) =
> _checkForArgumentTypeNotAssignable(expression, expectedStaticType, _getStaticT
ype(expression), expectedPropagatedType, expression.propagatedType, errorCode); |
| 18311 | 18311 |
| 18312 /** | 18312 /** |
| 18313 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. | 18313 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. |
| 18314 * | 18314 * |
| 18315 * @param node the arguments to evaluate | 18315 * @param node the arguments to evaluate |
| 18316 * @return `true` if and only if an error code is generated on the passed node | 18316 * @return `true` if and only if an error code is generated on the passed node |
| 18317 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 18317 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 18318 */ | 18318 */ |
| 18319 bool checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) { | 18319 bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) { |
| 18320 if (argumentList == null) { | 18320 if (argumentList == null) { |
| 18321 return false; | 18321 return false; |
| 18322 } | 18322 } |
| 18323 bool problemReported = false; | 18323 bool problemReported = false; |
| 18324 for (Expression argument in argumentList.arguments) { | 18324 for (Expression argument in argumentList.arguments) { |
| 18325 problemReported = javaBooleanOr(problemReported, checkForArgumentTypeNotAs
signableForArgument(argument)); | 18325 problemReported = javaBooleanOr(problemReported, _checkForArgumentTypeNotA
ssignableForArgument(argument)); |
| 18326 } | 18326 } |
| 18327 // done | 18327 // done |
| 18328 return problemReported; | 18328 return problemReported; |
| 18329 } | 18329 } |
| 18330 | 18330 |
| 18331 /** | 18331 /** |
| 18332 * This verifies that the passed expression is not final. | 18332 * This verifies that the passed expression is not final. |
| 18333 * | 18333 * |
| 18334 * @param node the expression to evaluate | 18334 * @param node the expression to evaluate |
| 18335 * @return `true` if and only if an error code is generated on the passed node | 18335 * @return `true` if and only if an error code is generated on the passed node |
| 18336 * @see StaticWarningCode#ASSIGNMENT_TO_CONST | 18336 * @see StaticWarningCode#ASSIGNMENT_TO_CONST |
| 18337 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL | 18337 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL |
| 18338 * @see StaticWarningCode#ASSIGNMENT_TO_METHOD | 18338 * @see StaticWarningCode#ASSIGNMENT_TO_METHOD |
| 18339 */ | 18339 */ |
| 18340 bool checkForAssignmentToFinal(Expression expression) { | 18340 bool _checkForAssignmentToFinal(Expression expression) { |
| 18341 // prepare element | 18341 // prepare element |
| 18342 Element element = null; | 18342 Element element = null; |
| 18343 if (expression is Identifier) { | 18343 if (expression is Identifier) { |
| 18344 element = expression.staticElement; | 18344 element = expression.staticElement; |
| 18345 } | 18345 } |
| 18346 if (expression is PropertyAccess) { | 18346 if (expression is PropertyAccess) { |
| 18347 element = expression.propertyName.staticElement; | 18347 element = expression.propertyName.staticElement; |
| 18348 } | 18348 } |
| 18349 // check if element is assignable | 18349 // check if element is assignable |
| 18350 if (element is PropertyAccessorElement) { | 18350 if (element is PropertyAccessorElement) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 18378 * @param errorCode if the passed identifier is a keyword then this error code
is created on the | 18378 * @param errorCode if the passed identifier is a keyword then this error code
is created on the |
| 18379 * identifier, the error code will be one of | 18379 * identifier, the error code will be one of |
| 18380 * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME], | 18380 * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME], |
| 18381 * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]
or | 18381 * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]
or |
| 18382 * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME] | 18382 * [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME] |
| 18383 * @return `true` if and only if an error code is generated on the passed node | 18383 * @return `true` if and only if an error code is generated on the passed node |
| 18384 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME | 18384 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME |
| 18385 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME | 18385 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME |
| 18386 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME | 18386 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME |
| 18387 */ | 18387 */ |
| 18388 bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode er
rorCode) { | 18388 bool _checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode e
rrorCode) { |
| 18389 sc.Token token = identifier.token; | 18389 sc.Token token = identifier.token; |
| 18390 if (identical(token.type, sc.TokenType.KEYWORD)) { | 18390 if (identical(token.type, sc.TokenType.KEYWORD)) { |
| 18391 _errorReporter.reportErrorForNode(errorCode, identifier, [identifier.name]
); | 18391 _errorReporter.reportErrorForNode(errorCode, identifier, [identifier.name]
); |
| 18392 return true; | 18392 return true; |
| 18393 } | 18393 } |
| 18394 return false; | 18394 return false; |
| 18395 } | 18395 } |
| 18396 | 18396 |
| 18397 /** | 18397 /** |
| 18398 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or | 18398 * This verifies that the given switch case is terminated with 'break', 'conti
nue', 'return' or |
| 18399 * 'throw'. | 18399 * 'throw'. |
| 18400 * | 18400 * |
| 18401 * @param node the switch case to evaluate | 18401 * @param node the switch case to evaluate |
| 18402 * @return `true` if and only if an error code is generated on the passed node | 18402 * @return `true` if and only if an error code is generated on the passed node |
| 18403 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED | 18403 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED |
| 18404 */ | 18404 */ |
| 18405 bool checkForCaseBlockNotTerminated(SwitchCase node) { | 18405 bool _checkForCaseBlockNotTerminated(SwitchCase node) { |
| 18406 NodeList<Statement> statements = node.statements; | 18406 NodeList<Statement> statements = node.statements; |
| 18407 if (statements.isEmpty) { | 18407 if (statements.isEmpty) { |
| 18408 // fall-through without statements at all | 18408 // fall-through without statements at all |
| 18409 AstNode parent = node.parent; | 18409 AstNode parent = node.parent; |
| 18410 if (parent is SwitchStatement) { | 18410 if (parent is SwitchStatement) { |
| 18411 SwitchStatement switchStatement = parent; | 18411 SwitchStatement switchStatement = parent; |
| 18412 NodeList<SwitchMember> members = switchStatement.members; | 18412 NodeList<SwitchMember> members = switchStatement.members; |
| 18413 int index = members.indexOf(node); | 18413 int index = members.indexOf(node); |
| 18414 if (index != -1 && index < members.length - 1) { | 18414 if (index != -1 && index < members.length - 1) { |
| 18415 return false; | 18415 return false; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 18435 } | 18435 } |
| 18436 | 18436 |
| 18437 /** | 18437 /** |
| 18438 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', | 18438 * This verifies that the switch cases in the given switch statement is termin
ated with 'break', |
| 18439 * 'continue', 'return' or 'throw'. | 18439 * 'continue', 'return' or 'throw'. |
| 18440 * | 18440 * |
| 18441 * @param node the switch statement containing the cases to be checked | 18441 * @param node the switch statement containing the cases to be checked |
| 18442 * @return `true` if and only if an error code is generated on the passed node | 18442 * @return `true` if and only if an error code is generated on the passed node |
| 18443 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED | 18443 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED |
| 18444 */ | 18444 */ |
| 18445 bool checkForCaseBlocksNotTerminated(SwitchStatement node) { | 18445 bool _checkForCaseBlocksNotTerminated(SwitchStatement node) { |
| 18446 bool foundError = false; | 18446 bool foundError = false; |
| 18447 NodeList<SwitchMember> members = node.members; | 18447 NodeList<SwitchMember> members = node.members; |
| 18448 int lastMember = members.length - 1; | 18448 int lastMember = members.length - 1; |
| 18449 for (int i = 0; i < lastMember; i++) { | 18449 for (int i = 0; i < lastMember; i++) { |
| 18450 SwitchMember member = members[i]; | 18450 SwitchMember member = members[i]; |
| 18451 if (member is SwitchCase) { | 18451 if (member is SwitchCase) { |
| 18452 foundError = javaBooleanOr(foundError, checkForCaseBlockNotTerminated(me
mber)); | 18452 foundError = javaBooleanOr(foundError, _checkForCaseBlockNotTerminated(m
ember)); |
| 18453 } | 18453 } |
| 18454 } | 18454 } |
| 18455 return foundError; | 18455 return foundError; |
| 18456 } | 18456 } |
| 18457 | 18457 |
| 18458 /** | 18458 /** |
| 18459 * This verifies that the passed switch statement does not have a case express
ion with the | 18459 * This verifies that the passed switch statement does not have a case express
ion with the |
| 18460 * operator '==' overridden. | 18460 * operator '==' overridden. |
| 18461 * | 18461 * |
| 18462 * @param node the switch statement to evaluate | 18462 * @param node the switch statement to evaluate |
| 18463 * @param type the common type of all 'case' expressions | 18463 * @param type the common type of all 'case' expressions |
| 18464 * @return `true` if and only if an error code is generated on the passed node | 18464 * @return `true` if and only if an error code is generated on the passed node |
| 18465 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS | 18465 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS |
| 18466 */ | 18466 */ |
| 18467 bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 ty
pe) { | 18467 bool _checkForCaseExpressionTypeImplementsEquals(SwitchStatement node, Type2 t
ype) { |
| 18468 if (!implementsEqualsWhenNotAllowed(type)) { | 18468 if (!_implementsEqualsWhenNotAllowed(type)) { |
| 18469 return false; | 18469 return false; |
| 18470 } | 18470 } |
| 18471 // report error | 18471 // report error |
| 18472 _errorReporter.reportErrorForToken(CompileTimeErrorCode.CASE_EXPRESSION_TYPE
_IMPLEMENTS_EQUALS, node.keyword, [type.displayName]); | 18472 _errorReporter.reportErrorForToken(CompileTimeErrorCode.CASE_EXPRESSION_TYPE
_IMPLEMENTS_EQUALS, node.keyword, [type.displayName]); |
| 18473 return true; | 18473 return true; |
| 18474 } | 18474 } |
| 18475 | 18475 |
| 18476 /** | 18476 /** |
| 18477 * This verifies that the passed method declaration is abstract only if the en
closing class is | 18477 * This verifies that the passed method declaration is abstract only if the en
closing class is |
| 18478 * also abstract. | 18478 * also abstract. |
| 18479 * | 18479 * |
| 18480 * @param node the method declaration to evaluate | 18480 * @param node the method declaration to evaluate |
| 18481 * @return `true` if and only if an error code is generated on the passed node | 18481 * @return `true` if and only if an error code is generated on the passed node |
| 18482 * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER | 18482 * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER |
| 18483 */ | 18483 */ |
| 18484 bool checkForConcreteClassWithAbstractMember(MethodDeclaration node) { | 18484 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { |
| 18485 if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstrac
t) { | 18485 if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstrac
t) { |
| 18486 SimpleIdentifier methodName = node.name; | 18486 SimpleIdentifier methodName = node.name; |
| 18487 _errorReporter.reportErrorForNode(StaticWarningCode.CONCRETE_CLASS_WITH_AB
STRACT_MEMBER, methodName, [methodName.name, _enclosingClass.displayName]); | 18487 _errorReporter.reportErrorForNode(StaticWarningCode.CONCRETE_CLASS_WITH_AB
STRACT_MEMBER, methodName, [methodName.name, _enclosingClass.displayName]); |
| 18488 return true; | 18488 return true; |
| 18489 } | 18489 } |
| 18490 return false; | 18490 return false; |
| 18491 } | 18491 } |
| 18492 | 18492 |
| 18493 /** | 18493 /** |
| 18494 * This verifies all possible conflicts of the constructor name with other con
structors and | 18494 * This verifies all possible conflicts of the constructor name with other con
structors and |
| 18495 * members of the same class. | 18495 * members of the same class. |
| 18496 * | 18496 * |
| 18497 * @param node the constructor declaration to evaluate | 18497 * @param node the constructor declaration to evaluate |
| 18498 * @return `true` if and only if an error code is generated on the passed node | 18498 * @return `true` if and only if an error code is generated on the passed node |
| 18499 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT | 18499 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT |
| 18500 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME | 18500 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME |
| 18501 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD | 18501 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD |
| 18502 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD | 18502 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD |
| 18503 */ | 18503 */ |
| 18504 bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node)
{ | 18504 bool _checkForConflictingConstructorNameAndMember(ConstructorDeclaration node)
{ |
| 18505 ConstructorElement constructorElement = node.element; | 18505 ConstructorElement constructorElement = node.element; |
| 18506 SimpleIdentifier constructorName = node.name; | 18506 SimpleIdentifier constructorName = node.name; |
| 18507 String name = constructorElement.name; | 18507 String name = constructorElement.name; |
| 18508 ClassElement classElement = constructorElement.enclosingElement; | 18508 ClassElement classElement = constructorElement.enclosingElement; |
| 18509 // constructors | 18509 // constructors |
| 18510 List<ConstructorElement> constructors = classElement.constructors; | 18510 List<ConstructorElement> constructors = classElement.constructors; |
| 18511 for (ConstructorElement otherConstructor in constructors) { | 18511 for (ConstructorElement otherConstructor in constructors) { |
| 18512 if (identical(otherConstructor, constructorElement)) { | 18512 if (identical(otherConstructor, constructorElement)) { |
| 18513 continue; | 18513 continue; |
| 18514 } | 18514 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 18540 } | 18540 } |
| 18541 | 18541 |
| 18542 /** | 18542 /** |
| 18543 * This verifies that the [enclosingClass] does not have a method and getter p
air with the | 18543 * This verifies that the [enclosingClass] does not have a method and getter p
air with the |
| 18544 * same name on, via inheritance. | 18544 * same name on, via inheritance. |
| 18545 * | 18545 * |
| 18546 * @return `true` if and only if an error code is generated on the passed node | 18546 * @return `true` if and only if an error code is generated on the passed node |
| 18547 * @see CompileTimeErrorCode#CONFLICTING_GETTER_AND_METHOD | 18547 * @see CompileTimeErrorCode#CONFLICTING_GETTER_AND_METHOD |
| 18548 * @see CompileTimeErrorCode#CONFLICTING_METHOD_AND_GETTER | 18548 * @see CompileTimeErrorCode#CONFLICTING_METHOD_AND_GETTER |
| 18549 */ | 18549 */ |
| 18550 bool checkForConflictingGetterAndMethod() { | 18550 bool _checkForConflictingGetterAndMethod() { |
| 18551 if (_enclosingClass == null) { | 18551 if (_enclosingClass == null) { |
| 18552 return false; | 18552 return false; |
| 18553 } | 18553 } |
| 18554 bool hasProblem = false; | 18554 bool hasProblem = false; |
| 18555 // method declared in the enclosing class vs. inherited getter | 18555 // method declared in the enclosing class vs. inherited getter |
| 18556 for (MethodElement method in _enclosingClass.methods) { | 18556 for (MethodElement method in _enclosingClass.methods) { |
| 18557 String name = method.name; | 18557 String name = method.name; |
| 18558 // find inherited property accessor (and can be only getter) | 18558 // find inherited property accessor (and can be only getter) |
| 18559 ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclo
singClass, name); | 18559 ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclo
singClass, name); |
| 18560 if (inherited is! PropertyAccessorElement) { | 18560 if (inherited is! PropertyAccessorElement) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18592 /** | 18592 /** |
| 18593 * This verifies that the superclass of the [enclosingClass] does not declare
accessible | 18593 * This verifies that the superclass of the [enclosingClass] does not declare
accessible |
| 18594 * static members with the same name as the instance getters/setters declared
in | 18594 * static members with the same name as the instance getters/setters declared
in |
| 18595 * [enclosingClass]. | 18595 * [enclosingClass]. |
| 18596 * | 18596 * |
| 18597 * @param node the method declaration to evaluate | 18597 * @param node the method declaration to evaluate |
| 18598 * @return `true` if and only if an error code is generated on the passed node | 18598 * @return `true` if and only if an error code is generated on the passed node |
| 18599 * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER | 18599 * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER |
| 18600 * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER | 18600 * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER |
| 18601 */ | 18601 */ |
| 18602 bool checkForConflictingInstanceGetterAndSuperclassMember() { | 18602 bool _checkForConflictingInstanceGetterAndSuperclassMember() { |
| 18603 if (_enclosingClass == null) { | 18603 if (_enclosingClass == null) { |
| 18604 return false; | 18604 return false; |
| 18605 } | 18605 } |
| 18606 InterfaceType enclosingType = _enclosingClass.type; | 18606 InterfaceType enclosingType = _enclosingClass.type; |
| 18607 // check every accessor | 18607 // check every accessor |
| 18608 bool hasProblem = false; | 18608 bool hasProblem = false; |
| 18609 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 18609 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
| 18610 // we analyze instance accessors here | 18610 // we analyze instance accessors here |
| 18611 if (accessor.isStatic) { | 18611 if (accessor.isStatic) { |
| 18612 continue; | 18612 continue; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18652 /** | 18652 /** |
| 18653 * This verifies that the enclosing class does not have a setter with the same
name as the passed | 18653 * This verifies that the enclosing class does not have a setter with the same
name as the passed |
| 18654 * instance method declaration. | 18654 * instance method declaration. |
| 18655 * | 18655 * |
| 18656 * TODO(jwren) add other "conflicting" error codes into algorithm/ data struct
ure | 18656 * TODO(jwren) add other "conflicting" error codes into algorithm/ data struct
ure |
| 18657 * | 18657 * |
| 18658 * @param node the method declaration to evaluate | 18658 * @param node the method declaration to evaluate |
| 18659 * @return `true` if and only if an error code is generated on the passed node | 18659 * @return `true` if and only if an error code is generated on the passed node |
| 18660 * @see StaticWarningCode#CONFLICTING_INSTANCE_METHOD_SETTER | 18660 * @see StaticWarningCode#CONFLICTING_INSTANCE_METHOD_SETTER |
| 18661 */ | 18661 */ |
| 18662 bool checkForConflictingInstanceMethodSetter(ClassDeclaration node) { | 18662 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) { |
| 18663 // Reference all of the class members in this class. | 18663 // Reference all of the class members in this class. |
| 18664 NodeList<ClassMember> classMembers = node.members; | 18664 NodeList<ClassMember> classMembers = node.members; |
| 18665 if (classMembers.isEmpty) { | 18665 if (classMembers.isEmpty) { |
| 18666 return false; | 18666 return false; |
| 18667 } | 18667 } |
| 18668 // Create a HashMap to track conflicting members, and then loop through memb
ers in the class to | 18668 // Create a HashMap to track conflicting members, and then loop through memb
ers in the class to |
| 18669 // construct the HashMap, at the same time, look for violations. Don't add
members if they are | 18669 // construct the HashMap, at the same time, look for violations. Don't add
members if they are |
| 18670 // part of a conflict, this prevents multiple warnings for one issue. | 18670 // part of a conflict, this prevents multiple warnings for one issue. |
| 18671 bool foundError = false; | 18671 bool foundError = false; |
| 18672 Map<String, ClassMember> memberHashMap = new Map<String, ClassMember>(); | 18672 Map<String, ClassMember> memberHashMap = new Map<String, ClassMember>(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18733 } | 18733 } |
| 18734 | 18734 |
| 18735 /** | 18735 /** |
| 18736 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 18736 * This verifies that the enclosing class does not have an instance member wit
h the same name as |
| 18737 * the passed static getter method declaration. | 18737 * the passed static getter method declaration. |
| 18738 * | 18738 * |
| 18739 * @param node the method declaration to evaluate | 18739 * @param node the method declaration to evaluate |
| 18740 * @return `true` if and only if an error code is generated on the passed node | 18740 * @return `true` if and only if an error code is generated on the passed node |
| 18741 * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER | 18741 * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER |
| 18742 */ | 18742 */ |
| 18743 bool checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node)
{ | 18743 bool _checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node)
{ |
| 18744 if (!node.isStatic) { | 18744 if (!node.isStatic) { |
| 18745 return false; | 18745 return false; |
| 18746 } | 18746 } |
| 18747 // prepare name | 18747 // prepare name |
| 18748 SimpleIdentifier nameNode = node.name; | 18748 SimpleIdentifier nameNode = node.name; |
| 18749 if (nameNode == null) { | 18749 if (nameNode == null) { |
| 18750 return false; | 18750 return false; |
| 18751 } | 18751 } |
| 18752 String name = nameNode.name; | 18752 String name = nameNode.name; |
| 18753 // prepare enclosing type | 18753 // prepare enclosing type |
| (...skipping 19 matching lines...) Expand all Loading... |
| 18773 } | 18773 } |
| 18774 | 18774 |
| 18775 /** | 18775 /** |
| 18776 * This verifies that the enclosing class does not have an instance member wit
h the same name as | 18776 * This verifies that the enclosing class does not have an instance member wit
h the same name as |
| 18777 * the passed static getter method declaration. | 18777 * the passed static getter method declaration. |
| 18778 * | 18778 * |
| 18779 * @param node the method declaration to evaluate | 18779 * @param node the method declaration to evaluate |
| 18780 * @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 |
| 18781 * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER | 18781 * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER |
| 18782 */ | 18782 */ |
| 18783 bool checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node)
{ | 18783 bool _checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node)
{ |
| 18784 if (!node.isStatic) { | 18784 if (!node.isStatic) { |
| 18785 return false; | 18785 return false; |
| 18786 } | 18786 } |
| 18787 // prepare name | 18787 // prepare name |
| 18788 SimpleIdentifier nameNode = node.name; | 18788 SimpleIdentifier nameNode = node.name; |
| 18789 if (nameNode == null) { | 18789 if (nameNode == null) { |
| 18790 return false; | 18790 return false; |
| 18791 } | 18791 } |
| 18792 String name = nameNode.name; | 18792 String name = nameNode.name; |
| 18793 // prepare enclosing type | 18793 // prepare enclosing type |
| (...skipping 26 matching lines...) Expand all Loading... |
| 18820 } | 18820 } |
| 18821 | 18821 |
| 18822 /** | 18822 /** |
| 18823 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) | 18823 * This verifies all conflicts between type variable and enclosing class. TODO
(scheglov) |
| 18824 * | 18824 * |
| 18825 * @param node the class declaration to evaluate | 18825 * @param node the class declaration to evaluate |
| 18826 * @return `true` if and only if an error code is generated on the passed node | 18826 * @return `true` if and only if an error code is generated on the passed node |
| 18827 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_CLASS | 18827 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_CLASS |
| 18828 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_MEMBER | 18828 * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_MEMBER |
| 18829 */ | 18829 */ |
| 18830 bool checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { | 18830 bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { |
| 18831 bool problemReported = false; | 18831 bool problemReported = false; |
| 18832 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { | 18832 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { |
| 18833 String name = typeParameter.name; | 18833 String name = typeParameter.name; |
| 18834 // name is same as the name of the enclosing class | 18834 // name is same as the name of the enclosing class |
| 18835 if (_enclosingClass.name == name) { | 18835 if (_enclosingClass.name == name) { |
| 18836 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYP
E_VARIABLE_AND_CLASS, typeParameter.nameOffset, name.length, [name]); | 18836 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYP
E_VARIABLE_AND_CLASS, typeParameter.nameOffset, name.length, [name]); |
| 18837 problemReported = true; | 18837 problemReported = true; |
| 18838 } | 18838 } |
| 18839 // check members | 18839 // check members |
| 18840 if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(n
ame) != null || _enclosingClass.getSetter(name) != null) { | 18840 if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(n
ame) != null || _enclosingClass.getSetter(name) != null) { |
| 18841 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYP
E_VARIABLE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]); | 18841 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYP
E_VARIABLE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]); |
| 18842 problemReported = true; | 18842 problemReported = true; |
| 18843 } | 18843 } |
| 18844 } | 18844 } |
| 18845 return problemReported; | 18845 return problemReported; |
| 18846 } | 18846 } |
| 18847 | 18847 |
| 18848 /** | 18848 /** |
| 18849 * This verifies that if the passed constructor declaration is 'const' then th
ere are no | 18849 * This verifies that if the passed constructor declaration is 'const' then th
ere are no |
| 18850 * invocations of non-'const' super constructors. | 18850 * invocations of non-'const' super constructors. |
| 18851 * | 18851 * |
| 18852 * @param node the constructor declaration to evaluate | 18852 * @param node the constructor declaration to evaluate |
| 18853 * @return `true` if and only if an error code is generated on the passed node | 18853 * @return `true` if and only if an error code is generated on the passed node |
| 18854 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER | 18854 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER |
| 18855 */ | 18855 */ |
| 18856 bool checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { | 18856 bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { |
| 18857 if (!_isEnclosingConstructorConst) { | 18857 if (!_isEnclosingConstructorConst) { |
| 18858 return false; | 18858 return false; |
| 18859 } | 18859 } |
| 18860 // OK, const factory, checked elsewhere | 18860 // OK, const factory, checked elsewhere |
| 18861 if (node.factoryKeyword != null) { | 18861 if (node.factoryKeyword != null) { |
| 18862 return false; | 18862 return false; |
| 18863 } | 18863 } |
| 18864 // try to find and check super constructor invocation | 18864 // try to find and check super constructor invocation |
| 18865 for (ConstructorInitializer initializer in node.initializers) { | 18865 for (ConstructorInitializer initializer in node.initializers) { |
| 18866 if (initializer is SuperConstructorInvocation) { | 18866 if (initializer is SuperConstructorInvocation) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 18894 } | 18894 } |
| 18895 | 18895 |
| 18896 /** | 18896 /** |
| 18897 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final | 18897 * This verifies that if the passed constructor declaration is 'const' then th
ere are no non-final |
| 18898 * instance variable. | 18898 * instance variable. |
| 18899 * | 18899 * |
| 18900 * @param node the constructor declaration to evaluate | 18900 * @param node the constructor declaration to evaluate |
| 18901 * @return `true` if and only if an error code is generated on the passed node | 18901 * @return `true` if and only if an error code is generated on the passed node |
| 18902 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD | 18902 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD |
| 18903 */ | 18903 */ |
| 18904 bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) { | 18904 bool _checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) { |
| 18905 if (!_isEnclosingConstructorConst) { | 18905 if (!_isEnclosingConstructorConst) { |
| 18906 return false; | 18906 return false; |
| 18907 } | 18907 } |
| 18908 // check if there is non-final field | 18908 // check if there is non-final field |
| 18909 ConstructorElement constructorElement = node.element; | 18909 ConstructorElement constructorElement = node.element; |
| 18910 ClassElement classElement = constructorElement.enclosingElement; | 18910 ClassElement classElement = constructorElement.enclosingElement; |
| 18911 if (!classElement.hasNonFinalField) { | 18911 if (!classElement.hasNonFinalField) { |
| 18912 return false; | 18912 return false; |
| 18913 } | 18913 } |
| 18914 // report problem | 18914 // report problem |
| 18915 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WIT
H_NON_FINAL_FIELD, node, []); | 18915 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WIT
H_NON_FINAL_FIELD, node, []); |
| 18916 return true; | 18916 return true; |
| 18917 } | 18917 } |
| 18918 | 18918 |
| 18919 /** | 18919 /** |
| 18920 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor | 18920 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor |
| 18921 * declaration. | 18921 * declaration. |
| 18922 * | 18922 * |
| 18923 * @param node the throw expression expression to evaluate | 18923 * @param node the throw expression expression to evaluate |
| 18924 * @return `true` if and only if an error code is generated on the passed node | 18924 * @return `true` if and only if an error code is generated on the passed node |
| 18925 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_THROWS_EXCEPTION | 18925 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_THROWS_EXCEPTION |
| 18926 */ | 18926 */ |
| 18927 bool checkForConstEvalThrowsException(ThrowExpression node) { | 18927 bool _checkForConstEvalThrowsException(ThrowExpression node) { |
| 18928 if (_isEnclosingConstructorConst) { | 18928 if (_isEnclosingConstructorConst) { |
| 18929 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_T
HROWS_EXCEPTION, node, []); | 18929 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_T
HROWS_EXCEPTION, node, []); |
| 18930 return true; | 18930 return true; |
| 18931 } | 18931 } |
| 18932 return false; | 18932 return false; |
| 18933 } | 18933 } |
| 18934 | 18934 |
| 18935 /** | 18935 /** |
| 18936 * This verifies that the passed normal formal parameter is not 'const'. | 18936 * This verifies that the passed normal formal parameter is not 'const'. |
| 18937 * | 18937 * |
| 18938 * @param node the normal formal parameter to evaluate | 18938 * @param node the normal formal parameter to evaluate |
| 18939 * @return `true` if and only if an error code is generated on the passed node | 18939 * @return `true` if and only if an error code is generated on the passed node |
| 18940 * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER | 18940 * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER |
| 18941 */ | 18941 */ |
| 18942 bool checkForConstFormalParameter(NormalFormalParameter node) { | 18942 bool _checkForConstFormalParameter(NormalFormalParameter node) { |
| 18943 if (node.isConst) { | 18943 if (node.isConst) { |
| 18944 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FORMAL_PARAME
TER, node, []); | 18944 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FORMAL_PARAME
TER, node, []); |
| 18945 return true; | 18945 return true; |
| 18946 } | 18946 } |
| 18947 return false; | 18947 return false; |
| 18948 } | 18948 } |
| 18949 | 18949 |
| 18950 /** | 18950 /** |
| 18951 * This verifies that the all keys of the passed map literal have class type t
hat does not declare | 18951 * This verifies that the all keys of the passed map literal have class type t
hat does not declare |
| 18952 * operator <i>==<i>. | 18952 * operator <i>==<i>. |
| 18953 * | 18953 * |
| 18954 * @param key the map literal to evaluate | 18954 * @param key the map literal to evaluate |
| 18955 * @return `true` if and only if an error code is generated on the passed node | 18955 * @return `true` if and only if an error code is generated on the passed node |
| 18956 * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS | 18956 * @see CompileTimeErrorCode#CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS |
| 18957 */ | 18957 */ |
| 18958 bool checkForConstMapKeyExpressionTypeImplementsEquals(MapLiteral node) { | 18958 bool _checkForConstMapKeyExpressionTypeImplementsEquals(MapLiteral node) { |
| 18959 // OK, not const. | 18959 // OK, not const. |
| 18960 if (node.constKeyword == null) { | 18960 if (node.constKeyword == null) { |
| 18961 return false; | 18961 return false; |
| 18962 } | 18962 } |
| 18963 // Check every map entry. | 18963 // Check every map entry. |
| 18964 bool hasProblems = false; | 18964 bool hasProblems = false; |
| 18965 for (MapLiteralEntry entry in node.entries) { | 18965 for (MapLiteralEntry entry in node.entries) { |
| 18966 Expression key = entry.key; | 18966 Expression key = entry.key; |
| 18967 Type2 type = key.staticType; | 18967 Type2 type = key.staticType; |
| 18968 if (implementsEqualsWhenNotAllowed(type)) { | 18968 if (_implementsEqualsWhenNotAllowed(type)) { |
| 18969 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_MAP_KEY_EXP
RESSION_TYPE_IMPLEMENTS_EQUALS, key, [type.displayName]); | 18969 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_MAP_KEY_EXP
RESSION_TYPE_IMPLEMENTS_EQUALS, key, [type.displayName]); |
| 18970 hasProblems = true; | 18970 hasProblems = true; |
| 18971 } | 18971 } |
| 18972 } | 18972 } |
| 18973 return hasProblems; | 18973 return hasProblems; |
| 18974 } | 18974 } |
| 18975 | 18975 |
| 18976 /** | 18976 /** |
| 18977 * This verifies that the passed instance creation expression is not being inv
oked on an abstract | 18977 * This verifies that the passed instance creation expression is not being inv
oked on an abstract |
| 18978 * class. | 18978 * class. |
| 18979 * | 18979 * |
| 18980 * @param node the instance creation expression to evaluate | 18980 * @param node the instance creation expression to evaluate |
| 18981 * @param typeName the [TypeName] of the [ConstructorName] from the | 18981 * @param typeName the [TypeName] of the [ConstructorName] from the |
| 18982 * [InstanceCreationExpression], this is the AST node that the error
is attached to | 18982 * [InstanceCreationExpression], this is the AST node that the error
is attached to |
| 18983 * @param type the type being constructed with this [InstanceCreationExpressio
n] | 18983 * @param type the type being constructed with this [InstanceCreationExpressio
n] |
| 18984 * @return `true` if and only if an error code is generated on the passed node | 18984 * @return `true` if and only if an error code is generated on the passed node |
| 18985 * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS | 18985 * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS |
| 18986 * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS | 18986 * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS |
| 18987 */ | 18987 */ |
| 18988 bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, Type
Name typeName, InterfaceType type) { | 18988 bool _checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, Typ
eName typeName, InterfaceType type) { |
| 18989 if (type.element.isAbstract) { | 18989 if (type.element.isAbstract) { |
| 18990 ConstructorElement element = node.staticElement; | 18990 ConstructorElement element = node.staticElement; |
| 18991 if (element != null && !element.isFactory) { | 18991 if (element != null && !element.isFactory) { |
| 18992 if (identical((node.keyword as sc.KeywordToken).keyword, sc.Keyword.CONS
T)) { | 18992 if (identical((node.keyword as sc.KeywordToken).keyword, sc.Keyword.CONS
T)) { |
| 18993 _errorReporter.reportErrorForNode(StaticWarningCode.CONST_WITH_ABSTRAC
T_CLASS, typeName, []); | 18993 _errorReporter.reportErrorForNode(StaticWarningCode.CONST_WITH_ABSTRAC
T_CLASS, typeName, []); |
| 18994 } else { | 18994 } else { |
| 18995 _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_ABSTRACT_
CLASS, typeName, []); | 18995 _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_ABSTRACT_
CLASS, typeName, []); |
| 18996 } | 18996 } |
| 18997 return true; | 18997 return true; |
| 18998 } | 18998 } |
| 18999 } | 18999 } |
| 19000 return false; | 19000 return false; |
| 19001 } | 19001 } |
| 19002 | 19002 |
| 19003 /** | 19003 /** |
| 19004 * This verifies that the passed 'const' instance creation expression is not b
eing invoked on a | 19004 * This verifies that the passed 'const' instance creation expression is not b
eing invoked on a |
| 19005 * constructor that is not 'const'. | 19005 * constructor that is not 'const'. |
| 19006 * | 19006 * |
| 19007 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 19007 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. |
| 19008 * | 19008 * |
| 19009 * @param node the instance creation expression to evaluate | 19009 * @param node the instance creation expression to evaluate |
| 19010 * @return `true` if and only if an error code is generated on the passed node | 19010 * @return `true` if and only if an error code is generated on the passed node |
| 19011 * @see CompileTimeErrorCode#CONST_WITH_NON_CONST | 19011 * @see CompileTimeErrorCode#CONST_WITH_NON_CONST |
| 19012 */ | 19012 */ |
| 19013 bool checkForConstWithNonConst(InstanceCreationExpression node) { | 19013 bool _checkForConstWithNonConst(InstanceCreationExpression node) { |
| 19014 ConstructorElement constructorElement = node.staticElement; | 19014 ConstructorElement constructorElement = node.staticElement; |
| 19015 if (constructorElement != null && !constructorElement.isConst) { | 19015 if (constructorElement != null && !constructorElement.isConst) { |
| 19016 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_CONS
T, node, []); | 19016 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_CONS
T, node, []); |
| 19017 return true; | 19017 return true; |
| 19018 } | 19018 } |
| 19019 return false; | 19019 return false; |
| 19020 } | 19020 } |
| 19021 | 19021 |
| 19022 /** | 19022 /** |
| 19023 * This verifies that the passed type name does not reference any type paramet
ers. | 19023 * This verifies that the passed type name does not reference any type paramet
ers. |
| 19024 * | 19024 * |
| 19025 * @param typeName the type name to evaluate | 19025 * @param typeName the type name to evaluate |
| 19026 * @return `true` if and only if an error code is generated on the passed node | 19026 * @return `true` if and only if an error code is generated on the passed node |
| 19027 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS | 19027 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS |
| 19028 */ | 19028 */ |
| 19029 bool checkForConstWithTypeParameters(TypeName typeName) { | 19029 bool _checkForConstWithTypeParameters(TypeName typeName) { |
| 19030 // something wrong with AST | 19030 // something wrong with AST |
| 19031 if (typeName == null) { | 19031 if (typeName == null) { |
| 19032 return false; | 19032 return false; |
| 19033 } | 19033 } |
| 19034 Identifier name = typeName.name; | 19034 Identifier name = typeName.name; |
| 19035 if (name == null) { | 19035 if (name == null) { |
| 19036 return false; | 19036 return false; |
| 19037 } | 19037 } |
| 19038 // should not be a type parameter | 19038 // should not be a type parameter |
| 19039 if (name.staticElement is TypeParameterElement) { | 19039 if (name.staticElement is TypeParameterElement) { |
| 19040 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_TYPE_PAR
AMETERS, name, []); | 19040 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_TYPE_PAR
AMETERS, name, []); |
| 19041 } | 19041 } |
| 19042 // check type arguments | 19042 // check type arguments |
| 19043 TypeArgumentList typeArguments = typeName.typeArguments; | 19043 TypeArgumentList typeArguments = typeName.typeArguments; |
| 19044 if (typeArguments != null) { | 19044 if (typeArguments != null) { |
| 19045 bool hasError = false; | 19045 bool hasError = false; |
| 19046 for (TypeName argument in typeArguments.arguments) { | 19046 for (TypeName argument in typeArguments.arguments) { |
| 19047 hasError = javaBooleanOr(hasError, checkForConstWithTypeParameters(argum
ent)); | 19047 hasError = javaBooleanOr(hasError, _checkForConstWithTypeParameters(argu
ment)); |
| 19048 } | 19048 } |
| 19049 return hasError; | 19049 return hasError; |
| 19050 } | 19050 } |
| 19051 // OK | 19051 // OK |
| 19052 return false; | 19052 return false; |
| 19053 } | 19053 } |
| 19054 | 19054 |
| 19055 /** | 19055 /** |
| 19056 * This verifies that the passed 'const' instance creation expression does not
reference any type | 19056 * This verifies that the passed 'const' instance creation expression does not
reference any type |
| 19057 * parameters. | 19057 * parameters. |
| 19058 * | 19058 * |
| 19059 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 19059 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. |
| 19060 * | 19060 * |
| 19061 * @param node the instance creation expression to evaluate | 19061 * @param node the instance creation expression to evaluate |
| 19062 * @return `true` if and only if an error code is generated on the passed node | 19062 * @return `true` if and only if an error code is generated on the passed node |
| 19063 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS | 19063 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS |
| 19064 */ | 19064 */ |
| 19065 bool checkForConstWithTypeParametersInCreation(InstanceCreationExpression node
) { | 19065 bool _checkForConstWithTypeParametersInCreation(InstanceCreationExpression nod
e) { |
| 19066 ConstructorName constructorName = node.constructorName; | 19066 ConstructorName constructorName = node.constructorName; |
| 19067 if (constructorName == null) { | 19067 if (constructorName == null) { |
| 19068 return false; | 19068 return false; |
| 19069 } | 19069 } |
| 19070 TypeName typeName = constructorName.type; | 19070 TypeName typeName = constructorName.type; |
| 19071 return checkForConstWithTypeParameters(typeName); | 19071 return _checkForConstWithTypeParameters(typeName); |
| 19072 } | 19072 } |
| 19073 | 19073 |
| 19074 /** | 19074 /** |
| 19075 * This verifies that if the passed 'const' instance creation expression is be
ing invoked on the | 19075 * This verifies that if the passed 'const' instance creation expression is be
ing invoked on the |
| 19076 * resolved constructor. | 19076 * resolved constructor. |
| 19077 * | 19077 * |
| 19078 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. | 19078 * This method assumes that the instance creation was tested to be 'const' bef
ore being called. |
| 19079 * | 19079 * |
| 19080 * @param node the instance creation expression to evaluate | 19080 * @param node the instance creation expression to evaluate |
| 19081 * @return `true` if and only if an error code is generated on the passed node | 19081 * @return `true` if and only if an error code is generated on the passed node |
| 19082 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR | 19082 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR |
| 19083 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT | 19083 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT |
| 19084 */ | 19084 */ |
| 19085 bool checkForConstWithUndefinedConstructor(InstanceCreationExpression node) { | 19085 bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node) { |
| 19086 // OK if resolved | 19086 // OK if resolved |
| 19087 if (node.staticElement != null) { | 19087 if (node.staticElement != null) { |
| 19088 return false; | 19088 return false; |
| 19089 } | 19089 } |
| 19090 // prepare constructor name | 19090 // prepare constructor name |
| 19091 ConstructorName constructorName = node.constructorName; | 19091 ConstructorName constructorName = node.constructorName; |
| 19092 if (constructorName == null) { | 19092 if (constructorName == null) { |
| 19093 return false; | 19093 return false; |
| 19094 } | 19094 } |
| 19095 // prepare class name | 19095 // prepare class name |
| (...skipping 12 matching lines...) Expand all Loading... |
| 19108 return true; | 19108 return true; |
| 19109 } | 19109 } |
| 19110 | 19110 |
| 19111 /** | 19111 /** |
| 19112 * This verifies that there are no default parameters in the passed function t
ype alias. | 19112 * This verifies that there are no default parameters in the passed function t
ype alias. |
| 19113 * | 19113 * |
| 19114 * @param node the function type alias to evaluate | 19114 * @param node the function type alias to evaluate |
| 19115 * @return `true` if and only if an error code is generated on the passed node | 19115 * @return `true` if and only if an error code is generated on the passed node |
| 19116 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS | 19116 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS |
| 19117 */ | 19117 */ |
| 19118 bool checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { | 19118 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { |
| 19119 bool result = false; | 19119 bool result = false; |
| 19120 FormalParameterList formalParameterList = node.parameters; | 19120 FormalParameterList formalParameterList = node.parameters; |
| 19121 NodeList<FormalParameter> parameters = formalParameterList.parameters; | 19121 NodeList<FormalParameter> parameters = formalParameterList.parameters; |
| 19122 for (FormalParameter formalParameter in parameters) { | 19122 for (FormalParameter formalParameter in parameters) { |
| 19123 if (formalParameter is DefaultFormalParameter) { | 19123 if (formalParameter is DefaultFormalParameter) { |
| 19124 DefaultFormalParameter defaultFormalParameter = formalParameter; | 19124 DefaultFormalParameter defaultFormalParameter = formalParameter; |
| 19125 if (defaultFormalParameter.defaultValue != null) { | 19125 if (defaultFormalParameter.defaultValue != null) { |
| 19126 _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_I
N_FUNCTION_TYPE_ALIAS, node, []); | 19126 _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_I
N_FUNCTION_TYPE_ALIAS, node, []); |
| 19127 result = true; | 19127 result = true; |
| 19128 } | 19128 } |
| 19129 } | 19129 } |
| 19130 } | 19130 } |
| 19131 return result; | 19131 return result; |
| 19132 } | 19132 } |
| 19133 | 19133 |
| 19134 /** | 19134 /** |
| 19135 * This verifies that the given default formal parameter is not part of a func
tion typed | 19135 * This verifies that the given default formal parameter is not part of a func
tion typed |
| 19136 * parameter. | 19136 * parameter. |
| 19137 * | 19137 * |
| 19138 * @param node the default formal parameter to evaluate | 19138 * @param node the default formal parameter to evaluate |
| 19139 * @return `true` if and only if an error code is generated on the passed node | 19139 * @return `true` if and only if an error code is generated on the passed node |
| 19140 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER | 19140 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER |
| 19141 */ | 19141 */ |
| 19142 bool checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node)
{ | 19142 bool _checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node
) { |
| 19143 // OK, not in a function typed parameter. | 19143 // OK, not in a function typed parameter. |
| 19144 if (!_isInFunctionTypedFormalParameter) { | 19144 if (!_isInFunctionTypedFormalParameter) { |
| 19145 return false; | 19145 return false; |
| 19146 } | 19146 } |
| 19147 // OK, no default value. | 19147 // OK, no default value. |
| 19148 if (node.defaultValue == null) { | 19148 if (node.defaultValue == null) { |
| 19149 return false; | 19149 return false; |
| 19150 } | 19150 } |
| 19151 // Report problem. | 19151 // Report problem. |
| 19152 _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNC
TION_TYPED_PARAMETER, node, []); | 19152 _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNC
TION_TYPED_PARAMETER, node, []); |
| 19153 return true; | 19153 return true; |
| 19154 } | 19154 } |
| 19155 | 19155 |
| 19156 /** | 19156 /** |
| 19157 * This verifies that the enclosing class does not have an instance member wit
h the given name of | 19157 * This verifies that the enclosing class does not have an instance member wit
h the given name of |
| 19158 * the static member. | 19158 * the static member. |
| 19159 * | 19159 * |
| 19160 * @return `true` if and only if an error code is generated on the passed node | 19160 * @return `true` if and only if an error code is generated on the passed node |
| 19161 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE | 19161 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE |
| 19162 */ | 19162 */ |
| 19163 bool checkForDuplicateDefinitionInheritance() { | 19163 bool _checkForDuplicateDefinitionInheritance() { |
| 19164 if (_enclosingClass == null) { | 19164 if (_enclosingClass == null) { |
| 19165 return false; | 19165 return false; |
| 19166 } | 19166 } |
| 19167 bool hasProblem = false; | 19167 bool hasProblem = false; |
| 19168 for (ExecutableElement member in _enclosingClass.methods) { | 19168 for (ExecutableElement member in _enclosingClass.methods) { |
| 19169 if (!member.isStatic) { | 19169 if (!member.isStatic) { |
| 19170 continue; | 19170 continue; |
| 19171 } | 19171 } |
| 19172 hasProblem = javaBooleanOr(hasProblem, checkForDuplicateDefinitionOfMember
(member)); | 19172 hasProblem = javaBooleanOr(hasProblem, _checkForDuplicateDefinitionOfMembe
r(member)); |
| 19173 } | 19173 } |
| 19174 for (ExecutableElement member in _enclosingClass.accessors) { | 19174 for (ExecutableElement member in _enclosingClass.accessors) { |
| 19175 if (!member.isStatic) { | 19175 if (!member.isStatic) { |
| 19176 continue; | 19176 continue; |
| 19177 } | 19177 } |
| 19178 hasProblem = javaBooleanOr(hasProblem, checkForDuplicateDefinitionOfMember
(member)); | 19178 hasProblem = javaBooleanOr(hasProblem, _checkForDuplicateDefinitionOfMembe
r(member)); |
| 19179 } | 19179 } |
| 19180 return hasProblem; | 19180 return hasProblem; |
| 19181 } | 19181 } |
| 19182 | 19182 |
| 19183 /** | 19183 /** |
| 19184 * This verifies that the enclosing class does not have an instance member wit
h the given name of | 19184 * This verifies that the enclosing class does not have an instance member wit
h the given name of |
| 19185 * the static member. | 19185 * the static member. |
| 19186 * | 19186 * |
| 19187 * @param staticMember the static member to check conflict for | 19187 * @param staticMember the static member to check conflict for |
| 19188 * @return `true` if and only if an error code is generated on the passed node | 19188 * @return `true` if and only if an error code is generated on the passed node |
| 19189 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE | 19189 * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE |
| 19190 */ | 19190 */ |
| 19191 bool checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) { | 19191 bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) { |
| 19192 // prepare name | 19192 // prepare name |
| 19193 String name = staticMember.name; | 19193 String name = staticMember.name; |
| 19194 if (name == null) { | 19194 if (name == null) { |
| 19195 return false; | 19195 return false; |
| 19196 } | 19196 } |
| 19197 // try to find member | 19197 // try to find member |
| 19198 ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_e
nclosingClass, name); | 19198 ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_e
nclosingClass, name); |
| 19199 if (inheritedMember == null) { | 19199 if (inheritedMember == null) { |
| 19200 return false; | 19200 return false; |
| 19201 } | 19201 } |
| 19202 // OK, also static | 19202 // OK, also static |
| 19203 if (inheritedMember.isStatic) { | 19203 if (inheritedMember.isStatic) { |
| 19204 return false; | 19204 return false; |
| 19205 } | 19205 } |
| 19206 // report problem | 19206 // report problem |
| 19207 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.DUPLICATE_DEFINITIO
N_INHERITANCE, staticMember.nameOffset, name.length, [name, inheritedMember.encl
osingElement.displayName]); | 19207 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.DUPLICATE_DEFINITIO
N_INHERITANCE, staticMember.nameOffset, name.length, [name, inheritedMember.encl
osingElement.displayName]); |
| 19208 return true; | 19208 return true; |
| 19209 } | 19209 } |
| 19210 | 19210 |
| 19211 /** | 19211 /** |
| 19212 * This verifies if the passed list literal has type arguments then there is e
xactly one. | 19212 * This verifies if the passed list literal has type arguments then there is e
xactly one. |
| 19213 * | 19213 * |
| 19214 * @param node the list literal to evaluate | 19214 * @param node the list literal to evaluate |
| 19215 * @return `true` if and only if an error code is generated on the passed node | 19215 * @return `true` if and only if an error code is generated on the passed node |
| 19216 * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS | 19216 * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS |
| 19217 */ | 19217 */ |
| 19218 bool checkForExpectedOneListTypeArgument(ListLiteral node) { | 19218 bool _checkForExpectedOneListTypeArgument(ListLiteral node) { |
| 19219 // prepare type arguments | 19219 // prepare type arguments |
| 19220 TypeArgumentList typeArguments = node.typeArguments; | 19220 TypeArgumentList typeArguments = node.typeArguments; |
| 19221 if (typeArguments == null) { | 19221 if (typeArguments == null) { |
| 19222 return false; | 19222 return false; |
| 19223 } | 19223 } |
| 19224 // check number of type arguments | 19224 // check number of type arguments |
| 19225 int num = typeArguments.arguments.length; | 19225 int num = typeArguments.arguments.length; |
| 19226 if (num == 1) { | 19226 if (num == 1) { |
| 19227 return false; | 19227 return false; |
| 19228 } | 19228 } |
| 19229 // report problem | 19229 // report problem |
| 19230 _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_ONE_LIST_TY
PE_ARGUMENTS, typeArguments, [num]); | 19230 _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_ONE_LIST_TY
PE_ARGUMENTS, typeArguments, [num]); |
| 19231 return true; | 19231 return true; |
| 19232 } | 19232 } |
| 19233 | 19233 |
| 19234 /** | 19234 /** |
| 19235 * This verifies the passed import has unique name among other exported librar
ies. | 19235 * This verifies the passed import has unique name among other exported librar
ies. |
| 19236 * | 19236 * |
| 19237 * @param node the export directive to evaluate | 19237 * @param node the export directive to evaluate |
| 19238 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 19238 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
| 19239 * node was `null`, then this method is not called | 19239 * node was `null`, then this method is not called |
| 19240 * @return `true` if and only if an error code is generated on the passed node | 19240 * @return `true` if and only if an error code is generated on the passed node |
| 19241 * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME | 19241 * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME |
| 19242 */ | 19242 */ |
| 19243 bool checkForExportDuplicateLibraryName(ExportDirective node, ExportElement ex
portElement) { | 19243 bool _checkForExportDuplicateLibraryName(ExportDirective node, ExportElement e
xportElement) { |
| 19244 // prepare exported library | 19244 // prepare exported library |
| 19245 LibraryElement nodeLibrary = exportElement.exportedLibrary; | 19245 LibraryElement nodeLibrary = exportElement.exportedLibrary; |
| 19246 if (nodeLibrary == null) { | 19246 if (nodeLibrary == null) { |
| 19247 return false; | 19247 return false; |
| 19248 } | 19248 } |
| 19249 String name = nodeLibrary.name; | 19249 String name = nodeLibrary.name; |
| 19250 // check if there is other exported library with the same name | 19250 // check if there is other exported library with the same name |
| 19251 LibraryElement prevLibrary = _nameToExportElement[name]; | 19251 LibraryElement prevLibrary = _nameToExportElement[name]; |
| 19252 if (prevLibrary != null) { | 19252 if (prevLibrary != null) { |
| 19253 if (prevLibrary != nodeLibrary) { | 19253 if (prevLibrary != nodeLibrary) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 19267 /** | 19267 /** |
| 19268 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 19268 * Check that if the visiting library is not system, then any passed library s
hould not be SDK |
| 19269 * internal library. | 19269 * internal library. |
| 19270 * | 19270 * |
| 19271 * @param node the export directive to evaluate | 19271 * @param node the export directive to evaluate |
| 19272 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 19272 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
| 19273 * node was `null`, then this method is not called | 19273 * node was `null`, then this method is not called |
| 19274 * @return `true` if and only if an error code is generated on the passed node | 19274 * @return `true` if and only if an error code is generated on the passed node |
| 19275 * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY | 19275 * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY |
| 19276 */ | 19276 */ |
| 19277 bool checkForExportInternalLibrary(ExportDirective node, ExportElement exportE
lement) { | 19277 bool _checkForExportInternalLibrary(ExportDirective node, ExportElement export
Element) { |
| 19278 if (_isInSystemLibrary) { | 19278 if (_isInSystemLibrary) { |
| 19279 return false; | 19279 return false; |
| 19280 } | 19280 } |
| 19281 // should be private | 19281 // should be private |
| 19282 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 19282 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 19283 String uri = exportElement.uri; | 19283 String uri = exportElement.uri; |
| 19284 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 19284 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 19285 if (sdkLibrary == null) { | 19285 if (sdkLibrary == null) { |
| 19286 return false; | 19286 return false; |
| 19287 } | 19287 } |
| 19288 if (!sdkLibrary.isInternal) { | 19288 if (!sdkLibrary.isInternal) { |
| 19289 return false; | 19289 return false; |
| 19290 } | 19290 } |
| 19291 // report problem | 19291 // report problem |
| 19292 _errorReporter.reportErrorForNode(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRA
RY, node, [node.uri]); | 19292 _errorReporter.reportErrorForNode(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRA
RY, node, [node.uri]); |
| 19293 return true; | 19293 return true; |
| 19294 } | 19294 } |
| 19295 | 19295 |
| 19296 /** | 19296 /** |
| 19297 * This verifies that the passed extends clause does not extend classes such a
s num or String. | 19297 * This verifies that the passed extends clause does not extend classes such a
s num or String. |
| 19298 * | 19298 * |
| 19299 * @param node the extends clause to test | 19299 * @param node the extends clause to test |
| 19300 * @return `true` if and only if an error code is generated on the passed node | 19300 * @return `true` if and only if an error code is generated on the passed node |
| 19301 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS | 19301 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS |
| 19302 */ | 19302 */ |
| 19303 bool checkForExtendsDisallowedClass(ExtendsClause node) { | 19303 bool _checkForExtendsDisallowedClass(ExtendsClause node) { |
| 19304 if (node == null) { | 19304 if (node == null) { |
| 19305 return false; | 19305 return false; |
| 19306 } | 19306 } |
| 19307 return checkForExtendsOrImplementsDisallowedClass(node.superclass, CompileTi
meErrorCode.EXTENDS_DISALLOWED_CLASS); | 19307 return _checkForExtendsOrImplementsDisallowedClass(node.superclass, CompileT
imeErrorCode.EXTENDS_DISALLOWED_CLASS); |
| 19308 } | 19308 } |
| 19309 | 19309 |
| 19310 /** | 19310 /** |
| 19311 * This verifies that the passed type name does not extend or implement classe
s such as 'num' or | 19311 * This verifies that the passed type name does not extend or implement classe
s such as 'num' or |
| 19312 * 'String'. | 19312 * 'String'. |
| 19313 * | 19313 * |
| 19314 * @param node the type name to test | 19314 * @param node the type name to test |
| 19315 * @return `true` if and only if an error code is generated on the passed node | 19315 * @return `true` if and only if an error code is generated on the passed node |
| 19316 * @see #checkForExtendsDisallowedClass(ExtendsClause) | 19316 * @see #checkForExtendsDisallowedClass(ExtendsClause) |
| 19317 * @see #checkForImplementsDisallowedClass(ImplementsClause) | 19317 * @see #checkForImplementsDisallowedClass(ImplementsClause) |
| 19318 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS | 19318 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS |
| 19319 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS | 19319 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS |
| 19320 */ | 19320 */ |
| 19321 bool checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode e
rrorCode) { | 19321 bool _checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode
errorCode) { |
| 19322 if (typeName.isSynthetic) { | 19322 if (typeName.isSynthetic) { |
| 19323 return false; | 19323 return false; |
| 19324 } | 19324 } |
| 19325 Type2 superType = typeName.type; | 19325 Type2 superType = typeName.type; |
| 19326 for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMEN
T) { | 19326 for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMEN
T) { |
| 19327 if (superType != null && superType == disallowedType) { | 19327 if (superType != null && superType == disallowedType) { |
| 19328 // if the violating type happens to be 'num', we need to rule out the ca
se where the | 19328 // if the violating type happens to be 'num', we need to rule out the ca
se where the |
| 19329 // enclosing class is 'int' or 'double' | 19329 // enclosing class is 'int' or 'double' |
| 19330 if (superType == _typeProvider.numType) { | 19330 if (superType == _typeProvider.numType) { |
| 19331 AstNode grandParent = typeName.parent.parent; | 19331 AstNode grandParent = typeName.parent.parent; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 19351 | 19351 |
| 19352 /** | 19352 /** |
| 19353 * This verifies that the passed constructor field initializer has compatible
field and | 19353 * This verifies that the passed constructor field initializer has compatible
field and |
| 19354 * initializer expression types. | 19354 * initializer expression types. |
| 19355 * | 19355 * |
| 19356 * @param node the constructor field initializer to test | 19356 * @param node the constructor field initializer to test |
| 19357 * @return `true` if and only if an error code is generated on the passed node | 19357 * @return `true` if and only if an error code is generated on the passed node |
| 19358 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE | 19358 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE |
| 19359 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE | 19359 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE |
| 19360 */ | 19360 */ |
| 19361 bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) { | 19361 bool _checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node)
{ |
| 19362 // prepare field element | 19362 // prepare field element |
| 19363 Element staticElement = node.fieldName.staticElement; | 19363 Element staticElement = node.fieldName.staticElement; |
| 19364 if (staticElement is! FieldElement) { | 19364 if (staticElement is! FieldElement) { |
| 19365 return false; | 19365 return false; |
| 19366 } | 19366 } |
| 19367 FieldElement fieldElement = staticElement as FieldElement; | 19367 FieldElement fieldElement = staticElement as FieldElement; |
| 19368 // prepare field type | 19368 // prepare field type |
| 19369 Type2 fieldType = fieldElement.type; | 19369 Type2 fieldType = fieldElement.type; |
| 19370 // prepare expression type | 19370 // prepare expression type |
| 19371 Expression expression = node.expression; | 19371 Expression expression = node.expression; |
| 19372 if (expression == null) { | 19372 if (expression == null) { |
| 19373 return false; | 19373 return false; |
| 19374 } | 19374 } |
| 19375 // test the static type of the expression | 19375 // test the static type of the expression |
| 19376 Type2 staticType = getStaticType(expression); | 19376 Type2 staticType = _getStaticType(expression); |
| 19377 if (staticType == null) { | 19377 if (staticType == null) { |
| 19378 return false; | 19378 return false; |
| 19379 } | 19379 } |
| 19380 if (staticType.isAssignableTo(fieldType)) { | 19380 if (staticType.isAssignableTo(fieldType)) { |
| 19381 return false; | 19381 return false; |
| 19382 } | 19382 } |
| 19383 // report problem | 19383 // report problem |
| 19384 if (_isEnclosingConstructorConst) { | 19384 if (_isEnclosingConstructorConst) { |
| 19385 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FIELD_INITIAL
IZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]
); | 19385 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FIELD_INITIAL
IZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]
); |
| 19386 } else { | 19386 } else { |
| 19387 _errorReporter.reportErrorForNode(StaticWarningCode.FIELD_INITIALIZER_NOT_
ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); | 19387 _errorReporter.reportErrorForNode(StaticWarningCode.FIELD_INITIALIZER_NOT_
ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); |
| 19388 } | 19388 } |
| 19389 return true; | 19389 return true; |
| 19390 } | 19390 } |
| 19391 | 19391 |
| 19392 /** | 19392 /** |
| 19393 * This verifies that the passed field formal parameter is in a constructor de
claration. | 19393 * This verifies that the passed field formal parameter is in a constructor de
claration. |
| 19394 * | 19394 * |
| 19395 * @param node the field formal parameter to test | 19395 * @param node the field formal parameter to test |
| 19396 * @return `true` if and only if an error code is generated on the passed node | 19396 * @return `true` if and only if an error code is generated on the passed node |
| 19397 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR | 19397 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR |
| 19398 */ | 19398 */ |
| 19399 bool checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParamete
r node) { | 19399 bool _checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParamet
er node) { |
| 19400 ConstructorDeclaration constructor = node.getAncestor((node) => node is Cons
tructorDeclaration); | 19400 ConstructorDeclaration constructor = node.getAncestor((node) => node is Cons
tructorDeclaration); |
| 19401 if (constructor == null) { | 19401 if (constructor == null) { |
| 19402 _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_O
UTSIDE_CONSTRUCTOR, node, []); | 19402 _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_O
UTSIDE_CONSTRUCTOR, node, []); |
| 19403 return true; | 19403 return true; |
| 19404 } | 19404 } |
| 19405 // constructor cannot be a factory | 19405 // constructor cannot be a factory |
| 19406 if (constructor.factoryKeyword != null) { | 19406 if (constructor.factoryKeyword != null) { |
| 19407 _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_F
ACTORY_CONSTRUCTOR, node, []); | 19407 _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_F
ACTORY_CONSTRUCTOR, node, []); |
| 19408 return true; | 19408 return true; |
| 19409 } | 19409 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 19423 * list is final or const. This method is called by | 19423 * list is final or const. This method is called by |
| 19424 * [checkForFinalNotInitializedInClass], | 19424 * [checkForFinalNotInitializedInClass], |
| 19425 * [visitTopLevelVariableDeclaration] and | 19425 * [visitTopLevelVariableDeclaration] and |
| 19426 * [visitVariableDeclarationStatement]. | 19426 * [visitVariableDeclarationStatement]. |
| 19427 * | 19427 * |
| 19428 * @param node the class declaration to test | 19428 * @param node the class declaration to test |
| 19429 * @return `true` if and only if an error code is generated on the passed node | 19429 * @return `true` if and only if an error code is generated on the passed node |
| 19430 * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED | 19430 * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED |
| 19431 * @see StaticWarningCode#FINAL_NOT_INITIALIZED | 19431 * @see StaticWarningCode#FINAL_NOT_INITIALIZED |
| 19432 */ | 19432 */ |
| 19433 bool checkForFinalNotInitialized(VariableDeclarationList node) { | 19433 bool _checkForFinalNotInitialized(VariableDeclarationList node) { |
| 19434 if (_isInNativeClass) { | 19434 if (_isInNativeClass) { |
| 19435 return false; | 19435 return false; |
| 19436 } | 19436 } |
| 19437 bool foundError = false; | 19437 bool foundError = false; |
| 19438 if (!node.isSynthetic) { | 19438 if (!node.isSynthetic) { |
| 19439 NodeList<VariableDeclaration> variables = node.variables; | 19439 NodeList<VariableDeclaration> variables = node.variables; |
| 19440 for (VariableDeclaration variable in variables) { | 19440 for (VariableDeclaration variable in variables) { |
| 19441 if (variable.initializer == null) { | 19441 if (variable.initializer == null) { |
| 19442 if (node.isConst) { | 19442 if (node.isConst) { |
| 19443 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INI
TIALIZED, variable.name, [variable.name.name]); | 19443 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INI
TIALIZED, variable.name, [variable.name.name]); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 19454 /** | 19454 /** |
| 19455 * This verifies that final fields that are declared, without any constructors
in the enclosing | 19455 * This verifies that final fields that are declared, without any constructors
in the enclosing |
| 19456 * class, are initialized. Cases in which there is at least one constructor ar
e handled at the end | 19456 * class, are initialized. Cases in which there is at least one constructor ar
e handled at the end |
| 19457 * of [checkForAllFinalInitializedErrorCodes]. | 19457 * of [checkForAllFinalInitializedErrorCodes]. |
| 19458 * | 19458 * |
| 19459 * @param node the class declaration to test | 19459 * @param node the class declaration to test |
| 19460 * @return `true` if and only if an error code is generated on the passed node | 19460 * @return `true` if and only if an error code is generated on the passed node |
| 19461 * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED | 19461 * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED |
| 19462 * @see StaticWarningCode#FINAL_NOT_INITIALIZED | 19462 * @see StaticWarningCode#FINAL_NOT_INITIALIZED |
| 19463 */ | 19463 */ |
| 19464 bool checkForFinalNotInitializedInClass(ClassDeclaration node) { | 19464 bool _checkForFinalNotInitializedInClass(ClassDeclaration node) { |
| 19465 NodeList<ClassMember> classMembers = node.members; | 19465 NodeList<ClassMember> classMembers = node.members; |
| 19466 for (ClassMember classMember in classMembers) { | 19466 for (ClassMember classMember in classMembers) { |
| 19467 if (classMember is ConstructorDeclaration) { | 19467 if (classMember is ConstructorDeclaration) { |
| 19468 return false; | 19468 return false; |
| 19469 } | 19469 } |
| 19470 } | 19470 } |
| 19471 bool foundError = false; | 19471 bool foundError = false; |
| 19472 for (ClassMember classMember in classMembers) { | 19472 for (ClassMember classMember in classMembers) { |
| 19473 if (classMember is FieldDeclaration) { | 19473 if (classMember is FieldDeclaration) { |
| 19474 FieldDeclaration field = classMember; | 19474 FieldDeclaration field = classMember; |
| 19475 foundError = javaBooleanOr(foundError, checkForFinalNotInitialized(field
.fields)); | 19475 foundError = javaBooleanOr(foundError, _checkForFinalNotInitialized(fiel
d.fields)); |
| 19476 } | 19476 } |
| 19477 } | 19477 } |
| 19478 return foundError; | 19478 return foundError; |
| 19479 } | 19479 } |
| 19480 | 19480 |
| 19481 /** | 19481 /** |
| 19482 * This verifies that the passed implements clause does not implement classes
such as 'num' or | 19482 * This verifies that the passed implements clause does not implement classes
such as 'num' or |
| 19483 * 'String'. | 19483 * 'String'. |
| 19484 * | 19484 * |
| 19485 * @param node the implements clause to test | 19485 * @param node the implements clause to test |
| 19486 * @return `true` if and only if an error code is generated on the passed node | 19486 * @return `true` if and only if an error code is generated on the passed node |
| 19487 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS | 19487 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS |
| 19488 */ | 19488 */ |
| 19489 bool checkForImplementsDisallowedClass(ImplementsClause node) { | 19489 bool _checkForImplementsDisallowedClass(ImplementsClause node) { |
| 19490 if (node == null) { | 19490 if (node == null) { |
| 19491 return false; | 19491 return false; |
| 19492 } | 19492 } |
| 19493 bool foundError = false; | 19493 bool foundError = false; |
| 19494 for (TypeName type in node.interfaces) { | 19494 for (TypeName type in node.interfaces) { |
| 19495 foundError = javaBooleanOr(foundError, checkForExtendsOrImplementsDisallow
edClass(type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)); | 19495 foundError = javaBooleanOr(foundError, _checkForExtendsOrImplementsDisallo
wedClass(type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)); |
| 19496 } | 19496 } |
| 19497 return foundError; | 19497 return foundError; |
| 19498 } | 19498 } |
| 19499 | 19499 |
| 19500 /** | 19500 /** |
| 19501 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does | 19501 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does |
| 19502 * not reference implicitly 'this' expression. | 19502 * not reference implicitly 'this' expression. |
| 19503 * | 19503 * |
| 19504 * @param node the simple identifier to test | 19504 * @param node the simple identifier to test |
| 19505 * @return `true` if and only if an error code is generated on the passed node | 19505 * @return `true` if and only if an error code is generated on the passed node |
| 19506 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER | 19506 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER |
| 19507 * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov)
rename thid method | 19507 * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov)
rename thid method |
| 19508 */ | 19508 */ |
| 19509 bool checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { | 19509 bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { |
| 19510 if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInInstanceVari
ableInitializer && !_isInStaticVariableDeclaration) { | 19510 if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInInstanceVari
ableInitializer && !_isInStaticVariableDeclaration) { |
| 19511 return false; | 19511 return false; |
| 19512 } | 19512 } |
| 19513 // prepare element | 19513 // prepare element |
| 19514 Element element = node.staticElement; | 19514 Element element = node.staticElement; |
| 19515 if (!(element is MethodElement || element is PropertyAccessorElement)) { | 19515 if (!(element is MethodElement || element is PropertyAccessorElement)) { |
| 19516 return false; | 19516 return false; |
| 19517 } | 19517 } |
| 19518 // static element | 19518 // static element |
| 19519 ExecutableElement executableElement = element as ExecutableElement; | 19519 ExecutableElement executableElement = element as ExecutableElement; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19561 | 19561 |
| 19562 /** | 19562 /** |
| 19563 * This verifies the passed import has unique name among other imported librar
ies. | 19563 * This verifies the passed import has unique name among other imported librar
ies. |
| 19564 * | 19564 * |
| 19565 * @param node the import directive to evaluate | 19565 * @param node the import directive to evaluate |
| 19566 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the | 19566 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the |
| 19567 * node was `null`, then this method is not called | 19567 * node was `null`, then this method is not called |
| 19568 * @return `true` if and only if an error code is generated on the passed node | 19568 * @return `true` if and only if an error code is generated on the passed node |
| 19569 * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME | 19569 * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME |
| 19570 */ | 19570 */ |
| 19571 bool checkForImportDuplicateLibraryName(ImportDirective node, ImportElement im
portElement) { | 19571 bool _checkForImportDuplicateLibraryName(ImportDirective node, ImportElement i
mportElement) { |
| 19572 // prepare imported library | 19572 // prepare imported library |
| 19573 LibraryElement nodeLibrary = importElement.importedLibrary; | 19573 LibraryElement nodeLibrary = importElement.importedLibrary; |
| 19574 if (nodeLibrary == null) { | 19574 if (nodeLibrary == null) { |
| 19575 return false; | 19575 return false; |
| 19576 } | 19576 } |
| 19577 String name = nodeLibrary.name; | 19577 String name = nodeLibrary.name; |
| 19578 // check if there is other imported library with the same name | 19578 // check if there is other imported library with the same name |
| 19579 LibraryElement prevLibrary = _nameToImportElement[name]; | 19579 LibraryElement prevLibrary = _nameToImportElement[name]; |
| 19580 if (prevLibrary != null) { | 19580 if (prevLibrary != null) { |
| 19581 if (prevLibrary != nodeLibrary) { | 19581 if (prevLibrary != nodeLibrary) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 19595 /** | 19595 /** |
| 19596 * Check that if the visiting library is not system, then any passed library s
hould not be SDK | 19596 * Check that if the visiting library is not system, then any passed library s
hould not be SDK |
| 19597 * internal library. | 19597 * internal library. |
| 19598 * | 19598 * |
| 19599 * @param node the import directive to evaluate | 19599 * @param node the import directive to evaluate |
| 19600 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the | 19600 * @param importElement the [ImportElement] retrieved from the node, if the el
ement in the |
| 19601 * node was `null`, then this method is not called | 19601 * node was `null`, then this method is not called |
| 19602 * @return `true` if and only if an error code is generated on the passed node | 19602 * @return `true` if and only if an error code is generated on the passed node |
| 19603 * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY | 19603 * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY |
| 19604 */ | 19604 */ |
| 19605 bool checkForImportInternalLibrary(ImportDirective node, ImportElement importE
lement) { | 19605 bool _checkForImportInternalLibrary(ImportDirective node, ImportElement import
Element) { |
| 19606 if (_isInSystemLibrary) { | 19606 if (_isInSystemLibrary) { |
| 19607 return false; | 19607 return false; |
| 19608 } | 19608 } |
| 19609 // should be private | 19609 // should be private |
| 19610 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 19610 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 19611 String uri = importElement.uri; | 19611 String uri = importElement.uri; |
| 19612 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 19612 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 19613 if (sdkLibrary == null) { | 19613 if (sdkLibrary == null) { |
| 19614 return false; | 19614 return false; |
| 19615 } | 19615 } |
| 19616 if (!sdkLibrary.isInternal) { | 19616 if (!sdkLibrary.isInternal) { |
| 19617 return false; | 19617 return false; |
| 19618 } | 19618 } |
| 19619 // report problem | 19619 // report problem |
| 19620 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRA
RY, node, [node.uri]); | 19620 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRA
RY, node, [node.uri]); |
| 19621 return true; | 19621 return true; |
| 19622 } | 19622 } |
| 19623 | 19623 |
| 19624 /** | 19624 /** |
| 19625 * This verifies that the passed switch statement case expressions all have th
e same type. | 19625 * This verifies that the passed switch statement case expressions all have th
e same type. |
| 19626 * | 19626 * |
| 19627 * @param node the switch statement to evaluate | 19627 * @param node the switch statement to evaluate |
| 19628 * @return `true` if and only if an error code is generated on the passed node | 19628 * @return `true` if and only if an error code is generated on the passed node |
| 19629 * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES | 19629 * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES |
| 19630 */ | 19630 */ |
| 19631 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) { | 19631 bool _checkForInconsistentCaseExpressionTypes(SwitchStatement node) { |
| 19632 // TODO(jwren) Revisit this algorithm, should there up to n-1 errors? | 19632 // TODO(jwren) Revisit this algorithm, should there up to n-1 errors? |
| 19633 NodeList<SwitchMember> switchMembers = node.members; | 19633 NodeList<SwitchMember> switchMembers = node.members; |
| 19634 bool foundError = false; | 19634 bool foundError = false; |
| 19635 Type2 firstType = null; | 19635 Type2 firstType = null; |
| 19636 for (SwitchMember switchMember in switchMembers) { | 19636 for (SwitchMember switchMember in switchMembers) { |
| 19637 if (switchMember is SwitchCase) { | 19637 if (switchMember is SwitchCase) { |
| 19638 SwitchCase switchCase = switchMember; | 19638 SwitchCase switchCase = switchMember; |
| 19639 Expression expression = switchCase.expression; | 19639 Expression expression = switchCase.expression; |
| 19640 if (firstType == null) { | 19640 if (firstType == null) { |
| 19641 // TODO(brianwilkerson) This is failing with const variables whose dec
lared type is | 19641 // TODO(brianwilkerson) This is failing with const variables whose dec
lared type is |
| 19642 // dynamic. The problem is that we don't have any way to propagate typ
e information for | 19642 // dynamic. The problem is that we don't have any way to propagate typ
e information for |
| 19643 // the variable. | 19643 // the variable. |
| 19644 firstType = expression.bestType; | 19644 firstType = expression.bestType; |
| 19645 } else { | 19645 } else { |
| 19646 Type2 nType = expression.bestType; | 19646 Type2 nType = expression.bestType; |
| 19647 if (firstType != nType) { | 19647 if (firstType != nType) { |
| 19648 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INCONSISTENT_
CASE_EXPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName
]); | 19648 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INCONSISTENT_
CASE_EXPRESSION_TYPES, expression, [expression.toSource(), firstType.displayName
]); |
| 19649 foundError = true; | 19649 foundError = true; |
| 19650 } | 19650 } |
| 19651 } | 19651 } |
| 19652 } | 19652 } |
| 19653 } | 19653 } |
| 19654 if (!foundError) { | 19654 if (!foundError) { |
| 19655 checkForCaseExpressionTypeImplementsEquals(node, firstType); | 19655 _checkForCaseExpressionTypeImplementsEquals(node, firstType); |
| 19656 } | 19656 } |
| 19657 return foundError; | 19657 return foundError; |
| 19658 } | 19658 } |
| 19659 | 19659 |
| 19660 /** | 19660 /** |
| 19661 * For each class declaration, this method is called which verifies that all i
nherited members are | 19661 * For each class declaration, this method is called which verifies that all i
nherited members are |
| 19662 * inherited consistently. | 19662 * inherited consistently. |
| 19663 * | 19663 * |
| 19664 * @return `true` if and only if an error code is generated on the passed node | 19664 * @return `true` if and only if an error code is generated on the passed node |
| 19665 * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE | 19665 * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE |
| 19666 */ | 19666 */ |
| 19667 bool checkForInconsistentMethodInheritance() { | 19667 bool _checkForInconsistentMethodInheritance() { |
| 19668 // Ensure that the inheritance manager has a chance to generate all errors w
e may care about, | 19668 // Ensure that the inheritance manager has a chance to generate all errors w
e may care about, |
| 19669 // note that we ensure that the interfaces data since there are no errors. | 19669 // note that we ensure that the interfaces data since there are no errors. |
| 19670 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); | 19670 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass); |
| 19671 Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass); | 19671 Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass); |
| 19672 if (errors == null || errors.isEmpty) { | 19672 if (errors == null || errors.isEmpty) { |
| 19673 return false; | 19673 return false; |
| 19674 } | 19674 } |
| 19675 for (AnalysisError error in errors) { | 19675 for (AnalysisError error in errors) { |
| 19676 _errorReporter.reportError(error); | 19676 _errorReporter.reportError(error); |
| 19677 } | 19677 } |
| 19678 return true; | 19678 return true; |
| 19679 } | 19679 } |
| 19680 | 19680 |
| 19681 /** | 19681 /** |
| 19682 * This checks the given "typeReference" is not a type reference and that then
the "name" is | 19682 * This checks the given "typeReference" is not a type reference and that then
the "name" is |
| 19683 * reference to an instance member. | 19683 * reference to an instance member. |
| 19684 * | 19684 * |
| 19685 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 19685 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
| 19686 * or `null`, aka, the class element of 'C' in 'C.x', see | 19686 * or `null`, aka, the class element of 'C' in 'C.x', see |
| 19687 * [getTypeReference] | 19687 * [getTypeReference] |
| 19688 * @param name the accessed name to evaluate | 19688 * @param name the accessed name to evaluate |
| 19689 * @return `true` if and only if an error code is generated on the passed node | 19689 * @return `true` if and only if an error code is generated on the passed node |
| 19690 * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER | 19690 * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER |
| 19691 */ | 19691 */ |
| 19692 bool checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleId
entifier name) { | 19692 bool _checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleI
dentifier name) { |
| 19693 // OK, in comment | 19693 // OK, in comment |
| 19694 if (_isInComment) { | 19694 if (_isInComment) { |
| 19695 return false; | 19695 return false; |
| 19696 } | 19696 } |
| 19697 // OK, target is a type | 19697 // OK, target is a type |
| 19698 if (typeReference != null) { | 19698 if (typeReference != null) { |
| 19699 return false; | 19699 return false; |
| 19700 } | 19700 } |
| 19701 // prepare member Element | 19701 // prepare member Element |
| 19702 Element element = name.staticElement; | 19702 Element element = name.staticElement; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 19719 | 19719 |
| 19720 /** | 19720 /** |
| 19721 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given | 19721 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given |
| 19722 * expression. This is used for prefix and postfix expressions where the argum
ent value is | 19722 * expression. This is used for prefix and postfix expressions where the argum
ent value is |
| 19723 * implicit. | 19723 * implicit. |
| 19724 * | 19724 * |
| 19725 * @param argument the expression to which the operator is being applied | 19725 * @param argument the expression to which the operator is being applied |
| 19726 * @return `true` if and only if an error code is generated on the passed node | 19726 * @return `true` if and only if an error code is generated on the passed node |
| 19727 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 19727 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 19728 */ | 19728 */ |
| 19729 bool checkForIntNotAssignable(Expression argument) { | 19729 bool _checkForIntNotAssignable(Expression argument) { |
| 19730 if (argument == null) { | 19730 if (argument == null) { |
| 19731 return false; | 19731 return false; |
| 19732 } | 19732 } |
| 19733 ParameterElement staticParameterElement = argument.staticParameterElement; | 19733 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 19734 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; | 19734 Type2 staticParameterType = staticParameterElement == null ? null : staticPa
rameterElement.type; |
| 19735 ParameterElement propagatedParameterElement = argument.propagatedParameterEl
ement; | 19735 ParameterElement propagatedParameterElement = argument.propagatedParameterEl
ement; |
| 19736 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; | 19736 Type2 propagatedParameterType = propagatedParameterElement == null ? null :
propagatedParameterElement.type; |
| 19737 return checkForArgumentTypeNotAssignable(argument, staticParameterType, _int
Type, propagatedParameterType, _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASS
IGNABLE); | 19737 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, _in
tType, propagatedParameterType, _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_AS
SIGNABLE); |
| 19738 } | 19738 } |
| 19739 | 19739 |
| 19740 /** | 19740 /** |
| 19741 * This verifies that the passed left hand side and right hand side represent
a valid assignment. | 19741 * This verifies that the passed left hand side and right hand side represent
a valid assignment. |
| 19742 * | 19742 * |
| 19743 * @param lhs the left hand side expression | 19743 * @param lhs the left hand side expression |
| 19744 * @param rhs the right hand side expression | 19744 * @param rhs the right hand side expression |
| 19745 * @return `true` if and only if an error code is generated on the passed node | 19745 * @return `true` if and only if an error code is generated on the passed node |
| 19746 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT | 19746 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT |
| 19747 */ | 19747 */ |
| 19748 bool checkForInvalidAssignment(Expression lhs, Expression rhs) { | 19748 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { |
| 19749 if (lhs == null || rhs == null) { | 19749 if (lhs == null || rhs == null) { |
| 19750 return false; | 19750 return false; |
| 19751 } | 19751 } |
| 19752 VariableElement leftElement = getVariableElement(lhs); | 19752 VariableElement leftElement = _getVariableElement(lhs); |
| 19753 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; | 19753 Type2 leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.t
ype; |
| 19754 Type2 staticRightType = getStaticType(rhs); | 19754 Type2 staticRightType = _getStaticType(rhs); |
| 19755 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); | 19755 bool isStaticAssignable = staticRightType.isAssignableTo(leftType); |
| 19756 if (!isStaticAssignable) { | 19756 if (!isStaticAssignable) { |
| 19757 String leftName = leftType.displayName; | 19757 String leftName = leftType.displayName; |
| 19758 String rightName = staticRightType.displayName; | 19758 String rightName = staticRightType.displayName; |
| 19759 if (leftName == rightName) { | 19759 if (leftName == rightName) { |
| 19760 leftName = getExtendedDisplayName(leftType); | 19760 leftName = _getExtendedDisplayName(leftType); |
| 19761 rightName = getExtendedDisplayName(staticRightType); | 19761 rightName = _getExtendedDisplayName(staticRightType); |
| 19762 } | 19762 } |
| 19763 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT
, rhs, [rightName, leftName]); | 19763 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT
, rhs, [rightName, leftName]); |
| 19764 return true; | 19764 return true; |
| 19765 } | 19765 } |
| 19766 // TODO(brianwilkerson) Define a hint corresponding to the warning and repor
t it if appropriate. | 19766 // TODO(brianwilkerson) Define a hint corresponding to the warning and repor
t it if appropriate. |
| 19767 // Type propagatedRightType = rhs.getPropagatedType(); | 19767 // Type propagatedRightType = rhs.getPropagatedType(); |
| 19768 // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(le
ftType); | 19768 // boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(le
ftType); |
| 19769 // if (!isStaticAssignable && !isPropagatedAssignable) { | 19769 // if (!isStaticAssignable && !isPropagatedAssignable) { |
| 19770 // errorReporter.reportError( | 19770 // errorReporter.reportError( |
| 19771 // StaticTypeWarningCode.INVALID_ASSIGNMENT, | 19771 // StaticTypeWarningCode.INVALID_ASSIGNMENT, |
| 19772 // rhs, | 19772 // rhs, |
| 19773 // staticRightType.getDisplayName(), | 19773 // staticRightType.getDisplayName(), |
| 19774 // leftType.getDisplayName()); | 19774 // leftType.getDisplayName()); |
| 19775 // return true; | 19775 // return true; |
| 19776 // } | 19776 // } |
| 19777 return false; | 19777 return false; |
| 19778 } | 19778 } |
| 19779 | 19779 |
| 19780 /** | 19780 /** |
| 19781 * Given an assignment using a compound assignment operator, this verifies tha
t the given | 19781 * Given an assignment using a compound assignment operator, this verifies tha
t the given |
| 19782 * assignment is valid. | 19782 * assignment is valid. |
| 19783 * | 19783 * |
| 19784 * @param node the assignment expression being tested | 19784 * @param node the assignment expression being tested |
| 19785 * @return `true` if and only if an error code is generated on the passed node | 19785 * @return `true` if and only if an error code is generated on the passed node |
| 19786 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT | 19786 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT |
| 19787 */ | 19787 */ |
| 19788 bool checkForInvalidCompoundAssignment(AssignmentExpression node) { | 19788 bool _checkForInvalidCompoundAssignment(AssignmentExpression node) { |
| 19789 Expression lhs = node.leftHandSide; | 19789 Expression lhs = node.leftHandSide; |
| 19790 if (lhs == null) { | 19790 if (lhs == null) { |
| 19791 return false; | 19791 return false; |
| 19792 } | 19792 } |
| 19793 VariableElement leftElement = getVariableElement(lhs); | 19793 VariableElement leftElement = _getVariableElement(lhs); |
| 19794 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty
pe; | 19794 Type2 leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.t
ype; |
| 19795 MethodElement invokedMethod = node.staticElement; | 19795 MethodElement invokedMethod = node.staticElement; |
| 19796 if (invokedMethod == null) { | 19796 if (invokedMethod == null) { |
| 19797 return false; | 19797 return false; |
| 19798 } | 19798 } |
| 19799 Type2 rightType = invokedMethod.type.returnType; | 19799 Type2 rightType = invokedMethod.type.returnType; |
| 19800 if (leftType == null || rightType == null) { | 19800 if (leftType == null || rightType == null) { |
| 19801 return false; | 19801 return false; |
| 19802 } | 19802 } |
| 19803 if (!rightType.isAssignableTo(leftType)) { | 19803 if (!rightType.isAssignableTo(leftType)) { |
| 19804 String leftName = leftType.displayName; | 19804 String leftName = leftType.displayName; |
| 19805 String rightName = rightType.displayName; | 19805 String rightName = rightType.displayName; |
| 19806 if (leftName == rightName) { | 19806 if (leftName == rightName) { |
| 19807 leftName = getExtendedDisplayName(leftType); | 19807 leftName = _getExtendedDisplayName(leftType); |
| 19808 rightName = getExtendedDisplayName(rightType); | 19808 rightName = _getExtendedDisplayName(rightType); |
| 19809 } | 19809 } |
| 19810 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT
, node.rightHandSide, [rightName, leftName]); | 19810 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT
, node.rightHandSide, [rightName, leftName]); |
| 19811 return true; | 19811 return true; |
| 19812 } | 19812 } |
| 19813 return false; | 19813 return false; |
| 19814 } | 19814 } |
| 19815 | 19815 |
| 19816 /** | 19816 /** |
| 19817 * Check the given initializer to ensure that the field being initialized is a
valid field. | 19817 * Check the given initializer to ensure that the field being initialized is a
valid field. |
| 19818 * | 19818 * |
| 19819 * @param node the field initializer being checked | 19819 * @param node the field initializer being checked |
| 19820 */ | 19820 */ |
| 19821 void checkForInvalidField(ConstructorFieldInitializer node) { | 19821 void _checkForInvalidField(ConstructorFieldInitializer node) { |
| 19822 SimpleIdentifier fieldName = node.fieldName; | 19822 SimpleIdentifier fieldName = node.fieldName; |
| 19823 Element staticElement = fieldName.staticElement; | 19823 Element staticElement = fieldName.staticElement; |
| 19824 if (staticElement is FieldElement) { | 19824 if (staticElement is FieldElement) { |
| 19825 FieldElement fieldElement = staticElement; | 19825 FieldElement fieldElement = staticElement; |
| 19826 if (fieldElement.isSynthetic) { | 19826 if (fieldElement.isSynthetic) { |
| 19827 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_N
ON_EXISTANT_FIELD, node, [fieldName]); | 19827 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_N
ON_EXISTANT_FIELD, node, [fieldName]); |
| 19828 } else if (fieldElement.isStatic) { | 19828 } else if (fieldElement.isStatic) { |
| 19829 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_S
TATIC_FIELD, node, [fieldName]); | 19829 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_S
TATIC_FIELD, node, [fieldName]); |
| 19830 } | 19830 } |
| 19831 } else { | 19831 } else { |
| 19832 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_NON
_EXISTANT_FIELD, node, [fieldName]); | 19832 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_NON
_EXISTANT_FIELD, node, [fieldName]); |
| 19833 return; | 19833 return; |
| 19834 } | 19834 } |
| 19835 } | 19835 } |
| 19836 | 19836 |
| 19837 /** | 19837 /** |
| 19838 * This verifies that the usage of the passed 'this' is valid. | 19838 * This verifies that the usage of the passed 'this' is valid. |
| 19839 * | 19839 * |
| 19840 * @param node the 'this' expression to evaluate | 19840 * @param node the 'this' expression to evaluate |
| 19841 * @return `true` if and only if an error code is generated on the passed node | 19841 * @return `true` if and only if an error code is generated on the passed node |
| 19842 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS | 19842 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS |
| 19843 */ | 19843 */ |
| 19844 bool checkForInvalidReferenceToThis(ThisExpression node) { | 19844 bool _checkForInvalidReferenceToThis(ThisExpression node) { |
| 19845 if (!isThisInValidContext(node)) { | 19845 if (!_isThisInValidContext(node)) { |
| 19846 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INVALID_REFERENCE_T
O_THIS, node, []); | 19846 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INVALID_REFERENCE_T
O_THIS, node, []); |
| 19847 return true; | 19847 return true; |
| 19848 } | 19848 } |
| 19849 return false; | 19849 return false; |
| 19850 } | 19850 } |
| 19851 | 19851 |
| 19852 /** | 19852 /** |
| 19853 * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not hav
e a type | 19853 * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not hav
e a type |
| 19854 * parameter as a type argument. | 19854 * parameter as a type argument. |
| 19855 * | 19855 * |
| 19856 * @param arguments a non-`null`, non-empty [TypeName] node list from the resp
ective | 19856 * @param arguments a non-`null`, non-empty [TypeName] node list from the resp
ective |
| 19857 * [ListLiteral] or [MapLiteral] | 19857 * [ListLiteral] or [MapLiteral] |
| 19858 * @param errorCode either [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONS
T_LIST] or | 19858 * @param errorCode either [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONS
T_LIST] or |
| 19859 * [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP] | 19859 * [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP] |
| 19860 * @return `true` if and only if an error code is generated on the passed node | 19860 * @return `true` if and only if an error code is generated on the passed node |
| 19861 */ | 19861 */ |
| 19862 bool checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> argumen
ts, ErrorCode errorCode) { | 19862 bool _checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> argume
nts, ErrorCode errorCode) { |
| 19863 bool foundError = false; | 19863 bool foundError = false; |
| 19864 for (TypeName typeName in arguments) { | 19864 for (TypeName typeName in arguments) { |
| 19865 if (typeName.type is TypeParameterType) { | 19865 if (typeName.type is TypeParameterType) { |
| 19866 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 19866 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); |
| 19867 foundError = true; | 19867 foundError = true; |
| 19868 } | 19868 } |
| 19869 } | 19869 } |
| 19870 return foundError; | 19870 return foundError; |
| 19871 } | 19871 } |
| 19872 | 19872 |
| 19873 /** | 19873 /** |
| 19874 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element | 19874 * This verifies that the elements given [ListLiteral] are subtypes of the spe
cified element |
| 19875 * type. | 19875 * type. |
| 19876 * | 19876 * |
| 19877 * @param node the list literal to evaluate | 19877 * @param node the list literal to evaluate |
| 19878 * @return `true` if and only if an error code is generated on the passed node | 19878 * @return `true` if and only if an error code is generated on the passed node |
| 19879 * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE | 19879 * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE |
| 19880 * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE | 19880 * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE |
| 19881 */ | 19881 */ |
| 19882 bool checkForListElementTypeNotAssignable(ListLiteral node) { | 19882 bool _checkForListElementTypeNotAssignable(ListLiteral node) { |
| 19883 // Prepare list element type. | 19883 // Prepare list element type. |
| 19884 TypeArgumentList typeArgumentList = node.typeArguments; | 19884 TypeArgumentList typeArgumentList = node.typeArguments; |
| 19885 if (typeArgumentList == null) { | 19885 if (typeArgumentList == null) { |
| 19886 return false; | 19886 return false; |
| 19887 } | 19887 } |
| 19888 NodeList<TypeName> typeArguments = typeArgumentList.arguments; | 19888 NodeList<TypeName> typeArguments = typeArgumentList.arguments; |
| 19889 if (typeArguments.length < 1) { | 19889 if (typeArguments.length < 1) { |
| 19890 return false; | 19890 return false; |
| 19891 } | 19891 } |
| 19892 Type2 listElementType = typeArguments[0].type; | 19892 Type2 listElementType = typeArguments[0].type; |
| 19893 // Prepare problem to report. | 19893 // Prepare problem to report. |
| 19894 ErrorCode errorCode; | 19894 ErrorCode errorCode; |
| 19895 if (node.constKeyword != null) { | 19895 if (node.constKeyword != null) { |
| 19896 errorCode = CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; | 19896 errorCode = CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; |
| 19897 } else { | 19897 } else { |
| 19898 errorCode = StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; | 19898 errorCode = StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE; |
| 19899 } | 19899 } |
| 19900 // Check every list element. | 19900 // Check every list element. |
| 19901 bool hasProblems = false; | 19901 bool hasProblems = false; |
| 19902 for (Expression element in node.elements) { | 19902 for (Expression element in node.elements) { |
| 19903 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
WithExpectedTypes(element, listElementType, null, errorCode)); | 19903 hasProblems = javaBooleanOr(hasProblems, _checkForArgumentTypeNotAssignabl
eWithExpectedTypes(element, listElementType, null, errorCode)); |
| 19904 } | 19904 } |
| 19905 return hasProblems; | 19905 return hasProblems; |
| 19906 } | 19906 } |
| 19907 | 19907 |
| 19908 /** | 19908 /** |
| 19909 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the | 19909 * This verifies that the key/value of entries of the given [MapLiteral] are s
ubtypes of the |
| 19910 * key/value types specified in the type arguments. | 19910 * key/value types specified in the type arguments. |
| 19911 * | 19911 * |
| 19912 * @param node the map literal to evaluate | 19912 * @param node the map literal to evaluate |
| 19913 * @return `true` if and only if an error code is generated on the passed node | 19913 * @return `true` if and only if an error code is generated on the passed node |
| 19914 * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE | 19914 * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE |
| 19915 * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE | 19915 * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE |
| 19916 * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE | 19916 * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE |
| 19917 * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE | 19917 * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE |
| 19918 */ | 19918 */ |
| 19919 bool checkForMapTypeNotAssignable(MapLiteral node) { | 19919 bool _checkForMapTypeNotAssignable(MapLiteral node) { |
| 19920 // Prepare maps key/value types. | 19920 // Prepare maps key/value types. |
| 19921 TypeArgumentList typeArgumentList = node.typeArguments; | 19921 TypeArgumentList typeArgumentList = node.typeArguments; |
| 19922 if (typeArgumentList == null) { | 19922 if (typeArgumentList == null) { |
| 19923 return false; | 19923 return false; |
| 19924 } | 19924 } |
| 19925 NodeList<TypeName> typeArguments = typeArgumentList.arguments; | 19925 NodeList<TypeName> typeArguments = typeArgumentList.arguments; |
| 19926 if (typeArguments.length < 2) { | 19926 if (typeArguments.length < 2) { |
| 19927 return false; | 19927 return false; |
| 19928 } | 19928 } |
| 19929 Type2 keyType = typeArguments[0].type; | 19929 Type2 keyType = typeArguments[0].type; |
| 19930 Type2 valueType = typeArguments[1].type; | 19930 Type2 valueType = typeArguments[1].type; |
| 19931 // Prepare problem to report. | 19931 // Prepare problem to report. |
| 19932 ErrorCode keyErrorCode; | 19932 ErrorCode keyErrorCode; |
| 19933 ErrorCode valueErrorCode; | 19933 ErrorCode valueErrorCode; |
| 19934 if (node.constKeyword != null) { | 19934 if (node.constKeyword != null) { |
| 19935 keyErrorCode = CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; | 19935 keyErrorCode = CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; |
| 19936 valueErrorCode = CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; | 19936 valueErrorCode = CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; |
| 19937 } else { | 19937 } else { |
| 19938 keyErrorCode = StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; | 19938 keyErrorCode = StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE; |
| 19939 valueErrorCode = StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; | 19939 valueErrorCode = StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE; |
| 19940 } | 19940 } |
| 19941 // Check every map entry. | 19941 // Check every map entry. |
| 19942 bool hasProblems = false; | 19942 bool hasProblems = false; |
| 19943 NodeList<MapLiteralEntry> entries = node.entries; | 19943 NodeList<MapLiteralEntry> entries = node.entries; |
| 19944 for (MapLiteralEntry entry in entries) { | 19944 for (MapLiteralEntry entry in entries) { |
| 19945 Expression key = entry.key; | 19945 Expression key = entry.key; |
| 19946 Expression value = entry.value; | 19946 Expression value = entry.value; |
| 19947 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
WithExpectedTypes(key, keyType, null, keyErrorCode)); | 19947 hasProblems = javaBooleanOr(hasProblems, _checkForArgumentTypeNotAssignabl
eWithExpectedTypes(key, keyType, null, keyErrorCode)); |
| 19948 hasProblems = javaBooleanOr(hasProblems, checkForArgumentTypeNotAssignable
WithExpectedTypes(value, valueType, null, valueErrorCode)); | 19948 hasProblems = javaBooleanOr(hasProblems, _checkForArgumentTypeNotAssignabl
eWithExpectedTypes(value, valueType, null, valueErrorCode)); |
| 19949 } | 19949 } |
| 19950 return hasProblems; | 19950 return hasProblems; |
| 19951 } | 19951 } |
| 19952 | 19952 |
| 19953 /** | 19953 /** |
| 19954 * This verifies that the [enclosingClass] does not define members with the sa
me name as | 19954 * This verifies that the [enclosingClass] does not define members with the sa
me name as |
| 19955 * the enclosing class. | 19955 * the enclosing class. |
| 19956 * | 19956 * |
| 19957 * @return `true` if and only if an error code is generated on the passed node | 19957 * @return `true` if and only if an error code is generated on the passed node |
| 19958 * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME | 19958 * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME |
| 19959 */ | 19959 */ |
| 19960 bool checkForMemberWithClassName() { | 19960 bool _checkForMemberWithClassName() { |
| 19961 if (_enclosingClass == null) { | 19961 if (_enclosingClass == null) { |
| 19962 return false; | 19962 return false; |
| 19963 } | 19963 } |
| 19964 String className = _enclosingClass.name; | 19964 String className = _enclosingClass.name; |
| 19965 if (className == null) { | 19965 if (className == null) { |
| 19966 return false; | 19966 return false; |
| 19967 } | 19967 } |
| 19968 bool problemReported = false; | 19968 bool problemReported = false; |
| 19969 // check accessors | 19969 // check accessors |
| 19970 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { | 19970 for (PropertyAccessorElement accessor in _enclosingClass.accessors) { |
| 19971 if (className == accessor.name) { | 19971 if (className == accessor.name) { |
| 19972 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.MEMBER_WITH_CLA
SS_NAME, accessor.nameOffset, className.length, []); | 19972 _errorReporter.reportErrorForOffset(CompileTimeErrorCode.MEMBER_WITH_CLA
SS_NAME, accessor.nameOffset, className.length, []); |
| 19973 problemReported = true; | 19973 problemReported = true; |
| 19974 } | 19974 } |
| 19975 } | 19975 } |
| 19976 // don't check methods, they would be constructors | 19976 // don't check methods, they would be constructors |
| 19977 // done | 19977 // done |
| 19978 return problemReported; | 19978 return problemReported; |
| 19979 } | 19979 } |
| 19980 | 19980 |
| 19981 /** | 19981 /** |
| 19982 * Check to make sure that all similarly typed accessors are of the same type
(including inherited | 19982 * Check to make sure that all similarly typed accessors are of the same type
(including inherited |
| 19983 * accessors). | 19983 * accessors). |
| 19984 * | 19984 * |
| 19985 * @param node the accessor currently being visited | 19985 * @param node the accessor currently being visited |
| 19986 * @return `true` if and only if an error code is generated on the passed node | 19986 * @return `true` if and only if an error code is generated on the passed node |
| 19987 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES | 19987 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES |
| 19988 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE | 19988 * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE |
| 19989 */ | 19989 */ |
| 19990 bool checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String a
ccessorTextName) { | 19990 bool _checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String
accessorTextName) { |
| 19991 ExecutableElement accessorElement = accessorDeclaration.element as Executabl
eElement; | 19991 ExecutableElement accessorElement = accessorDeclaration.element as Executabl
eElement; |
| 19992 if (accessorElement is! PropertyAccessorElement) { | 19992 if (accessorElement is! PropertyAccessorElement) { |
| 19993 return false; | 19993 return false; |
| 19994 } | 19994 } |
| 19995 PropertyAccessorElement propertyAccessorElement = accessorElement as Propert
yAccessorElement; | 19995 PropertyAccessorElement propertyAccessorElement = accessorElement as Propert
yAccessorElement; |
| 19996 PropertyAccessorElement counterpartAccessor = null; | 19996 PropertyAccessorElement counterpartAccessor = null; |
| 19997 ClassElement enclosingClassForCounterpart = null; | 19997 ClassElement enclosingClassForCounterpart = null; |
| 19998 if (propertyAccessorElement.isGetter) { | 19998 if (propertyAccessorElement.isGetter) { |
| 19999 counterpartAccessor = propertyAccessorElement.correspondingSetter; | 19999 counterpartAccessor = propertyAccessorElement.correspondingSetter; |
| 20000 } else { | 20000 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 20026 } | 20026 } |
| 20027 if (counterpartAccessor == null) { | 20027 if (counterpartAccessor == null) { |
| 20028 return false; | 20028 return false; |
| 20029 } | 20029 } |
| 20030 } | 20030 } |
| 20031 // Default of null == no accessor or no type (dynamic) | 20031 // Default of null == no accessor or no type (dynamic) |
| 20032 Type2 getterType = null; | 20032 Type2 getterType = null; |
| 20033 Type2 setterType = null; | 20033 Type2 setterType = null; |
| 20034 // Get an existing counterpart accessor if any. | 20034 // Get an existing counterpart accessor if any. |
| 20035 if (propertyAccessorElement.isGetter) { | 20035 if (propertyAccessorElement.isGetter) { |
| 20036 getterType = getGetterType(propertyAccessorElement); | 20036 getterType = _getGetterType(propertyAccessorElement); |
| 20037 setterType = getSetterType(counterpartAccessor); | 20037 setterType = _getSetterType(counterpartAccessor); |
| 20038 } else if (propertyAccessorElement.isSetter) { | 20038 } else if (propertyAccessorElement.isSetter) { |
| 20039 setterType = getSetterType(propertyAccessorElement); | 20039 setterType = _getSetterType(propertyAccessorElement); |
| 20040 getterType = getGetterType(counterpartAccessor); | 20040 getterType = _getGetterType(counterpartAccessor); |
| 20041 } | 20041 } |
| 20042 // If either types are not assignable to each other, report an error (if the
getter is null, | 20042 // If either types are not assignable to each other, report an error (if the
getter is null, |
| 20043 // it is dynamic which is assignable to everything). | 20043 // it is dynamic which is assignable to everything). |
| 20044 if (setterType != null && getterType != null && !getterType.isAssignableTo(s
etterType)) { | 20044 if (setterType != null && getterType != null && !getterType.isAssignableTo(s
etterType)) { |
| 20045 if (enclosingClassForCounterpart == null) { | 20045 if (enclosingClassForCounterpart == null) { |
| 20046 _errorReporter.reportErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AN
D_SETTER_TYPES, accessorDeclaration, [ | 20046 _errorReporter.reportErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AN
D_SETTER_TYPES, accessorDeclaration, [ |
| 20047 accessorTextName, | 20047 accessorTextName, |
| 20048 setterType.displayName, | 20048 setterType.displayName, |
| 20049 getterType.displayName]); | 20049 getterType.displayName]); |
| 20050 return true; | 20050 return true; |
| 20051 } else { | 20051 } else { |
| 20052 _errorReporter.reportErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AN
D_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [ | 20052 _errorReporter.reportErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AN
D_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [ |
| 20053 accessorTextName, | 20053 accessorTextName, |
| 20054 setterType.displayName, | 20054 setterType.displayName, |
| 20055 getterType.displayName, | 20055 getterType.displayName, |
| 20056 enclosingClassForCounterpart.displayName]); | 20056 enclosingClassForCounterpart.displayName]); |
| 20057 } | 20057 } |
| 20058 } | 20058 } |
| 20059 return false; | 20059 return false; |
| 20060 } | 20060 } |
| 20061 | 20061 |
| 20062 /** | 20062 /** |
| 20063 * This verifies that the given function body does not contain return statemen
ts that both have | 20063 * This verifies that the given function body does not contain return statemen
ts that both have |
| 20064 * and do not have return values. | 20064 * and do not have return values. |
| 20065 * | 20065 * |
| 20066 * @param node the function body being tested | 20066 * @param node the function body being tested |
| 20067 * @return `true` if and only if an error code is generated on the passed node | 20067 * @return `true` if and only if an error code is generated on the passed node |
| 20068 * @see StaticWarningCode#MIXED_RETURN_TYPES | 20068 * @see StaticWarningCode#MIXED_RETURN_TYPES |
| 20069 */ | 20069 */ |
| 20070 bool checkForMixedReturns(BlockFunctionBody node) { | 20070 bool _checkForMixedReturns(BlockFunctionBody node) { |
| 20071 int withCount = _returnsWith.length; | 20071 int withCount = _returnsWith.length; |
| 20072 int withoutCount = _returnsWithout.length; | 20072 int withoutCount = _returnsWithout.length; |
| 20073 if (withCount > 0 && withoutCount > 0) { | 20073 if (withCount > 0 && withoutCount > 0) { |
| 20074 for (int i = 0; i < withCount; i++) { | 20074 for (int i = 0; i < withCount; i++) { |
| 20075 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES,
_returnsWith[i].keyword, []); | 20075 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES,
_returnsWith[i].keyword, []); |
| 20076 } | 20076 } |
| 20077 for (int i = 0; i < withoutCount; i++) { | 20077 for (int i = 0; i < withoutCount; i++) { |
| 20078 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES,
_returnsWithout[i].keyword, []); | 20078 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES,
_returnsWithout[i].keyword, []); |
| 20079 } | 20079 } |
| 20080 return true; | 20080 return true; |
| 20081 } | 20081 } |
| 20082 return false; | 20082 return false; |
| 20083 } | 20083 } |
| 20084 | 20084 |
| 20085 /** | 20085 /** |
| 20086 * This verifies that the passed mixin does not have an explicitly declared co
nstructor. | 20086 * This verifies that the passed mixin does not have an explicitly declared co
nstructor. |
| 20087 * | 20087 * |
| 20088 * @param mixinName the node to report problem on | 20088 * @param mixinName the node to report problem on |
| 20089 * @param mixinElement the mixing to evaluate | 20089 * @param mixinElement the mixing to evaluate |
| 20090 * @return `true` if and only if an error code is generated on the passed node | 20090 * @return `true` if and only if an error code is generated on the passed node |
| 20091 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR | 20091 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR |
| 20092 */ | 20092 */ |
| 20093 bool checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinEl
ement) { | 20093 bool _checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinE
lement) { |
| 20094 for (ConstructorElement constructor in mixinElement.constructors) { | 20094 for (ConstructorElement constructor in mixinElement.constructors) { |
| 20095 if (!constructor.isSynthetic && !constructor.isFactory) { | 20095 if (!constructor.isSynthetic && !constructor.isFactory) { |
| 20096 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_DECLARES_CO
NSTRUCTOR, mixinName, [mixinElement.name]); | 20096 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_DECLARES_CO
NSTRUCTOR, mixinName, [mixinElement.name]); |
| 20097 return true; | 20097 return true; |
| 20098 } | 20098 } |
| 20099 } | 20099 } |
| 20100 return false; | 20100 return false; |
| 20101 } | 20101 } |
| 20102 | 20102 |
| 20103 /** | 20103 /** |
| 20104 * This verifies that the passed mixin has the 'Object' superclass. | 20104 * This verifies that the passed mixin has the 'Object' superclass. |
| 20105 * | 20105 * |
| 20106 * @param mixinName the node to report problem on | 20106 * @param mixinName the node to report problem on |
| 20107 * @param mixinElement the mixing to evaluate | 20107 * @param mixinElement the mixing to evaluate |
| 20108 * @return `true` if and only if an error code is generated on the passed node | 20108 * @return `true` if and only if an error code is generated on the passed node |
| 20109 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT | 20109 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT |
| 20110 */ | 20110 */ |
| 20111 bool checkForMixinInheritsNotFromObject(TypeName mixinName, ClassElement mixin
Element) { | 20111 bool _checkForMixinInheritsNotFromObject(TypeName mixinName, ClassElement mixi
nElement) { |
| 20112 InterfaceType mixinSupertype = mixinElement.supertype; | 20112 InterfaceType mixinSupertype = mixinElement.supertype; |
| 20113 if (mixinSupertype != null) { | 20113 if (mixinSupertype != null) { |
| 20114 if (!mixinSupertype.isObject || !mixinElement.isTypedef && mixinElement.mi
xins.length != 0) { | 20114 if (!mixinSupertype.isObject || !mixinElement.isTypedef && mixinElement.mi
xins.length != 0) { |
| 20115 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_INHERITS_FR
OM_NOT_OBJECT, mixinName, [mixinElement.name]); | 20115 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_INHERITS_FR
OM_NOT_OBJECT, mixinName, [mixinElement.name]); |
| 20116 return true; | 20116 return true; |
| 20117 } | 20117 } |
| 20118 } | 20118 } |
| 20119 return false; | 20119 return false; |
| 20120 } | 20120 } |
| 20121 | 20121 |
| 20122 /** | 20122 /** |
| 20123 * This verifies that the passed mixin does not reference 'super'. | 20123 * This verifies that the passed mixin does not reference 'super'. |
| 20124 * | 20124 * |
| 20125 * @param mixinName the node to report problem on | 20125 * @param mixinName the node to report problem on |
| 20126 * @param mixinElement the mixing to evaluate | 20126 * @param mixinElement the mixing to evaluate |
| 20127 * @return `true` if and only if an error code is generated on the passed node | 20127 * @return `true` if and only if an error code is generated on the passed node |
| 20128 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER | 20128 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER |
| 20129 */ | 20129 */ |
| 20130 bool checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinElemen
t) { | 20130 bool _checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinEleme
nt) { |
| 20131 if (mixinElement.hasReferenceToSuper) { | 20131 if (mixinElement.hasReferenceToSuper) { |
| 20132 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_REFERENCES_SU
PER, mixinName, [mixinElement.name]); | 20132 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_REFERENCES_SU
PER, mixinName, [mixinElement.name]); |
| 20133 } | 20133 } |
| 20134 return false; | 20134 return false; |
| 20135 } | 20135 } |
| 20136 | 20136 |
| 20137 /** | 20137 /** |
| 20138 * This verifies that the passed constructor has at most one 'super' initializ
er. | 20138 * This verifies that the passed constructor has at most one 'super' initializ
er. |
| 20139 * | 20139 * |
| 20140 * @param node the constructor declaration to evaluate | 20140 * @param node the constructor declaration to evaluate |
| 20141 * @return `true` if and only if an error code is generated on the passed node | 20141 * @return `true` if and only if an error code is generated on the passed node |
| 20142 * @see CompileTimeErrorCode#MULTIPLE_SUPER_INITIALIZERS | 20142 * @see CompileTimeErrorCode#MULTIPLE_SUPER_INITIALIZERS |
| 20143 */ | 20143 */ |
| 20144 bool checkForMultipleSuperInitializers(ConstructorDeclaration node) { | 20144 bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) { |
| 20145 int numSuperInitializers = 0; | 20145 int numSuperInitializers = 0; |
| 20146 for (ConstructorInitializer initializer in node.initializers) { | 20146 for (ConstructorInitializer initializer in node.initializers) { |
| 20147 if (initializer is SuperConstructorInvocation) { | 20147 if (initializer is SuperConstructorInvocation) { |
| 20148 numSuperInitializers++; | 20148 numSuperInitializers++; |
| 20149 if (numSuperInitializers > 1) { | 20149 if (numSuperInitializers > 1) { |
| 20150 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MULTIPLE_SUPER_
INITIALIZERS, initializer, []); | 20150 _errorReporter.reportErrorForNode(CompileTimeErrorCode.MULTIPLE_SUPER_
INITIALIZERS, initializer, []); |
| 20151 } | 20151 } |
| 20152 } | 20152 } |
| 20153 } | 20153 } |
| 20154 return numSuperInitializers > 0; | 20154 return numSuperInitializers > 0; |
| 20155 } | 20155 } |
| 20156 | 20156 |
| 20157 /** | 20157 /** |
| 20158 * Checks to ensure that native function bodies can only in SDK code. | 20158 * Checks to ensure that native function bodies can only in SDK code. |
| 20159 * | 20159 * |
| 20160 * @param node the native function body to test | 20160 * @param node the native function body to test |
| 20161 * @return `true` if and only if an error code is generated on the passed node | 20161 * @return `true` if and only if an error code is generated on the passed node |
| 20162 * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE | 20162 * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE |
| 20163 */ | 20163 */ |
| 20164 bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { | 20164 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { |
| 20165 if (!_isInSystemLibrary && !_hasExtUri) { | 20165 if (!_isInSystemLibrary && !_hasExtUri) { |
| 20166 _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_
NON_SDK_CODE, node, []); | 20166 _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_
NON_SDK_CODE, node, []); |
| 20167 return true; | 20167 return true; |
| 20168 } | 20168 } |
| 20169 return false; | 20169 return false; |
| 20170 } | 20170 } |
| 20171 | 20171 |
| 20172 /** | 20172 /** |
| 20173 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. | 20173 * This verifies that the passed 'new' instance creation expression invokes ex
isting constructor. |
| 20174 * | 20174 * |
| 20175 * This method assumes that the instance creation was tested to be 'new' befor
e being called. | 20175 * This method assumes that the instance creation was tested to be 'new' befor
e being called. |
| 20176 * | 20176 * |
| 20177 * @param node the instance creation expression to evaluate | 20177 * @param node the instance creation expression to evaluate |
| 20178 * @return `true` if and only if an error code is generated on the passed node | 20178 * @return `true` if and only if an error code is generated on the passed node |
| 20179 * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR | 20179 * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR |
| 20180 */ | 20180 */ |
| 20181 bool checkForNewWithUndefinedConstructor(InstanceCreationExpression node) { | 20181 bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node) { |
| 20182 // OK if resolved | 20182 // OK if resolved |
| 20183 if (node.staticElement != null) { | 20183 if (node.staticElement != null) { |
| 20184 return false; | 20184 return false; |
| 20185 } | 20185 } |
| 20186 // prepare constructor name | 20186 // prepare constructor name |
| 20187 ConstructorName constructorName = node.constructorName; | 20187 ConstructorName constructorName = node.constructorName; |
| 20188 if (constructorName == null) { | 20188 if (constructorName == null) { |
| 20189 return false; | 20189 return false; |
| 20190 } | 20190 } |
| 20191 // prepare class name | 20191 // prepare class name |
| (...skipping 13 matching lines...) Expand all Loading... |
| 20205 } | 20205 } |
| 20206 | 20206 |
| 20207 /** | 20207 /** |
| 20208 * This checks that if the passed class declaration implicitly calls default c
onstructor of its | 20208 * This checks that if the passed class declaration implicitly calls default c
onstructor of its |
| 20209 * superclass, there should be such default constructor - implicit or explicit
. | 20209 * superclass, there should be such default constructor - implicit or explicit
. |
| 20210 * | 20210 * |
| 20211 * @param node the [ClassDeclaration] to evaluate | 20211 * @param node the [ClassDeclaration] to evaluate |
| 20212 * @return `true` if and only if an error code is generated on the passed node | 20212 * @return `true` if and only if an error code is generated on the passed node |
| 20213 * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT | 20213 * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT |
| 20214 */ | 20214 */ |
| 20215 bool checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { | 20215 bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { |
| 20216 // do nothing if there is explicit constructor | 20216 // do nothing if there is explicit constructor |
| 20217 List<ConstructorElement> constructors = _enclosingClass.constructors; | 20217 List<ConstructorElement> constructors = _enclosingClass.constructors; |
| 20218 if (!constructors[0].isSynthetic) { | 20218 if (!constructors[0].isSynthetic) { |
| 20219 return false; | 20219 return false; |
| 20220 } | 20220 } |
| 20221 // prepare super | 20221 // prepare super |
| 20222 InterfaceType superType = _enclosingClass.supertype; | 20222 InterfaceType superType = _enclosingClass.supertype; |
| 20223 if (superType == null) { | 20223 if (superType == null) { |
| 20224 return false; | 20224 return false; |
| 20225 } | 20225 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 20245 * and interfaces. | 20245 * and interfaces. |
| 20246 * | 20246 * |
| 20247 * @param node the [ClassDeclaration] to evaluate | 20247 * @param node the [ClassDeclaration] to evaluate |
| 20248 * @return `true` if and only if an error code is generated on the passed node | 20248 * @return `true` if and only if an error code is generated on the passed node |
| 20249 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE | 20249 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE |
| 20250 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO | 20250 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO |
| 20251 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE | 20251 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE |
| 20252 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR | 20252 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR |
| 20253 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S | 20253 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU
S |
| 20254 */ | 20254 */ |
| 20255 bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) { | 20255 bool _checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) { |
| 20256 if (_enclosingClass.isAbstract) { | 20256 if (_enclosingClass.isAbstract) { |
| 20257 return false; | 20257 return false; |
| 20258 } | 20258 } |
| 20259 // | 20259 // |
| 20260 // Store in local sets the set of all method and accessor names | 20260 // Store in local sets the set of all method and accessor names |
| 20261 // | 20261 // |
| 20262 List<MethodElement> methods = _enclosingClass.methods; | 20262 List<MethodElement> methods = _enclosingClass.methods; |
| 20263 List<PropertyAccessorElement> accessors = _enclosingClass.accessors; | 20263 List<PropertyAccessorElement> accessors = _enclosingClass.accessors; |
| 20264 Set<String> methodsInEnclosingClass = new Set<String>(); | 20264 Set<String> methodsInEnclosingClass = new Set<String>(); |
| 20265 for (MethodElement method in methods) { | 20265 for (MethodElement method in methods) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 20290 break; | 20290 break; |
| 20291 } | 20291 } |
| 20292 // If the element is not synthetic and can be determined to be defined in
Object, skip it. | 20292 // If the element is not synthetic and can be determined to be defined in
Object, skip it. |
| 20293 if (executableElt.enclosingElement != null && (executableElt.enclosingElem
ent as ClassElement).type.isObject) { | 20293 if (executableElt.enclosingElement != null && (executableElt.enclosingElem
ent as ClassElement).type.isObject) { |
| 20294 continue; | 20294 continue; |
| 20295 } | 20295 } |
| 20296 // Reference the type of the enclosing class | 20296 // Reference the type of the enclosing class |
| 20297 InterfaceType enclosingType = _enclosingClass.type; | 20297 InterfaceType enclosingType = _enclosingClass.type; |
| 20298 // Check to see if some element is in local enclosing class that matches t
he name of the | 20298 // Check to see if some element is in local enclosing class that matches t
he name of the |
| 20299 // required member. | 20299 // required member. |
| 20300 if (isMemberInClassOrMixin(executableElt, _enclosingClass)) { | 20300 if (_isMemberInClassOrMixin(executableElt, _enclosingClass)) { |
| 20301 // We do not have to verify that this implementation of the found method
matches the | 20301 // We do not have to verify that this implementation of the found method
matches the |
| 20302 // required function type: the set of StaticWarningCode.INVALID_METHOD_O
VERRIDE_* warnings | 20302 // required function type: the set of StaticWarningCode.INVALID_METHOD_O
VERRIDE_* warnings |
| 20303 // break out the different specific situations. | 20303 // break out the different specific situations. |
| 20304 continue; | 20304 continue; |
| 20305 } | 20305 } |
| 20306 // First check to see if this element was declared in the superclass chain
, in which case | 20306 // First check to see if this element was declared in the superclass chain
, in which case |
| 20307 // there is already a concrete implementation. | 20307 // there is already a concrete implementation. |
| 20308 ExecutableElement elt = membersInheritedFromSuperclasses.get(executableElt
.name); | 20308 ExecutableElement elt = membersInheritedFromSuperclasses.get(executableElt
.name); |
| 20309 // Check to see if an element was found in the superclass chain with the c
orrect name. | 20309 // Check to see if an element was found in the superclass chain with the c
orrect name. |
| 20310 if (elt != null) { | 20310 if (elt != null) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20375 } | 20375 } |
| 20376 | 20376 |
| 20377 /** | 20377 /** |
| 20378 * Checks to ensure that the expressions that need to be of type bool, are. Ot
herwise an error is | 20378 * Checks to ensure that the expressions that need to be of type bool, are. Ot
herwise an error is |
| 20379 * reported on the expression. | 20379 * reported on the expression. |
| 20380 * | 20380 * |
| 20381 * @param condition the conditional expression to test | 20381 * @param condition the conditional expression to test |
| 20382 * @return `true` if and only if an error code is generated on the passed node | 20382 * @return `true` if and only if an error code is generated on the passed node |
| 20383 * @see StaticTypeWarningCode#NON_BOOL_CONDITION | 20383 * @see StaticTypeWarningCode#NON_BOOL_CONDITION |
| 20384 */ | 20384 */ |
| 20385 bool checkForNonBoolCondition(Expression condition) { | 20385 bool _checkForNonBoolCondition(Expression condition) { |
| 20386 Type2 conditionType = getStaticType(condition); | 20386 Type2 conditionType = _getStaticType(condition); |
| 20387 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { | 20387 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { |
| 20388 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION
, condition, []); | 20388 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION
, condition, []); |
| 20389 return true; | 20389 return true; |
| 20390 } | 20390 } |
| 20391 return false; | 20391 return false; |
| 20392 } | 20392 } |
| 20393 | 20393 |
| 20394 /** | 20394 /** |
| 20395 * This verifies that the passed assert statement has either a 'bool' or '() -
> bool' input. | 20395 * This verifies that the passed assert statement has either a 'bool' or '() -
> bool' input. |
| 20396 * | 20396 * |
| 20397 * @param node the assert statement to evaluate | 20397 * @param node the assert statement to evaluate |
| 20398 * @return `true` if and only if an error code is generated on the passed node | 20398 * @return `true` if and only if an error code is generated on the passed node |
| 20399 * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION | 20399 * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION |
| 20400 */ | 20400 */ |
| 20401 bool checkForNonBoolExpression(AssertStatement node) { | 20401 bool _checkForNonBoolExpression(AssertStatement node) { |
| 20402 Expression expression = node.condition; | 20402 Expression expression = node.condition; |
| 20403 Type2 type = getStaticType(expression); | 20403 Type2 type = _getStaticType(expression); |
| 20404 if (type is InterfaceType) { | 20404 if (type is InterfaceType) { |
| 20405 if (!type.isAssignableTo(_boolType)) { | 20405 if (!type.isAssignableTo(_boolType)) { |
| 20406 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESS
ION, expression, []); | 20406 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESS
ION, expression, []); |
| 20407 return true; | 20407 return true; |
| 20408 } | 20408 } |
| 20409 } else if (type is FunctionType) { | 20409 } else if (type is FunctionType) { |
| 20410 FunctionType functionType = type; | 20410 FunctionType functionType = type; |
| 20411 if (functionType.typeArguments.length == 0 && !functionType.returnType.isA
ssignableTo(_boolType)) { | 20411 if (functionType.typeArguments.length == 0 && !functionType.returnType.isA
ssignableTo(_boolType)) { |
| 20412 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESS
ION, expression, []); | 20412 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESS
ION, expression, []); |
| 20413 return true; | 20413 return true; |
| 20414 } | 20414 } |
| 20415 } | 20415 } |
| 20416 return false; | 20416 return false; |
| 20417 } | 20417 } |
| 20418 | 20418 |
| 20419 /** | 20419 /** |
| 20420 * Checks to ensure that the given expression is assignable to bool. | 20420 * Checks to ensure that the given expression is assignable to bool. |
| 20421 * | 20421 * |
| 20422 * @param expression the expression expression to test | 20422 * @param expression the expression expression to test |
| 20423 * @return `true` if and only if an error code is generated on the passed node | 20423 * @return `true` if and only if an error code is generated on the passed node |
| 20424 * @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION | 20424 * @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION |
| 20425 */ | 20425 */ |
| 20426 bool checkForNonBoolNegationExpression(Expression expression) { | 20426 bool _checkForNonBoolNegationExpression(Expression expression) { |
| 20427 Type2 conditionType = getStaticType(expression); | 20427 Type2 conditionType = _getStaticType(expression); |
| 20428 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { | 20428 if (conditionType != null && !conditionType.isAssignableTo(_boolType)) { |
| 20429 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_
EXPRESSION, expression, []); | 20429 _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_
EXPRESSION, expression, []); |
| 20430 return true; | 20430 return true; |
| 20431 } | 20431 } |
| 20432 return false; | 20432 return false; |
| 20433 } | 20433 } |
| 20434 | 20434 |
| 20435 /** | 20435 /** |
| 20436 * This verifies the passed map literal either: | 20436 * This verifies the passed map literal either: |
| 20437 * * has `const modifier` | 20437 * * has `const modifier` |
| 20438 * * has explicit type arguments | 20438 * * has explicit type arguments |
| 20439 * * is not start of the statement | 20439 * * is not start of the statement |
| 20440 * | 20440 * |
| 20441 * @param node the map literal to evaluate | 20441 * @param node the map literal to evaluate |
| 20442 * @return `true` if and only if an error code is generated on the passed node | 20442 * @return `true` if and only if an error code is generated on the passed node |
| 20443 * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT | 20443 * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT |
| 20444 */ | 20444 */ |
| 20445 bool checkForNonConstMapAsExpressionStatement(MapLiteral node) { | 20445 bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) { |
| 20446 // "const" | 20446 // "const" |
| 20447 if (node.constKeyword != null) { | 20447 if (node.constKeyword != null) { |
| 20448 return false; | 20448 return false; |
| 20449 } | 20449 } |
| 20450 // has type arguments | 20450 // has type arguments |
| 20451 if (node.typeArguments != null) { | 20451 if (node.typeArguments != null) { |
| 20452 return false; | 20452 return false; |
| 20453 } | 20453 } |
| 20454 // prepare statement | 20454 // prepare statement |
| 20455 Statement statement = node.getAncestor((node) => node is ExpressionStatement
); | 20455 Statement statement = node.getAncestor((node) => node is ExpressionStatement
); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 20466 } | 20466 } |
| 20467 | 20467 |
| 20468 /** | 20468 /** |
| 20469 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn | 20469 * This verifies the passed method declaration of operator `[]=`, has `void` r
eturn |
| 20470 * type. | 20470 * type. |
| 20471 * | 20471 * |
| 20472 * @param node the method declaration to evaluate | 20472 * @param node the method declaration to evaluate |
| 20473 * @return `true` if and only if an error code is generated on the passed node | 20473 * @return `true` if and only if an error code is generated on the passed node |
| 20474 * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR | 20474 * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR |
| 20475 */ | 20475 */ |
| 20476 bool checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { | 20476 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { |
| 20477 // check that []= operator | 20477 // check that []= operator |
| 20478 SimpleIdentifier name = node.name; | 20478 SimpleIdentifier name = node.name; |
| 20479 if (name.name != "[]=") { | 20479 if (name.name != "[]=") { |
| 20480 return false; | 20480 return false; |
| 20481 } | 20481 } |
| 20482 // check return type | 20482 // check return type |
| 20483 TypeName typeName = node.returnType; | 20483 TypeName typeName = node.returnType; |
| 20484 if (typeName != null) { | 20484 if (typeName != null) { |
| 20485 Type2 type = typeName.type; | 20485 Type2 type = typeName.type; |
| 20486 if (type != null && !type.isVoid) { | 20486 if (type != null && !type.isVoid) { |
| 20487 _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_
OPERATOR, typeName, []); | 20487 _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_
OPERATOR, typeName, []); |
| 20488 } | 20488 } |
| 20489 } | 20489 } |
| 20490 // no warning | 20490 // no warning |
| 20491 return false; | 20491 return false; |
| 20492 } | 20492 } |
| 20493 | 20493 |
| 20494 /** | 20494 /** |
| 20495 * This verifies the passed setter has no return type or the `void` return typ
e. | 20495 * This verifies the passed setter has no return type or the `void` return typ
e. |
| 20496 * | 20496 * |
| 20497 * @param typeName the type name to evaluate | 20497 * @param typeName the type name to evaluate |
| 20498 * @return `true` if and only if an error code is generated on the passed node | 20498 * @return `true` if and only if an error code is generated on the passed node |
| 20499 * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER | 20499 * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER |
| 20500 */ | 20500 */ |
| 20501 bool checkForNonVoidReturnTypeForSetter(TypeName typeName) { | 20501 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { |
| 20502 if (typeName != null) { | 20502 if (typeName != null) { |
| 20503 Type2 type = typeName.type; | 20503 Type2 type = typeName.type; |
| 20504 if (type != null && !type.isVoid) { | 20504 if (type != null && !type.isVoid) { |
| 20505 _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_
SETTER, typeName, []); | 20505 _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_
SETTER, typeName, []); |
| 20506 } | 20506 } |
| 20507 } | 20507 } |
| 20508 return false; | 20508 return false; |
| 20509 } | 20509 } |
| 20510 | 20510 |
| 20511 /** | 20511 /** |
| 20512 * This verifies the passed operator-method declaration, does not have an opti
onal parameter. | 20512 * This verifies the passed operator-method declaration, does not have an opti
onal parameter. |
| 20513 * | 20513 * |
| 20514 * This method assumes that the method declaration was tested to be an operato
r declaration before | 20514 * This method assumes that the method declaration was tested to be an operato
r declaration before |
| 20515 * being called. | 20515 * being called. |
| 20516 * | 20516 * |
| 20517 * @param node the method declaration to evaluate | 20517 * @param node the method declaration to evaluate |
| 20518 * @return `true` if and only if an error code is generated on the passed node | 20518 * @return `true` if and only if an error code is generated on the passed node |
| 20519 * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR | 20519 * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR |
| 20520 */ | 20520 */ |
| 20521 bool checkForOptionalParameterInOperator(MethodDeclaration node) { | 20521 bool _checkForOptionalParameterInOperator(MethodDeclaration node) { |
| 20522 FormalParameterList parameterList = node.parameters; | 20522 FormalParameterList parameterList = node.parameters; |
| 20523 if (parameterList == null) { | 20523 if (parameterList == null) { |
| 20524 return false; | 20524 return false; |
| 20525 } | 20525 } |
| 20526 bool foundError = false; | 20526 bool foundError = false; |
| 20527 NodeList<FormalParameter> formalParameters = parameterList.parameters; | 20527 NodeList<FormalParameter> formalParameters = parameterList.parameters; |
| 20528 for (FormalParameter formalParameter in formalParameters) { | 20528 for (FormalParameter formalParameter in formalParameters) { |
| 20529 if (formalParameter.kind.isOptional) { | 20529 if (formalParameter.kind.isOptional) { |
| 20530 _errorReporter.reportErrorForNode(CompileTimeErrorCode.OPTIONAL_PARAMETE
R_IN_OPERATOR, formalParameter, []); | 20530 _errorReporter.reportErrorForNode(CompileTimeErrorCode.OPTIONAL_PARAMETE
R_IN_OPERATOR, formalParameter, []); |
| 20531 foundError = true; | 20531 foundError = true; |
| 20532 } | 20532 } |
| 20533 } | 20533 } |
| 20534 return foundError; | 20534 return foundError; |
| 20535 } | 20535 } |
| 20536 | 20536 |
| 20537 /** | 20537 /** |
| 20538 * This checks for named optional parameters that begin with '_'. | 20538 * This checks for named optional parameters that begin with '_'. |
| 20539 * | 20539 * |
| 20540 * @param node the default formal parameter to evaluate | 20540 * @param node the default formal parameter to evaluate |
| 20541 * @return `true` if and only if an error code is generated on the passed node | 20541 * @return `true` if and only if an error code is generated on the passed node |
| 20542 * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER | 20542 * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER |
| 20543 */ | 20543 */ |
| 20544 bool checkForPrivateOptionalParameter(FormalParameter node) { | 20544 bool _checkForPrivateOptionalParameter(FormalParameter node) { |
| 20545 // should be named parameter | 20545 // should be named parameter |
| 20546 if (node.kind != ParameterKind.NAMED) { | 20546 if (node.kind != ParameterKind.NAMED) { |
| 20547 return false; | 20547 return false; |
| 20548 } | 20548 } |
| 20549 // name should start with '_' | 20549 // name should start with '_' |
| 20550 SimpleIdentifier name = node.identifier; | 20550 SimpleIdentifier name = node.identifier; |
| 20551 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { | 20551 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { |
| 20552 return false; | 20552 return false; |
| 20553 } | 20553 } |
| 20554 // report problem | 20554 // report problem |
| 20555 _errorReporter.reportErrorForNode(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARA
METER, node, []); | 20555 _errorReporter.reportErrorForNode(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARA
METER, node, []); |
| 20556 return true; | 20556 return true; |
| 20557 } | 20557 } |
| 20558 | 20558 |
| 20559 /** | 20559 /** |
| 20560 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and | 20560 * This checks if the passed constructor declaration is the redirecting genera
tive constructor and |
| 20561 * references itself directly or indirectly. | 20561 * references itself directly or indirectly. |
| 20562 * | 20562 * |
| 20563 * @param node the constructor declaration to evaluate | 20563 * @param node the constructor declaration to evaluate |
| 20564 * @return `true` if and only if an error code is generated on the passed node | 20564 * @return `true` if and only if an error code is generated on the passed node |
| 20565 * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT | 20565 * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT |
| 20566 */ | 20566 */ |
| 20567 bool checkForRecursiveConstructorRedirect(ConstructorDeclaration node) { | 20567 bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration node) { |
| 20568 // we check generative constructor here | 20568 // we check generative constructor here |
| 20569 if (node.factoryKeyword != null) { | 20569 if (node.factoryKeyword != null) { |
| 20570 return false; | 20570 return false; |
| 20571 } | 20571 } |
| 20572 // try to find redirecting constructor invocation and analyzer it for recurs
ion | 20572 // try to find redirecting constructor invocation and analyzer it for recurs
ion |
| 20573 for (ConstructorInitializer initializer in node.initializers) { | 20573 for (ConstructorInitializer initializer in node.initializers) { |
| 20574 if (initializer is RedirectingConstructorInvocation) { | 20574 if (initializer is RedirectingConstructorInvocation) { |
| 20575 // OK if no cycle | 20575 // OK if no cycle |
| 20576 ConstructorElement element = node.element; | 20576 ConstructorElement element = node.element; |
| 20577 if (!hasRedirectingFactoryConstructorCycle(element)) { | 20577 if (!_hasRedirectingFactoryConstructorCycle(element)) { |
| 20578 return false; | 20578 return false; |
| 20579 } | 20579 } |
| 20580 // report error | 20580 // report error |
| 20581 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_CONSTRU
CTOR_REDIRECT, initializer, []); | 20581 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_CONSTRU
CTOR_REDIRECT, initializer, []); |
| 20582 return true; | 20582 return true; |
| 20583 } | 20583 } |
| 20584 } | 20584 } |
| 20585 // OK, no redirecting constructor invocation | 20585 // OK, no redirecting constructor invocation |
| 20586 return false; | 20586 return false; |
| 20587 } | 20587 } |
| 20588 | 20588 |
| 20589 /** | 20589 /** |
| 20590 * This checks if the passed constructor declaration has redirected constructo
r and references | 20590 * This checks if the passed constructor declaration has redirected constructo
r and references |
| 20591 * itself directly or indirectly. | 20591 * itself directly or indirectly. |
| 20592 * | 20592 * |
| 20593 * @param node the constructor declaration to evaluate | 20593 * @param node the constructor declaration to evaluate |
| 20594 * @return `true` if and only if an error code is generated on the passed node | 20594 * @return `true` if and only if an error code is generated on the passed node |
| 20595 * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT | 20595 * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT |
| 20596 */ | 20596 */ |
| 20597 bool checkForRecursiveFactoryRedirect(ConstructorDeclaration node) { | 20597 bool _checkForRecursiveFactoryRedirect(ConstructorDeclaration node) { |
| 20598 // prepare redirected constructor | 20598 // prepare redirected constructor |
| 20599 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 20599 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
| 20600 if (redirectedConstructorNode == null) { | 20600 if (redirectedConstructorNode == null) { |
| 20601 return false; | 20601 return false; |
| 20602 } | 20602 } |
| 20603 // OK if no cycle | 20603 // OK if no cycle |
| 20604 ConstructorElement element = node.element; | 20604 ConstructorElement element = node.element; |
| 20605 if (!hasRedirectingFactoryConstructorCycle(element)) { | 20605 if (!_hasRedirectingFactoryConstructorCycle(element)) { |
| 20606 return false; | 20606 return false; |
| 20607 } | 20607 } |
| 20608 // report error | 20608 // report error |
| 20609 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_FACTORY_RED
IRECT, redirectedConstructorNode, []); | 20609 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_FACTORY_RED
IRECT, redirectedConstructorNode, []); |
| 20610 return true; | 20610 return true; |
| 20611 } | 20611 } |
| 20612 | 20612 |
| 20613 /** | 20613 /** |
| 20614 * This checks the class declaration is not a superinterface to itself. | 20614 * This checks the class declaration is not a superinterface to itself. |
| 20615 * | 20615 * |
| 20616 * @param classElt the class element to test | 20616 * @param classElt the class element to test |
| 20617 * @return `true` if and only if an error code is generated on the passed elem
ent | 20617 * @return `true` if and only if an error code is generated on the passed elem
ent |
| 20618 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE | 20618 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE |
| 20619 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS | 20619 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS |
| 20620 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS | 20620 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS |
| 20621 */ | 20621 */ |
| 20622 bool checkForRecursiveInterfaceInheritance(ClassElement classElt) { | 20622 bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) { |
| 20623 if (classElt == null) { | 20623 if (classElt == null) { |
| 20624 return false; | 20624 return false; |
| 20625 } | 20625 } |
| 20626 return safeCheckForRecursiveInterfaceInheritance(classElt, new List<ClassEle
ment>()); | 20626 return _safeCheckForRecursiveInterfaceInheritance(classElt, new List<ClassEl
ement>()); |
| 20627 } | 20627 } |
| 20628 | 20628 |
| 20629 /** | 20629 /** |
| 20630 * This checks the passed constructor declaration has a valid combination of r
edirected | 20630 * This checks the passed constructor declaration has a valid combination of r
edirected |
| 20631 * constructor invocation(s), super constructor invocations and field initiali
zers. | 20631 * constructor invocation(s), super constructor invocations and field initiali
zers. |
| 20632 * | 20632 * |
| 20633 * @param node the constructor declaration to evaluate | 20633 * @param node the constructor declaration to evaluate |
| 20634 * @return `true` if and only if an error code is generated on the passed node | 20634 * @return `true` if and only if an error code is generated on the passed node |
| 20635 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR | 20635 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR |
| 20636 * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR | 20636 * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR |
| 20637 * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS | 20637 * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS |
| 20638 * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR | 20638 * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR |
| 20639 */ | 20639 */ |
| 20640 bool checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { | 20640 bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { |
| 20641 bool errorReported = false; | 20641 bool errorReported = false; |
| 20642 // | 20642 // |
| 20643 // Check for default values in the parameters | 20643 // Check for default values in the parameters |
| 20644 // | 20644 // |
| 20645 ConstructorName redirectedConstructor = node.redirectedConstructor; | 20645 ConstructorName redirectedConstructor = node.redirectedConstructor; |
| 20646 if (redirectedConstructor != null) { | 20646 if (redirectedConstructor != null) { |
| 20647 for (FormalParameter parameter in node.parameters.parameters) { | 20647 for (FormalParameter parameter in node.parameters.parameters) { |
| 20648 if (parameter is DefaultFormalParameter && parameter.defaultValue != nul
l) { | 20648 if (parameter is DefaultFormalParameter && parameter.defaultValue != nul
l) { |
| 20649 _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_I
N_REDIRECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []); | 20649 _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_I
N_REDIRECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []); |
| 20650 errorReported = true; | 20650 errorReported = true; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 20680 } | 20680 } |
| 20681 | 20681 |
| 20682 /** | 20682 /** |
| 20683 * This checks if the passed constructor declaration has redirected constructo
r and references | 20683 * This checks if the passed constructor declaration has redirected constructo
r and references |
| 20684 * itself directly or indirectly. | 20684 * itself directly or indirectly. |
| 20685 * | 20685 * |
| 20686 * @param node the constructor declaration to evaluate | 20686 * @param node the constructor declaration to evaluate |
| 20687 * @return `true` if and only if an error code is generated on the passed node | 20687 * @return `true` if and only if an error code is generated on the passed node |
| 20688 * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR | 20688 * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR |
| 20689 */ | 20689 */ |
| 20690 bool checkForRedirectToNonConstConstructor(ConstructorDeclaration node) { | 20690 bool _checkForRedirectToNonConstConstructor(ConstructorDeclaration node) { |
| 20691 // prepare redirected constructor | 20691 // prepare redirected constructor |
| 20692 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 20692 ConstructorName redirectedConstructorNode = node.redirectedConstructor; |
| 20693 if (redirectedConstructorNode == null) { | 20693 if (redirectedConstructorNode == null) { |
| 20694 return false; | 20694 return false; |
| 20695 } | 20695 } |
| 20696 // prepare element | 20696 // prepare element |
| 20697 ConstructorElement element = node.element; | 20697 ConstructorElement element = node.element; |
| 20698 if (element == null) { | 20698 if (element == null) { |
| 20699 return false; | 20699 return false; |
| 20700 } | 20700 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 20716 return true; | 20716 return true; |
| 20717 } | 20717 } |
| 20718 | 20718 |
| 20719 /** | 20719 /** |
| 20720 * This checks that the rethrow is inside of a catch clause. | 20720 * This checks that the rethrow is inside of a catch clause. |
| 20721 * | 20721 * |
| 20722 * @param node the rethrow expression to evaluate | 20722 * @param node the rethrow expression to evaluate |
| 20723 * @return `true` if and only if an error code is generated on the passed node | 20723 * @return `true` if and only if an error code is generated on the passed node |
| 20724 * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH | 20724 * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH |
| 20725 */ | 20725 */ |
| 20726 bool checkForRethrowOutsideCatch(RethrowExpression node) { | 20726 bool _checkForRethrowOutsideCatch(RethrowExpression node) { |
| 20727 if (!_isInCatchClause) { | 20727 if (!_isInCatchClause) { |
| 20728 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETHROW_OUTSIDE_CAT
CH, node, []); | 20728 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETHROW_OUTSIDE_CAT
CH, node, []); |
| 20729 return true; | 20729 return true; |
| 20730 } | 20730 } |
| 20731 return false; | 20731 return false; |
| 20732 } | 20732 } |
| 20733 | 20733 |
| 20734 /** | 20734 /** |
| 20735 * This checks that if the the given constructor declaration is generative, th
en it does not have | 20735 * This checks that if the the given constructor declaration is generative, th
en it does not have |
| 20736 * an expression function body. | 20736 * an expression function body. |
| 20737 * | 20737 * |
| 20738 * @param node the constructor to evaluate | 20738 * @param node the constructor to evaluate |
| 20739 * @return `true` if and only if an error code is generated on the passed node | 20739 * @return `true` if and only if an error code is generated on the passed node |
| 20740 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR | 20740 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 20741 */ | 20741 */ |
| 20742 bool checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { | 20742 bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { |
| 20743 // ignore factory | 20743 // ignore factory |
| 20744 if (node.factoryKeyword != null) { | 20744 if (node.factoryKeyword != null) { |
| 20745 return false; | 20745 return false; |
| 20746 } | 20746 } |
| 20747 // block body (with possible return statement) is checked elsewhere | 20747 // block body (with possible return statement) is checked elsewhere |
| 20748 FunctionBody body = node.body; | 20748 FunctionBody body = node.body; |
| 20749 if (body is! ExpressionFunctionBody) { | 20749 if (body is! ExpressionFunctionBody) { |
| 20750 return false; | 20750 return false; |
| 20751 } | 20751 } |
| 20752 // report error | 20752 // report error |
| 20753 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIVE_
CONSTRUCTOR, body, []); | 20753 _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIVE_
CONSTRUCTOR, body, []); |
| 20754 return true; | 20754 return true; |
| 20755 } | 20755 } |
| 20756 | 20756 |
| 20757 /** | 20757 /** |
| 20758 * This checks that a type mis-match between the return type and the expressed
return type by the | 20758 * This checks that a type mis-match between the return type and the expressed
return type by the |
| 20759 * enclosing method or function. | 20759 * enclosing method or function. |
| 20760 * | 20760 * |
| 20761 * This method is called both by [checkForAllReturnStatementErrorCodes] | 20761 * This method is called both by [checkForAllReturnStatementErrorCodes] |
| 20762 * and [visitExpressionFunctionBody]. | 20762 * and [visitExpressionFunctionBody]. |
| 20763 * | 20763 * |
| 20764 * @param returnExpression the returned expression to evaluate | 20764 * @param returnExpression the returned expression to evaluate |
| 20765 * @param expectedReturnType the expressed return type by the enclosing method
or function | 20765 * @param expectedReturnType the expressed return type by the enclosing method
or function |
| 20766 * @return `true` if and only if an error code is generated on the passed node | 20766 * @return `true` if and only if an error code is generated on the passed node |
| 20767 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE | 20767 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE |
| 20768 */ | 20768 */ |
| 20769 bool checkForReturnOfInvalidType(Expression returnExpression, Type2 expectedRe
turnType) { | 20769 bool _checkForReturnOfInvalidType(Expression returnExpression, Type2 expectedR
eturnType) { |
| 20770 Type2 staticReturnType = getStaticType(returnExpression); | 20770 Type2 staticReturnType = _getStaticType(returnExpression); |
| 20771 if (expectedReturnType.isVoid) { | 20771 if (expectedReturnType.isVoid) { |
| 20772 if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnT
ype.isBottom) { | 20772 if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnT
ype.isBottom) { |
| 20773 return false; | 20773 return false; |
| 20774 } | 20774 } |
| 20775 _errorReporter.reportErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_
TYPE, returnExpression, [ | 20775 _errorReporter.reportErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_
TYPE, returnExpression, [ |
| 20776 staticReturnType.displayName, | 20776 staticReturnType.displayName, |
| 20777 expectedReturnType.displayName, | 20777 expectedReturnType.displayName, |
| 20778 _enclosingFunction.displayName]); | 20778 _enclosingFunction.displayName]); |
| 20779 return true; | 20779 return true; |
| 20780 } | 20780 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 20793 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance | 20793 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance |
| 20794 * member. | 20794 * member. |
| 20795 * | 20795 * |
| 20796 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 20796 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
| 20797 * or `null`, aka, the class element of 'C' in 'C.x', see | 20797 * or `null`, aka, the class element of 'C' in 'C.x', see |
| 20798 * [getTypeReference] | 20798 * [getTypeReference] |
| 20799 * @param name the accessed name to evaluate | 20799 * @param name the accessed name to evaluate |
| 20800 * @return `true` if and only if an error code is generated on the passed node | 20800 * @return `true` if and only if an error code is generated on the passed node |
| 20801 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER | 20801 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER |
| 20802 */ | 20802 */ |
| 20803 bool checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleId
entifier name) { | 20803 bool _checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleI
dentifier name) { |
| 20804 // OK, target is not a type | 20804 // OK, target is not a type |
| 20805 if (typeReference == null) { | 20805 if (typeReference == null) { |
| 20806 return false; | 20806 return false; |
| 20807 } | 20807 } |
| 20808 // prepare member Element | 20808 // prepare member Element |
| 20809 Element element = name.staticElement; | 20809 Element element = name.staticElement; |
| 20810 if (element is! ExecutableElement) { | 20810 if (element is! ExecutableElement) { |
| 20811 return false; | 20811 return false; |
| 20812 } | 20812 } |
| 20813 ExecutableElement memberElement = element as ExecutableElement; | 20813 ExecutableElement memberElement = element as ExecutableElement; |
| 20814 // OK, static | 20814 // OK, static |
| 20815 if (memberElement.isStatic) { | 20815 if (memberElement.isStatic) { |
| 20816 return false; | 20816 return false; |
| 20817 } | 20817 } |
| 20818 // report problem | 20818 // report problem |
| 20819 _errorReporter.reportErrorForNode(StaticWarningCode.STATIC_ACCESS_TO_INSTANC
E_MEMBER, name, [name.name]); | 20819 _errorReporter.reportErrorForNode(StaticWarningCode.STATIC_ACCESS_TO_INSTANC
E_MEMBER, name, [name.name]); |
| 20820 return true; | 20820 return true; |
| 20821 } | 20821 } |
| 20822 | 20822 |
| 20823 /** | 20823 /** |
| 20824 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the | 20824 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the |
| 20825 * 'case' members. | 20825 * 'case' members. |
| 20826 * | 20826 * |
| 20827 * @param node the 'switch' statement to evaluate | 20827 * @param node the 'switch' statement to evaluate |
| 20828 * @return `true` if and only if an error code is generated on the passed node | 20828 * @return `true` if and only if an error code is generated on the passed node |
| 20829 * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE | 20829 * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE |
| 20830 */ | 20830 */ |
| 20831 bool checkForSwitchExpressionNotAssignable(SwitchStatement node) { | 20831 bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) { |
| 20832 // prepare 'switch' expression type | 20832 // prepare 'switch' expression type |
| 20833 Expression expression = node.expression; | 20833 Expression expression = node.expression; |
| 20834 Type2 expressionType = getStaticType(expression); | 20834 Type2 expressionType = _getStaticType(expression); |
| 20835 if (expressionType == null) { | 20835 if (expressionType == null) { |
| 20836 return false; | 20836 return false; |
| 20837 } | 20837 } |
| 20838 // compare with type of the first 'case' | 20838 // compare with type of the first 'case' |
| 20839 NodeList<SwitchMember> members = node.members; | 20839 NodeList<SwitchMember> members = node.members; |
| 20840 for (SwitchMember switchMember in members) { | 20840 for (SwitchMember switchMember in members) { |
| 20841 if (switchMember is! SwitchCase) { | 20841 if (switchMember is! SwitchCase) { |
| 20842 continue; | 20842 continue; |
| 20843 } | 20843 } |
| 20844 SwitchCase switchCase = switchMember as SwitchCase; | 20844 SwitchCase switchCase = switchMember as SwitchCase; |
| 20845 // prepare 'case' type | 20845 // prepare 'case' type |
| 20846 Expression caseExpression = switchCase.expression; | 20846 Expression caseExpression = switchCase.expression; |
| 20847 Type2 caseType = getStaticType(caseExpression); | 20847 Type2 caseType = _getStaticType(caseExpression); |
| 20848 // check types | 20848 // check types |
| 20849 if (expressionType.isAssignableTo(caseType)) { | 20849 if (expressionType.isAssignableTo(caseType)) { |
| 20850 return false; | 20850 return false; |
| 20851 } | 20851 } |
| 20852 // report problem | 20852 // report problem |
| 20853 _errorReporter.reportErrorForNode(StaticWarningCode.SWITCH_EXPRESSION_NOT_
ASSIGNABLE, expression, [expressionType, caseType]); | 20853 _errorReporter.reportErrorForNode(StaticWarningCode.SWITCH_EXPRESSION_NOT_
ASSIGNABLE, expression, [expressionType, caseType]); |
| 20854 return true; | 20854 return true; |
| 20855 } | 20855 } |
| 20856 return false; | 20856 return false; |
| 20857 } | 20857 } |
| 20858 | 20858 |
| 20859 /** | 20859 /** |
| 20860 * This verifies that the passed function type alias does not reference itself
directly. | 20860 * This verifies that the passed function type alias does not reference itself
directly. |
| 20861 * | 20861 * |
| 20862 * @param node the function type alias to evaluate | 20862 * @param node the function type alias to evaluate |
| 20863 * @return `true` if and only if an error code is generated on the passed node | 20863 * @return `true` if and only if an error code is generated on the passed node |
| 20864 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF | 20864 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF |
| 20865 */ | 20865 */ |
| 20866 bool checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node) { | 20866 bool _checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node)
{ |
| 20867 FunctionTypeAliasElement element = node.element; | 20867 FunctionTypeAliasElement element = node.element; |
| 20868 if (!hasTypedefSelfReference(element)) { | 20868 if (!_hasTypedefSelfReference(element)) { |
| 20869 return false; | 20869 return false; |
| 20870 } | 20870 } |
| 20871 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); | 20871 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); |
| 20872 return true; | 20872 return true; |
| 20873 } | 20873 } |
| 20874 | 20874 |
| 20875 /** | 20875 /** |
| 20876 * This verifies that the given class type alias does not reference itself. | 20876 * This verifies that the given class type alias does not reference itself. |
| 20877 * | 20877 * |
| 20878 * @return `true` if and only if an error code is generated on the passed node | 20878 * @return `true` if and only if an error code is generated on the passed node |
| 20879 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF | 20879 * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF |
| 20880 */ | 20880 */ |
| 20881 bool checkForTypeAliasCannotReferenceItself_mixin(ClassTypeAlias node) { | 20881 bool _checkForTypeAliasCannotReferenceItself_mixin(ClassTypeAlias node) { |
| 20882 ClassElement element = node.element; | 20882 ClassElement element = node.element; |
| 20883 if (!hasTypedefSelfReference(element)) { | 20883 if (!_hasTypedefSelfReference(element)) { |
| 20884 return false; | 20884 return false; |
| 20885 } | 20885 } |
| 20886 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); | 20886 _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REF
ERENCE_ITSELF, node, []); |
| 20887 return true; | 20887 return true; |
| 20888 } | 20888 } |
| 20889 | 20889 |
| 20890 /** | 20890 /** |
| 20891 * This verifies that the type arguments in the passed type name are all withi
n their bounds. | 20891 * This verifies that the type arguments in the passed type name are all withi
n their bounds. |
| 20892 * | 20892 * |
| 20893 * @param node the [TypeName] to evaluate | 20893 * @param node the [TypeName] to evaluate |
| 20894 * @return `true` if and only if an error code is generated on the passed node | 20894 * @return `true` if and only if an error code is generated on the passed node |
| 20895 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS | 20895 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS |
| 20896 */ | 20896 */ |
| 20897 bool checkForTypeArgumentNotMatchingBounds(TypeName node) { | 20897 bool _checkForTypeArgumentNotMatchingBounds(TypeName node) { |
| 20898 if (node.typeArguments == null) { | 20898 if (node.typeArguments == null) { |
| 20899 return false; | 20899 return false; |
| 20900 } | 20900 } |
| 20901 // prepare Type | 20901 // prepare Type |
| 20902 Type2 type = node.type; | 20902 Type2 type = node.type; |
| 20903 if (type == null) { | 20903 if (type == null) { |
| 20904 return false; | 20904 return false; |
| 20905 } | 20905 } |
| 20906 // prepare ClassElement | 20906 // prepare ClassElement |
| 20907 Element element = type.element; | 20907 Element element = type.element; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20939 } | 20939 } |
| 20940 | 20940 |
| 20941 /** | 20941 /** |
| 20942 * This checks that if the passed type name is a type parameter being used to
define a static | 20942 * This checks that if the passed type name is a type parameter being used to
define a static |
| 20943 * member. | 20943 * member. |
| 20944 * | 20944 * |
| 20945 * @param node the type name to evaluate | 20945 * @param node the type name to evaluate |
| 20946 * @return `true` if and only if an error code is generated on the passed node | 20946 * @return `true` if and only if an error code is generated on the passed node |
| 20947 * @see StaticWarningCode#TYPE_PARAMETER_REFERENCED_BY_STATIC | 20947 * @see StaticWarningCode#TYPE_PARAMETER_REFERENCED_BY_STATIC |
| 20948 */ | 20948 */ |
| 20949 bool checkForTypeParameterReferencedByStatic(TypeName node) { | 20949 bool _checkForTypeParameterReferencedByStatic(TypeName node) { |
| 20950 if (_isInStaticMethod || _isInStaticVariableDeclaration) { | 20950 if (_isInStaticMethod || _isInStaticVariableDeclaration) { |
| 20951 Type2 type = node.type; | 20951 Type2 type = node.type; |
| 20952 if (type is TypeParameterType) { | 20952 if (type is TypeParameterType) { |
| 20953 _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_PARAMETER_REFER
ENCED_BY_STATIC, node, []); | 20953 _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_PARAMETER_REFER
ENCED_BY_STATIC, node, []); |
| 20954 return true; | 20954 return true; |
| 20955 } | 20955 } |
| 20956 } | 20956 } |
| 20957 return false; | 20957 return false; |
| 20958 } | 20958 } |
| 20959 | 20959 |
| 20960 /** | 20960 /** |
| 20961 * This checks that if the passed type parameter is a supertype of its bound. | 20961 * This checks that if the passed type parameter is a supertype of its bound. |
| 20962 * | 20962 * |
| 20963 * @param node the type parameter to evaluate | 20963 * @param node the type parameter to evaluate |
| 20964 * @return `true` if and only if an error code is generated on the passed node | 20964 * @return `true` if and only if an error code is generated on the passed node |
| 20965 * @see StaticTypeWarningCode#TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND | 20965 * @see StaticTypeWarningCode#TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND |
| 20966 */ | 20966 */ |
| 20967 bool checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { | 20967 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { |
| 20968 TypeParameterElement element = node.element; | 20968 TypeParameterElement element = node.element; |
| 20969 // prepare bound | 20969 // prepare bound |
| 20970 Type2 bound = element.bound; | 20970 Type2 bound = element.bound; |
| 20971 if (bound == null) { | 20971 if (bound == null) { |
| 20972 return false; | 20972 return false; |
| 20973 } | 20973 } |
| 20974 // OK, type parameter is not supertype of its bound | 20974 // OK, type parameter is not supertype of its bound |
| 20975 if (!bound.isMoreSpecificThan(element.type)) { | 20975 if (!bound.isMoreSpecificThan(element.type)) { |
| 20976 return false; | 20976 return false; |
| 20977 } | 20977 } |
| 20978 // report problem | 20978 // report problem |
| 20979 _errorReporter.reportErrorForNode(StaticTypeWarningCode.TYPE_PARAMETER_SUPER
TYPE_OF_ITS_BOUND, node, [element.displayName]); | 20979 _errorReporter.reportErrorForNode(StaticTypeWarningCode.TYPE_PARAMETER_SUPER
TYPE_OF_ITS_BOUND, node, [element.displayName]); |
| 20980 return true; | 20980 return true; |
| 20981 } | 20981 } |
| 20982 | 20982 |
| 20983 /** | 20983 /** |
| 20984 * This checks that if the passed generative constructor has neither an explic
it super constructor | 20984 * This checks that if the passed generative constructor has neither an explic
it super constructor |
| 20985 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default | 20985 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default |
| 20986 * generative constructor. | 20986 * generative constructor. |
| 20987 * | 20987 * |
| 20988 * @param node the constructor declaration to evaluate | 20988 * @param node the constructor declaration to evaluate |
| 20989 * @return `true` if and only if an error code is generated on the passed node | 20989 * @return `true` if and only if an error code is generated on the passed node |
| 20990 * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT | 20990 * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT |
| 20991 * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR | 20991 * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR |
| 20992 * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT | 20992 * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT |
| 20993 */ | 20993 */ |
| 20994 bool checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration
node) { | 20994 bool _checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration
node) { |
| 20995 // | 20995 // |
| 20996 // Ignore if the constructor is not generative. | 20996 // Ignore if the constructor is not generative. |
| 20997 // | 20997 // |
| 20998 if (node.factoryKeyword != null) { | 20998 if (node.factoryKeyword != null) { |
| 20999 return false; | 20999 return false; |
| 21000 } | 21000 } |
| 21001 // | 21001 // |
| 21002 // Ignore if the constructor has either an implicit super constructor invoca
tion or a | 21002 // Ignore if the constructor has either an implicit super constructor invoca
tion or a |
| 21003 // redirecting constructor invocation. | 21003 // redirecting constructor invocation. |
| 21004 // | 21004 // |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21042 } | 21042 } |
| 21043 | 21043 |
| 21044 /** | 21044 /** |
| 21045 * This checks that if the given name is a reference to a static member it is
defined in the | 21045 * This checks that if the given name is a reference to a static member it is
defined in the |
| 21046 * enclosing class rather than in a superclass. | 21046 * enclosing class rather than in a superclass. |
| 21047 * | 21047 * |
| 21048 * @param name the name to be evaluated | 21048 * @param name the name to be evaluated |
| 21049 * @return `true` if and only if an error code is generated on the passed node | 21049 * @return `true` if and only if an error code is generated on the passed node |
| 21050 * @see StaticTypeWarningCode#UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER | 21050 * @see StaticTypeWarningCode#UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER |
| 21051 */ | 21051 */ |
| 21052 bool checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name)
{ | 21052 bool _checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name
) { |
| 21053 Element element = name.staticElement; | 21053 Element element = name.staticElement; |
| 21054 if (element == null || element is TypeParameterElement) { | 21054 if (element == null || element is TypeParameterElement) { |
| 21055 return false; | 21055 return false; |
| 21056 } | 21056 } |
| 21057 Element enclosingElement = element.enclosingElement; | 21057 Element enclosingElement = element.enclosingElement; |
| 21058 if (enclosingElement is! ClassElement) { | 21058 if (enclosingElement is! ClassElement) { |
| 21059 return false; | 21059 return false; |
| 21060 } | 21060 } |
| 21061 if ((element is MethodElement && !element.isStatic) || (element is PropertyA
ccessorElement && !element.isStatic)) { | 21061 if ((element is MethodElement && !element.isStatic) || (element is PropertyA
ccessorElement && !element.isStatic)) { |
| 21062 return false; | 21062 return false; |
| 21063 } | 21063 } |
| 21064 if (identical(enclosingElement, _enclosingClass)) { | 21064 if (identical(enclosingElement, _enclosingClass)) { |
| 21065 return false; | 21065 return false; |
| 21066 } | 21066 } |
| 21067 _errorReporter.reportErrorForNode(StaticTypeWarningCode.UNQUALIFIED_REFERENC
E_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]); | 21067 _errorReporter.reportErrorForNode(StaticTypeWarningCode.UNQUALIFIED_REFERENC
E_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]); |
| 21068 return true; | 21068 return true; |
| 21069 } | 21069 } |
| 21070 | 21070 |
| 21071 void checkForValidField(FieldFormalParameter node) { | 21071 void _checkForValidField(FieldFormalParameter node) { |
| 21072 ParameterElement element = node.element; | 21072 ParameterElement element = node.element; |
| 21073 if (element is FieldFormalParameterElement) { | 21073 if (element is FieldFormalParameterElement) { |
| 21074 FieldElement fieldElement = element.field; | 21074 FieldElement fieldElement = element.field; |
| 21075 if (fieldElement == null || fieldElement.isSynthetic) { | 21075 if (fieldElement == null || fieldElement.isSynthetic) { |
| 21076 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORM
AL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); | 21076 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORM
AL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); |
| 21077 } else { | 21077 } else { |
| 21078 ParameterElement parameterElement = node.element; | 21078 ParameterElement parameterElement = node.element; |
| 21079 if (parameterElement is FieldFormalParameterElementImpl) { | 21079 if (parameterElement is FieldFormalParameterElementImpl) { |
| 21080 FieldFormalParameterElementImpl fieldFormal = parameterElement; | 21080 FieldFormalParameterElementImpl fieldFormal = parameterElement; |
| 21081 Type2 declaredType = fieldFormal.type; | 21081 Type2 declaredType = fieldFormal.type; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 21101 /** | 21101 /** |
| 21102 * This verifies the passed operator-method declaration, has correct number of
parameters. | 21102 * This verifies the passed operator-method declaration, has correct number of
parameters. |
| 21103 * | 21103 * |
| 21104 * This method assumes that the method declaration was tested to be an operato
r declaration before | 21104 * This method assumes that the method declaration was tested to be an operato
r declaration before |
| 21105 * being called. | 21105 * being called. |
| 21106 * | 21106 * |
| 21107 * @param node the method declaration to evaluate | 21107 * @param node the method declaration to evaluate |
| 21108 * @return `true` if and only if an error code is generated on the passed node | 21108 * @return `true` if and only if an error code is generated on the passed node |
| 21109 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR | 21109 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR |
| 21110 */ | 21110 */ |
| 21111 bool checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { | 21111 bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { |
| 21112 // prepare number of parameters | 21112 // prepare number of parameters |
| 21113 FormalParameterList parameterList = node.parameters; | 21113 FormalParameterList parameterList = node.parameters; |
| 21114 if (parameterList == null) { | 21114 if (parameterList == null) { |
| 21115 return false; | 21115 return false; |
| 21116 } | 21116 } |
| 21117 int numParameters = parameterList.parameters.length; | 21117 int numParameters = parameterList.parameters.length; |
| 21118 // prepare operator name | 21118 // prepare operator name |
| 21119 SimpleIdentifier nameNode = node.name; | 21119 SimpleIdentifier nameNode = node.name; |
| 21120 if (nameNode == null) { | 21120 if (nameNode == null) { |
| 21121 return false; | 21121 return false; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 21146 /** | 21146 /** |
| 21147 * This verifies if the passed setter parameter list have only one required pa
rameter. | 21147 * This verifies if the passed setter parameter list have only one required pa
rameter. |
| 21148 * | 21148 * |
| 21149 * This method assumes that the method declaration was tested to be a setter b
efore being called. | 21149 * This method assumes that the method declaration was tested to be a setter b
efore being called. |
| 21150 * | 21150 * |
| 21151 * @param setterName the name of the setter to report problems on | 21151 * @param setterName the name of the setter to report problems on |
| 21152 * @param parameterList the parameter list to evaluate | 21152 * @param parameterList the parameter list to evaluate |
| 21153 * @return `true` if and only if an error code is generated on the passed node | 21153 * @return `true` if and only if an error code is generated on the passed node |
| 21154 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER | 21154 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER |
| 21155 */ | 21155 */ |
| 21156 bool checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, For
malParameterList parameterList) { | 21156 bool _checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, Fo
rmalParameterList parameterList) { |
| 21157 if (setterName == null) { | 21157 if (setterName == null) { |
| 21158 return false; | 21158 return false; |
| 21159 } | 21159 } |
| 21160 if (parameterList == null) { | 21160 if (parameterList == null) { |
| 21161 return false; | 21161 return false; |
| 21162 } | 21162 } |
| 21163 NodeList<FormalParameter> parameters = parameterList.parameters; | 21163 NodeList<FormalParameter> parameters = parameterList.parameters; |
| 21164 if (parameters.length != 1 || parameters[0].kind != ParameterKind.REQUIRED)
{ | 21164 if (parameters.length != 1 || parameters[0].kind != ParameterKind.REQUIRED)
{ |
| 21165 _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PAR
AMETERS_FOR_SETTER, setterName, []); | 21165 _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PAR
AMETERS_FOR_SETTER, setterName, []); |
| 21166 return true; | 21166 return true; |
| 21167 } | 21167 } |
| 21168 return false; | 21168 return false; |
| 21169 } | 21169 } |
| 21170 | 21170 |
| 21171 /** | 21171 /** |
| 21172 * This verifies that if the given class declaration implements the class Func
tion that it has a | 21172 * This verifies that if the given class declaration implements the class Func
tion that it has a |
| 21173 * concrete implementation of the call method. | 21173 * concrete implementation of the call method. |
| 21174 * | 21174 * |
| 21175 * @return `true` if and only if an error code is generated on the passed node | 21175 * @return `true` if and only if an error code is generated on the passed node |
| 21176 * @see StaticWarningCode#FUNCTION_WITHOUT_CALL | 21176 * @see StaticWarningCode#FUNCTION_WITHOUT_CALL |
| 21177 */ | 21177 */ |
| 21178 bool checkImplementsFunctionWithoutCall(ClassDeclaration node) { | 21178 bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) { |
| 21179 if (node.abstractKeyword != null) { | 21179 if (node.abstractKeyword != null) { |
| 21180 return false; | 21180 return false; |
| 21181 } | 21181 } |
| 21182 ClassElement classElement = node.element; | 21182 ClassElement classElement = node.element; |
| 21183 if (classElement == null) { | 21183 if (classElement == null) { |
| 21184 return false; | 21184 return false; |
| 21185 } | 21185 } |
| 21186 if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) { | 21186 if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) { |
| 21187 return false; | 21187 return false; |
| 21188 } | 21188 } |
| 21189 ExecutableElement callMethod = _inheritanceManager.lookupMember(classElement
, "call"); | 21189 ExecutableElement callMethod = _inheritanceManager.lookupMember(classElement
, "call"); |
| 21190 if (callMethod == null || callMethod is! MethodElement || (callMethod as Met
hodElement).isAbstract) { | 21190 if (callMethod == null || callMethod is! MethodElement || (callMethod as Met
hodElement).isAbstract) { |
| 21191 _errorReporter.reportErrorForNode(StaticWarningCode.FUNCTION_WITHOUT_CALL,
node.name, []); | 21191 _errorReporter.reportErrorForNode(StaticWarningCode.FUNCTION_WITHOUT_CALL,
node.name, []); |
| 21192 return true; | 21192 return true; |
| 21193 } | 21193 } |
| 21194 return false; | 21194 return false; |
| 21195 } | 21195 } |
| 21196 | 21196 |
| 21197 /** | 21197 /** |
| 21198 * This verifies that the given class declaration does not have the same class
in the 'extends' | 21198 * This verifies that the given class declaration does not have the same class
in the 'extends' |
| 21199 * and 'implements' clauses. | 21199 * and 'implements' clauses. |
| 21200 * | 21200 * |
| 21201 * @return `true` if and only if an error code is generated on the passed node | 21201 * @return `true` if and only if an error code is generated on the passed node |
| 21202 * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS | 21202 * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS |
| 21203 */ | 21203 */ |
| 21204 bool checkImplementsSuperClass(ClassDeclaration node) { | 21204 bool _checkImplementsSuperClass(ClassDeclaration node) { |
| 21205 // prepare super type | 21205 // prepare super type |
| 21206 InterfaceType superType = _enclosingClass.supertype; | 21206 InterfaceType superType = _enclosingClass.supertype; |
| 21207 if (superType == null) { | 21207 if (superType == null) { |
| 21208 return false; | 21208 return false; |
| 21209 } | 21209 } |
| 21210 // prepare interfaces | 21210 // prepare interfaces |
| 21211 ImplementsClause implementsClause = node.implementsClause; | 21211 ImplementsClause implementsClause = node.implementsClause; |
| 21212 if (implementsClause == null) { | 21212 if (implementsClause == null) { |
| 21213 return false; | 21213 return false; |
| 21214 } | 21214 } |
| 21215 // check interfaces | 21215 // check interfaces |
| 21216 bool hasProblem = false; | 21216 bool hasProblem = false; |
| 21217 for (TypeName interfaceNode in implementsClause.interfaces) { | 21217 for (TypeName interfaceNode in implementsClause.interfaces) { |
| 21218 if (interfaceNode.type == superType) { | 21218 if (interfaceNode.type == superType) { |
| 21219 hasProblem = true; | 21219 hasProblem = true; |
| 21220 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLEMENTS_SUPER_
CLASS, interfaceNode, [superType.displayName]); | 21220 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLEMENTS_SUPER_
CLASS, interfaceNode, [superType.displayName]); |
| 21221 } | 21221 } |
| 21222 } | 21222 } |
| 21223 // done | 21223 // done |
| 21224 return hasProblem; | 21224 return hasProblem; |
| 21225 } | 21225 } |
| 21226 | 21226 |
| 21227 /** | 21227 /** |
| 21228 * Return a display name for the given type that includes the path to the comp
ilation unit in | 21228 * Return a display name for the given type that includes the path to the comp
ilation unit in |
| 21229 * which the type is defined. | 21229 * which the type is defined. |
| 21230 * | 21230 * |
| 21231 * @param type the type for which an extended display name is to be returned | 21231 * @param type the type for which an extended display name is to be returned |
| 21232 * @return a display name that can help distiguish between two types with the
same name | 21232 * @return a display name that can help distiguish between two types with the
same name |
| 21233 */ | 21233 */ |
| 21234 String getExtendedDisplayName(Type2 type) { | 21234 String _getExtendedDisplayName(Type2 type) { |
| 21235 Element element = type.element; | 21235 Element element = type.element; |
| 21236 if (element != null) { | 21236 if (element != null) { |
| 21237 Source source = element.source; | 21237 Source source = element.source; |
| 21238 if (source != null) { | 21238 if (source != null) { |
| 21239 return "${type.displayName} (${source.fullName})"; | 21239 return "${type.displayName} (${source.fullName})"; |
| 21240 } | 21240 } |
| 21241 } | 21241 } |
| 21242 return type.displayName; | 21242 return type.displayName; |
| 21243 } | 21243 } |
| 21244 | 21244 |
| 21245 /** | 21245 /** |
| 21246 * Returns the Type (return type) for a given getter. | 21246 * Returns the Type (return type) for a given getter. |
| 21247 * | 21247 * |
| 21248 * @param propertyAccessorElement | 21248 * @param propertyAccessorElement |
| 21249 * @return The type of the given getter. | 21249 * @return The type of the given getter. |
| 21250 */ | 21250 */ |
| 21251 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) { | 21251 Type2 _getGetterType(PropertyAccessorElement propertyAccessorElement) { |
| 21252 FunctionType functionType = propertyAccessorElement.type; | 21252 FunctionType functionType = propertyAccessorElement.type; |
| 21253 if (functionType != null) { | 21253 if (functionType != null) { |
| 21254 return functionType.returnType; | 21254 return functionType.returnType; |
| 21255 } else { | 21255 } else { |
| 21256 return null; | 21256 return null; |
| 21257 } | 21257 } |
| 21258 } | 21258 } |
| 21259 | 21259 |
| 21260 /** | 21260 /** |
| 21261 * Returns the Type (first and only parameter) for a given setter. | 21261 * Returns the Type (first and only parameter) for a given setter. |
| 21262 * | 21262 * |
| 21263 * @param propertyAccessorElement | 21263 * @param propertyAccessorElement |
| 21264 * @return The type of the given setter. | 21264 * @return The type of the given setter. |
| 21265 */ | 21265 */ |
| 21266 Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) { | 21266 Type2 _getSetterType(PropertyAccessorElement propertyAccessorElement) { |
| 21267 // Get the parameters for MethodDeclaration or FunctionDeclaration | 21267 // Get the parameters for MethodDeclaration or FunctionDeclaration |
| 21268 List<ParameterElement> setterParameters = propertyAccessorElement.parameters
; | 21268 List<ParameterElement> setterParameters = propertyAccessorElement.parameters
; |
| 21269 // If there are no setter parameters, return no type. | 21269 // If there are no setter parameters, return no type. |
| 21270 if (setterParameters.length == 0) { | 21270 if (setterParameters.length == 0) { |
| 21271 return null; | 21271 return null; |
| 21272 } | 21272 } |
| 21273 return setterParameters[0].type; | 21273 return setterParameters[0].type; |
| 21274 } | 21274 } |
| 21275 | 21275 |
| 21276 /** | 21276 /** |
| 21277 * Return the static type of the given expression that is to be used for type
analysis. | 21277 * Return the static type of the given expression that is to be used for type
analysis. |
| 21278 * | 21278 * |
| 21279 * @param expression the expression whose type is to be returned | 21279 * @param expression the expression whose type is to be returned |
| 21280 * @return the static type of the given expression | 21280 * @return the static type of the given expression |
| 21281 */ | 21281 */ |
| 21282 Type2 getStaticType(Expression expression) { | 21282 Type2 _getStaticType(Expression expression) { |
| 21283 Type2 type = expression.staticType; | 21283 Type2 type = expression.staticType; |
| 21284 if (type == null) { | 21284 if (type == null) { |
| 21285 // TODO(brianwilkerson) This should never happen. | 21285 // TODO(brianwilkerson) This should never happen. |
| 21286 return _dynamicType; | 21286 return _dynamicType; |
| 21287 } | 21287 } |
| 21288 return type; | 21288 return type; |
| 21289 } | 21289 } |
| 21290 | 21290 |
| 21291 /** | 21291 /** |
| 21292 * Return the variable element represented by the given expression, or `null`
if there is no | 21292 * Return the variable element represented by the given expression, or `null`
if there is no |
| 21293 * such element. | 21293 * such element. |
| 21294 * | 21294 * |
| 21295 * @param expression the expression whose element is to be returned | 21295 * @param expression the expression whose element is to be returned |
| 21296 * @return the variable element represented by the expression | 21296 * @return the variable element represented by the expression |
| 21297 */ | 21297 */ |
| 21298 VariableElement getVariableElement(Expression expression) { | 21298 VariableElement _getVariableElement(Expression expression) { |
| 21299 if (expression is Identifier) { | 21299 if (expression is Identifier) { |
| 21300 Element element = expression.staticElement; | 21300 Element element = expression.staticElement; |
| 21301 if (element is VariableElement) { | 21301 if (element is VariableElement) { |
| 21302 return element; | 21302 return element; |
| 21303 } | 21303 } |
| 21304 } | 21304 } |
| 21305 return null; | 21305 return null; |
| 21306 } | 21306 } |
| 21307 | 21307 |
| 21308 /** | 21308 /** |
| 21309 * @return `true` if the given constructor redirects to itself, directly or in
directly | 21309 * @return `true` if the given constructor redirects to itself, directly or in
directly |
| 21310 */ | 21310 */ |
| 21311 bool hasRedirectingFactoryConstructorCycle(ConstructorElement element) { | 21311 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) { |
| 21312 Set<ConstructorElement> constructors = new Set<ConstructorElement>(); | 21312 Set<ConstructorElement> constructors = new Set<ConstructorElement>(); |
| 21313 ConstructorElement current = element; | 21313 ConstructorElement current = element; |
| 21314 while (current != null) { | 21314 while (current != null) { |
| 21315 if (constructors.contains(current)) { | 21315 if (constructors.contains(current)) { |
| 21316 return identical(current, element); | 21316 return identical(current, element); |
| 21317 } | 21317 } |
| 21318 constructors.add(current); | 21318 constructors.add(current); |
| 21319 current = current.redirectedConstructor; | 21319 current = current.redirectedConstructor; |
| 21320 if (current is ConstructorMember) { | 21320 if (current is ConstructorMember) { |
| 21321 current = (current as ConstructorMember).baseElement; | 21321 current = (current as ConstructorMember).baseElement; |
| 21322 } | 21322 } |
| 21323 } | 21323 } |
| 21324 return false; | 21324 return false; |
| 21325 } | 21325 } |
| 21326 | 21326 |
| 21327 /** | 21327 /** |
| 21328 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself | 21328 * @return <code>true</code> if given [Element] has direct or indirect referen
ce to itself |
| 21329 * from anywhere except [ClassElement] or type parameter bounds. | 21329 * from anywhere except [ClassElement] or type parameter bounds. |
| 21330 */ | 21330 */ |
| 21331 bool hasTypedefSelfReference(Element target) { | 21331 bool _hasTypedefSelfReference(Element target) { |
| 21332 Set<Element> checked = new Set<Element>(); | 21332 Set<Element> checked = new Set<Element>(); |
| 21333 List<Element> toCheck = new List<Element>(); | 21333 List<Element> toCheck = new List<Element>(); |
| 21334 toCheck.add(target); | 21334 toCheck.add(target); |
| 21335 bool firstIteration = true; | 21335 bool firstIteration = true; |
| 21336 while (true) { | 21336 while (true) { |
| 21337 Element current; | 21337 Element current; |
| 21338 // get next element | 21338 // get next element |
| 21339 while (true) { | 21339 while (true) { |
| 21340 // may be no more elements to check | 21340 // may be no more elements to check |
| 21341 if (toCheck.isEmpty) { | 21341 if (toCheck.isEmpty) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 21358 // check current element | 21358 // check current element |
| 21359 current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelf
Reference(target, toCheck)); | 21359 current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelf
Reference(target, toCheck)); |
| 21360 checked.add(current); | 21360 checked.add(current); |
| 21361 } | 21361 } |
| 21362 } | 21362 } |
| 21363 | 21363 |
| 21364 /** | 21364 /** |
| 21365 * @return `true` if given [Type] implements operator <i>==</i>, and it is not | 21365 * @return `true` if given [Type] implements operator <i>==</i>, and it is not |
| 21366 * <i>int</i> or <i>String</i>. | 21366 * <i>int</i> or <i>String</i>. |
| 21367 */ | 21367 */ |
| 21368 bool implementsEqualsWhenNotAllowed(Type2 type) { | 21368 bool _implementsEqualsWhenNotAllowed(Type2 type) { |
| 21369 // ignore int or String | 21369 // ignore int or String |
| 21370 if (type == null || type == _intType || type == _typeProvider.stringType) { | 21370 if (type == null || type == _intType || type == _typeProvider.stringType) { |
| 21371 return false; | 21371 return false; |
| 21372 } | 21372 } |
| 21373 // prepare ClassElement | 21373 // prepare ClassElement |
| 21374 Element element = type.element; | 21374 Element element = type.element; |
| 21375 if (element is! ClassElement) { | 21375 if (element is! ClassElement) { |
| 21376 return false; | 21376 return false; |
| 21377 } | 21377 } |
| 21378 ClassElement classElement = element as ClassElement; | 21378 ClassElement classElement = element as ClassElement; |
| 21379 // lookup for == | 21379 // lookup for == |
| 21380 MethodElement method = classElement.lookUpMethod("==", _currentLibrary); | 21380 MethodElement method = classElement.lookUpMethod("==", _currentLibrary); |
| 21381 if (method == null || method.enclosingElement.type.isObject) { | 21381 if (method == null || method.enclosingElement.type.isObject) { |
| 21382 return false; | 21382 return false; |
| 21383 } | 21383 } |
| 21384 // there is == that we don't like | 21384 // there is == that we don't like |
| 21385 return true; | 21385 return true; |
| 21386 } | 21386 } |
| 21387 | 21387 |
| 21388 bool isFunctionType(Type2 type) { | 21388 bool _isFunctionType(Type2 type) { |
| 21389 if (type.isDynamic || type.isBottom) { | 21389 if (type.isDynamic || type.isBottom) { |
| 21390 return true; | 21390 return true; |
| 21391 } else if (type is FunctionType || type.isDartCoreFunction) { | 21391 } else if (type is FunctionType || type.isDartCoreFunction) { |
| 21392 return true; | 21392 return true; |
| 21393 } else if (type is InterfaceType) { | 21393 } else if (type is InterfaceType) { |
| 21394 MethodElement callMethod = type.lookUpMethod(ElementResolver.CALL_METHOD_N
AME, _currentLibrary); | 21394 MethodElement callMethod = type.lookUpMethod(ElementResolver.CALL_METHOD_N
AME, _currentLibrary); |
| 21395 return callMethod != null; | 21395 return callMethod != null; |
| 21396 } | 21396 } |
| 21397 return false; | 21397 return false; |
| 21398 } | 21398 } |
| 21399 | 21399 |
| 21400 /** | 21400 /** |
| 21401 * Return `true` iff the passed [ClassElement] has a method, getter or setter
that | 21401 * Return `true` iff the passed [ClassElement] has a method, getter or setter
that |
| 21402 * matches the name of the passed [ExecutableElement] in either the class itse
lf, or one of | 21402 * matches the name of the passed [ExecutableElement] in either the class itse
lf, or one of |
| 21403 * its' mixins. | 21403 * its' mixins. |
| 21404 * | 21404 * |
| 21405 * By "match", only the name of the member is tested to match, it does not hav
e to equal or be a | 21405 * By "match", only the name of the member is tested to match, it does not hav
e to equal or be a |
| 21406 * subtype of the passed executable element, this is due to the specific use w
here this method is | 21406 * subtype of the passed executable element, this is due to the specific use w
here this method is |
| 21407 * used in [checkForNonAbstractClassInheritsAbstractMember]. | 21407 * used in [checkForNonAbstractClassInheritsAbstractMember]. |
| 21408 * | 21408 * |
| 21409 * @param executableElt the executable to search for in the passed class eleme
nt | 21409 * @param executableElt the executable to search for in the passed class eleme
nt |
| 21410 * @param classElt the class method to search through the members of | 21410 * @param classElt the class method to search through the members of |
| 21411 * @return `true` iff the passed member is found in the passed class element | 21411 * @return `true` iff the passed member is found in the passed class element |
| 21412 */ | 21412 */ |
| 21413 bool isMemberInClassOrMixin(ExecutableElement executableElt, ClassElement clas
sElt) { | 21413 bool _isMemberInClassOrMixin(ExecutableElement executableElt, ClassElement cla
ssElt) { |
| 21414 ExecutableElement foundElt; | 21414 ExecutableElement foundElt; |
| 21415 String executableName = executableElt.name; | 21415 String executableName = executableElt.name; |
| 21416 if (executableElt is MethodElement) { | 21416 if (executableElt is MethodElement) { |
| 21417 foundElt = classElt.getMethod(executableName); | 21417 foundElt = classElt.getMethod(executableName); |
| 21418 if (foundElt != null) { | 21418 if (foundElt != null) { |
| 21419 return true; | 21419 return true; |
| 21420 } | 21420 } |
| 21421 List<InterfaceType> mixins = classElt.mixins; | 21421 List<InterfaceType> mixins = classElt.mixins; |
| 21422 for (int i = 0; i < mixins.length && foundElt == null; i++) { | 21422 for (int i = 0; i < mixins.length && foundElt == null; i++) { |
| 21423 foundElt = mixins[i].getMethod(executableName); | 21423 foundElt = mixins[i].getMethod(executableName); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 21444 return true; | 21444 return true; |
| 21445 } | 21445 } |
| 21446 } | 21446 } |
| 21447 return false; | 21447 return false; |
| 21448 } | 21448 } |
| 21449 | 21449 |
| 21450 /** | 21450 /** |
| 21451 * @param node the 'this' expression to analyze | 21451 * @param node the 'this' expression to analyze |
| 21452 * @return `true` if the given 'this' expression is in the valid context | 21452 * @return `true` if the given 'this' expression is in the valid context |
| 21453 */ | 21453 */ |
| 21454 bool isThisInValidContext(ThisExpression node) { | 21454 bool _isThisInValidContext(ThisExpression node) { |
| 21455 for (AstNode n = node; n != null; n = n.parent) { | 21455 for (AstNode n = node; n != null; n = n.parent) { |
| 21456 if (n is CompilationUnit) { | 21456 if (n is CompilationUnit) { |
| 21457 return false; | 21457 return false; |
| 21458 } | 21458 } |
| 21459 if (n is ConstructorDeclaration) { | 21459 if (n is ConstructorDeclaration) { |
| 21460 ConstructorDeclaration constructor = n as ConstructorDeclaration; | 21460 ConstructorDeclaration constructor = n as ConstructorDeclaration; |
| 21461 return constructor.factoryKeyword == null; | 21461 return constructor.factoryKeyword == null; |
| 21462 } | 21462 } |
| 21463 if (n is ConstructorInitializer) { | 21463 if (n is ConstructorInitializer) { |
| 21464 return false; | 21464 return false; |
| 21465 } | 21465 } |
| 21466 if (n is MethodDeclaration) { | 21466 if (n is MethodDeclaration) { |
| 21467 MethodDeclaration method = n as MethodDeclaration; | 21467 MethodDeclaration method = n as MethodDeclaration; |
| 21468 return !method.isStatic; | 21468 return !method.isStatic; |
| 21469 } | 21469 } |
| 21470 } | 21470 } |
| 21471 return false; | 21471 return false; |
| 21472 } | 21472 } |
| 21473 | 21473 |
| 21474 /** | 21474 /** |
| 21475 * Return `true` if the given identifier is in a location where it is allowed
to resolve to | 21475 * Return `true` if the given identifier is in a location where it is allowed
to resolve to |
| 21476 * a static member of a supertype. | 21476 * a static member of a supertype. |
| 21477 * | 21477 * |
| 21478 * @param node the node being tested | 21478 * @param node the node being tested |
| 21479 * @return `true` if the given identifier is in a location where it is allowed
to resolve to | 21479 * @return `true` if the given identifier is in a location where it is allowed
to resolve to |
| 21480 * a static member of a supertype | 21480 * a static member of a supertype |
| 21481 */ | 21481 */ |
| 21482 bool isUnqualifiedReferenceToNonLocalStaticMemberAllowed(SimpleIdentifier node
) { | 21482 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(SimpleIdentifier nod
e) { |
| 21483 if (node.inDeclarationContext()) { | 21483 if (node.inDeclarationContext()) { |
| 21484 return true; | 21484 return true; |
| 21485 } | 21485 } |
| 21486 AstNode parent = node.parent; | 21486 AstNode parent = node.parent; |
| 21487 if (parent is ConstructorName || parent is MethodInvocation || parent is Pro
pertyAccess || parent is SuperConstructorInvocation) { | 21487 if (parent is ConstructorName || parent is MethodInvocation || parent is Pro
pertyAccess || parent is SuperConstructorInvocation) { |
| 21488 return true; | 21488 return true; |
| 21489 } | 21489 } |
| 21490 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { | 21490 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { |
| 21491 return true; | 21491 return true; |
| 21492 } | 21492 } |
| 21493 if (parent is Annotation && identical(parent.constructorName, node)) { | 21493 if (parent is Annotation && identical(parent.constructorName, node)) { |
| 21494 return true; | 21494 return true; |
| 21495 } | 21495 } |
| 21496 if (parent is CommentReference) { | 21496 if (parent is CommentReference) { |
| 21497 CommentReference commentReference = parent; | 21497 CommentReference commentReference = parent; |
| 21498 if (commentReference.newKeyword != null) { | 21498 if (commentReference.newKeyword != null) { |
| 21499 return true; | 21499 return true; |
| 21500 } | 21500 } |
| 21501 } | 21501 } |
| 21502 return false; | 21502 return false; |
| 21503 } | 21503 } |
| 21504 | 21504 |
| 21505 bool isUserDefinedObject(EvaluationResultImpl result) => result == null || (re
sult is ValidResult && result.isUserDefinedObject); | 21505 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || (r
esult is ValidResult && result.isUserDefinedObject); |
| 21506 | 21506 |
| 21507 /** | 21507 /** |
| 21508 * This checks the class declaration is not a superinterface to itself. | 21508 * This checks the class declaration is not a superinterface to itself. |
| 21509 * | 21509 * |
| 21510 * @param classElt the class element to test | 21510 * @param classElt the class element to test |
| 21511 * @param path a list containing the potentially cyclic implements path | 21511 * @param path a list containing the potentially cyclic implements path |
| 21512 * @return `true` if and only if an error code is generated on the passed elem
ent | 21512 * @return `true` if and only if an error code is generated on the passed elem
ent |
| 21513 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE | 21513 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE |
| 21514 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS | 21514 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS |
| 21515 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS | 21515 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME
NTS |
| 21516 */ | 21516 */ |
| 21517 bool safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, List<Cla
ssElement> path) { | 21517 bool _safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, List<Cl
assElement> path) { |
| 21518 // Detect error condition. | 21518 // Detect error condition. |
| 21519 int size = path.length; | 21519 int size = path.length; |
| 21520 // If this is not the base case (size > 0), and the enclosing class is the p
assed class | 21520 // If this is not the base case (size > 0), and the enclosing class is the p
assed class |
| 21521 // element then an error an error. | 21521 // element then an error an error. |
| 21522 if (size > 0 && _enclosingClass == classElt) { | 21522 if (size > 0 && _enclosingClass == classElt) { |
| 21523 String enclosingClassName = _enclosingClass.displayName; | 21523 String enclosingClassName = _enclosingClass.displayName; |
| 21524 if (size > 1) { | 21524 if (size > 1) { |
| 21525 // Construct a string showing the cyclic implements path: "A, B, C, D, A
" | 21525 // Construct a string showing the cyclic implements path: "A, B, C, D, A
" |
| 21526 String separator = ", "; | 21526 String separator = ", "; |
| 21527 JavaStringBuilder builder = new JavaStringBuilder(); | 21527 JavaStringBuilder builder = new JavaStringBuilder(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 21539 _errorReporter.reportErrorForOffset(errorCode, _enclosingClass.nameOffse
t, enclosingClassName.length, [enclosingClassName]); | 21539 _errorReporter.reportErrorForOffset(errorCode, _enclosingClass.nameOffse
t, enclosingClassName.length, [enclosingClassName]); |
| 21540 return true; | 21540 return true; |
| 21541 } | 21541 } |
| 21542 } | 21542 } |
| 21543 if (path.indexOf(classElt) > 0) { | 21543 if (path.indexOf(classElt) > 0) { |
| 21544 return false; | 21544 return false; |
| 21545 } | 21545 } |
| 21546 path.add(classElt); | 21546 path.add(classElt); |
| 21547 // n-case | 21547 // n-case |
| 21548 InterfaceType supertype = classElt.supertype; | 21548 InterfaceType supertype = classElt.supertype; |
| 21549 if (supertype != null && safeCheckForRecursiveInterfaceInheritance(supertype
.element, path)) { | 21549 if (supertype != null && _safeCheckForRecursiveInterfaceInheritance(supertyp
e.element, path)) { |
| 21550 return true; | 21550 return true; |
| 21551 } | 21551 } |
| 21552 List<InterfaceType> interfaceTypes = classElt.interfaces; | 21552 List<InterfaceType> interfaceTypes = classElt.interfaces; |
| 21553 for (InterfaceType interfaceType in interfaceTypes) { | 21553 for (InterfaceType interfaceType in interfaceTypes) { |
| 21554 if (safeCheckForRecursiveInterfaceInheritance(interfaceType.element, path)
) { | 21554 if (_safeCheckForRecursiveInterfaceInheritance(interfaceType.element, path
)) { |
| 21555 return true; | 21555 return true; |
| 21556 } | 21556 } |
| 21557 } | 21557 } |
| 21558 path.removeAt(path.length - 1); | 21558 path.removeAt(path.length - 1); |
| 21559 return false; | 21559 return false; |
| 21560 } | 21560 } |
| 21561 } | 21561 } |
| 21562 | 21562 |
| 21563 /** | 21563 /** |
| 21564 * This enum holds one of four states of a field initialization state through a
constructor | 21564 * This enum holds one of four states of a field initialization state through a
constructor |
| (...skipping 21 matching lines...) Expand all Loading... |
| 21586 class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends G
eneralizingElementVisitor<Object> { | 21586 class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends G
eneralizingElementVisitor<Object> { |
| 21587 Element target; | 21587 Element target; |
| 21588 | 21588 |
| 21589 List<Element> toCheck; | 21589 List<Element> toCheck; |
| 21590 | 21590 |
| 21591 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.target,
this.toCheck) : super(); | 21591 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.target,
this.toCheck) : super(); |
| 21592 | 21592 |
| 21593 bool _inClass = false; | 21593 bool _inClass = false; |
| 21594 | 21594 |
| 21595 Object visitClassElement(ClassElement element) { | 21595 Object visitClassElement(ClassElement element) { |
| 21596 addTypeToCheck(element.supertype); | 21596 _addTypeToCheck(element.supertype); |
| 21597 for (InterfaceType mixin in element.mixins) { | 21597 for (InterfaceType mixin in element.mixins) { |
| 21598 addTypeToCheck(mixin); | 21598 _addTypeToCheck(mixin); |
| 21599 } | 21599 } |
| 21600 _inClass = !element.isTypedef; | 21600 _inClass = !element.isTypedef; |
| 21601 try { | 21601 try { |
| 21602 return super.visitClassElement(element); | 21602 return super.visitClassElement(element); |
| 21603 } finally { | 21603 } finally { |
| 21604 _inClass = false; | 21604 _inClass = false; |
| 21605 } | 21605 } |
| 21606 } | 21606 } |
| 21607 | 21607 |
| 21608 Object visitExecutableElement(ExecutableElement element) { | 21608 Object visitExecutableElement(ExecutableElement element) { |
| 21609 if (element.isSynthetic) { | 21609 if (element.isSynthetic) { |
| 21610 return null; | 21610 return null; |
| 21611 } | 21611 } |
| 21612 addTypeToCheck(element.returnType); | 21612 _addTypeToCheck(element.returnType); |
| 21613 return super.visitExecutableElement(element); | 21613 return super.visitExecutableElement(element); |
| 21614 } | 21614 } |
| 21615 | 21615 |
| 21616 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { | 21616 Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { |
| 21617 addTypeToCheck(element.returnType); | 21617 _addTypeToCheck(element.returnType); |
| 21618 return super.visitFunctionTypeAliasElement(element); | 21618 return super.visitFunctionTypeAliasElement(element); |
| 21619 } | 21619 } |
| 21620 | 21620 |
| 21621 Object visitParameterElement(ParameterElement element) { | 21621 Object visitParameterElement(ParameterElement element) { |
| 21622 addTypeToCheck(element.type); | 21622 _addTypeToCheck(element.type); |
| 21623 return super.visitParameterElement(element); | 21623 return super.visitParameterElement(element); |
| 21624 } | 21624 } |
| 21625 | 21625 |
| 21626 Object visitTypeParameterElement(TypeParameterElement element) { | 21626 Object visitTypeParameterElement(TypeParameterElement element) { |
| 21627 addTypeToCheck(element.bound); | 21627 _addTypeToCheck(element.bound); |
| 21628 return super.visitTypeParameterElement(element); | 21628 return super.visitTypeParameterElement(element); |
| 21629 } | 21629 } |
| 21630 | 21630 |
| 21631 Object visitVariableElement(VariableElement element) { | 21631 Object visitVariableElement(VariableElement element) { |
| 21632 addTypeToCheck(element.type); | 21632 _addTypeToCheck(element.type); |
| 21633 return super.visitVariableElement(element); | 21633 return super.visitVariableElement(element); |
| 21634 } | 21634 } |
| 21635 | 21635 |
| 21636 void addTypeToCheck(Type2 type) { | 21636 void _addTypeToCheck(Type2 type) { |
| 21637 if (type == null) { | 21637 if (type == null) { |
| 21638 return; | 21638 return; |
| 21639 } | 21639 } |
| 21640 Element element = type.element; | 21640 Element element = type.element; |
| 21641 // it is OK to reference target from class | 21641 // it is OK to reference target from class |
| 21642 if (_inClass && target == element) { | 21642 if (_inClass && target == element) { |
| 21643 return; | 21643 return; |
| 21644 } | 21644 } |
| 21645 // schedule for checking | 21645 // schedule for checking |
| 21646 toCheck.add(element); | 21646 toCheck.add(element); |
| 21647 // type arguments | 21647 // type arguments |
| 21648 if (type is InterfaceType) { | 21648 if (type is InterfaceType) { |
| 21649 InterfaceType interfaceType = type; | 21649 InterfaceType interfaceType = type; |
| 21650 for (Type2 typeArgument in interfaceType.typeArguments) { | 21650 for (Type2 typeArgument in interfaceType.typeArguments) { |
| 21651 addTypeToCheck(typeArgument); | 21651 _addTypeToCheck(typeArgument); |
| 21652 } | 21652 } |
| 21653 } | 21653 } |
| 21654 } | 21654 } |
| 21655 } | 21655 } |
| 21656 | 21656 |
| 21657 /** | 21657 /** |
| 21658 * The enumeration `ResolverErrorCode` defines the error codes used for errors d
etected by the | 21658 * The enumeration `ResolverErrorCode` defines the error codes used for errors d
etected by the |
| 21659 * resolver. The convention for this class is for the name of the error code to
indicate the problem | 21659 * resolver. The convention for this class is for the name of the error code to
indicate the problem |
| 21660 * that caused the error to be generated and for the error message to explain wh
at is wrong and, | 21660 * that caused the error to be generated and for the error message to explain wh
at is wrong and, |
| 21661 * when appropriate, how the problem can be corrected. | 21661 * when appropriate, how the problem can be corrected. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21704 * @param correction the template used to create the correction to be displaye
d for the error | 21704 * @param correction the template used to create the correction to be displaye
d for the error |
| 21705 */ | 21705 */ |
| 21706 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri
ng correction) : super(name, ordinal) { | 21706 ResolverErrorCode.con2(String name, int ordinal, this.type, this.message, Stri
ng correction) : super(name, ordinal) { |
| 21707 this.correction9 = correction; | 21707 this.correction9 = correction; |
| 21708 } | 21708 } |
| 21709 | 21709 |
| 21710 String get correction => correction9; | 21710 String get correction => correction9; |
| 21711 | 21711 |
| 21712 ErrorSeverity get errorSeverity => type.severity; | 21712 ErrorSeverity get errorSeverity => type.severity; |
| 21713 } | 21713 } |
| OLD | NEW |