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 library engine.resolver; | 5 library engine.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'ast.dart'; | 9 import 'ast.dart'; |
10 import 'constant.dart'; | 10 import 'constant.dart'; |
(...skipping 26 matching lines...) Expand all Loading... |
37 typedef ResolverVisitor ResolverVisitorFactory( | 37 typedef ResolverVisitor ResolverVisitorFactory( |
38 Library library, Source source, TypeProvider typeProvider); | 38 Library library, Source source, TypeProvider typeProvider); |
39 | 39 |
40 typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor); | 40 typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor); |
41 | 41 |
42 typedef TypeResolverVisitor TypeResolverVisitorFactory( | 42 typedef TypeResolverVisitor TypeResolverVisitorFactory( |
43 Library library, Source source, TypeProvider typeProvider); | 43 Library library, Source source, TypeProvider typeProvider); |
44 | 44 |
45 typedef void VoidFunction(); | 45 typedef void VoidFunction(); |
46 | 46 |
| 47 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited); |
| 48 |
| 49 typedef bool _SubtypeChecker<T>(T t1, T t2); |
| 50 |
47 /** | 51 /** |
48 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for | 52 * Instances of the class `BestPracticesVerifier` traverse an AST structure look
ing for |
49 * violations of Dart best practices. | 53 * violations of Dart best practices. |
50 */ | 54 */ |
51 class BestPracticesVerifier extends RecursiveAstVisitor<Object> { | 55 class BestPracticesVerifier extends RecursiveAstVisitor<Object> { |
52 // static String _HASHCODE_GETTER_NAME = "hashCode"; | 56 // static String _HASHCODE_GETTER_NAME = "hashCode"; |
53 | 57 |
54 static String _NULL_TYPE_NAME = "Null"; | 58 static String _NULL_TYPE_NAME = "Null"; |
55 | 59 |
56 static String _TO_INT_METHOD_NAME = "toInt"; | 60 static String _TO_INT_METHOD_NAME = "toInt"; |
57 | 61 |
58 /** | 62 /** |
59 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of | 63 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of |
60 * a class. | 64 * a class. |
61 */ | 65 */ |
62 ClassElement _enclosingClass; | 66 ClassElement _enclosingClass; |
63 | 67 |
64 /** | 68 /** |
65 * The error reporter by which errors will be reported. | 69 * The error reporter by which errors will be reported. |
66 */ | 70 */ |
67 final ErrorReporter _errorReporter; | 71 final ErrorReporter _errorReporter; |
68 | 72 |
69 /** | 73 /** |
70 * The type Future<Null>, which is needed for determining whether it is safe | 74 * The type Future<Null>, which is needed for determining whether it is safe |
71 * to have a bare "return;" in an async method. | 75 * to have a bare "return;" in an async method. |
72 */ | 76 */ |
73 final InterfaceType _futureNullType; | 77 final InterfaceType _futureNullType; |
74 | 78 |
75 /** | 79 /** |
| 80 * The type system primitives |
| 81 */ |
| 82 TypeSystem _typeSystem; |
| 83 |
| 84 /** |
76 * Create a new instance of the [BestPracticesVerifier]. | 85 * Create a new instance of the [BestPracticesVerifier]. |
77 * | 86 * |
78 * @param errorReporter the error reporter | 87 * @param errorReporter the error reporter |
79 */ | 88 */ |
80 BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider) | 89 BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider, |
81 : _futureNullType = typeProvider.futureNullType; | 90 {TypeSystem typeSystem}) |
| 91 : _futureNullType = typeProvider.futureNullType, |
| 92 _typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl(); |
82 | 93 |
83 @override | 94 @override |
84 Object visitArgumentList(ArgumentList node) { | 95 Object visitArgumentList(ArgumentList node) { |
85 _checkForArgumentTypesNotAssignableInList(node); | 96 _checkForArgumentTypesNotAssignableInList(node); |
86 return super.visitArgumentList(node); | 97 return super.visitArgumentList(node); |
87 } | 98 } |
88 | 99 |
89 @override | 100 @override |
90 Object visitAsExpression(AsExpression node) { | 101 Object visitAsExpression(AsExpression node) { |
91 _checkForUnnecessaryCast(node); | 102 _checkForUnnecessaryCast(node); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 * | 297 * |
287 * @param expression the expression to evaluate | 298 * @param expression the expression to evaluate |
288 * @param expectedStaticType the expected static type of the parameter | 299 * @param expectedStaticType the expected static type of the parameter |
289 * @param actualStaticType the actual static type of the argument | 300 * @param actualStaticType the actual static type of the argument |
290 * @param expectedPropagatedType the expected propagated type of the parameter
, may be | 301 * @param expectedPropagatedType the expected propagated type of the parameter
, may be |
291 * `null` | 302 * `null` |
292 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` | 303 * @param actualPropagatedType the expected propagated type of the parameter,
may be `null` |
293 * @return `true` if and only if an hint code is generated on the passed node | 304 * @return `true` if and only if an hint code is generated on the passed node |
294 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 305 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
295 */ | 306 */ |
296 bool _checkForArgumentTypeNotAssignable(Expression expression, | 307 bool _checkForArgumentTypeNotAssignable( |
297 DartType expectedStaticType, DartType actualStaticType, | 308 Expression expression, |
298 DartType expectedPropagatedType, DartType actualPropagatedType, | 309 DartType expectedStaticType, |
| 310 DartType actualStaticType, |
| 311 DartType expectedPropagatedType, |
| 312 DartType actualPropagatedType, |
299 ErrorCode hintCode) { | 313 ErrorCode hintCode) { |
300 // | 314 // |
301 // Warning case: test static type information | 315 // Warning case: test static type information |
302 // | 316 // |
303 if (actualStaticType != null && expectedStaticType != null) { | 317 if (actualStaticType != null && expectedStaticType != null) { |
304 if (!actualStaticType.isAssignableTo(expectedStaticType)) { | 318 if (!_typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) { |
305 // A warning was created in the ErrorVerifier, return false, don't | 319 // A warning was created in the ErrorVerifier, return false, don't |
306 // create a hint when a warning has already been created. | 320 // create a hint when a warning has already been created. |
307 return false; | 321 return false; |
308 } | 322 } |
309 } | 323 } |
310 // | 324 // |
311 // Hint case: test propagated type information | 325 // Hint case: test propagated type information |
312 // | 326 // |
313 // Compute the best types to use. | 327 // Compute the best types to use. |
314 DartType expectedBestType = expectedPropagatedType != null | 328 DartType expectedBestType = expectedPropagatedType != null |
315 ? expectedPropagatedType | 329 ? expectedPropagatedType |
316 : expectedStaticType; | 330 : expectedStaticType; |
317 DartType actualBestType = | 331 DartType actualBestType = |
318 actualPropagatedType != null ? actualPropagatedType : actualStaticType; | 332 actualPropagatedType != null ? actualPropagatedType : actualStaticType; |
319 if (actualBestType != null && expectedBestType != null) { | 333 if (actualBestType != null && expectedBestType != null) { |
320 if (!actualBestType.isAssignableTo(expectedBestType)) { | 334 if (!_typeSystem.isAssignableTo(actualBestType, expectedBestType)) { |
321 _errorReporter.reportTypeErrorForNode( | 335 _errorReporter.reportTypeErrorForNode( |
322 hintCode, expression, [actualBestType, expectedBestType]); | 336 hintCode, expression, [actualBestType, expectedBestType]); |
323 return true; | 337 return true; |
324 } | 338 } |
325 } | 339 } |
326 return false; | 340 return false; |
327 } | 341 } |
328 | 342 |
329 /** | 343 /** |
330 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 344 * This verifies that the passed argument can be assigned to its corresponding
parameter. |
331 * | 345 * |
332 * This method corresponds to ErrorCode.checkForArgumentTypeNotAssignableForAr
gument. | 346 * This method corresponds to ErrorCode.checkForArgumentTypeNotAssignableForAr
gument. |
333 * | 347 * |
334 * @param argument the argument to evaluate | 348 * @param argument the argument to evaluate |
335 * @return `true` if and only if an hint code is generated on the passed node | 349 * @return `true` if and only if an hint code is generated on the passed node |
336 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 350 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
337 */ | 351 */ |
338 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { | 352 bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) { |
339 if (argument == null) { | 353 if (argument == null) { |
340 return false; | 354 return false; |
341 } | 355 } |
342 ParameterElement staticParameterElement = argument.staticParameterElement; | 356 ParameterElement staticParameterElement = argument.staticParameterElement; |
343 DartType staticParameterType = | 357 DartType staticParameterType = |
344 staticParameterElement == null ? null : staticParameterElement.type; | 358 staticParameterElement == null ? null : staticParameterElement.type; |
345 ParameterElement propagatedParameterElement = | 359 ParameterElement propagatedParameterElement = |
346 argument.propagatedParameterElement; | 360 argument.propagatedParameterElement; |
347 DartType propagatedParameterType = propagatedParameterElement == null | 361 DartType propagatedParameterType = propagatedParameterElement == null |
348 ? null | 362 ? null |
349 : propagatedParameterElement.type; | 363 : propagatedParameterElement.type; |
350 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, | 364 return _checkForArgumentTypeNotAssignableWithExpectedTypes( |
351 staticParameterType, propagatedParameterType, | 365 argument, |
| 366 staticParameterType, |
| 367 propagatedParameterType, |
352 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | 368 HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
353 } | 369 } |
354 | 370 |
355 /** | 371 /** |
356 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 372 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
357 * | 373 * |
358 * This method corresponds to ErrorCode.checkForArgumentTypeNotAssignableWithE
xpectedTypes. | 374 * This method corresponds to ErrorCode.checkForArgumentTypeNotAssignableWithE
xpectedTypes. |
359 * | 375 * |
360 * @param expression the expression to evaluate | 376 * @param expression the expression to evaluate |
361 * @param expectedStaticType the expected static type | 377 * @param expectedStaticType the expected static type |
362 * @param expectedPropagatedType the expected propagated type, may be `null` | 378 * @param expectedPropagatedType the expected propagated type, may be `null` |
363 * @return `true` if and only if an hint code is generated on the passed node | 379 * @return `true` if and only if an hint code is generated on the passed node |
364 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 380 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
365 */ | 381 */ |
366 bool _checkForArgumentTypeNotAssignableWithExpectedTypes( | 382 bool _checkForArgumentTypeNotAssignableWithExpectedTypes( |
367 Expression expression, DartType expectedStaticType, | 383 Expression expression, |
368 DartType expectedPropagatedType, ErrorCode errorCode) => | 384 DartType expectedStaticType, |
369 _checkForArgumentTypeNotAssignable(expression, expectedStaticType, | 385 DartType expectedPropagatedType, |
370 expression.staticType, expectedPropagatedType, | 386 ErrorCode errorCode) => |
371 expression.propagatedType, errorCode); | 387 _checkForArgumentTypeNotAssignable( |
| 388 expression, |
| 389 expectedStaticType, |
| 390 expression.staticType, |
| 391 expectedPropagatedType, |
| 392 expression.propagatedType, |
| 393 errorCode); |
372 | 394 |
373 /** | 395 /** |
374 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. | 396 * This verifies that the passed arguments can be assigned to their correspond
ing parameters. |
375 * | 397 * |
376 * This method corresponds to ErrorCode.checkForArgumentTypesNotAssignableInLi
st. | 398 * This method corresponds to ErrorCode.checkForArgumentTypesNotAssignableInLi
st. |
377 * | 399 * |
378 * @param node the arguments to evaluate | 400 * @param node the arguments to evaluate |
379 * @return `true` if and only if an hint code is generated on the passed node | 401 * @return `true` if and only if an hint code is generated on the passed node |
380 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 402 * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
381 */ | 403 */ |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 */ | 523 */ |
502 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { | 524 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { |
503 if (lhs == null || rhs == null) { | 525 if (lhs == null || rhs == null) { |
504 return false; | 526 return false; |
505 } | 527 } |
506 VariableElement leftVariableElement = ErrorVerifier.getVariableElement(lhs); | 528 VariableElement leftVariableElement = ErrorVerifier.getVariableElement(lhs); |
507 DartType leftType = (leftVariableElement == null) | 529 DartType leftType = (leftVariableElement == null) |
508 ? ErrorVerifier.getStaticType(lhs) | 530 ? ErrorVerifier.getStaticType(lhs) |
509 : leftVariableElement.type; | 531 : leftVariableElement.type; |
510 DartType staticRightType = ErrorVerifier.getStaticType(rhs); | 532 DartType staticRightType = ErrorVerifier.getStaticType(rhs); |
511 if (!staticRightType.isAssignableTo(leftType)) { | 533 if (!_typeSystem.isAssignableTo(staticRightType, leftType)) { |
512 // The warning was generated on this rhs | 534 // The warning was generated on this rhs |
513 return false; | 535 return false; |
514 } | 536 } |
515 // Test for, and then generate the hint | 537 // Test for, and then generate the hint |
516 DartType bestRightType = rhs.bestType; | 538 DartType bestRightType = rhs.bestType; |
517 if (leftType != null && bestRightType != null) { | 539 if (leftType != null && bestRightType != null) { |
518 if (!bestRightType.isAssignableTo(leftType)) { | 540 if (!_typeSystem.isAssignableTo(bestRightType, leftType)) { |
519 _errorReporter.reportTypeErrorForNode( | 541 _errorReporter.reportTypeErrorForNode( |
520 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]); | 542 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]); |
521 return true; | 543 return true; |
522 } | 544 } |
523 } | 545 } |
524 return false; | 546 return false; |
525 } | 547 } |
526 | 548 |
527 /** | 549 /** |
528 * Check that the imported library does not define a loadLibrary function. The
import has already | 550 * Check that the imported library does not define a loadLibrary function. The
import has already |
529 * been determined to be deferred when this is called. | 551 * been determined to be deferred when this is called. |
530 * | 552 * |
531 * @param node the import directive to evaluate | 553 * @param node the import directive to evaluate |
532 * @param importElement the [ImportElement] retrieved from the node | 554 * @param importElement the [ImportElement] retrieved from the node |
533 * @return `true` if and only if an error code is generated on the passed node | 555 * @return `true` if and only if an error code is generated on the passed node |
534 * See [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]. | 556 * See [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]. |
535 */ | 557 */ |
536 bool _checkForLoadLibraryFunction( | 558 bool _checkForLoadLibraryFunction( |
537 ImportDirective node, ImportElement importElement) { | 559 ImportDirective node, ImportElement importElement) { |
538 LibraryElement importedLibrary = importElement.importedLibrary; | 560 LibraryElement importedLibrary = importElement.importedLibrary; |
539 if (importedLibrary == null) { | 561 if (importedLibrary == null) { |
540 return false; | 562 return false; |
541 } | 563 } |
542 if (importedLibrary.hasLoadLibraryFunction) { | 564 if (importedLibrary.hasLoadLibraryFunction) { |
543 _errorReporter.reportErrorForNode( | 565 _errorReporter.reportErrorForNode( |
544 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node, | 566 HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, |
| 567 node, |
545 [importedLibrary.name]); | 568 [importedLibrary.name]); |
546 return true; | 569 return true; |
547 } | 570 } |
548 return false; | 571 return false; |
549 } | 572 } |
550 | 573 |
551 /** | 574 /** |
552 * Generate a hint for functions or methods that have a return type, but do no
t have a return | 575 * Generate a hint for functions or methods that have a return type, but do no
t have a return |
553 * statement on all branches. At the end of blocks with no return, Dart implic
itly returns | 576 * statement on all branches. At the end of blocks with no return, Dart implic
itly returns |
554 * `null`, avoiding these implicit returns is considered a best practice. | 577 * `null`, avoiding these implicit returns is considered a best practice. |
(...skipping 19 matching lines...) Expand all Loading... |
574 if (body.isGenerator) { | 597 if (body.isGenerator) { |
575 return false; | 598 return false; |
576 } | 599 } |
577 // Check that the type is resolvable, and is not "void" | 600 // Check that the type is resolvable, and is not "void" |
578 DartType returnTypeType = returnType.type; | 601 DartType returnTypeType = returnType.type; |
579 if (returnTypeType == null || returnTypeType.isVoid) { | 602 if (returnTypeType == null || returnTypeType.isVoid) { |
580 return false; | 603 return false; |
581 } | 604 } |
582 // For async, give no hint if Future<Null> is assignable to the return | 605 // For async, give no hint if Future<Null> is assignable to the return |
583 // type. | 606 // type. |
584 if (body.isAsynchronous && _futureNullType.isAssignableTo(returnTypeType)) { | 607 if (body.isAsynchronous && |
| 608 _typeSystem.isAssignableTo(_futureNullType, returnTypeType)) { |
585 return false; | 609 return false; |
586 } | 610 } |
587 // Check the block for a return statement, if not, create the hint | 611 // Check the block for a return statement, if not, create the hint |
588 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; | 612 BlockFunctionBody blockFunctionBody = body as BlockFunctionBody; |
589 if (!ExitDetector.exits(blockFunctionBody)) { | 613 if (!ExitDetector.exits(blockFunctionBody)) { |
590 _errorReporter.reportErrorForNode( | 614 _errorReporter.reportErrorForNode( |
591 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); | 615 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); |
592 return true; | 616 return true; |
593 } | 617 } |
594 return false; | 618 return false; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 if (typeElement == null) { | 757 if (typeElement == null) { |
734 throw new IllegalArgumentException("class element cannot be null"); | 758 throw new IllegalArgumentException("class element cannot be null"); |
735 } | 759 } |
736 _defineMembers(typeElement); | 760 _defineMembers(typeElement); |
737 } | 761 } |
738 | 762 |
739 @override | 763 @override |
740 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 764 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
741 if (existing is PropertyAccessorElement && duplicate is MethodElement) { | 765 if (existing is PropertyAccessorElement && duplicate is MethodElement) { |
742 if (existing.nameOffset < duplicate.nameOffset) { | 766 if (existing.nameOffset < duplicate.nameOffset) { |
743 return new AnalysisError(duplicate.source, duplicate.nameOffset, | 767 return new AnalysisError( |
744 duplicate.displayName.length, | 768 duplicate.source, |
| 769 duplicate.nameOffset, |
| 770 duplicate.nameLength, |
745 CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME, | 771 CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME, |
746 [existing.displayName]); | 772 [existing.displayName]); |
747 } else { | 773 } else { |
748 return new AnalysisError(existing.source, existing.nameOffset, | 774 return new AnalysisError( |
749 existing.displayName.length, | 775 existing.source, |
| 776 existing.nameOffset, |
| 777 existing.nameLength, |
750 CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME, | 778 CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME, |
751 [existing.displayName]); | 779 [existing.displayName]); |
752 } | 780 } |
753 } | 781 } |
754 return super.getErrorForDuplicate(existing, duplicate); | 782 return super.getErrorForDuplicate(existing, duplicate); |
755 } | 783 } |
756 | 784 |
757 /** | 785 /** |
758 * Define the instance members defined by the class. | 786 * Define the instance members defined by the class. |
759 * | 787 * |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 * The error reporter by which errors will be reported. | 844 * The error reporter by which errors will be reported. |
817 */ | 845 */ |
818 final ErrorReporter _errorReporter; | 846 final ErrorReporter _errorReporter; |
819 | 847 |
820 /** | 848 /** |
821 * The type provider used to access the known types. | 849 * The type provider used to access the known types. |
822 */ | 850 */ |
823 final TypeProvider _typeProvider; | 851 final TypeProvider _typeProvider; |
824 | 852 |
825 /** | 853 /** |
| 854 * The type system in use. |
| 855 */ |
| 856 final TypeSystem _typeSystem; |
| 857 |
| 858 /** |
826 * The set of variables declared using '-D' on the command line. | 859 * The set of variables declared using '-D' on the command line. |
827 */ | 860 */ |
828 final DeclaredVariables declaredVariables; | 861 final DeclaredVariables declaredVariables; |
829 | 862 |
830 /** | 863 /** |
831 * The type representing the type 'bool'. | 864 * The type representing the type 'bool'. |
832 */ | 865 */ |
833 InterfaceType _boolType; | 866 InterfaceType _boolType; |
834 | 867 |
835 /** | 868 /** |
(...skipping 14 matching lines...) Expand all Loading... |
850 /** | 883 /** |
851 * The current library that is being analyzed. | 884 * The current library that is being analyzed. |
852 */ | 885 */ |
853 final LibraryElement _currentLibrary; | 886 final LibraryElement _currentLibrary; |
854 | 887 |
855 /** | 888 /** |
856 * Initialize a newly created constant verifier. | 889 * Initialize a newly created constant verifier. |
857 * | 890 * |
858 * @param errorReporter the error reporter by which errors will be reported | 891 * @param errorReporter the error reporter by which errors will be reported |
859 */ | 892 */ |
860 ConstantVerifier(this._errorReporter, this._currentLibrary, | 893 ConstantVerifier(this._errorReporter, LibraryElement currentLibrary, |
861 this._typeProvider, this.declaredVariables) { | 894 this._typeProvider, this.declaredVariables) |
| 895 : _currentLibrary = currentLibrary, |
| 896 _typeSystem = currentLibrary.context.typeSystem { |
862 this._boolType = _typeProvider.boolType; | 897 this._boolType = _typeProvider.boolType; |
863 this._intType = _typeProvider.intType; | 898 this._intType = _typeProvider.intType; |
864 this._numType = _typeProvider.numType; | 899 this._numType = _typeProvider.numType; |
865 this._stringType = _typeProvider.stringType; | 900 this._stringType = _typeProvider.stringType; |
866 } | 901 } |
867 | 902 |
868 @override | 903 @override |
869 Object visitAnnotation(Annotation node) { | 904 Object visitAnnotation(Annotation node) { |
870 super.visitAnnotation(node); | 905 super.visitAnnotation(node); |
871 // check annotation creation | 906 // check annotation creation |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 } | 944 } |
910 | 945 |
911 @override | 946 @override |
912 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 947 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
913 if (node.isConst) { | 948 if (node.isConst) { |
914 // We need to evaluate the constant to see if any errors occur during its | 949 // We need to evaluate the constant to see if any errors occur during its |
915 // evaluation. | 950 // evaluation. |
916 ConstructorElement constructor = node.staticElement; | 951 ConstructorElement constructor = node.staticElement; |
917 if (constructor != null) { | 952 if (constructor != null) { |
918 ConstantEvaluationEngine evaluationEngine = | 953 ConstantEvaluationEngine evaluationEngine = |
919 new ConstantEvaluationEngine(_typeProvider, declaredVariables); | 954 new ConstantEvaluationEngine(_typeProvider, declaredVariables, |
| 955 typeSystem: _typeSystem); |
920 ConstantVisitor constantVisitor = | 956 ConstantVisitor constantVisitor = |
921 new ConstantVisitor(evaluationEngine, _errorReporter); | 957 new ConstantVisitor(evaluationEngine, _errorReporter); |
922 evaluationEngine.evaluateConstructorCall(node, | 958 evaluationEngine.evaluateConstructorCall( |
923 node.argumentList.arguments, constructor, constantVisitor, | 959 node, |
| 960 node.argumentList.arguments, |
| 961 constructor, |
| 962 constantVisitor, |
924 _errorReporter); | 963 _errorReporter); |
925 } | 964 } |
926 } | 965 } |
927 _validateInstanceCreationArguments(node); | 966 _validateInstanceCreationArguments(node); |
928 return super.visitInstanceCreationExpression(node); | 967 return super.visitInstanceCreationExpression(node); |
929 } | 968 } |
930 | 969 |
931 @override | 970 @override |
932 Object visitListLiteral(ListLiteral node) { | 971 Object visitListLiteral(ListLiteral node) { |
933 super.visitListLiteral(node); | 972 super.visitListLiteral(node); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY); | 1008 CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY); |
970 if (keys.contains(keyResult)) { | 1009 if (keys.contains(keyResult)) { |
971 invalidKeys.add(key); | 1010 invalidKeys.add(key); |
972 } else { | 1011 } else { |
973 keys.add(keyResult); | 1012 keys.add(keyResult); |
974 } | 1013 } |
975 DartType type = keyResult.type; | 1014 DartType type = keyResult.type; |
976 if (_implementsEqualsWhenNotAllowed(type)) { | 1015 if (_implementsEqualsWhenNotAllowed(type)) { |
977 _errorReporter.reportErrorForNode( | 1016 _errorReporter.reportErrorForNode( |
978 CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQ
UALS, | 1017 CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQ
UALS, |
979 key, [type.displayName]); | 1018 key, |
| 1019 [type.displayName]); |
980 } | 1020 } |
981 } | 1021 } |
982 } else { | 1022 } else { |
983 // Note: we throw the errors away because this isn't actually a const. | 1023 // Note: we throw the errors away because this isn't actually a const. |
984 AnalysisErrorListener errorListener = | 1024 AnalysisErrorListener errorListener = |
985 AnalysisErrorListener.NULL_LISTENER; | 1025 AnalysisErrorListener.NULL_LISTENER; |
986 ErrorReporter subErrorReporter = | 1026 ErrorReporter subErrorReporter = |
987 new ErrorReporter(errorListener, _errorReporter.source); | 1027 new ErrorReporter(errorListener, _errorReporter.source); |
988 DartObjectImpl result = key.accept(new ConstantVisitor( | 1028 DartObjectImpl result = key.accept(new ConstantVisitor( |
989 new ConstantEvaluationEngine(_typeProvider, declaredVariables), | 1029 new ConstantEvaluationEngine(_typeProvider, declaredVariables, |
| 1030 typeSystem: _typeSystem), |
990 subErrorReporter)); | 1031 subErrorReporter)); |
991 if (result != null) { | 1032 if (result != null) { |
992 if (keys.contains(result)) { | 1033 if (keys.contains(result)) { |
993 invalidKeys.add(key); | 1034 invalidKeys.add(key); |
994 } else { | 1035 } else { |
995 keys.add(result); | 1036 keys.add(result); |
996 } | 1037 } |
997 } else { | 1038 } else { |
998 reportEqualKeys = false; | 1039 reportEqualKeys = false; |
999 } | 1040 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 _reportErrorIfFromDeferredLibrary(expression, | 1074 _reportErrorIfFromDeferredLibrary(expression, |
1034 CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LI
BRARY); | 1075 CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LI
BRARY); |
1035 DartObject value = caseResult; | 1076 DartObject value = caseResult; |
1036 if (firstType == null) { | 1077 if (firstType == null) { |
1037 firstType = value.type; | 1078 firstType = value.type; |
1038 } else { | 1079 } else { |
1039 DartType nType = value.type; | 1080 DartType nType = value.type; |
1040 if (firstType != nType) { | 1081 if (firstType != nType) { |
1041 _errorReporter.reportErrorForNode( | 1082 _errorReporter.reportErrorForNode( |
1042 CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES, | 1083 CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES, |
1043 expression, [expression.toSource(), firstType.displayName]); | 1084 expression, |
| 1085 [expression.toSource(), firstType.displayName]); |
1044 foundError = true; | 1086 foundError = true; |
1045 } | 1087 } |
1046 } | 1088 } |
1047 } | 1089 } |
1048 } | 1090 } |
1049 } | 1091 } |
1050 if (!foundError) { | 1092 if (!foundError) { |
1051 _checkForCaseExpressionTypeImplementsEquals(node, firstType); | 1093 _checkForCaseExpressionTypeImplementsEquals(node, firstType); |
1052 } | 1094 } |
1053 return super.visitSwitchStatement(node); | 1095 return super.visitSwitchStatement(node); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 * See [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]. | 1128 * See [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]. |
1087 */ | 1129 */ |
1088 bool _checkForCaseExpressionTypeImplementsEquals( | 1130 bool _checkForCaseExpressionTypeImplementsEquals( |
1089 SwitchStatement node, DartType type) { | 1131 SwitchStatement node, DartType type) { |
1090 if (!_implementsEqualsWhenNotAllowed(type)) { | 1132 if (!_implementsEqualsWhenNotAllowed(type)) { |
1091 return false; | 1133 return false; |
1092 } | 1134 } |
1093 // report error | 1135 // report error |
1094 _errorReporter.reportErrorForToken( | 1136 _errorReporter.reportErrorForToken( |
1095 CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, | 1137 CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS, |
1096 node.switchKeyword, [type.displayName]); | 1138 node.switchKeyword, |
| 1139 [type.displayName]); |
1097 return true; | 1140 return true; |
1098 } | 1141 } |
1099 | 1142 |
1100 /** | 1143 /** |
1101 * @return `true` if given [Type] implements operator <i>==</i>, and it is not | 1144 * @return `true` if given [Type] implements operator <i>==</i>, and it is not |
1102 * <i>int</i> or <i>String</i>. | 1145 * <i>int</i> or <i>String</i>. |
1103 */ | 1146 */ |
1104 bool _implementsEqualsWhenNotAllowed(DartType type) { | 1147 bool _implementsEqualsWhenNotAllowed(DartType type) { |
1105 // ignore int or String | 1148 // ignore int or String |
1106 if (type == null || type == _intType || type == _typeProvider.stringType) { | 1149 if (type == null || type == _intType || type == _typeProvider.stringType) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 * | 1226 * |
1184 * @param expression the expression to be validated | 1227 * @param expression the expression to be validated |
1185 * @param errorCode the error code to be used if the expression is not a compi
le time constant | 1228 * @param errorCode the error code to be used if the expression is not a compi
le time constant |
1186 * @return the value of the compile time constant | 1229 * @return the value of the compile time constant |
1187 */ | 1230 */ |
1188 DartObjectImpl _validate(Expression expression, ErrorCode errorCode) { | 1231 DartObjectImpl _validate(Expression expression, ErrorCode errorCode) { |
1189 RecordingErrorListener errorListener = new RecordingErrorListener(); | 1232 RecordingErrorListener errorListener = new RecordingErrorListener(); |
1190 ErrorReporter subErrorReporter = | 1233 ErrorReporter subErrorReporter = |
1191 new ErrorReporter(errorListener, _errorReporter.source); | 1234 new ErrorReporter(errorListener, _errorReporter.source); |
1192 DartObjectImpl result = expression.accept(new ConstantVisitor( | 1235 DartObjectImpl result = expression.accept(new ConstantVisitor( |
1193 new ConstantEvaluationEngine(_typeProvider, declaredVariables), | 1236 new ConstantEvaluationEngine(_typeProvider, declaredVariables, |
| 1237 typeSystem: _typeSystem), |
1194 subErrorReporter)); | 1238 subErrorReporter)); |
1195 _reportErrors(errorListener.errors, errorCode); | 1239 _reportErrors(errorListener.errors, errorCode); |
1196 return result; | 1240 return result; |
1197 } | 1241 } |
1198 | 1242 |
1199 /** | 1243 /** |
1200 * Validate that if the passed arguments are constant expressions. | 1244 * Validate that if the passed arguments are constant expressions. |
1201 * | 1245 * |
1202 * @param argumentList the argument list to evaluate | 1246 * @param argumentList the argument list to evaluate |
1203 */ | 1247 */ |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 in fieldDeclaration.fields.variables) { | 1335 in fieldDeclaration.fields.variables) { |
1292 Expression initializer = variableDeclaration.initializer; | 1336 Expression initializer = variableDeclaration.initializer; |
1293 if (initializer != null) { | 1337 if (initializer != null) { |
1294 // Ignore any errors produced during validation--if the constant | 1338 // Ignore any errors produced during validation--if the constant |
1295 // can't be eavluated we'll just report a single error. | 1339 // can't be eavluated we'll just report a single error. |
1296 AnalysisErrorListener errorListener = | 1340 AnalysisErrorListener errorListener = |
1297 AnalysisErrorListener.NULL_LISTENER; | 1341 AnalysisErrorListener.NULL_LISTENER; |
1298 ErrorReporter subErrorReporter = | 1342 ErrorReporter subErrorReporter = |
1299 new ErrorReporter(errorListener, _errorReporter.source); | 1343 new ErrorReporter(errorListener, _errorReporter.source); |
1300 DartObjectImpl result = initializer.accept(new ConstantVisitor( | 1344 DartObjectImpl result = initializer.accept(new ConstantVisitor( |
1301 new ConstantEvaluationEngine( | 1345 new ConstantEvaluationEngine(_typeProvider, declaredVariables, |
1302 _typeProvider, declaredVariables), subErrorReporter)); | 1346 typeSystem: _typeSystem), |
| 1347 subErrorReporter)); |
1303 if (result == null) { | 1348 if (result == null) { |
1304 _errorReporter.reportErrorForNode( | 1349 _errorReporter.reportErrorForNode( |
1305 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZE
D_BY_NON_CONST, | 1350 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZE
D_BY_NON_CONST, |
1306 errorSite, [variableDeclaration.name.name]); | 1351 errorSite, |
| 1352 [variableDeclaration.name.name]); |
1307 } | 1353 } |
1308 } | 1354 } |
1309 } | 1355 } |
1310 } | 1356 } |
1311 } | 1357 } |
1312 } | 1358 } |
1313 } | 1359 } |
1314 | 1360 |
1315 /** | 1361 /** |
1316 * Validates that the given expression is a compile time constant. | 1362 * Validates that the given expression is a compile time constant. |
1317 * | 1363 * |
1318 * @param parameterElements the elements of parameters of constant constructor
, they are | 1364 * @param parameterElements the elements of parameters of constant constructor
, they are |
1319 * considered as a valid potentially constant expressions | 1365 * considered as a valid potentially constant expressions |
1320 * @param expression the expression to validate | 1366 * @param expression the expression to validate |
1321 */ | 1367 */ |
1322 void _validateInitializerExpression( | 1368 void _validateInitializerExpression( |
1323 List<ParameterElement> parameterElements, Expression expression) { | 1369 List<ParameterElement> parameterElements, Expression expression) { |
1324 RecordingErrorListener errorListener = new RecordingErrorListener(); | 1370 RecordingErrorListener errorListener = new RecordingErrorListener(); |
1325 ErrorReporter subErrorReporter = | 1371 ErrorReporter subErrorReporter = |
1326 new ErrorReporter(errorListener, _errorReporter.source); | 1372 new ErrorReporter(errorListener, _errorReporter.source); |
1327 DartObjectImpl result = expression.accept( | 1373 DartObjectImpl result = expression.accept( |
1328 new _ConstantVerifier_validateInitializerExpression(_typeProvider, | 1374 new _ConstantVerifier_validateInitializerExpression(_typeProvider, |
1329 subErrorReporter, this, parameterElements, declaredVariables)); | 1375 subErrorReporter, this, parameterElements, declaredVariables, |
| 1376 typeSystem: _typeSystem)); |
1330 _reportErrors(errorListener.errors, | 1377 _reportErrors(errorListener.errors, |
1331 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER); | 1378 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER); |
1332 if (result != null) { | 1379 if (result != null) { |
1333 _reportErrorIfFromDeferredLibrary(expression, | 1380 _reportErrorIfFromDeferredLibrary(expression, |
1334 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_L
IBRARY); | 1381 CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_L
IBRARY); |
1335 } | 1382 } |
1336 } | 1383 } |
1337 | 1384 |
1338 /** | 1385 /** |
1339 * Validates that all of the arguments of a constructor initializer are compil
e time constants. | 1386 * Validates that all of the arguments of a constructor initializer are compil
e time constants. |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1444 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f
or cases of | 1491 * Instances of the class `DeadCodeVerifier` traverse an AST structure looking f
or cases of |
1445 * [HintCode.DEAD_CODE]. | 1492 * [HintCode.DEAD_CODE]. |
1446 */ | 1493 */ |
1447 class DeadCodeVerifier extends RecursiveAstVisitor<Object> { | 1494 class DeadCodeVerifier extends RecursiveAstVisitor<Object> { |
1448 /** | 1495 /** |
1449 * The error reporter by which errors will be reported. | 1496 * The error reporter by which errors will be reported. |
1450 */ | 1497 */ |
1451 final ErrorReporter _errorReporter; | 1498 final ErrorReporter _errorReporter; |
1452 | 1499 |
1453 /** | 1500 /** |
| 1501 * The type system for this visitor |
| 1502 */ |
| 1503 final TypeSystem _typeSystem; |
| 1504 |
| 1505 /** |
1454 * Create a new instance of the [DeadCodeVerifier]. | 1506 * Create a new instance of the [DeadCodeVerifier]. |
1455 * | 1507 * |
1456 * @param errorReporter the error reporter | 1508 * @param errorReporter the error reporter |
1457 */ | 1509 */ |
1458 DeadCodeVerifier(this._errorReporter); | 1510 DeadCodeVerifier(this._errorReporter, {TypeSystem typeSystem}) |
| 1511 : this._typeSystem = |
| 1512 (typeSystem != null) ? typeSystem : new TypeSystemImpl(); |
1459 | 1513 |
1460 @override | 1514 @override |
1461 Object visitBinaryExpression(BinaryExpression node) { | 1515 Object visitBinaryExpression(BinaryExpression node) { |
1462 sc.Token operator = node.operator; | 1516 sc.Token operator = node.operator; |
1463 bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND; | 1517 bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND; |
1464 bool isBarBar = operator.type == sc.TokenType.BAR_BAR; | 1518 bool isBarBar = operator.type == sc.TokenType.BAR_BAR; |
1465 if (isAmpAmp || isBarBar) { | 1519 if (isAmpAmp || isBarBar) { |
1466 Expression lhsCondition = node.leftOperand; | 1520 Expression lhsCondition = node.leftOperand; |
1467 if (!_isDebugConstant(lhsCondition)) { | 1521 if (!_isDebugConstant(lhsCondition)) { |
1468 EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition); | 1522 EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 CatchClause nextCatchClause = catchClauses[i + 1]; | 1667 CatchClause nextCatchClause = catchClauses[i + 1]; |
1614 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 1668 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
1615 int offset = nextCatchClause.offset; | 1669 int offset = nextCatchClause.offset; |
1616 int length = lastCatchClause.end - offset; | 1670 int length = lastCatchClause.end - offset; |
1617 _errorReporter.reportErrorForOffset( | 1671 _errorReporter.reportErrorForOffset( |
1618 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); | 1672 HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length); |
1619 return null; | 1673 return null; |
1620 } | 1674 } |
1621 } | 1675 } |
1622 for (DartType type in visitedTypes) { | 1676 for (DartType type in visitedTypes) { |
1623 if (currentType.isSubtypeOf(type)) { | 1677 if (_typeSystem.isSubtypeOf(currentType, type)) { |
1624 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; | 1678 CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1]; |
1625 int offset = catchClause.offset; | 1679 int offset = catchClause.offset; |
1626 int length = lastCatchClause.end - offset; | 1680 int length = lastCatchClause.end - offset; |
1627 _errorReporter.reportErrorForOffset( | 1681 _errorReporter.reportErrorForOffset( |
1628 HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, offset, length, [ | 1682 HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, |
1629 currentType.displayName, | 1683 offset, |
1630 type.displayName | 1684 length, |
1631 ]); | 1685 [currentType.displayName, type.displayName]); |
1632 return null; | 1686 return null; |
1633 } | 1687 } |
1634 } | 1688 } |
1635 visitedTypes.add(currentType); | 1689 visitedTypes.add(currentType); |
1636 } | 1690 } |
1637 _safelyVisit(catchClause); | 1691 _safelyVisit(catchClause); |
1638 } else { | 1692 } else { |
1639 // Found catch clause clause that doesn't have an exception type, | 1693 // Found catch clause clause that doesn't have an exception type, |
1640 // visit the block, but generate an error on any following catch clauses | 1694 // visit the block, but generate an error on any following catch clauses |
1641 // (and don't visit them). | 1695 // (and don't visit them). |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 _findIdentifier(constants, constant.name); | 1972 _findIdentifier(constants, constant.name); |
1919 } | 1973 } |
1920 return super.visitEnumDeclaration(node); | 1974 return super.visitEnumDeclaration(node); |
1921 } | 1975 } |
1922 | 1976 |
1923 @override | 1977 @override |
1924 Object visitExportDirective(ExportDirective node) { | 1978 Object visitExportDirective(ExportDirective node) { |
1925 String uri = _getStringValue(node.uri); | 1979 String uri = _getStringValue(node.uri); |
1926 if (uri != null) { | 1980 if (uri != null) { |
1927 LibraryElement library = _enclosingUnit.library; | 1981 LibraryElement library = _enclosingUnit.library; |
1928 ExportElement exportElement = _findExport(library.exports, | 1982 ExportElement exportElement = _findExport( |
1929 _enclosingUnit.context.sourceFactory.resolveUri( | 1983 library.exports, |
1930 _enclosingUnit.source, uri)); | 1984 _enclosingUnit.context.sourceFactory |
| 1985 .resolveUri(_enclosingUnit.source, uri)); |
1931 node.element = exportElement; | 1986 node.element = exportElement; |
1932 } | 1987 } |
1933 return super.visitExportDirective(node); | 1988 return super.visitExportDirective(node); |
1934 } | 1989 } |
1935 | 1990 |
1936 @override | 1991 @override |
1937 Object visitFieldFormalParameter(FieldFormalParameter node) { | 1992 Object visitFieldFormalParameter(FieldFormalParameter node) { |
1938 if (node.parent is! DefaultFormalParameter) { | 1993 if (node.parent is! DefaultFormalParameter) { |
1939 SimpleIdentifier parameterName = node.identifier; | 1994 SimpleIdentifier parameterName = node.identifier; |
1940 ParameterElement element = _getElementForParameter(node, parameterName); | 1995 ParameterElement element = _getElementForParameter(node, parameterName); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2024 } else { | 2079 } else { |
2025 return super.visitFunctionTypedFormalParameter(node); | 2080 return super.visitFunctionTypedFormalParameter(node); |
2026 } | 2081 } |
2027 } | 2082 } |
2028 | 2083 |
2029 @override | 2084 @override |
2030 Object visitImportDirective(ImportDirective node) { | 2085 Object visitImportDirective(ImportDirective node) { |
2031 String uri = _getStringValue(node.uri); | 2086 String uri = _getStringValue(node.uri); |
2032 if (uri != null) { | 2087 if (uri != null) { |
2033 LibraryElement library = _enclosingUnit.library; | 2088 LibraryElement library = _enclosingUnit.library; |
2034 ImportElement importElement = _findImport(library.imports, | 2089 ImportElement importElement = _findImport( |
2035 _enclosingUnit.context.sourceFactory.resolveUri( | 2090 library.imports, |
2036 _enclosingUnit.source, uri), node.prefix); | 2091 _enclosingUnit.context.sourceFactory |
| 2092 .resolveUri(_enclosingUnit.source, uri), |
| 2093 node.prefix); |
2037 node.element = importElement; | 2094 node.element = importElement; |
2038 } | 2095 } |
2039 return super.visitImportDirective(node); | 2096 return super.visitImportDirective(node); |
2040 } | 2097 } |
2041 | 2098 |
2042 @override | 2099 @override |
2043 Object visitLabeledStatement(LabeledStatement node) { | 2100 Object visitLabeledStatement(LabeledStatement node) { |
2044 for (Label label in node.labels) { | 2101 for (Label label in node.labels) { |
2045 SimpleIdentifier labelName = label.label; | 2102 SimpleIdentifier labelName = label.label; |
2046 _findIdentifier(_enclosingExecutable.labels, labelName); | 2103 _findIdentifier(_enclosingExecutable.labels, labelName); |
(...skipping 30 matching lines...) Expand all Loading... |
2077 return super.visitMethodDeclaration(node); | 2134 return super.visitMethodDeclaration(node); |
2078 } finally { | 2135 } finally { |
2079 _enclosingExecutable = outerExecutable; | 2136 _enclosingExecutable = outerExecutable; |
2080 } | 2137 } |
2081 } | 2138 } |
2082 | 2139 |
2083 @override | 2140 @override |
2084 Object visitPartDirective(PartDirective node) { | 2141 Object visitPartDirective(PartDirective node) { |
2085 String uri = _getStringValue(node.uri); | 2142 String uri = _getStringValue(node.uri); |
2086 if (uri != null) { | 2143 if (uri != null) { |
2087 Source partSource = _enclosingUnit.context.sourceFactory.resolveUri( | 2144 Source partSource = _enclosingUnit.context.sourceFactory |
2088 _enclosingUnit.source, uri); | 2145 .resolveUri(_enclosingUnit.source, uri); |
2089 node.element = _findPart(_enclosingUnit.library.parts, partSource); | 2146 node.element = _findPart(_enclosingUnit.library.parts, partSource); |
2090 } | 2147 } |
2091 return super.visitPartDirective(node); | 2148 return super.visitPartDirective(node); |
2092 } | 2149 } |
2093 | 2150 |
2094 @override | 2151 @override |
2095 Object visitPartOfDirective(PartOfDirective node) { | 2152 Object visitPartOfDirective(PartOfDirective node) { |
2096 node.element = _enclosingUnit.library; | 2153 node.element = _enclosingUnit.library; |
2097 return super.visitPartOfDirective(node); | 2154 return super.visitPartOfDirective(node); |
2098 } | 2155 } |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2397 return null; | 2454 return null; |
2398 } | 2455 } |
2399 | 2456 |
2400 @override | 2457 @override |
2401 Object visitCatchClause(CatchClause node) { | 2458 Object visitCatchClause(CatchClause node) { |
2402 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 2459 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
2403 if (exceptionParameter != null) { | 2460 if (exceptionParameter != null) { |
2404 // exception | 2461 // exception |
2405 LocalVariableElementImpl exception = | 2462 LocalVariableElementImpl exception = |
2406 new LocalVariableElementImpl.forNode(exceptionParameter); | 2463 new LocalVariableElementImpl.forNode(exceptionParameter); |
| 2464 if (node.exceptionType == null) { |
| 2465 exception.hasImplicitType = true; |
| 2466 } |
2407 _currentHolder.addLocalVariable(exception); | 2467 _currentHolder.addLocalVariable(exception); |
2408 exceptionParameter.staticElement = exception; | 2468 exceptionParameter.staticElement = exception; |
2409 // stack trace | 2469 // stack trace |
2410 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; | 2470 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
2411 if (stackTraceParameter != null) { | 2471 if (stackTraceParameter != null) { |
2412 LocalVariableElementImpl stackTrace = | 2472 LocalVariableElementImpl stackTrace = |
2413 new LocalVariableElementImpl.forNode(stackTraceParameter); | 2473 new LocalVariableElementImpl.forNode(stackTraceParameter); |
2414 _currentHolder.addLocalVariable(stackTrace); | 2474 _currentHolder.addLocalVariable(stackTrace); |
2415 stackTraceParameter.staticElement = stackTrace; | 2475 stackTraceParameter.staticElement = stackTrace; |
2416 } | 2476 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2448 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); | 2508 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); |
2449 interfaceType.typeArguments = typeArguments; | 2509 interfaceType.typeArguments = typeArguments; |
2450 element.type = interfaceType; | 2510 element.type = interfaceType; |
2451 List<ConstructorElement> constructors = holder.constructors; | 2511 List<ConstructorElement> constructors = holder.constructors; |
2452 if (constructors.length == 0) { | 2512 if (constructors.length == 0) { |
2453 // | 2513 // |
2454 // Create the default constructor. | 2514 // Create the default constructor. |
2455 // | 2515 // |
2456 constructors = _createDefaultConstructors(interfaceType); | 2516 constructors = _createDefaultConstructors(interfaceType); |
2457 } | 2517 } |
| 2518 _setDocRange(element, node); |
2458 element.abstract = node.isAbstract; | 2519 element.abstract = node.isAbstract; |
2459 element.accessors = holder.accessors; | 2520 element.accessors = holder.accessors; |
2460 element.constructors = constructors; | 2521 element.constructors = constructors; |
2461 element.fields = holder.fields; | 2522 element.fields = holder.fields; |
2462 element.methods = holder.methods; | 2523 element.methods = holder.methods; |
2463 element.typeParameters = typeParameters; | 2524 element.typeParameters = typeParameters; |
2464 element.validMixin = _isValidMixin; | 2525 element.validMixin = _isValidMixin; |
2465 int functionTypeCount = _functionTypesToFix.length; | 2526 int functionTypeCount = _functionTypesToFix.length; |
2466 for (int i = 0; i < functionTypeCount; i++) { | 2527 for (int i = 0; i < functionTypeCount; i++) { |
2467 _functionTypesToFix[i].typeArguments = typeArguments; | 2528 _functionTypesToFix[i].typeArguments = typeArguments; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2521 _inFunction = true; | 2582 _inFunction = true; |
2522 try { | 2583 try { |
2523 _visitChildren(holder, node); | 2584 _visitChildren(holder, node); |
2524 } finally { | 2585 } finally { |
2525 _inFunction = wasInFunction; | 2586 _inFunction = wasInFunction; |
2526 } | 2587 } |
2527 FunctionBody body = node.body; | 2588 FunctionBody body = node.body; |
2528 SimpleIdentifier constructorName = node.name; | 2589 SimpleIdentifier constructorName = node.name; |
2529 ConstructorElementImpl element = | 2590 ConstructorElementImpl element = |
2530 new ConstructorElementImpl.forNode(constructorName); | 2591 new ConstructorElementImpl.forNode(constructorName); |
| 2592 _setDocRange(element, node); |
2531 if (node.externalKeyword != null) { | 2593 if (node.externalKeyword != null) { |
2532 element.external = true; | 2594 element.external = true; |
2533 } | 2595 } |
2534 if (node.factoryKeyword != null) { | 2596 if (node.factoryKeyword != null) { |
2535 element.factory = true; | 2597 element.factory = true; |
2536 } | 2598 } |
2537 element.functions = holder.functions; | 2599 element.functions = holder.functions; |
2538 element.labels = holder.labels; | 2600 element.labels = holder.labels; |
2539 element.localVariables = holder.localVariables; | 2601 element.localVariables = holder.localVariables; |
2540 element.parameters = holder.parameters; | 2602 element.parameters = holder.parameters; |
(...skipping 25 matching lines...) Expand all Loading... |
2566 Object visitDeclaredIdentifier(DeclaredIdentifier node) { | 2628 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
2567 SimpleIdentifier variableName = node.identifier; | 2629 SimpleIdentifier variableName = node.identifier; |
2568 LocalVariableElementImpl element = | 2630 LocalVariableElementImpl element = |
2569 new LocalVariableElementImpl.forNode(variableName); | 2631 new LocalVariableElementImpl.forNode(variableName); |
2570 ForEachStatement statement = node.parent as ForEachStatement; | 2632 ForEachStatement statement = node.parent as ForEachStatement; |
2571 int declarationEnd = node.offset + node.length; | 2633 int declarationEnd = node.offset + node.length; |
2572 int statementEnd = statement.offset + statement.length; | 2634 int statementEnd = statement.offset + statement.length; |
2573 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); | 2635 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); |
2574 element.const3 = node.isConst; | 2636 element.const3 = node.isConst; |
2575 element.final2 = node.isFinal; | 2637 element.final2 = node.isFinal; |
| 2638 if (node.type == null) { |
| 2639 element.hasImplicitType = true; |
| 2640 } |
2576 _currentHolder.addLocalVariable(element); | 2641 _currentHolder.addLocalVariable(element); |
2577 variableName.staticElement = element; | 2642 variableName.staticElement = element; |
2578 return super.visitDeclaredIdentifier(node); | 2643 return super.visitDeclaredIdentifier(node); |
2579 } | 2644 } |
2580 | 2645 |
2581 @override | 2646 @override |
2582 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 2647 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
2583 ElementHolder holder = new ElementHolder(); | 2648 ElementHolder holder = new ElementHolder(); |
2584 NormalFormalParameter normalParameter = node.parameter; | 2649 NormalFormalParameter normalParameter = node.parameter; |
2585 SimpleIdentifier parameterName = normalParameter.identifier; | 2650 SimpleIdentifier parameterName = normalParameter.identifier; |
(...skipping 20 matching lines...) Expand all Loading... |
2606 initializer.functions = holder.functions; | 2671 initializer.functions = holder.functions; |
2607 initializer.labels = holder.labels; | 2672 initializer.labels = holder.labels; |
2608 initializer.localVariables = holder.localVariables; | 2673 initializer.localVariables = holder.localVariables; |
2609 initializer.parameters = holder.parameters; | 2674 initializer.parameters = holder.parameters; |
2610 initializer.synthetic = true; | 2675 initializer.synthetic = true; |
2611 parameter.initializer = initializer; | 2676 parameter.initializer = initializer; |
2612 parameter.defaultValueCode = defaultValue.toSource(); | 2677 parameter.defaultValueCode = defaultValue.toSource(); |
2613 } | 2678 } |
2614 // visible range | 2679 // visible range |
2615 _setParameterVisibleRange(node, parameter); | 2680 _setParameterVisibleRange(node, parameter); |
| 2681 if (normalParameter is SimpleFormalParameter && |
| 2682 normalParameter.type == null) { |
| 2683 parameter.hasImplicitType = true; |
| 2684 } |
2616 _currentHolder.addParameter(parameter); | 2685 _currentHolder.addParameter(parameter); |
2617 parameterName.staticElement = parameter; | 2686 parameterName.staticElement = parameter; |
2618 normalParameter.accept(this); | 2687 normalParameter.accept(this); |
2619 holder.validate(); | 2688 holder.validate(); |
2620 return null; | 2689 return null; |
2621 } | 2690 } |
2622 | 2691 |
2623 @override | 2692 @override |
2624 Object visitEnumDeclaration(EnumDeclaration node) { | 2693 Object visitEnumDeclaration(EnumDeclaration node) { |
2625 SimpleIdentifier enumName = node.name; | 2694 SimpleIdentifier enumName = node.name; |
2626 ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName); | 2695 ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName); |
2627 enumElement.enum2 = true; | 2696 enumElement.enum2 = true; |
| 2697 _setDocRange(enumElement, node); |
2628 InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement); | 2698 InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement); |
2629 enumElement.type = enumType; | 2699 enumElement.type = enumType; |
2630 // The equivalent code for enums in the spec shows a single constructor, | 2700 // The equivalent code for enums in the spec shows a single constructor, |
2631 // but that constructor is not callable (since it is a compile-time error | 2701 // but that constructor is not callable (since it is a compile-time error |
2632 // to subclass, mix-in, implement, or explicitly instantiate an enum). So | 2702 // to subclass, mix-in, implement, or explicitly instantiate an enum). So |
2633 // we represent this as having no constructors. | 2703 // we represent this as having no constructors. |
2634 enumElement.constructors = ConstructorElement.EMPTY_LIST; | 2704 enumElement.constructors = ConstructorElement.EMPTY_LIST; |
2635 _currentHolder.addEnum(enumElement); | 2705 _currentHolder.addEnum(enumElement); |
2636 enumName.staticElement = enumElement; | 2706 enumName.staticElement = enumElement; |
2637 return super.visitEnumDeclaration(node); | 2707 return super.visitEnumDeclaration(node); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2690 _visitChildren(holder, node); | 2760 _visitChildren(holder, node); |
2691 } finally { | 2761 } finally { |
2692 _inFunction = wasInFunction; | 2762 _inFunction = wasInFunction; |
2693 } | 2763 } |
2694 FunctionBody body = expression.body; | 2764 FunctionBody body = expression.body; |
2695 sc.Token property = node.propertyKeyword; | 2765 sc.Token property = node.propertyKeyword; |
2696 if (property == null || _inFunction) { | 2766 if (property == null || _inFunction) { |
2697 SimpleIdentifier functionName = node.name; | 2767 SimpleIdentifier functionName = node.name; |
2698 FunctionElementImpl element = | 2768 FunctionElementImpl element = |
2699 new FunctionElementImpl.forNode(functionName); | 2769 new FunctionElementImpl.forNode(functionName); |
| 2770 _setDocRange(element, node); |
2700 if (node.externalKeyword != null) { | 2771 if (node.externalKeyword != null) { |
2701 element.external = true; | 2772 element.external = true; |
2702 } | 2773 } |
2703 element.functions = holder.functions; | 2774 element.functions = holder.functions; |
2704 element.labels = holder.labels; | 2775 element.labels = holder.labels; |
2705 element.localVariables = holder.localVariables; | 2776 element.localVariables = holder.localVariables; |
2706 element.parameters = holder.parameters; | 2777 element.parameters = holder.parameters; |
2707 element.typeParameters = holder.typeParameters; | 2778 element.typeParameters = holder.typeParameters; |
2708 if (body.isAsynchronous) { | 2779 if (body.isAsynchronous) { |
2709 element.asynchronous = true; | 2780 element.asynchronous = true; |
2710 } | 2781 } |
2711 if (body.isGenerator) { | 2782 if (body.isGenerator) { |
2712 element.generator = true; | 2783 element.generator = true; |
2713 } | 2784 } |
2714 if (_inFunction) { | 2785 if (_inFunction) { |
2715 Block enclosingBlock = node.getAncestor((node) => node is Block); | 2786 Block enclosingBlock = node.getAncestor((node) => node is Block); |
2716 if (enclosingBlock != null) { | 2787 if (enclosingBlock != null) { |
2717 int functionEnd = node.offset + node.length; | 2788 int functionEnd = node.offset + node.length; |
2718 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 2789 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
2719 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 2790 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
2720 } | 2791 } |
2721 } | 2792 } |
| 2793 if (node.returnType == null) { |
| 2794 element.hasImplicitReturnType = true; |
| 2795 } |
2722 _currentHolder.addFunction(element); | 2796 _currentHolder.addFunction(element); |
2723 expression.element = element; | 2797 expression.element = element; |
2724 functionName.staticElement = element; | 2798 functionName.staticElement = element; |
2725 } else { | 2799 } else { |
2726 SimpleIdentifier propertyNameNode = node.name; | 2800 SimpleIdentifier propertyNameNode = node.name; |
2727 if (propertyNameNode == null) { | 2801 if (propertyNameNode == null) { |
2728 // TODO(brianwilkerson) Report this internal error. | 2802 // TODO(brianwilkerson) Report this internal error. |
2729 return null; | 2803 return null; |
2730 } | 2804 } |
2731 String propertyName = propertyNameNode.name; | 2805 String propertyName = propertyNameNode.name; |
2732 TopLevelVariableElementImpl variable = _currentHolder | 2806 TopLevelVariableElementImpl variable = _currentHolder |
2733 .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl; | 2807 .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl; |
2734 if (variable == null) { | 2808 if (variable == null) { |
2735 variable = new TopLevelVariableElementImpl(node.name.name, -1); | 2809 variable = new TopLevelVariableElementImpl(node.name.name, -1); |
2736 variable.final2 = true; | 2810 variable.final2 = true; |
2737 variable.synthetic = true; | 2811 variable.synthetic = true; |
2738 _currentHolder.addTopLevelVariable(variable); | 2812 _currentHolder.addTopLevelVariable(variable); |
2739 } | 2813 } |
2740 if (node.isGetter) { | 2814 if (node.isGetter) { |
2741 PropertyAccessorElementImpl getter = | 2815 PropertyAccessorElementImpl getter = |
2742 new PropertyAccessorElementImpl.forNode(propertyNameNode); | 2816 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 2817 _setDocRange(getter, node); |
2743 if (node.externalKeyword != null) { | 2818 if (node.externalKeyword != null) { |
2744 getter.external = true; | 2819 getter.external = true; |
2745 } | 2820 } |
2746 getter.functions = holder.functions; | 2821 getter.functions = holder.functions; |
2747 getter.labels = holder.labels; | 2822 getter.labels = holder.labels; |
2748 getter.localVariables = holder.localVariables; | 2823 getter.localVariables = holder.localVariables; |
2749 if (body.isAsynchronous) { | 2824 if (body.isAsynchronous) { |
2750 getter.asynchronous = true; | 2825 getter.asynchronous = true; |
2751 } | 2826 } |
2752 if (body.isGenerator) { | 2827 if (body.isGenerator) { |
2753 getter.generator = true; | 2828 getter.generator = true; |
2754 } | 2829 } |
2755 getter.variable = variable; | 2830 getter.variable = variable; |
2756 getter.getter = true; | 2831 getter.getter = true; |
2757 getter.static = true; | 2832 getter.static = true; |
2758 variable.getter = getter; | 2833 variable.getter = getter; |
| 2834 if (node.returnType == null) { |
| 2835 getter.hasImplicitReturnType = true; |
| 2836 } |
2759 _currentHolder.addAccessor(getter); | 2837 _currentHolder.addAccessor(getter); |
2760 expression.element = getter; | 2838 expression.element = getter; |
2761 propertyNameNode.staticElement = getter; | 2839 propertyNameNode.staticElement = getter; |
2762 } else { | 2840 } else { |
2763 PropertyAccessorElementImpl setter = | 2841 PropertyAccessorElementImpl setter = |
2764 new PropertyAccessorElementImpl.forNode(propertyNameNode); | 2842 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 2843 _setDocRange(setter, node); |
2765 if (node.externalKeyword != null) { | 2844 if (node.externalKeyword != null) { |
2766 setter.external = true; | 2845 setter.external = true; |
2767 } | 2846 } |
2768 setter.functions = holder.functions; | 2847 setter.functions = holder.functions; |
2769 setter.labels = holder.labels; | 2848 setter.labels = holder.labels; |
2770 setter.localVariables = holder.localVariables; | 2849 setter.localVariables = holder.localVariables; |
2771 setter.parameters = holder.parameters; | 2850 setter.parameters = holder.parameters; |
2772 if (body.isAsynchronous) { | 2851 if (body.isAsynchronous) { |
2773 setter.asynchronous = true; | 2852 setter.asynchronous = true; |
2774 } | 2853 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2825 int functionEnd = node.offset + node.length; | 2904 int functionEnd = node.offset + node.length; |
2826 int blockEnd = enclosingBlock.offset + enclosingBlock.length; | 2905 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
2827 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); | 2906 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
2828 } | 2907 } |
2829 } | 2908 } |
2830 FunctionTypeImpl type = new FunctionTypeImpl(element); | 2909 FunctionTypeImpl type = new FunctionTypeImpl(element); |
2831 if (_functionTypesToFix != null) { | 2910 if (_functionTypesToFix != null) { |
2832 _functionTypesToFix.add(type); | 2911 _functionTypesToFix.add(type); |
2833 } | 2912 } |
2834 element.type = type; | 2913 element.type = type; |
| 2914 element.hasImplicitReturnType = true; |
2835 _currentHolder.addFunction(element); | 2915 _currentHolder.addFunction(element); |
2836 node.element = element; | 2916 node.element = element; |
2837 holder.validate(); | 2917 holder.validate(); |
2838 return null; | 2918 return null; |
2839 } | 2919 } |
2840 | 2920 |
2841 @override | 2921 @override |
2842 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 2922 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
2843 ElementHolder holder = new ElementHolder(); | 2923 ElementHolder holder = new ElementHolder(); |
2844 _visitChildren(holder, node); | 2924 _visitChildren(holder, node); |
2845 SimpleIdentifier aliasName = node.name; | 2925 SimpleIdentifier aliasName = node.name; |
2846 List<ParameterElement> parameters = holder.parameters; | 2926 List<ParameterElement> parameters = holder.parameters; |
2847 List<TypeParameterElement> typeParameters = holder.typeParameters; | 2927 List<TypeParameterElement> typeParameters = holder.typeParameters; |
2848 FunctionTypeAliasElementImpl element = | 2928 FunctionTypeAliasElementImpl element = |
2849 new FunctionTypeAliasElementImpl.forNode(aliasName); | 2929 new FunctionTypeAliasElementImpl.forNode(aliasName); |
| 2930 _setDocRange(element, node); |
2850 element.parameters = parameters; | 2931 element.parameters = parameters; |
2851 element.typeParameters = typeParameters; | 2932 element.typeParameters = typeParameters; |
2852 FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(element); | 2933 FunctionTypeImpl type = new FunctionTypeImpl.forTypedef(element); |
2853 type.typeArguments = _createTypeParameterTypes(typeParameters); | 2934 type.typeArguments = _createTypeParameterTypes(typeParameters); |
2854 element.type = type; | 2935 element.type = type; |
2855 _currentHolder.addTypeAlias(element); | 2936 _currentHolder.addTypeAlias(element); |
2856 aliasName.staticElement = element; | 2937 aliasName.staticElement = element; |
2857 holder.validate(); | 2938 holder.validate(); |
2858 return null; | 2939 return null; |
2859 } | 2940 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2911 FunctionBody body = node.body; | 2992 FunctionBody body = node.body; |
2912 if (property == null) { | 2993 if (property == null) { |
2913 SimpleIdentifier methodName = node.name; | 2994 SimpleIdentifier methodName = node.name; |
2914 String nameOfMethod = methodName.name; | 2995 String nameOfMethod = methodName.name; |
2915 if (nameOfMethod == sc.TokenType.MINUS.lexeme && | 2996 if (nameOfMethod == sc.TokenType.MINUS.lexeme && |
2916 node.parameters.parameters.length == 0) { | 2997 node.parameters.parameters.length == 0) { |
2917 nameOfMethod = "unary-"; | 2998 nameOfMethod = "unary-"; |
2918 } | 2999 } |
2919 MethodElementImpl element = | 3000 MethodElementImpl element = |
2920 new MethodElementImpl(nameOfMethod, methodName.offset); | 3001 new MethodElementImpl(nameOfMethod, methodName.offset); |
| 3002 _setDocRange(element, node); |
2921 element.abstract = node.isAbstract; | 3003 element.abstract = node.isAbstract; |
2922 if (node.externalKeyword != null) { | 3004 if (node.externalKeyword != null) { |
2923 element.external = true; | 3005 element.external = true; |
2924 } | 3006 } |
2925 element.functions = holder.functions; | 3007 element.functions = holder.functions; |
2926 element.labels = holder.labels; | 3008 element.labels = holder.labels; |
2927 element.localVariables = holder.localVariables; | 3009 element.localVariables = holder.localVariables; |
2928 element.parameters = holder.parameters; | 3010 element.parameters = holder.parameters; |
2929 element.static = isStatic; | 3011 element.static = isStatic; |
2930 element.typeParameters = holder.typeParameters; | 3012 element.typeParameters = holder.typeParameters; |
2931 if (body.isAsynchronous) { | 3013 if (body.isAsynchronous) { |
2932 element.asynchronous = true; | 3014 element.asynchronous = true; |
2933 } | 3015 } |
2934 if (body.isGenerator) { | 3016 if (body.isGenerator) { |
2935 element.generator = true; | 3017 element.generator = true; |
2936 } | 3018 } |
| 3019 if (node.returnType == null) { |
| 3020 element.hasImplicitReturnType = true; |
| 3021 } |
2937 _currentHolder.addMethod(element); | 3022 _currentHolder.addMethod(element); |
2938 methodName.staticElement = element; | 3023 methodName.staticElement = element; |
2939 } else { | 3024 } else { |
2940 SimpleIdentifier propertyNameNode = node.name; | 3025 SimpleIdentifier propertyNameNode = node.name; |
2941 String propertyName = propertyNameNode.name; | 3026 String propertyName = propertyNameNode.name; |
2942 FieldElementImpl field = | 3027 FieldElementImpl field = |
2943 _currentHolder.getField(propertyName) as FieldElementImpl; | 3028 _currentHolder.getField(propertyName) as FieldElementImpl; |
2944 if (field == null) { | 3029 if (field == null) { |
2945 field = new FieldElementImpl(node.name.name, -1); | 3030 field = new FieldElementImpl(node.name.name, -1); |
2946 field.final2 = true; | 3031 field.final2 = true; |
2947 field.static = isStatic; | 3032 field.static = isStatic; |
2948 field.synthetic = true; | 3033 field.synthetic = true; |
2949 _currentHolder.addField(field); | 3034 _currentHolder.addField(field); |
2950 } | 3035 } |
2951 if (node.isGetter) { | 3036 if (node.isGetter) { |
2952 PropertyAccessorElementImpl getter = | 3037 PropertyAccessorElementImpl getter = |
2953 new PropertyAccessorElementImpl.forNode(propertyNameNode); | 3038 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 3039 _setDocRange(getter, node); |
2954 if (node.externalKeyword != null) { | 3040 if (node.externalKeyword != null) { |
2955 getter.external = true; | 3041 getter.external = true; |
2956 } | 3042 } |
2957 getter.functions = holder.functions; | 3043 getter.functions = holder.functions; |
2958 getter.labels = holder.labels; | 3044 getter.labels = holder.labels; |
2959 getter.localVariables = holder.localVariables; | 3045 getter.localVariables = holder.localVariables; |
2960 if (body.isAsynchronous) { | 3046 if (body.isAsynchronous) { |
2961 getter.asynchronous = true; | 3047 getter.asynchronous = true; |
2962 } | 3048 } |
2963 if (body.isGenerator) { | 3049 if (body.isGenerator) { |
2964 getter.generator = true; | 3050 getter.generator = true; |
2965 } | 3051 } |
2966 getter.variable = field; | 3052 getter.variable = field; |
2967 getter.abstract = node.isAbstract; | 3053 getter.abstract = node.isAbstract; |
2968 getter.getter = true; | 3054 getter.getter = true; |
2969 getter.static = isStatic; | 3055 getter.static = isStatic; |
2970 field.getter = getter; | 3056 field.getter = getter; |
| 3057 if (node.returnType == null) { |
| 3058 getter.hasImplicitReturnType = true; |
| 3059 } |
2971 _currentHolder.addAccessor(getter); | 3060 _currentHolder.addAccessor(getter); |
2972 propertyNameNode.staticElement = getter; | 3061 propertyNameNode.staticElement = getter; |
2973 } else { | 3062 } else { |
2974 PropertyAccessorElementImpl setter = | 3063 PropertyAccessorElementImpl setter = |
2975 new PropertyAccessorElementImpl.forNode(propertyNameNode); | 3064 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 3065 _setDocRange(setter, node); |
2976 if (node.externalKeyword != null) { | 3066 if (node.externalKeyword != null) { |
2977 setter.external = true; | 3067 setter.external = true; |
2978 } | 3068 } |
2979 setter.functions = holder.functions; | 3069 setter.functions = holder.functions; |
2980 setter.labels = holder.labels; | 3070 setter.labels = holder.labels; |
2981 setter.localVariables = holder.localVariables; | 3071 setter.localVariables = holder.localVariables; |
2982 setter.parameters = holder.parameters; | 3072 setter.parameters = holder.parameters; |
2983 if (body.isAsynchronous) { | 3073 if (body.isAsynchronous) { |
2984 setter.asynchronous = true; | 3074 setter.asynchronous = true; |
2985 } | 3075 } |
(...skipping 19 matching lines...) Expand all Loading... |
3005 buffer.write("The element for the method "); | 3095 buffer.write("The element for the method "); |
3006 buffer.write(node.name); | 3096 buffer.write(node.name); |
3007 buffer.write(" in "); | 3097 buffer.write(" in "); |
3008 buffer.write(classNode.name); | 3098 buffer.write(classNode.name); |
3009 buffer.write(" was not set while trying to build the element model."); | 3099 buffer.write(" was not set while trying to build the element model."); |
3010 AnalysisEngine.instance.logger.logError( | 3100 AnalysisEngine.instance.logger.logError( |
3011 buffer.toString(), new CaughtException(exception, stackTrace)); | 3101 buffer.toString(), new CaughtException(exception, stackTrace)); |
3012 } else { | 3102 } else { |
3013 String message = | 3103 String message = |
3014 "Exception caught in ElementBuilder.visitMethodDeclaration()"; | 3104 "Exception caught in ElementBuilder.visitMethodDeclaration()"; |
3015 AnalysisEngine.instance.logger.logError( | 3105 AnalysisEngine.instance.logger |
3016 message, new CaughtException(exception, stackTrace)); | 3106 .logError(message, new CaughtException(exception, stackTrace)); |
3017 } | 3107 } |
3018 } finally { | 3108 } finally { |
3019 if (node.name.staticElement == null) { | 3109 if (node.name.staticElement == null) { |
3020 ClassDeclaration classNode = | 3110 ClassDeclaration classNode = |
3021 node.getAncestor((node) => node is ClassDeclaration); | 3111 node.getAncestor((node) => node is ClassDeclaration); |
3022 StringBuffer buffer = new StringBuffer(); | 3112 StringBuffer buffer = new StringBuffer(); |
3023 buffer.write("The element for the method "); | 3113 buffer.write("The element for the method "); |
3024 buffer.write(node.name); | 3114 buffer.write(node.name); |
3025 buffer.write(" in "); | 3115 buffer.write(" in "); |
3026 buffer.write(classNode.name); | 3116 buffer.write(classNode.name); |
3027 buffer.write(" was not set while trying to resolve types."); | 3117 buffer.write(" was not set while trying to resolve types."); |
3028 AnalysisEngine.instance.logger.logError(buffer.toString(), | 3118 AnalysisEngine.instance.logger.logError( |
| 3119 buffer.toString(), |
3029 new CaughtException( | 3120 new CaughtException( |
3030 new AnalysisException(buffer.toString()), null)); | 3121 new AnalysisException(buffer.toString()), null)); |
3031 } | 3122 } |
3032 } | 3123 } |
3033 return null; | 3124 return null; |
3034 } | 3125 } |
3035 | 3126 |
3036 @override | 3127 @override |
3037 Object visitSimpleFormalParameter(SimpleFormalParameter node) { | 3128 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
3038 if (node.parent is! DefaultFormalParameter) { | 3129 if (node.parent is! DefaultFormalParameter) { |
3039 SimpleIdentifier parameterName = node.identifier; | 3130 SimpleIdentifier parameterName = node.identifier; |
3040 ParameterElementImpl parameter = | 3131 ParameterElementImpl parameter = |
3041 new ParameterElementImpl.forNode(parameterName); | 3132 new ParameterElementImpl.forNode(parameterName); |
3042 parameter.const3 = node.isConst; | 3133 parameter.const3 = node.isConst; |
3043 parameter.final2 = node.isFinal; | 3134 parameter.final2 = node.isFinal; |
3044 parameter.parameterKind = node.kind; | 3135 parameter.parameterKind = node.kind; |
3045 _setParameterVisibleRange(node, parameter); | 3136 _setParameterVisibleRange(node, parameter); |
| 3137 if (node.type == null) { |
| 3138 parameter.hasImplicitType = true; |
| 3139 } |
3046 _currentHolder.addParameter(parameter); | 3140 _currentHolder.addParameter(parameter); |
3047 parameterName.staticElement = parameter; | 3141 parameterName.staticElement = parameter; |
3048 } | 3142 } |
3049 return super.visitSimpleFormalParameter(node); | 3143 return super.visitSimpleFormalParameter(node); |
3050 } | 3144 } |
3051 | 3145 |
3052 @override | 3146 @override |
3053 Object visitSuperExpression(SuperExpression node) { | 3147 Object visitSuperExpression(SuperExpression node) { |
3054 _isValidMixin = false; | 3148 _isValidMixin = false; |
3055 return super.visitSuperExpression(node); | 3149 return super.visitSuperExpression(node); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3098 VariableElementImpl element; | 3192 VariableElementImpl element; |
3099 if (_inFieldContext) { | 3193 if (_inFieldContext) { |
3100 SimpleIdentifier fieldName = node.name; | 3194 SimpleIdentifier fieldName = node.name; |
3101 FieldElementImpl field; | 3195 FieldElementImpl field; |
3102 if ((isConst || isFinal) && hasInitializer) { | 3196 if ((isConst || isFinal) && hasInitializer) { |
3103 field = new ConstFieldElementImpl.forNode(fieldName); | 3197 field = new ConstFieldElementImpl.forNode(fieldName); |
3104 } else { | 3198 } else { |
3105 field = new FieldElementImpl.forNode(fieldName); | 3199 field = new FieldElementImpl.forNode(fieldName); |
3106 } | 3200 } |
3107 element = field; | 3201 element = field; |
| 3202 if (node.parent.parent is FieldDeclaration) { |
| 3203 _setDocRange(element, node.parent.parent); |
| 3204 } |
| 3205 if ((node.parent as VariableDeclarationList).type == null) { |
| 3206 field.hasImplicitType = true; |
| 3207 } |
3108 _currentHolder.addField(field); | 3208 _currentHolder.addField(field); |
3109 fieldName.staticElement = field; | 3209 fieldName.staticElement = field; |
3110 } else if (_inFunction) { | 3210 } else if (_inFunction) { |
3111 SimpleIdentifier variableName = node.name; | 3211 SimpleIdentifier variableName = node.name; |
3112 LocalVariableElementImpl variable; | 3212 LocalVariableElementImpl variable; |
3113 if (isConst && hasInitializer) { | 3213 if (isConst && hasInitializer) { |
3114 variable = new ConstLocalVariableElementImpl.forNode(variableName); | 3214 variable = new ConstLocalVariableElementImpl.forNode(variableName); |
3115 } else { | 3215 } else { |
3116 variable = new LocalVariableElementImpl.forNode(variableName); | 3216 variable = new LocalVariableElementImpl.forNode(variableName); |
3117 } | 3217 } |
3118 element = variable; | 3218 element = variable; |
3119 Block enclosingBlock = node.getAncestor((node) => node is Block); | 3219 Block enclosingBlock = node.getAncestor((node) => node is Block); |
3120 // TODO(brianwilkerson) This isn't right for variables declared in a for | 3220 // TODO(brianwilkerson) This isn't right for variables declared in a for |
3121 // loop. | 3221 // loop. |
3122 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); | 3222 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); |
| 3223 if ((node.parent as VariableDeclarationList).type == null) { |
| 3224 variable.hasImplicitType = true; |
| 3225 } |
3123 _currentHolder.addLocalVariable(variable); | 3226 _currentHolder.addLocalVariable(variable); |
3124 variableName.staticElement = element; | 3227 variableName.staticElement = element; |
3125 } else { | 3228 } else { |
3126 SimpleIdentifier variableName = node.name; | 3229 SimpleIdentifier variableName = node.name; |
3127 TopLevelVariableElementImpl variable; | 3230 TopLevelVariableElementImpl variable; |
3128 if (isConst && hasInitializer) { | 3231 if (isConst && hasInitializer) { |
3129 variable = new ConstTopLevelVariableElementImpl(variableName); | 3232 variable = new ConstTopLevelVariableElementImpl(variableName); |
3130 } else { | 3233 } else { |
3131 variable = new TopLevelVariableElementImpl.forNode(variableName); | 3234 variable = new TopLevelVariableElementImpl.forNode(variableName); |
3132 } | 3235 } |
3133 element = variable; | 3236 element = variable; |
| 3237 if ((node.parent as VariableDeclarationList).type == null) { |
| 3238 variable.hasImplicitType = true; |
| 3239 } |
3134 _currentHolder.addTopLevelVariable(variable); | 3240 _currentHolder.addTopLevelVariable(variable); |
3135 variableName.staticElement = element; | 3241 variableName.staticElement = element; |
3136 } | 3242 } |
3137 element.const3 = isConst; | 3243 element.const3 = isConst; |
3138 element.final2 = isFinal; | 3244 element.final2 = isFinal; |
3139 if (hasInitializer) { | 3245 if (hasInitializer) { |
3140 ElementHolder holder = new ElementHolder(); | 3246 ElementHolder holder = new ElementHolder(); |
3141 bool wasInFieldContext = _inFieldContext; | 3247 bool wasInFieldContext = _inFieldContext; |
3142 _inFieldContext = false; | 3248 _inFieldContext = false; |
3143 try { | 3249 try { |
(...skipping 11 matching lines...) Expand all Loading... |
3155 holder.validate(); | 3261 holder.validate(); |
3156 } | 3262 } |
3157 if (element is PropertyInducingElementImpl) { | 3263 if (element is PropertyInducingElementImpl) { |
3158 if (_inFieldContext) { | 3264 if (_inFieldContext) { |
3159 (element as FieldElementImpl).static = | 3265 (element as FieldElementImpl).static = |
3160 (node.parent.parent as FieldDeclaration).isStatic; | 3266 (node.parent.parent as FieldDeclaration).isStatic; |
3161 } | 3267 } |
3162 PropertyAccessorElementImpl getter = | 3268 PropertyAccessorElementImpl getter = |
3163 new PropertyAccessorElementImpl.forVariable(element); | 3269 new PropertyAccessorElementImpl.forVariable(element); |
3164 getter.getter = true; | 3270 getter.getter = true; |
| 3271 if (element.hasImplicitType) { |
| 3272 getter.hasImplicitReturnType = true; |
| 3273 } |
3165 _currentHolder.addAccessor(getter); | 3274 _currentHolder.addAccessor(getter); |
3166 element.getter = getter; | 3275 element.getter = getter; |
3167 if (!isConst && !isFinal) { | 3276 if (!isConst && !isFinal) { |
3168 PropertyAccessorElementImpl setter = | 3277 PropertyAccessorElementImpl setter = |
3169 new PropertyAccessorElementImpl.forVariable(element); | 3278 new PropertyAccessorElementImpl.forVariable(element); |
3170 setter.setter = true; | 3279 setter.setter = true; |
3171 ParameterElementImpl parameter = | 3280 ParameterElementImpl parameter = |
3172 new ParameterElementImpl("_${element.name}", element.nameOffset); | 3281 new ParameterElementImpl("_${element.name}", element.nameOffset); |
3173 parameter.synthetic = true; | 3282 parameter.synthetic = true; |
3174 parameter.parameterKind = ParameterKind.REQUIRED; | 3283 parameter.parameterKind = ParameterKind.REQUIRED; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3251 return parent.body; | 3360 return parent.body; |
3252 } else if (parent is MethodDeclaration) { | 3361 } else if (parent is MethodDeclaration) { |
3253 return parent.body; | 3362 return parent.body; |
3254 } | 3363 } |
3255 parent = parent.parent; | 3364 parent = parent.parent; |
3256 } | 3365 } |
3257 return null; | 3366 return null; |
3258 } | 3367 } |
3259 | 3368 |
3260 /** | 3369 /** |
| 3370 * If the given [node] has a documentation comment, remember its range |
| 3371 * into the given [element]. |
| 3372 */ |
| 3373 void _setDocRange(ElementImpl element, AnnotatedNode node) { |
| 3374 Comment comment = node.documentationComment; |
| 3375 if (comment != null && comment.isDocumentation) { |
| 3376 element.setDocRange(comment.offset, comment.length); |
| 3377 } |
| 3378 } |
| 3379 |
| 3380 /** |
3261 * Sets the visible source range for formal parameter. | 3381 * Sets the visible source range for formal parameter. |
3262 */ | 3382 */ |
3263 void _setParameterVisibleRange( | 3383 void _setParameterVisibleRange( |
3264 FormalParameter node, ParameterElementImpl element) { | 3384 FormalParameter node, ParameterElementImpl element) { |
3265 FunctionBody body = _getFunctionBody(node); | 3385 FunctionBody body = _getFunctionBody(node); |
3266 if (body != null) { | 3386 if (body != null) { |
3267 element.setVisibleRange(body.offset, body.length); | 3387 element.setVisibleRange(body.offset, body.length); |
3268 } | 3388 } |
3269 } | 3389 } |
3270 | 3390 |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3719 Element internalLookup( | 3839 Element internalLookup( |
3720 Identifier identifier, String name, LibraryElement referencingLibrary) { | 3840 Identifier identifier, String name, LibraryElement referencingLibrary) { |
3721 Element element = localLookup(name, referencingLibrary); | 3841 Element element = localLookup(name, referencingLibrary); |
3722 if (element != null) { | 3842 if (element != null) { |
3723 return element; | 3843 return element; |
3724 } | 3844 } |
3725 // May be there is a hidden Element. | 3845 // May be there is a hidden Element. |
3726 if (_hasHiddenName) { | 3846 if (_hasHiddenName) { |
3727 Element hiddenElement = _hiddenElements[name]; | 3847 Element hiddenElement = _hiddenElements[name]; |
3728 if (hiddenElement != null) { | 3848 if (hiddenElement != null) { |
3729 errorListener.onError(new AnalysisError(getSource(identifier), | 3849 errorListener.onError(new AnalysisError( |
3730 identifier.offset, identifier.length, | 3850 getSource(identifier), |
| 3851 identifier.offset, |
| 3852 identifier.length, |
3731 CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, [])); | 3853 CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, [])); |
3732 return hiddenElement; | 3854 return hiddenElement; |
3733 } | 3855 } |
3734 } | 3856 } |
3735 // Check enclosing scope. | 3857 // Check enclosing scope. |
3736 return enclosingScope.internalLookup(identifier, name, referencingLibrary); | 3858 return enclosingScope.internalLookup(identifier, name, referencingLibrary); |
3737 } | 3859 } |
3738 } | 3860 } |
3739 | 3861 |
3740 /** | 3862 /** |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3855 bool _enclosingBlockContainsBreak = false; | 3977 bool _enclosingBlockContainsBreak = false; |
3856 | 3978 |
3857 @override | 3979 @override |
3858 bool visitArgumentList(ArgumentList node) => | 3980 bool visitArgumentList(ArgumentList node) => |
3859 _visitExpressions(node.arguments); | 3981 _visitExpressions(node.arguments); |
3860 | 3982 |
3861 @override | 3983 @override |
3862 bool visitAsExpression(AsExpression node) => _nodeExits(node.expression); | 3984 bool visitAsExpression(AsExpression node) => _nodeExits(node.expression); |
3863 | 3985 |
3864 @override | 3986 @override |
3865 bool visitAssertStatement(AssertStatement node) => _nodeExits(node.condition); | 3987 bool visitAssertStatement(AssertStatement node) => false; |
3866 | 3988 |
3867 @override | 3989 @override |
3868 bool visitAssignmentExpression(AssignmentExpression node) => | 3990 bool visitAssignmentExpression(AssignmentExpression node) { |
3869 _nodeExits(node.leftHandSide) || _nodeExits(node.rightHandSide); | 3991 Expression leftHandSide = node.leftHandSide; |
| 3992 if (_nodeExits(leftHandSide)) { |
| 3993 return true; |
| 3994 } |
| 3995 if (node.operator.type == sc.TokenType.QUESTION_QUESTION_EQ) { |
| 3996 return false; |
| 3997 } |
| 3998 if (leftHandSide is PropertyAccess && |
| 3999 leftHandSide.operator.type == sc.TokenType.QUESTION_PERIOD) { |
| 4000 return false; |
| 4001 } |
| 4002 return _nodeExits(node.rightHandSide); |
| 4003 } |
3870 | 4004 |
3871 @override | 4005 @override |
3872 bool visitAwaitExpression(AwaitExpression node) => | 4006 bool visitAwaitExpression(AwaitExpression node) => |
3873 _nodeExits(node.expression); | 4007 _nodeExits(node.expression); |
3874 | 4008 |
3875 @override | 4009 @override |
3876 bool visitBinaryExpression(BinaryExpression node) { | 4010 bool visitBinaryExpression(BinaryExpression node) { |
3877 Expression lhsExpression = node.leftOperand; | 4011 Expression lhsExpression = node.leftOperand; |
| 4012 Expression rhsExpression = node.rightOperand; |
3878 sc.TokenType operatorType = node.operator.type; | 4013 sc.TokenType operatorType = node.operator.type; |
3879 // If the operator is || and the left hand side is false literal, don't | 4014 // If the operator is ||, then only consider the RHS of the binary |
3880 // consider the RHS of the binary expression. | 4015 // expression if the left hand side is the false literal. |
3881 // TODO(jwren) Do we want to take constant expressions into account, | 4016 // TODO(jwren) Do we want to take constant expressions into account, |
3882 // evaluate if(false) {} differently than if(<condition>), when <condition> | 4017 // evaluate if(false) {} differently than if(<condition>), when <condition> |
3883 // evaluates to a constant false value? | 4018 // evaluates to a constant false value? |
3884 if (operatorType == sc.TokenType.BAR_BAR) { | 4019 if (operatorType == sc.TokenType.BAR_BAR) { |
3885 if (lhsExpression is BooleanLiteral) { | 4020 if (lhsExpression is BooleanLiteral) { |
3886 BooleanLiteral booleanLiteral = lhsExpression; | 4021 BooleanLiteral booleanLiteral = lhsExpression; |
3887 if (!booleanLiteral.value) { | 4022 if (!booleanLiteral.value) { |
3888 return false; | 4023 return _nodeExits(rhsExpression); |
3889 } | 4024 } |
3890 } | 4025 } |
| 4026 return _nodeExits(lhsExpression); |
3891 } | 4027 } |
3892 // If the operator is && and the left hand side is true literal, don't | 4028 // If the operator is &&, then only consider the RHS of the binary |
3893 // consider the RHS of the binary expression. | 4029 // expression if the left hand side is the true literal. |
3894 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { | 4030 if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) { |
3895 if (lhsExpression is BooleanLiteral) { | 4031 if (lhsExpression is BooleanLiteral) { |
3896 BooleanLiteral booleanLiteral = lhsExpression; | 4032 BooleanLiteral booleanLiteral = lhsExpression; |
3897 if (booleanLiteral.value) { | 4033 if (booleanLiteral.value) { |
3898 return false; | 4034 return _nodeExits(rhsExpression); |
3899 } | 4035 } |
3900 } | 4036 } |
| 4037 return _nodeExits(lhsExpression); |
3901 } | 4038 } |
3902 Expression rhsExpression = node.rightOperand; | 4039 // If the operator is ??, then don't consider the RHS of the binary |
| 4040 // expression. |
| 4041 if (operatorType == sc.TokenType.QUESTION_QUESTION) { |
| 4042 return _nodeExits(lhsExpression); |
| 4043 } |
3903 return _nodeExits(lhsExpression) || _nodeExits(rhsExpression); | 4044 return _nodeExits(lhsExpression) || _nodeExits(rhsExpression); |
3904 } | 4045 } |
3905 | 4046 |
3906 @override | 4047 @override |
3907 bool visitBlock(Block node) => _visitStatements(node.statements); | 4048 bool visitBlock(Block node) => _visitStatements(node.statements); |
3908 | 4049 |
3909 @override | 4050 @override |
3910 bool visitBlockFunctionBody(BlockFunctionBody node) => _nodeExits(node.block); | 4051 bool visitBlockFunctionBody(BlockFunctionBody node) => _nodeExits(node.block); |
3911 | 4052 |
3912 @override | 4053 @override |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4087 @override | 4228 @override |
4088 bool visitLabeledStatement(LabeledStatement node) => | 4229 bool visitLabeledStatement(LabeledStatement node) => |
4089 node.statement.accept(this); | 4230 node.statement.accept(this); |
4090 | 4231 |
4091 @override | 4232 @override |
4092 bool visitLiteral(Literal node) => false; | 4233 bool visitLiteral(Literal node) => false; |
4093 | 4234 |
4094 @override | 4235 @override |
4095 bool visitMethodInvocation(MethodInvocation node) { | 4236 bool visitMethodInvocation(MethodInvocation node) { |
4096 Expression target = node.realTarget; | 4237 Expression target = node.realTarget; |
4097 if (target != null && target.accept(this)) { | 4238 if (target != null) { |
4098 return true; | 4239 if (target.accept(this)) { |
| 4240 return true; |
| 4241 } |
| 4242 if (node.operator.type == sc.TokenType.QUESTION_PERIOD) { |
| 4243 return false; |
| 4244 } |
4099 } | 4245 } |
4100 return _nodeExits(node.argumentList); | 4246 return _nodeExits(node.argumentList); |
4101 } | 4247 } |
4102 | 4248 |
4103 @override | 4249 @override |
4104 bool visitNamedExpression(NamedExpression node) => | 4250 bool visitNamedExpression(NamedExpression node) => |
4105 node.expression.accept(this); | 4251 node.expression.accept(this); |
4106 | 4252 |
4107 @override | 4253 @override |
4108 bool visitParenthesizedExpression(ParenthesizedExpression node) => | 4254 bool visitParenthesizedExpression(ParenthesizedExpression node) => |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4700 } | 4846 } |
4701 _library.accept(new UnusedLocalElementsVerifier( | 4847 _library.accept(new UnusedLocalElementsVerifier( |
4702 _errorListener, _usedLocalElementsVisitor.usedElements)); | 4848 _errorListener, _usedLocalElementsVisitor.usedElements)); |
4703 }); | 4849 }); |
4704 } | 4850 } |
4705 | 4851 |
4706 void _generateForCompilationUnit(CompilationUnit unit, Source source) { | 4852 void _generateForCompilationUnit(CompilationUnit unit, Source source) { |
4707 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); | 4853 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); |
4708 unit.accept(_usedImportedElementsVisitor); | 4854 unit.accept(_usedImportedElementsVisitor); |
4709 // dead code analysis | 4855 // dead code analysis |
4710 unit.accept(new DeadCodeVerifier(errorReporter)); | 4856 unit.accept( |
| 4857 new DeadCodeVerifier(errorReporter, typeSystem: _context.typeSystem)); |
4711 unit.accept(_usedLocalElementsVisitor); | 4858 unit.accept(_usedLocalElementsVisitor); |
4712 // dart2js analysis | 4859 // dart2js analysis |
4713 if (_enableDart2JSHints) { | 4860 if (_enableDart2JSHints) { |
4714 unit.accept(new Dart2JSVerifier(errorReporter)); | 4861 unit.accept(new Dart2JSVerifier(errorReporter)); |
4715 } | 4862 } |
4716 // Dart best practices | 4863 // Dart best practices |
4717 unit.accept( | 4864 unit.accept(new BestPracticesVerifier(errorReporter, _context.typeProvider, |
4718 new BestPracticesVerifier(errorReporter, _context.typeProvider)); | 4865 typeSystem: _context.typeSystem)); |
4719 unit.accept(new OverrideVerifier(errorReporter, _manager)); | 4866 unit.accept(new OverrideVerifier(errorReporter, _manager)); |
4720 // Find to-do comments | 4867 // Find to-do comments |
4721 new ToDoFinder(errorReporter).findIn(unit); | 4868 new ToDoFinder(errorReporter).findIn(unit); |
4722 // pub analysis | 4869 // pub analysis |
4723 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are | 4870 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are |
4724 // fixed | 4871 // fixed |
4725 // unit.accept(new PubVerifier(context, errorReporter)); | 4872 // unit.accept(new PubVerifier(context, errorReporter)); |
4726 } | 4873 } |
4727 } | 4874 } |
4728 | 4875 |
(...skipping 22 matching lines...) Expand all Loading... |
4751 /** | 4898 /** |
4752 * Initialize a newly created information holder to hold the given information
about the tags in | 4899 * Initialize a newly created information holder to hold the given information
about the tags in |
4753 * an HTML file. | 4900 * an HTML file. |
4754 * | 4901 * |
4755 * @param allTags an array containing all of the tags used in the HTML file | 4902 * @param allTags an array containing all of the tags used in the HTML file |
4756 * @param idToTagMap a table mapping the id's defined in the HTML file to an a
rray containing the | 4903 * @param idToTagMap a table mapping the id's defined in the HTML file to an a
rray containing the |
4757 * names of tags with that identifier | 4904 * names of tags with that identifier |
4758 * @param classToTagsMap a table mapping the classes defined in the HTML file
to an array | 4905 * @param classToTagsMap a table mapping the classes defined in the HTML file
to an array |
4759 * containing the names of tags with that class | 4906 * containing the names of tags with that class |
4760 */ | 4907 */ |
4761 HtmlTagInfo(List<String> allTags, HashMap<String, String> idToTagMap, | 4908 HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap); |
4762 HashMap<String, List<String>> classToTagsMap) { | |
4763 this.allTags = allTags; | |
4764 this.idToTagMap = idToTagMap; | |
4765 this.classToTagsMap = classToTagsMap; | |
4766 } | |
4767 | 4909 |
4768 /** | 4910 /** |
4769 * Return an array containing the tags that have the given class, or {@code nu
ll} if there are no | 4911 * Return an array containing the tags that have the given class, or {@code nu
ll} if there are no |
4770 * such tags. | 4912 * such tags. |
4771 * | 4913 * |
4772 * @return an array containing the tags that have the given class | 4914 * @return an array containing the tags that have the given class |
4773 */ | 4915 */ |
4774 List<String> getTagsWithClass(String identifier) { | 4916 List<String> getTagsWithClass(String identifier) { |
4775 return classToTagsMap[identifier]; | 4917 return classToTagsMap[identifier]; |
4776 } | 4918 } |
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5671 * This method takes some inherited [FunctionType], and resolves all the param
eterized types | 5813 * This method takes some inherited [FunctionType], and resolves all the param
eterized types |
5672 * in the function type, dependent on the class in which it is being overridde
n. | 5814 * in the function type, dependent on the class in which it is being overridde
n. |
5673 * | 5815 * |
5674 * @param baseFunctionType the function type that is being overridden | 5816 * @param baseFunctionType the function type that is being overridden |
5675 * @param memberName the name of the member, this is used to lookup the inheri
tance path of the | 5817 * @param memberName the name of the member, this is used to lookup the inheri
tance path of the |
5676 * override | 5818 * override |
5677 * @param definingType the type that is overriding the member | 5819 * @param definingType the type that is overriding the member |
5678 * @return the passed function type with any parameterized types substituted | 5820 * @return the passed function type with any parameterized types substituted |
5679 */ | 5821 */ |
5680 FunctionType substituteTypeArgumentsInMemberFromInheritance( | 5822 FunctionType substituteTypeArgumentsInMemberFromInheritance( |
5681 FunctionType baseFunctionType, String memberName, | 5823 FunctionType baseFunctionType, |
| 5824 String memberName, |
5682 InterfaceType definingType) { | 5825 InterfaceType definingType) { |
5683 // if the baseFunctionType is null, or does not have any parameters, | 5826 // if the baseFunctionType is null, or does not have any parameters, |
5684 // return it. | 5827 // return it. |
5685 if (baseFunctionType == null || | 5828 if (baseFunctionType == null || |
5686 baseFunctionType.typeArguments.length == 0) { | 5829 baseFunctionType.typeArguments.length == 0) { |
5687 return baseFunctionType; | 5830 return baseFunctionType; |
5688 } | 5831 } |
5689 // First, generate the path from the defining type to the overridden member | 5832 // First, generate the path from the defining type to the overridden member |
5690 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>(); | 5833 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>(); |
5691 _computeInheritancePath(inheritancePath, definingType, memberName); | 5834 _computeInheritancePath(inheritancePath, definingType, memberName); |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6173 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { | 6316 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { |
6174 executableElementTypes[i] = elements[i].type; | 6317 executableElementTypes[i] = elements[i].type; |
6175 } | 6318 } |
6176 List<int> subtypesOfAllOtherTypesIndexes = new List<int>(); | 6319 List<int> subtypesOfAllOtherTypesIndexes = new List<int>(); |
6177 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { | 6320 for (int i = 0; i < numOfEltsWithMatchingNames; i++) { |
6178 FunctionType subtype = executableElementTypes[i]; | 6321 FunctionType subtype = executableElementTypes[i]; |
6179 if (subtype == null) { | 6322 if (subtype == null) { |
6180 continue; | 6323 continue; |
6181 } | 6324 } |
6182 bool subtypeOfAllTypes = true; | 6325 bool subtypeOfAllTypes = true; |
| 6326 TypeSystem typeSystem = _library.context.typeSystem; |
6183 for (int j = 0; | 6327 for (int j = 0; |
6184 j < numOfEltsWithMatchingNames && subtypeOfAllTypes; | 6328 j < numOfEltsWithMatchingNames && subtypeOfAllTypes; |
6185 j++) { | 6329 j++) { |
6186 if (i != j) { | 6330 if (i != j) { |
6187 if (!subtype.isSubtypeOf(executableElementTypes[j])) { | 6331 if (!typeSystem.isSubtypeOf( |
| 6332 subtype, executableElementTypes[j])) { |
6188 subtypeOfAllTypes = false; | 6333 subtypeOfAllTypes = false; |
6189 break; | 6334 break; |
6190 } | 6335 } |
6191 } | 6336 } |
6192 } | 6337 } |
6193 if (subtypeOfAllTypes) { | 6338 if (subtypeOfAllTypes) { |
6194 subtypesOfAllOtherTypesIndexes.add(i); | 6339 subtypesOfAllOtherTypesIndexes.add(i); |
6195 } | 6340 } |
6196 } | 6341 } |
6197 // | 6342 // |
(...skipping 30 matching lines...) Expand all Loading... |
6228 } | 6373 } |
6229 // | 6374 // |
6230 // Example: class A inherited only 2 method named 'm'. | 6375 // Example: class A inherited only 2 method named 'm'. |
6231 // One has the function type '() -> int' and one has the function | 6376 // One has the function type '() -> int' and one has the function |
6232 // type '() -> String'. Since neither is a subtype of the other, | 6377 // type '() -> String'. Since neither is a subtype of the other, |
6233 // we create a warning, and have this class inherit nothing. | 6378 // we create a warning, and have this class inherit nothing. |
6234 // | 6379 // |
6235 if (!classHasMember) { | 6380 if (!classHasMember) { |
6236 String firstTwoFuntionTypesStr = | 6381 String firstTwoFuntionTypesStr = |
6237 "${executableElementTypes[0]}, ${executableElementTypes[1]}"
; | 6382 "${executableElementTypes[0]}, ${executableElementTypes[1]}"
; |
6238 _reportError(classElt, classElt.nameOffset, | 6383 _reportError( |
6239 classElt.displayName.length, | 6384 classElt, |
6240 StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [ | 6385 classElt.nameOffset, |
6241 key, | 6386 classElt.nameLength, |
6242 firstTwoFuntionTypesStr | 6387 StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, |
6243 ]); | 6388 [key, firstTwoFuntionTypesStr]); |
6244 } | 6389 } |
6245 } else { | 6390 } else { |
6246 // | 6391 // |
6247 // Example: class A inherits 2 methods named 'm'. | 6392 // Example: class A inherits 2 methods named 'm'. |
6248 // One has the function type '(int) -> dynamic' and one has the | 6393 // One has the function type '(int) -> dynamic' and one has the |
6249 // function type '(num) -> dynamic'. Since they are both a subtype | 6394 // function type '(num) -> dynamic'. Since they are both a subtype |
6250 // of the other, a synthetic function '(dynamic) -> dynamic' is | 6395 // of the other, a synthetic function '(dynamic) -> dynamic' is |
6251 // inherited. | 6396 // inherited. |
6252 // Tests: test_getMapOfMembersInheritedFromInterfaces_ | 6397 // Tests: test_getMapOfMembersInheritedFromInterfaces_ |
6253 // union_multipleSubtypes_* | 6398 // union_multipleSubtypes_* |
6254 // | 6399 // |
6255 List<ExecutableElement> elementArrayToMerge = | 6400 List<ExecutableElement> elementArrayToMerge = new List< |
6256 new List<ExecutableElement>( | 6401 ExecutableElement>(subtypesOfAllOtherTypesIndexes.length); |
6257 subtypesOfAllOtherTypesIndexes.length); | |
6258 for (int i = 0; i < elementArrayToMerge.length; i++) { | 6402 for (int i = 0; i < elementArrayToMerge.length; i++) { |
6259 elementArrayToMerge[i] = | 6403 elementArrayToMerge[i] = |
6260 elements[subtypesOfAllOtherTypesIndexes[i]]; | 6404 elements[subtypesOfAllOtherTypesIndexes[i]]; |
6261 } | 6405 } |
6262 ExecutableElement mergedExecutableElement = | 6406 ExecutableElement mergedExecutableElement = |
6263 _computeMergedExecutableElement(elementArrayToMerge); | 6407 _computeMergedExecutableElement(elementArrayToMerge); |
6264 resultMap.put(key, mergedExecutableElement); | 6408 resultMap.put(key, mergedExecutableElement); |
6265 } | 6409 } |
6266 } | 6410 } |
6267 } else { | 6411 } else { |
6268 _reportError(classElt, classElt.nameOffset, | 6412 _reportError( |
6269 classElt.displayName.length, | 6413 classElt, |
| 6414 classElt.nameOffset, |
| 6415 classElt.nameLength, |
6270 StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHO
D, | 6416 StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHO
D, |
6271 [key]); | 6417 [key]); |
6272 } | 6418 } |
6273 } | 6419 } |
6274 }); | 6420 }); |
6275 return resultMap; | 6421 return resultMap; |
6276 } | 6422 } |
6277 | 6423 |
6278 /** | 6424 /** |
6279 * Loop through all of the members in some [MemberMap], performing type parame
ter | 6425 * Loop through all of the members in some [MemberMap], performing type parame
ter |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6381 int numOfPositionalParams = _getNumOfPositionalParameters(element); | 6527 int numOfPositionalParams = _getNumOfPositionalParameters(element); |
6382 if (h < numOfPositionalParams) { | 6528 if (h < numOfPositionalParams) { |
6383 h = numOfPositionalParams; | 6529 h = numOfPositionalParams; |
6384 } | 6530 } |
6385 int numOfRequiredParams = _getNumOfRequiredParameters(element); | 6531 int numOfRequiredParams = _getNumOfRequiredParameters(element); |
6386 if (r > numOfRequiredParams) { | 6532 if (r > numOfRequiredParams) { |
6387 r = numOfRequiredParams; | 6533 r = numOfRequiredParams; |
6388 } | 6534 } |
6389 namedParametersList.addAll(_getNamedParameterNames(element)); | 6535 namedParametersList.addAll(_getNamedParameterNames(element)); |
6390 } | 6536 } |
6391 return _createSyntheticExecutableElement(elementArrayToMerge, | 6537 return _createSyntheticExecutableElement( |
6392 elementArrayToMerge[0].displayName, r, h - r, | 6538 elementArrayToMerge, |
| 6539 elementArrayToMerge[0].displayName, |
| 6540 r, |
| 6541 h - r, |
6393 new List.from(namedParametersList)); | 6542 new List.from(namedParametersList)); |
6394 } | 6543 } |
6395 | 6544 |
6396 /** | 6545 /** |
6397 * Used by [computeMergedExecutableElement] to actually create the | 6546 * Used by [computeMergedExecutableElement] to actually create the |
6398 * synthetic element. | 6547 * synthetic element. |
6399 * | 6548 * |
6400 * @param elementArrayToMerge the array used to create the synthetic element | 6549 * @param elementArrayToMerge the array used to create the synthetic element |
6401 * @param name the name of the method, getter or setter | 6550 * @param name the name of the method, getter or setter |
6402 * @param numOfRequiredParameters the number of required parameters | 6551 * @param numOfRequiredParameters the number of required parameters |
6403 * @param numOfPositionalParameters the number of positional parameters | 6552 * @param numOfPositionalParameters the number of positional parameters |
6404 * @param namedParameters the list of [String]s that are the named parameters | 6553 * @param namedParameters the list of [String]s that are the named parameters |
6405 * @return the created synthetic element | 6554 * @return the created synthetic element |
6406 */ | 6555 */ |
6407 static ExecutableElement _createSyntheticExecutableElement( | 6556 static ExecutableElement _createSyntheticExecutableElement( |
6408 List<ExecutableElement> elementArrayToMerge, String name, | 6557 List<ExecutableElement> elementArrayToMerge, |
6409 int numOfRequiredParameters, int numOfPositionalParameters, | 6558 String name, |
| 6559 int numOfRequiredParameters, |
| 6560 int numOfPositionalParameters, |
6410 List<String> namedParameters) { | 6561 List<String> namedParameters) { |
6411 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; | 6562 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance; |
6412 SimpleIdentifier nameIdentifier = new SimpleIdentifier( | 6563 SimpleIdentifier nameIdentifier = new SimpleIdentifier( |
6413 new sc.StringToken(sc.TokenType.IDENTIFIER, name, 0)); | 6564 new sc.StringToken(sc.TokenType.IDENTIFIER, name, 0)); |
6414 ExecutableElementImpl executable; | 6565 ExecutableElementImpl executable; |
6415 if (elementArrayToMerge[0] is MethodElement) { | 6566 if (elementArrayToMerge[0] is MethodElement) { |
6416 MultiplyInheritedMethodElementImpl unionedMethod = | 6567 MultiplyInheritedMethodElementImpl unionedMethod = |
6417 new MultiplyInheritedMethodElementImpl(nameIdentifier); | 6568 new MultiplyInheritedMethodElementImpl(nameIdentifier); |
6418 unionedMethod.inheritedElements = elementArrayToMerge; | 6569 unionedMethod.inheritedElements = elementArrayToMerge; |
6419 executable = unionedMethod; | 6570 executable = unionedMethod; |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6781 } | 6932 } |
6782 | 6933 |
6783 /** | 6934 /** |
6784 * Return the library element representing this library, creating it if necess
ary. | 6935 * Return the library element representing this library, creating it if necess
ary. |
6785 * | 6936 * |
6786 * @return the library element representing this library | 6937 * @return the library element representing this library |
6787 */ | 6938 */ |
6788 LibraryElementImpl get libraryElement { | 6939 LibraryElementImpl get libraryElement { |
6789 if (_libraryElement == null) { | 6940 if (_libraryElement == null) { |
6790 try { | 6941 try { |
6791 _libraryElement = _analysisContext | 6942 _libraryElement = _analysisContext.computeLibraryElement(librarySource) |
6792 .computeLibraryElement(librarySource) as LibraryElementImpl; | 6943 as LibraryElementImpl; |
6793 } on AnalysisException catch (exception, stackTrace) { | 6944 } on AnalysisException catch (exception, stackTrace) { |
6794 AnalysisEngine.instance.logger.logError( | 6945 AnalysisEngine.instance.logger.logError( |
6795 "Could not compute library element for ${librarySource.fullName}", | 6946 "Could not compute library element for ${librarySource.fullName}", |
6796 new CaughtException(exception, stackTrace)); | 6947 new CaughtException(exception, stackTrace)); |
6797 } | 6948 } |
6798 } | 6949 } |
6799 return _libraryElement; | 6950 return _libraryElement; |
6800 } | 6951 } |
6801 | 6952 |
6802 /** | 6953 /** |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6859 if (directive is ImportDirective && | 7010 if (directive is ImportDirective && |
6860 uriContent.startsWith(_DART_EXT_SCHEME)) { | 7011 uriContent.startsWith(_DART_EXT_SCHEME)) { |
6861 _libraryElement.hasExtUri = true; | 7012 _libraryElement.hasExtUri = true; |
6862 return null; | 7013 return null; |
6863 } | 7014 } |
6864 try { | 7015 try { |
6865 parseUriWithException(uriContent); | 7016 parseUriWithException(uriContent); |
6866 Source source = | 7017 Source source = |
6867 _analysisContext.sourceFactory.resolveUri(librarySource, uriContent); | 7018 _analysisContext.sourceFactory.resolveUri(librarySource, uriContent); |
6868 if (!_analysisContext.exists(source)) { | 7019 if (!_analysisContext.exists(source)) { |
6869 errorListener.onError(new AnalysisError(librarySource, | 7020 errorListener.onError(new AnalysisError( |
6870 uriLiteral.offset, uriLiteral.length, | 7021 librarySource, |
6871 CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent])); | 7022 uriLiteral.offset, |
| 7023 uriLiteral.length, |
| 7024 CompileTimeErrorCode.URI_DOES_NOT_EXIST, |
| 7025 [uriContent])); |
6872 } | 7026 } |
6873 return source; | 7027 return source; |
6874 } on URISyntaxException { | 7028 } on URISyntaxException { |
6875 errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset, | 7029 errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset, |
6876 uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent])); | 7030 uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent])); |
6877 } | 7031 } |
6878 return null; | 7032 return null; |
6879 } | 7033 } |
6880 | 7034 |
6881 /** | 7035 /** |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6927 * @throws AnalysisException if the analysis could not be performed | 7081 * @throws AnalysisException if the analysis could not be performed |
6928 */ | 7082 */ |
6929 LibraryElementImpl buildLibrary(Library library) { | 7083 LibraryElementImpl buildLibrary(Library library) { |
6930 CompilationUnitBuilder builder = new CompilationUnitBuilder(); | 7084 CompilationUnitBuilder builder = new CompilationUnitBuilder(); |
6931 Source librarySource = library.librarySource; | 7085 Source librarySource = library.librarySource; |
6932 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; | 7086 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; |
6933 CompilationUnitElementImpl definingCompilationUnitElement = builder | 7087 CompilationUnitElementImpl definingCompilationUnitElement = builder |
6934 .buildCompilationUnit( | 7088 .buildCompilationUnit( |
6935 librarySource, definingCompilationUnit, librarySource); | 7089 librarySource, definingCompilationUnit, librarySource); |
6936 NodeList<Directive> directives = definingCompilationUnit.directives; | 7090 NodeList<Directive> directives = definingCompilationUnit.directives; |
| 7091 LibraryDirective libraryDirective = null; |
6937 LibraryIdentifier libraryNameNode = null; | 7092 LibraryIdentifier libraryNameNode = null; |
6938 bool hasPartDirective = false; | 7093 bool hasPartDirective = false; |
6939 FunctionElement entryPoint = | 7094 FunctionElement entryPoint = |
6940 _findEntryPoint(definingCompilationUnitElement); | 7095 _findEntryPoint(definingCompilationUnitElement); |
6941 List<Directive> directivesToResolve = new List<Directive>(); | 7096 List<Directive> directivesToResolve = new List<Directive>(); |
6942 List<CompilationUnitElementImpl> sourcedCompilationUnits = | 7097 List<CompilationUnitElementImpl> sourcedCompilationUnits = |
6943 new List<CompilationUnitElementImpl>(); | 7098 new List<CompilationUnitElementImpl>(); |
6944 for (Directive directive in directives) { | 7099 for (Directive directive in directives) { |
6945 // | 7100 // |
6946 // We do not build the elements representing the import and export | 7101 // We do not build the elements representing the import and export |
6947 // directives at this point. That is not done until we get to | 7102 // directives at this point. That is not done until we get to |
6948 // LibraryResolver.buildDirectiveModels() because we need the | 7103 // LibraryResolver.buildDirectiveModels() because we need the |
6949 // LibraryElements for the referenced libraries, which might not exist at | 7104 // LibraryElements for the referenced libraries, which might not exist at |
6950 // this point (due to the possibility of circular references). | 7105 // this point (due to the possibility of circular references). |
6951 // | 7106 // |
6952 if (directive is LibraryDirective) { | 7107 if (directive is LibraryDirective) { |
6953 if (libraryNameNode == null) { | 7108 if (libraryNameNode == null) { |
| 7109 libraryDirective = directive; |
6954 libraryNameNode = directive.name; | 7110 libraryNameNode = directive.name; |
6955 directivesToResolve.add(directive); | 7111 directivesToResolve.add(directive); |
6956 } | 7112 } |
6957 } else if (directive is PartDirective) { | 7113 } else if (directive is PartDirective) { |
6958 PartDirective partDirective = directive; | 7114 PartDirective partDirective = directive; |
6959 StringLiteral partUri = partDirective.uri; | 7115 StringLiteral partUri = partDirective.uri; |
6960 Source partSource = partDirective.source; | 7116 Source partSource = partDirective.source; |
6961 if (_analysisContext.exists(partSource)) { | 7117 if (_analysisContext.exists(partSource)) { |
6962 hasPartDirective = true; | 7118 hasPartDirective = true; |
6963 CompilationUnit partUnit = library.getAST(partSource); | 7119 CompilationUnit partUnit = library.getAST(partSource); |
6964 CompilationUnitElementImpl part = | 7120 CompilationUnitElementImpl part = |
6965 builder.buildCompilationUnit(partSource, partUnit, librarySource); | 7121 builder.buildCompilationUnit(partSource, partUnit, librarySource); |
6966 part.uriOffset = partUri.offset; | 7122 part.uriOffset = partUri.offset; |
6967 part.uriEnd = partUri.end; | 7123 part.uriEnd = partUri.end; |
6968 part.uri = partDirective.uriContent; | 7124 part.uri = partDirective.uriContent; |
6969 // | 7125 // |
6970 // Validate that the part contains a part-of directive with the same | 7126 // Validate that the part contains a part-of directive with the same |
6971 // name as the library. | 7127 // name as the library. |
6972 // | 7128 // |
6973 String partLibraryName = | 7129 String partLibraryName = |
6974 _getPartLibraryName(partSource, partUnit, directivesToResolve); | 7130 _getPartLibraryName(partSource, partUnit, directivesToResolve); |
6975 if (partLibraryName == null) { | 7131 if (partLibraryName == null) { |
6976 _errorListener.onError(new AnalysisError(librarySource, | 7132 _errorListener.onError(new AnalysisError( |
6977 partUri.offset, partUri.length, | 7133 librarySource, |
6978 CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()])); | 7134 partUri.offset, |
| 7135 partUri.length, |
| 7136 CompileTimeErrorCode.PART_OF_NON_PART, |
| 7137 [partUri.toSource()])); |
6979 } else if (libraryNameNode == null) { | 7138 } else if (libraryNameNode == null) { |
6980 // TODO(brianwilkerson) Collect the names declared by the part. | 7139 // TODO(brianwilkerson) Collect the names declared by the part. |
6981 // If they are all the same then we can use that name as the | 7140 // If they are all the same then we can use that name as the |
6982 // inferred name of the library and present it in a quick-fix. | 7141 // inferred name of the library and present it in a quick-fix. |
6983 // partLibraryNames.add(partLibraryName); | 7142 // partLibraryNames.add(partLibraryName); |
6984 } else if (libraryNameNode.name != partLibraryName) { | 7143 } else if (libraryNameNode.name != partLibraryName) { |
6985 _errorListener.onError(new AnalysisError(librarySource, | 7144 _errorListener.onError(new AnalysisError( |
6986 partUri.offset, partUri.length, | 7145 librarySource, |
6987 StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [ | 7146 partUri.offset, |
6988 libraryNameNode.name, | 7147 partUri.length, |
6989 partLibraryName | 7148 StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, |
6990 ])); | 7149 [libraryNameNode.name, partLibraryName])); |
6991 } | 7150 } |
6992 if (entryPoint == null) { | 7151 if (entryPoint == null) { |
6993 entryPoint = _findEntryPoint(part); | 7152 entryPoint = _findEntryPoint(part); |
6994 } | 7153 } |
6995 directive.element = part; | 7154 directive.element = part; |
6996 sourcedCompilationUnits.add(part); | 7155 sourcedCompilationUnits.add(part); |
6997 } | 7156 } |
6998 } | 7157 } |
6999 } | 7158 } |
7000 if (hasPartDirective && libraryNameNode == null) { | 7159 if (hasPartDirective && libraryNameNode == null) { |
7001 _errorListener.onError(new AnalysisError(librarySource, 0, 0, | 7160 _errorListener.onError(new AnalysisError(librarySource, 0, 0, |
7002 ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)); | 7161 ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)); |
7003 } | 7162 } |
7004 // | 7163 // |
7005 // Create and populate the library element. | 7164 // Create and populate the library element. |
7006 // | 7165 // |
7007 LibraryElementImpl libraryElement = new LibraryElementImpl.forNode( | 7166 LibraryElementImpl libraryElement = new LibraryElementImpl.forNode( |
7008 _analysisContext.getContextFor(librarySource), libraryNameNode); | 7167 _analysisContext.getContextFor(librarySource), libraryNameNode); |
| 7168 _setDocRange(libraryElement, libraryDirective); |
7009 libraryElement.definingCompilationUnit = definingCompilationUnitElement; | 7169 libraryElement.definingCompilationUnit = definingCompilationUnitElement; |
7010 if (entryPoint != null) { | 7170 if (entryPoint != null) { |
7011 libraryElement.entryPoint = entryPoint; | 7171 libraryElement.entryPoint = entryPoint; |
7012 } | 7172 } |
7013 int sourcedUnitCount = sourcedCompilationUnits.length; | 7173 int sourcedUnitCount = sourcedCompilationUnits.length; |
7014 libraryElement.parts = sourcedCompilationUnits; | 7174 libraryElement.parts = sourcedCompilationUnits; |
7015 for (Directive directive in directivesToResolve) { | 7175 for (Directive directive in directivesToResolve) { |
7016 directive.element = libraryElement; | 7176 directive.element = libraryElement; |
7017 } | 7177 } |
7018 library.libraryElement = libraryElement; | 7178 library.libraryElement = libraryElement; |
(...skipping 11 matching lines...) Expand all Loading... |
7030 * @throws AnalysisException if the analysis could not be performed | 7190 * @throws AnalysisException if the analysis could not be performed |
7031 */ | 7191 */ |
7032 void buildLibrary2(ResolvableLibrary library) { | 7192 void buildLibrary2(ResolvableLibrary library) { |
7033 CompilationUnitBuilder builder = new CompilationUnitBuilder(); | 7193 CompilationUnitBuilder builder = new CompilationUnitBuilder(); |
7034 Source librarySource = library.librarySource; | 7194 Source librarySource = library.librarySource; |
7035 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; | 7195 CompilationUnit definingCompilationUnit = library.definingCompilationUnit; |
7036 CompilationUnitElementImpl definingCompilationUnitElement = builder | 7196 CompilationUnitElementImpl definingCompilationUnitElement = builder |
7037 .buildCompilationUnit( | 7197 .buildCompilationUnit( |
7038 librarySource, definingCompilationUnit, librarySource); | 7198 librarySource, definingCompilationUnit, librarySource); |
7039 NodeList<Directive> directives = definingCompilationUnit.directives; | 7199 NodeList<Directive> directives = definingCompilationUnit.directives; |
| 7200 LibraryDirective libraryDirective = null; |
7040 LibraryIdentifier libraryNameNode = null; | 7201 LibraryIdentifier libraryNameNode = null; |
7041 bool hasPartDirective = false; | 7202 bool hasPartDirective = false; |
7042 FunctionElement entryPoint = | 7203 FunctionElement entryPoint = |
7043 _findEntryPoint(definingCompilationUnitElement); | 7204 _findEntryPoint(definingCompilationUnitElement); |
7044 List<Directive> directivesToResolve = new List<Directive>(); | 7205 List<Directive> directivesToResolve = new List<Directive>(); |
7045 List<CompilationUnitElementImpl> sourcedCompilationUnits = | 7206 List<CompilationUnitElementImpl> sourcedCompilationUnits = |
7046 new List<CompilationUnitElementImpl>(); | 7207 new List<CompilationUnitElementImpl>(); |
7047 for (Directive directive in directives) { | 7208 for (Directive directive in directives) { |
7048 // | 7209 // |
7049 // We do not build the elements representing the import and export | 7210 // We do not build the elements representing the import and export |
7050 // directives at this point. That is not done until we get to | 7211 // directives at this point. That is not done until we get to |
7051 // LibraryResolver.buildDirectiveModels() because we need the | 7212 // LibraryResolver.buildDirectiveModels() because we need the |
7052 // LibraryElements for the referenced libraries, which might not exist at | 7213 // LibraryElements for the referenced libraries, which might not exist at |
7053 // this point (due to the possibility of circular references). | 7214 // this point (due to the possibility of circular references). |
7054 // | 7215 // |
7055 if (directive is LibraryDirective) { | 7216 if (directive is LibraryDirective) { |
7056 if (libraryNameNode == null) { | 7217 if (libraryNameNode == null) { |
| 7218 libraryDirective = directive; |
7057 libraryNameNode = directive.name; | 7219 libraryNameNode = directive.name; |
7058 directivesToResolve.add(directive); | 7220 directivesToResolve.add(directive); |
7059 } | 7221 } |
7060 } else if (directive is PartDirective) { | 7222 } else if (directive is PartDirective) { |
7061 PartDirective partDirective = directive; | 7223 PartDirective partDirective = directive; |
7062 StringLiteral partUri = partDirective.uri; | 7224 StringLiteral partUri = partDirective.uri; |
7063 Source partSource = partDirective.source; | 7225 Source partSource = partDirective.source; |
7064 if (_analysisContext.exists(partSource)) { | 7226 if (_analysisContext.exists(partSource)) { |
7065 hasPartDirective = true; | 7227 hasPartDirective = true; |
7066 CompilationUnit partUnit = library.getAST(partSource); | 7228 CompilationUnit partUnit = library.getAST(partSource); |
7067 if (partUnit != null) { | 7229 if (partUnit != null) { |
7068 CompilationUnitElementImpl part = builder.buildCompilationUnit( | 7230 CompilationUnitElementImpl part = builder.buildCompilationUnit( |
7069 partSource, partUnit, librarySource); | 7231 partSource, partUnit, librarySource); |
7070 part.uriOffset = partUri.offset; | 7232 part.uriOffset = partUri.offset; |
7071 part.uriEnd = partUri.end; | 7233 part.uriEnd = partUri.end; |
7072 part.uri = partDirective.uriContent; | 7234 part.uri = partDirective.uriContent; |
7073 // | 7235 // |
7074 // Validate that the part contains a part-of directive with the same | 7236 // Validate that the part contains a part-of directive with the same |
7075 // name as the library. | 7237 // name as the library. |
7076 // | 7238 // |
7077 String partLibraryName = | 7239 String partLibraryName = |
7078 _getPartLibraryName(partSource, partUnit, directivesToResolve); | 7240 _getPartLibraryName(partSource, partUnit, directivesToResolve); |
7079 if (partLibraryName == null) { | 7241 if (partLibraryName == null) { |
7080 _errorListener.onError(new AnalysisError(librarySource, | 7242 _errorListener.onError(new AnalysisError( |
7081 partUri.offset, partUri.length, | 7243 librarySource, |
7082 CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()])); | 7244 partUri.offset, |
| 7245 partUri.length, |
| 7246 CompileTimeErrorCode.PART_OF_NON_PART, |
| 7247 [partUri.toSource()])); |
7083 } else if (libraryNameNode == null) { | 7248 } else if (libraryNameNode == null) { |
7084 // TODO(brianwilkerson) Collect the names declared by the part. | 7249 // TODO(brianwilkerson) Collect the names declared by the part. |
7085 // If they are all the same then we can use that name as the | 7250 // If they are all the same then we can use that name as the |
7086 // inferred name of the library and present it in a quick-fix. | 7251 // inferred name of the library and present it in a quick-fix. |
7087 // partLibraryNames.add(partLibraryName); | 7252 // partLibraryNames.add(partLibraryName); |
7088 } else if (libraryNameNode.name != partLibraryName) { | 7253 } else if (libraryNameNode.name != partLibraryName) { |
7089 _errorListener.onError(new AnalysisError(librarySource, | 7254 _errorListener.onError(new AnalysisError( |
7090 partUri.offset, partUri.length, | 7255 librarySource, |
7091 StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [ | 7256 partUri.offset, |
7092 libraryNameNode.name, | 7257 partUri.length, |
7093 partLibraryName | 7258 StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, |
7094 ])); | 7259 [libraryNameNode.name, partLibraryName])); |
7095 } | 7260 } |
7096 if (entryPoint == null) { | 7261 if (entryPoint == null) { |
7097 entryPoint = _findEntryPoint(part); | 7262 entryPoint = _findEntryPoint(part); |
7098 } | 7263 } |
7099 directive.element = part; | 7264 directive.element = part; |
7100 sourcedCompilationUnits.add(part); | 7265 sourcedCompilationUnits.add(part); |
7101 } | 7266 } |
7102 } | 7267 } |
7103 } | 7268 } |
7104 } | 7269 } |
7105 if (hasPartDirective && libraryNameNode == null) { | 7270 if (hasPartDirective && libraryNameNode == null) { |
7106 _errorListener.onError(new AnalysisError(librarySource, 0, 0, | 7271 _errorListener.onError(new AnalysisError(librarySource, 0, 0, |
7107 ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)); | 7272 ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)); |
7108 } | 7273 } |
7109 // | 7274 // |
7110 // Create and populate the library element. | 7275 // Create and populate the library element. |
7111 // | 7276 // |
7112 LibraryElementImpl libraryElement = new LibraryElementImpl.forNode( | 7277 LibraryElementImpl libraryElement = new LibraryElementImpl.forNode( |
7113 _analysisContext.getContextFor(librarySource), libraryNameNode); | 7278 _analysisContext.getContextFor(librarySource), libraryNameNode); |
| 7279 _setDocRange(libraryElement, libraryDirective); |
7114 libraryElement.definingCompilationUnit = definingCompilationUnitElement; | 7280 libraryElement.definingCompilationUnit = definingCompilationUnitElement; |
7115 if (entryPoint != null) { | 7281 if (entryPoint != null) { |
7116 libraryElement.entryPoint = entryPoint; | 7282 libraryElement.entryPoint = entryPoint; |
7117 } | 7283 } |
7118 int sourcedUnitCount = sourcedCompilationUnits.length; | 7284 int sourcedUnitCount = sourcedCompilationUnits.length; |
7119 libraryElement.parts = sourcedCompilationUnits; | 7285 libraryElement.parts = sourcedCompilationUnits; |
7120 for (Directive directive in directivesToResolve) { | 7286 for (Directive directive in directivesToResolve) { |
7121 directive.element = libraryElement; | 7287 directive.element = libraryElement; |
7122 } | 7288 } |
7123 library.libraryElement = libraryElement; | 7289 library.libraryElement = libraryElement; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7207 for (PropertyAccessorElement setter in setters) { | 7373 for (PropertyAccessorElement setter in setters) { |
7208 PropertyAccessorElement getter = getters[setter.displayName]; | 7374 PropertyAccessorElement getter = getters[setter.displayName]; |
7209 if (getter != null) { | 7375 if (getter != null) { |
7210 PropertyInducingElementImpl variable = | 7376 PropertyInducingElementImpl variable = |
7211 getter.variable as PropertyInducingElementImpl; | 7377 getter.variable as PropertyInducingElementImpl; |
7212 variable.setter = setter; | 7378 variable.setter = setter; |
7213 (setter as PropertyAccessorElementImpl).variable = variable; | 7379 (setter as PropertyAccessorElementImpl).variable = variable; |
7214 } | 7380 } |
7215 } | 7381 } |
7216 } | 7382 } |
| 7383 |
| 7384 /** |
| 7385 * If the given [node] has a documentation comment, remember its range |
| 7386 * into the given [element]. |
| 7387 */ |
| 7388 void _setDocRange(ElementImpl element, LibraryDirective node) { |
| 7389 if (node != null) { |
| 7390 Comment comment = node.documentationComment; |
| 7391 if (comment != null && comment.isDocumentation) { |
| 7392 element.setDocRange(comment.offset, comment.length); |
| 7393 } |
| 7394 } |
| 7395 } |
7217 } | 7396 } |
7218 | 7397 |
7219 /** | 7398 /** |
7220 * Instances of the class `LibraryImportScope` represent the scope containing al
l of the names | 7399 * Instances of the class `LibraryImportScope` represent the scope containing al
l of the names |
7221 * available from imported libraries. | 7400 * available from imported libraries. |
7222 */ | 7401 */ |
7223 class LibraryImportScope extends Scope { | 7402 class LibraryImportScope extends Scope { |
7224 /** | 7403 /** |
7225 * The element representing the library in which this scope is enclosed. | 7404 * The element representing the library in which this scope is enclosed. |
7226 */ | 7405 */ |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7289 } | 7468 } |
7290 if (foundElement is MultiplyDefinedElementImpl) { | 7469 if (foundElement is MultiplyDefinedElementImpl) { |
7291 String foundEltName = foundElement.displayName; | 7470 String foundEltName = foundElement.displayName; |
7292 List<Element> conflictingMembers = foundElement.conflictingElements; | 7471 List<Element> conflictingMembers = foundElement.conflictingElements; |
7293 int count = conflictingMembers.length; | 7472 int count = conflictingMembers.length; |
7294 List<String> libraryNames = new List<String>(count); | 7473 List<String> libraryNames = new List<String>(count); |
7295 for (int i = 0; i < count; i++) { | 7474 for (int i = 0; i < count; i++) { |
7296 libraryNames[i] = _getLibraryName(conflictingMembers[i]); | 7475 libraryNames[i] = _getLibraryName(conflictingMembers[i]); |
7297 } | 7476 } |
7298 libraryNames.sort(); | 7477 libraryNames.sort(); |
7299 errorListener.onError(new AnalysisError(getSource(identifier), | 7478 errorListener.onError(new AnalysisError( |
7300 identifier.offset, identifier.length, | 7479 getSource(identifier), |
| 7480 identifier.offset, |
| 7481 identifier.length, |
7301 StaticWarningCode.AMBIGUOUS_IMPORT, [ | 7482 StaticWarningCode.AMBIGUOUS_IMPORT, [ |
7302 foundEltName, | 7483 foundEltName, |
7303 StringUtilities.printListOfQuotedNames(libraryNames) | 7484 StringUtilities.printListOfQuotedNames(libraryNames) |
7304 ])); | 7485 ])); |
7305 return foundElement; | 7486 return foundElement; |
7306 } | 7487 } |
7307 if (foundElement != null) { | 7488 if (foundElement != null) { |
7308 defineNameWithoutChecking(name, foundElement); | 7489 defineNameWithoutChecking(name, foundElement); |
7309 } | 7490 } |
7310 return foundElement; | 7491 return foundElement; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7391 for (Element member in conflictingElements) { | 7572 for (Element member in conflictingElements) { |
7392 if (member.library.isInSdk) { | 7573 if (member.library.isInSdk) { |
7393 sdkElement = member; | 7574 sdkElement = member; |
7394 } else { | 7575 } else { |
7395 nonSdkElements.add(member); | 7576 nonSdkElements.add(member); |
7396 } | 7577 } |
7397 } | 7578 } |
7398 if (sdkElement != null && nonSdkElements.length > 0) { | 7579 if (sdkElement != null && nonSdkElements.length > 0) { |
7399 String sdkLibName = _getLibraryName(sdkElement); | 7580 String sdkLibName = _getLibraryName(sdkElement); |
7400 String otherLibName = _getLibraryName(nonSdkElements[0]); | 7581 String otherLibName = _getLibraryName(nonSdkElements[0]); |
7401 errorListener.onError(new AnalysisError(getSource(identifier), | 7582 errorListener.onError(new AnalysisError( |
7402 identifier.offset, identifier.length, | 7583 getSource(identifier), |
7403 StaticWarningCode.CONFLICTING_DART_IMPORT, [ | 7584 identifier.offset, |
7404 name, | 7585 identifier.length, |
7405 sdkLibName, | 7586 StaticWarningCode.CONFLICTING_DART_IMPORT, |
7406 otherLibName | 7587 [name, sdkLibName, otherLibName])); |
7407 ])); | |
7408 } | 7588 } |
7409 if (nonSdkElements.length == conflictingElements.length) { | 7589 if (nonSdkElements.length == conflictingElements.length) { |
7410 // None of the members were removed | 7590 // None of the members were removed |
7411 return foundElement; | 7591 return foundElement; |
7412 } else if (nonSdkElements.length == 1) { | 7592 } else if (nonSdkElements.length == 1) { |
7413 // All but one member was removed | 7593 // All but one member was removed |
7414 return nonSdkElements[0]; | 7594 return nonSdkElements[0]; |
7415 } else if (nonSdkElements.length == 0) { | 7595 } else if (nonSdkElements.length == 0) { |
7416 // All members were removed | 7596 // All members were removed |
7417 AnalysisEngine.instance.logger | 7597 AnalysisEngine.instance.logger |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7459 * The object representing the async library. | 7639 * The object representing the async library. |
7460 */ | 7640 */ |
7461 Library _asyncLibrary; | 7641 Library _asyncLibrary; |
7462 | 7642 |
7463 /** | 7643 /** |
7464 * The object used to access the types from the core library. | 7644 * The object used to access the types from the core library. |
7465 */ | 7645 */ |
7466 TypeProvider _typeProvider; | 7646 TypeProvider _typeProvider; |
7467 | 7647 |
7468 /** | 7648 /** |
| 7649 * The type system in use for the library |
| 7650 */ |
| 7651 TypeSystem _typeSystem; |
| 7652 |
| 7653 /** |
7469 * A table mapping library sources to the information being maintained for tho
se libraries. | 7654 * A table mapping library sources to the information being maintained for tho
se libraries. |
7470 */ | 7655 */ |
7471 HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>(); | 7656 HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>(); |
7472 | 7657 |
7473 /** | 7658 /** |
7474 * A collection containing the libraries that are being resolved together. | 7659 * A collection containing the libraries that are being resolved together. |
7475 */ | 7660 */ |
7476 Set<Library> _librariesInCycles; | 7661 Set<Library> _librariesInCycles; |
7477 | 7662 |
7478 /** | 7663 /** |
(...skipping 22 matching lines...) Expand all Loading... |
7501 * @return an array containing the libraries that were resolved | 7686 * @return an array containing the libraries that were resolved |
7502 */ | 7687 */ |
7503 Set<Library> get resolvedLibraries => _librariesInCycles; | 7688 Set<Library> get resolvedLibraries => _librariesInCycles; |
7504 | 7689 |
7505 /** | 7690 /** |
7506 * The object used to access the types from the core library. | 7691 * The object used to access the types from the core library. |
7507 */ | 7692 */ |
7508 TypeProvider get typeProvider => _typeProvider; | 7693 TypeProvider get typeProvider => _typeProvider; |
7509 | 7694 |
7510 /** | 7695 /** |
| 7696 * The type system in use. |
| 7697 */ |
| 7698 TypeSystem get typeSystem => _typeSystem; |
| 7699 |
| 7700 /** |
7511 * Create an object to represent the information about the library defined by
the compilation unit | 7701 * Create an object to represent the information about the library defined by
the compilation unit |
7512 * with the given source. | 7702 * with the given source. |
7513 * | 7703 * |
7514 * @param librarySource the source of the library's defining compilation unit | 7704 * @param librarySource the source of the library's defining compilation unit |
7515 * @return the library object that was created | 7705 * @return the library object that was created |
7516 * @throws AnalysisException if the library source is not valid | 7706 * @throws AnalysisException if the library source is not valid |
7517 */ | 7707 */ |
7518 Library createLibrary(Source librarySource) { | 7708 Library createLibrary(Source librarySource) { |
7519 Library library = | 7709 Library library = |
7520 new Library(analysisContext, _errorListener, librarySource); | 7710 new Library(analysisContext, _errorListener, librarySource); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7585 LibraryElement coreElement = _coreLibrary.libraryElement; | 7775 LibraryElement coreElement = _coreLibrary.libraryElement; |
7586 if (coreElement == null) { | 7776 if (coreElement == null) { |
7587 throw new AnalysisException("Could not resolve dart:core"); | 7777 throw new AnalysisException("Could not resolve dart:core"); |
7588 } | 7778 } |
7589 LibraryElement asyncElement = _asyncLibrary.libraryElement; | 7779 LibraryElement asyncElement = _asyncLibrary.libraryElement; |
7590 if (asyncElement == null) { | 7780 if (asyncElement == null) { |
7591 throw new AnalysisException("Could not resolve dart:async"); | 7781 throw new AnalysisException("Could not resolve dart:async"); |
7592 } | 7782 } |
7593 _buildDirectiveModels(); | 7783 _buildDirectiveModels(); |
7594 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); | 7784 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); |
| 7785 _typeSystem = TypeSystem.create(analysisContext); |
7595 _buildTypeHierarchies(); | 7786 _buildTypeHierarchies(); |
7596 // | 7787 // |
7597 // Perform resolution and type analysis. | 7788 // Perform resolution and type analysis. |
7598 // | 7789 // |
7599 // TODO(brianwilkerson) Decide whether we want to resolve all of the | 7790 // TODO(brianwilkerson) Decide whether we want to resolve all of the |
7600 // libraries or whether we want to only resolve the target library. | 7791 // libraries or whether we want to only resolve the target library. |
7601 // The advantage to resolving everything is that we have already done part | 7792 // The advantage to resolving everything is that we have already done part |
7602 // of the work so we'll avoid duplicated effort. The disadvantage of | 7793 // of the work so we'll avoid duplicated effort. The disadvantage of |
7603 // resolving everything is that we might do extra work that we don't | 7794 // resolving everything is that we might do extra work that we don't |
7604 // really care about. Another possibility is to add a parameter to this | 7795 // really care about. Another possibility is to add a parameter to this |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7663 LibraryElement coreElement = _coreLibrary.libraryElement; | 7854 LibraryElement coreElement = _coreLibrary.libraryElement; |
7664 if (coreElement == null) { | 7855 if (coreElement == null) { |
7665 throw new AnalysisException("Could not resolve dart:core"); | 7856 throw new AnalysisException("Could not resolve dart:core"); |
7666 } | 7857 } |
7667 LibraryElement asyncElement = _asyncLibrary.libraryElement; | 7858 LibraryElement asyncElement = _asyncLibrary.libraryElement; |
7668 if (asyncElement == null) { | 7859 if (asyncElement == null) { |
7669 throw new AnalysisException("Could not resolve dart:async"); | 7860 throw new AnalysisException("Could not resolve dart:async"); |
7670 } | 7861 } |
7671 _buildDirectiveModels(); | 7862 _buildDirectiveModels(); |
7672 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); | 7863 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); |
| 7864 _typeSystem = TypeSystem.create(analysisContext); |
7673 _buildEnumMembers(); | 7865 _buildEnumMembers(); |
7674 _buildTypeHierarchies(); | 7866 _buildTypeHierarchies(); |
7675 // | 7867 // |
7676 // Perform resolution and type analysis. | 7868 // Perform resolution and type analysis. |
7677 // | 7869 // |
7678 // TODO(brianwilkerson) Decide whether we want to resolve all of the | 7870 // TODO(brianwilkerson) Decide whether we want to resolve all of the |
7679 // libraries or whether we want to only resolve the target library. The | 7871 // libraries or whether we want to only resolve the target library. The |
7680 // advantage to resolving everything is that we have already done part of | 7872 // advantage to resolving everything is that we have already done part of |
7681 // the work so we'll avoid duplicated effort. The disadvantage of | 7873 // the work so we'll avoid duplicated effort. The disadvantage of |
7682 // resolving everything is that we might do extra work that we don't | 7874 // resolving everything is that we might do extra work that we don't |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7746 | 7938 |
7747 /** | 7939 /** |
7748 * Add the given library, and all libraries reachable from it that have not al
ready been visited, | 7940 * Add the given library, and all libraries reachable from it that have not al
ready been visited, |
7749 * to the given dependency map. | 7941 * to the given dependency map. |
7750 * | 7942 * |
7751 * @param library the library currently being added to the dependency map | 7943 * @param library the library currently being added to the dependency map |
7752 * @param dependencyMap the dependency map being computed | 7944 * @param dependencyMap the dependency map being computed |
7753 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite | 7945 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite |
7754 * recursion | 7946 * recursion |
7755 */ | 7947 */ |
7756 void _addToDependencyMap(Library library, | 7948 void _addToDependencyMap( |
| 7949 Library library, |
7757 HashMap<Library, List<Library>> dependencyMap, | 7950 HashMap<Library, List<Library>> dependencyMap, |
7758 Set<Library> visitedLibraries) { | 7951 Set<Library> visitedLibraries) { |
7759 if (visitedLibraries.add(library)) { | 7952 if (visitedLibraries.add(library)) { |
7760 bool asyncFound = false; | 7953 bool asyncFound = false; |
7761 for (Library referencedLibrary in library.importsAndExports) { | 7954 for (Library referencedLibrary in library.importsAndExports) { |
7762 _addDependencyToMap(dependencyMap, library, referencedLibrary); | 7955 _addDependencyToMap(dependencyMap, library, referencedLibrary); |
7763 _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); | 7956 _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); |
7764 if (identical(referencedLibrary, _asyncLibrary)) { | 7957 if (identical(referencedLibrary, _asyncLibrary)) { |
7765 asyncFound = true; | 7958 asyncFound = true; |
7766 } | 7959 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7851 importElement.prefix = prefix; | 8044 importElement.prefix = prefix; |
7852 prefixNode.staticElement = prefix; | 8045 prefixNode.staticElement = prefix; |
7853 } | 8046 } |
7854 directive.element = importElement; | 8047 directive.element = importElement; |
7855 imports.add(importElement); | 8048 imports.add(importElement); |
7856 if (analysisContext.computeKindOf(importedSource) != | 8049 if (analysisContext.computeKindOf(importedSource) != |
7857 SourceKind.LIBRARY) { | 8050 SourceKind.LIBRARY) { |
7858 ErrorCode errorCode = (importElement.isDeferred | 8051 ErrorCode errorCode = (importElement.isDeferred |
7859 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY | 8052 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY |
7860 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); | 8053 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); |
7861 _errorListener.onError(new AnalysisError(library.librarySource, | 8054 _errorListener.onError(new AnalysisError( |
7862 uriLiteral.offset, uriLiteral.length, errorCode, | 8055 library.librarySource, |
| 8056 uriLiteral.offset, |
| 8057 uriLiteral.length, |
| 8058 errorCode, |
7863 [uriLiteral.toSource()])); | 8059 [uriLiteral.toSource()])); |
7864 } | 8060 } |
7865 } | 8061 } |
7866 } | 8062 } |
7867 } else if (directive is ExportDirective) { | 8063 } else if (directive is ExportDirective) { |
7868 ExportDirective exportDirective = directive; | 8064 ExportDirective exportDirective = directive; |
7869 Source exportedSource = exportDirective.source; | 8065 Source exportedSource = exportDirective.source; |
7870 if (exportedSource != null) { | 8066 if (exportedSource != null) { |
7871 // The exported source will be null if the URI in the export | 8067 // The exported source will be null if the URI in the export |
7872 // directive was invalid. | 8068 // directive was invalid. |
7873 Library exportedLibrary = _libraryMap[exportedSource]; | 8069 Library exportedLibrary = _libraryMap[exportedSource]; |
7874 if (exportedLibrary != null) { | 8070 if (exportedLibrary != null) { |
7875 ExportElementImpl exportElement = | 8071 ExportElementImpl exportElement = |
7876 new ExportElementImpl(directive.offset); | 8072 new ExportElementImpl(directive.offset); |
7877 StringLiteral uriLiteral = exportDirective.uri; | 8073 StringLiteral uriLiteral = exportDirective.uri; |
7878 exportElement.uriOffset = uriLiteral.offset; | 8074 exportElement.uriOffset = uriLiteral.offset; |
7879 exportElement.uriEnd = uriLiteral.end; | 8075 exportElement.uriEnd = uriLiteral.end; |
7880 exportElement.uri = exportDirective.uriContent; | 8076 exportElement.uri = exportDirective.uriContent; |
7881 exportElement.combinators = _buildCombinators(exportDirective); | 8077 exportElement.combinators = _buildCombinators(exportDirective); |
7882 LibraryElement exportedLibraryElement = | 8078 LibraryElement exportedLibraryElement = |
7883 exportedLibrary.libraryElement; | 8079 exportedLibrary.libraryElement; |
7884 if (exportedLibraryElement != null) { | 8080 if (exportedLibraryElement != null) { |
7885 exportElement.exportedLibrary = exportedLibraryElement; | 8081 exportElement.exportedLibrary = exportedLibraryElement; |
7886 } | 8082 } |
7887 directive.element = exportElement; | 8083 directive.element = exportElement; |
7888 exports.add(exportElement); | 8084 exports.add(exportElement); |
7889 if (analysisContext.computeKindOf(exportedSource) != | 8085 if (analysisContext.computeKindOf(exportedSource) != |
7890 SourceKind.LIBRARY) { | 8086 SourceKind.LIBRARY) { |
7891 _errorListener.onError(new AnalysisError(library.librarySource, | 8087 _errorListener.onError(new AnalysisError( |
7892 uriLiteral.offset, uriLiteral.length, | 8088 library.librarySource, |
| 8089 uriLiteral.offset, |
| 8090 uriLiteral.length, |
7893 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, | 8091 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, |
7894 [uriLiteral.toSource()])); | 8092 [uriLiteral.toSource()])); |
7895 } | 8093 } |
7896 } | 8094 } |
7897 } | 8095 } |
7898 } | 8096 } |
7899 } | 8097 } |
7900 Source librarySource = library.librarySource; | 8098 Source librarySource = library.librarySource; |
7901 if (!library.explicitlyImportsCore && | 8099 if (!library.explicitlyImportsCore && |
7902 _coreLibrarySource != librarySource) { | 8100 _coreLibrarySource != librarySource) { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8039 | 8237 |
8040 /** | 8238 /** |
8041 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 8239 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
8042 * class [Library] to represent them, and record the references in the library
objects. | 8240 * class [Library] to represent them, and record the references in the library
objects. |
8043 * | 8241 * |
8044 * @param library the library to be processed to find libraries that have not
yet been traversed | 8242 * @param library the library to be processed to find libraries that have not
yet been traversed |
8045 * @throws AnalysisException if some portion of the library graph could not be
traversed | 8243 * @throws AnalysisException if some portion of the library graph could not be
traversed |
8046 */ | 8244 */ |
8047 void _computeLibraryDependencies(Library library) { | 8245 void _computeLibraryDependencies(Library library) { |
8048 Source librarySource = library.librarySource; | 8246 Source librarySource = library.librarySource; |
8049 _computeLibraryDependenciesFromDirectives(library, | 8247 _computeLibraryDependenciesFromDirectives( |
| 8248 library, |
8050 analysisContext.computeImportedLibraries(librarySource), | 8249 analysisContext.computeImportedLibraries(librarySource), |
8051 analysisContext.computeExportedLibraries(librarySource)); | 8250 analysisContext.computeExportedLibraries(librarySource)); |
8052 } | 8251 } |
8053 | 8252 |
8054 /** | 8253 /** |
8055 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 8254 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
8056 * class [Library] to represent them, and record the references in the library
objects. | 8255 * class [Library] to represent them, and record the references in the library
objects. |
8057 * | 8256 * |
8058 * @param library the library to be processed to find libraries that have not
yet been traversed | 8257 * @param library the library to be processed to find libraries that have not
yet been traversed |
8059 * @param importedSources an array containing the sources that are imported in
to the given library | 8258 * @param importedSources an array containing the sources that are imported in
to the given library |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8168 } | 8367 } |
8169 return identifiers; | 8368 return identifiers; |
8170 } | 8369 } |
8171 | 8370 |
8172 /** | 8371 /** |
8173 * Compute a value for all of the constants in the libraries being analyzed. | 8372 * Compute a value for all of the constants in the libraries being analyzed. |
8174 */ | 8373 */ |
8175 void _performConstantEvaluation() { | 8374 void _performConstantEvaluation() { |
8176 PerformanceStatistics.resolve.makeCurrentWhile(() { | 8375 PerformanceStatistics.resolve.makeCurrentWhile(() { |
8177 ConstantValueComputer computer = new ConstantValueComputer( | 8376 ConstantValueComputer computer = new ConstantValueComputer( |
8178 analysisContext, _typeProvider, analysisContext.declaredVariables); | 8377 analysisContext, |
| 8378 _typeProvider, |
| 8379 analysisContext.declaredVariables, |
| 8380 null, |
| 8381 _typeSystem); |
8179 for (Library library in _librariesInCycles) { | 8382 for (Library library in _librariesInCycles) { |
8180 for (Source source in library.compilationUnitSources) { | 8383 for (Source source in library.compilationUnitSources) { |
8181 try { | 8384 try { |
8182 CompilationUnit unit = library.getAST(source); | 8385 CompilationUnit unit = library.getAST(source); |
8183 if (unit != null) { | 8386 if (unit != null) { |
8184 computer.add(unit, source, library.librarySource); | 8387 computer.add(unit, source, library.librarySource); |
8185 } | 8388 } |
8186 } on AnalysisException catch (exception, stackTrace) { | 8389 } on AnalysisException catch (exception, stackTrace) { |
8187 AnalysisEngine.instance.logger.logError( | 8390 AnalysisEngine.instance.logger.logError( |
8188 "Internal Error: Could not access AST for ${source.fullName} dur
ing constant evaluation", | 8391 "Internal Error: Could not access AST for ${source.fullName} dur
ing constant evaluation", |
8189 new CaughtException(exception, stackTrace)); | 8392 new CaughtException(exception, stackTrace)); |
8190 } | 8393 } |
8191 } | 8394 } |
8192 } | 8395 } |
8193 computer.computeValues(); | 8396 computer.computeValues(); |
8194 // As a temporary workaround for issue 21572, run ConstantVerifier now. | 8397 // As a temporary workaround for issue 21572, run ConstantVerifier now. |
8195 // TODO(paulberry): remove this workaround once issue 21572 is fixed. | 8398 // TODO(paulberry): remove this workaround once issue 21572 is fixed. |
8196 for (Library library in _librariesInCycles) { | 8399 for (Library library in _librariesInCycles) { |
8197 for (Source source in library.compilationUnitSources) { | 8400 for (Source source in library.compilationUnitSources) { |
8198 try { | 8401 try { |
8199 CompilationUnit unit = library.getAST(source); | 8402 CompilationUnit unit = library.getAST(source); |
8200 ErrorReporter errorReporter = | 8403 ErrorReporter errorReporter = |
8201 new ErrorReporter(_errorListener, source); | 8404 new ErrorReporter(_errorListener, source); |
8202 ConstantVerifier constantVerifier = new ConstantVerifier( | 8405 ConstantVerifier constantVerifier = new ConstantVerifier( |
8203 errorReporter, library.libraryElement, _typeProvider, | 8406 errorReporter, |
| 8407 library.libraryElement, |
| 8408 _typeProvider, |
8204 analysisContext.declaredVariables); | 8409 analysisContext.declaredVariables); |
8205 unit.accept(constantVerifier); | 8410 unit.accept(constantVerifier); |
8206 } on AnalysisException catch (exception, stackTrace) { | 8411 } on AnalysisException catch (exception, stackTrace) { |
8207 AnalysisEngine.instance.logger.logError( | 8412 AnalysisEngine.instance.logger.logError( |
8208 "Internal Error: Could not access AST for ${source.fullName} " | 8413 "Internal Error: Could not access AST for ${source.fullName} " |
8209 "during constant verification", | 8414 "during constant verification", |
8210 new CaughtException(exception, stackTrace)); | 8415 new CaughtException(exception, stackTrace)); |
8211 } | 8416 } |
8212 } | 8417 } |
8213 } | 8418 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8299 * The object representing the async library. | 8504 * The object representing the async library. |
8300 */ | 8505 */ |
8301 ResolvableLibrary _asyncLibrary; | 8506 ResolvableLibrary _asyncLibrary; |
8302 | 8507 |
8303 /** | 8508 /** |
8304 * The object used to access the types from the core library. | 8509 * The object used to access the types from the core library. |
8305 */ | 8510 */ |
8306 TypeProvider _typeProvider; | 8511 TypeProvider _typeProvider; |
8307 | 8512 |
8308 /** | 8513 /** |
| 8514 * The type system in use for the library |
| 8515 */ |
| 8516 TypeSystem _typeSystem; |
| 8517 |
| 8518 /** |
8309 * A table mapping library sources to the information being maintained for tho
se libraries. | 8519 * A table mapping library sources to the information being maintained for tho
se libraries. |
8310 */ | 8520 */ |
8311 HashMap<Source, ResolvableLibrary> _libraryMap = | 8521 HashMap<Source, ResolvableLibrary> _libraryMap = |
8312 new HashMap<Source, ResolvableLibrary>(); | 8522 new HashMap<Source, ResolvableLibrary>(); |
8313 | 8523 |
8314 /** | 8524 /** |
8315 * A collection containing the libraries that are being resolved together. | 8525 * A collection containing the libraries that are being resolved together. |
8316 */ | 8526 */ |
8317 List<ResolvableLibrary> _librariesInCycle; | 8527 List<ResolvableLibrary> _librariesInCycle; |
8318 | 8528 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8388 LibraryElement coreElement = _coreLibrary.libraryElement; | 8598 LibraryElement coreElement = _coreLibrary.libraryElement; |
8389 if (coreElement == null) { | 8599 if (coreElement == null) { |
8390 missingCoreLibrary(analysisContext, _coreLibrarySource); | 8600 missingCoreLibrary(analysisContext, _coreLibrarySource); |
8391 } | 8601 } |
8392 LibraryElement asyncElement = _asyncLibrary.libraryElement; | 8602 LibraryElement asyncElement = _asyncLibrary.libraryElement; |
8393 if (asyncElement == null) { | 8603 if (asyncElement == null) { |
8394 missingAsyncLibrary(analysisContext, _asyncLibrarySource); | 8604 missingAsyncLibrary(analysisContext, _asyncLibrarySource); |
8395 } | 8605 } |
8396 _buildDirectiveModels(); | 8606 _buildDirectiveModels(); |
8397 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); | 8607 _typeProvider = new TypeProviderImpl(coreElement, asyncElement); |
| 8608 _typeSystem = TypeSystem.create(analysisContext); |
8398 _buildEnumMembers(); | 8609 _buildEnumMembers(); |
8399 _buildTypeHierarchies(); | 8610 _buildTypeHierarchies(); |
8400 // | 8611 // |
8401 // Perform resolution and type analysis. | 8612 // Perform resolution and type analysis. |
8402 // | 8613 // |
8403 // TODO(brianwilkerson) Decide whether we want to resolve all of the | 8614 // TODO(brianwilkerson) Decide whether we want to resolve all of the |
8404 // libraries or whether we want to only resolve the target library. The | 8615 // libraries or whether we want to only resolve the target library. The |
8405 // advantage to resolving everything is that we have already done part of | 8616 // advantage to resolving everything is that we have already done part of |
8406 // the work so we'll avoid duplicated effort. The disadvantage of | 8617 // the work so we'll avoid duplicated effort. The disadvantage of |
8407 // resolving everything is that we might do extra work that we don't | 8618 // resolving everything is that we might do extra work that we don't |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8496 importElement.prefix = prefix; | 8707 importElement.prefix = prefix; |
8497 prefixNode.staticElement = prefix; | 8708 prefixNode.staticElement = prefix; |
8498 } | 8709 } |
8499 directive.element = importElement; | 8710 directive.element = importElement; |
8500 imports.add(importElement); | 8711 imports.add(importElement); |
8501 if (analysisContext.computeKindOf(importedSource) != | 8712 if (analysisContext.computeKindOf(importedSource) != |
8502 SourceKind.LIBRARY) { | 8713 SourceKind.LIBRARY) { |
8503 ErrorCode errorCode = (importElement.isDeferred | 8714 ErrorCode errorCode = (importElement.isDeferred |
8504 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY | 8715 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY |
8505 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); | 8716 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY); |
8506 _errorListener.onError(new AnalysisError(library.librarySource, | 8717 _errorListener.onError(new AnalysisError( |
8507 uriLiteral.offset, uriLiteral.length, errorCode, | 8718 library.librarySource, |
| 8719 uriLiteral.offset, |
| 8720 uriLiteral.length, |
| 8721 errorCode, |
8508 [uriLiteral.toSource()])); | 8722 [uriLiteral.toSource()])); |
8509 } | 8723 } |
8510 } | 8724 } |
8511 } | 8725 } |
8512 } else if (directive is ExportDirective) { | 8726 } else if (directive is ExportDirective) { |
8513 ExportDirective exportDirective = directive; | 8727 ExportDirective exportDirective = directive; |
8514 Source exportedSource = exportDirective.source; | 8728 Source exportedSource = exportDirective.source; |
8515 if (exportedSource != null && | 8729 if (exportedSource != null && |
8516 analysisContext.exists(exportedSource)) { | 8730 analysisContext.exists(exportedSource)) { |
8517 // The exported source will be null if the URI in the export | 8731 // The exported source will be null if the URI in the export |
(...skipping 11 matching lines...) Expand all Loading... |
8529 exportElement.combinators = _buildCombinators(exportDirective); | 8743 exportElement.combinators = _buildCombinators(exportDirective); |
8530 LibraryElement exportedLibraryElement = | 8744 LibraryElement exportedLibraryElement = |
8531 exportedLibrary.libraryElement; | 8745 exportedLibrary.libraryElement; |
8532 if (exportedLibraryElement != null) { | 8746 if (exportedLibraryElement != null) { |
8533 exportElement.exportedLibrary = exportedLibraryElement; | 8747 exportElement.exportedLibrary = exportedLibraryElement; |
8534 } | 8748 } |
8535 directive.element = exportElement; | 8749 directive.element = exportElement; |
8536 exports.add(exportElement); | 8750 exports.add(exportElement); |
8537 if (analysisContext.computeKindOf(exportedSource) != | 8751 if (analysisContext.computeKindOf(exportedSource) != |
8538 SourceKind.LIBRARY) { | 8752 SourceKind.LIBRARY) { |
8539 _errorListener.onError(new AnalysisError(library.librarySource, | 8753 _errorListener.onError(new AnalysisError( |
8540 uriLiteral.offset, uriLiteral.length, | 8754 library.librarySource, |
| 8755 uriLiteral.offset, |
| 8756 uriLiteral.length, |
8541 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, | 8757 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, |
8542 [uriLiteral.toSource()])); | 8758 [uriLiteral.toSource()])); |
8543 } | 8759 } |
8544 } | 8760 } |
8545 } | 8761 } |
8546 } | 8762 } |
8547 } | 8763 } |
8548 Source librarySource = library.librarySource; | 8764 Source librarySource = library.librarySource; |
8549 if (!library.explicitlyImportsCore && | 8765 if (!library.explicitlyImportsCore && |
8550 _coreLibrarySource != librarySource) { | 8766 _coreLibrarySource != librarySource) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8624 * @throws AnalysisException if any of the type hierarchies could not be resol
ved | 8840 * @throws AnalysisException if any of the type hierarchies could not be resol
ved |
8625 */ | 8841 */ |
8626 void _buildTypeHierarchies() { | 8842 void _buildTypeHierarchies() { |
8627 PerformanceStatistics.resolve.makeCurrentWhile(() { | 8843 PerformanceStatistics.resolve.makeCurrentWhile(() { |
8628 for (ResolvableLibrary library in _librariesInCycle) { | 8844 for (ResolvableLibrary library in _librariesInCycle) { |
8629 for (ResolvableCompilationUnit unit | 8845 for (ResolvableCompilationUnit unit |
8630 in library.resolvableCompilationUnits) { | 8846 in library.resolvableCompilationUnits) { |
8631 Source source = unit.source; | 8847 Source source = unit.source; |
8632 CompilationUnit ast = unit.compilationUnit; | 8848 CompilationUnit ast = unit.compilationUnit; |
8633 TypeResolverVisitor visitor = new TypeResolverVisitor( | 8849 TypeResolverVisitor visitor = new TypeResolverVisitor( |
8634 library.libraryElement, source, _typeProvider, | 8850 library.libraryElement, |
| 8851 source, |
| 8852 _typeProvider, |
8635 library.libraryScope.errorListener, | 8853 library.libraryScope.errorListener, |
8636 nameScope: library.libraryScope); | 8854 nameScope: library.libraryScope); |
8637 ast.accept(visitor); | 8855 ast.accept(visitor); |
8638 } | 8856 } |
8639 } | 8857 } |
8640 }); | 8858 }); |
8641 } | 8859 } |
8642 | 8860 |
8643 /** | 8861 /** |
8644 * Return an array containing the lexical identifiers associated with the node
s in the given list. | 8862 * Return an array containing the lexical identifiers associated with the node
s in the given list. |
8645 * | 8863 * |
8646 * @param names the AST nodes representing the identifiers | 8864 * @param names the AST nodes representing the identifiers |
8647 * @return the lexical identifiers associated with the nodes in the list | 8865 * @return the lexical identifiers associated with the nodes in the list |
8648 */ | 8866 */ |
8649 List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) { | 8867 List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) { |
8650 int count = names.length; | 8868 int count = names.length; |
8651 List<String> identifiers = new List<String>(count); | 8869 List<String> identifiers = new List<String>(count); |
8652 for (int i = 0; i < count; i++) { | 8870 for (int i = 0; i < count; i++) { |
8653 identifiers[i] = names[i].name; | 8871 identifiers[i] = names[i].name; |
8654 } | 8872 } |
8655 return identifiers; | 8873 return identifiers; |
8656 } | 8874 } |
8657 | 8875 |
8658 /** | 8876 /** |
8659 * Compute a value for all of the constants in the libraries being analyzed. | 8877 * Compute a value for all of the constants in the libraries being analyzed. |
8660 */ | 8878 */ |
8661 void _performConstantEvaluation() { | 8879 void _performConstantEvaluation() { |
8662 PerformanceStatistics.resolve.makeCurrentWhile(() { | 8880 PerformanceStatistics.resolve.makeCurrentWhile(() { |
8663 ConstantValueComputer computer = new ConstantValueComputer( | 8881 ConstantValueComputer computer = new ConstantValueComputer( |
8664 analysisContext, _typeProvider, analysisContext.declaredVariables); | 8882 analysisContext, |
| 8883 _typeProvider, |
| 8884 analysisContext.declaredVariables, |
| 8885 null, |
| 8886 _typeSystem); |
8665 for (ResolvableLibrary library in _librariesInCycle) { | 8887 for (ResolvableLibrary library in _librariesInCycle) { |
8666 for (ResolvableCompilationUnit unit | 8888 for (ResolvableCompilationUnit unit |
8667 in library.resolvableCompilationUnits) { | 8889 in library.resolvableCompilationUnits) { |
8668 CompilationUnit ast = unit.compilationUnit; | 8890 CompilationUnit ast = unit.compilationUnit; |
8669 if (ast != null) { | 8891 if (ast != null) { |
8670 computer.add(ast, unit.source, library.librarySource); | 8892 computer.add(ast, unit.source, library.librarySource); |
8671 } | 8893 } |
8672 } | 8894 } |
8673 } | 8895 } |
8674 computer.computeValues(); | 8896 computer.computeValues(); |
8675 // As a temporary workaround for issue 21572, run ConstantVerifier now. | 8897 // As a temporary workaround for issue 21572, run ConstantVerifier now. |
8676 // TODO(paulberry): remove this workaround once issue 21572 is fixed. | 8898 // TODO(paulberry): remove this workaround once issue 21572 is fixed. |
8677 for (ResolvableLibrary library in _librariesInCycle) { | 8899 for (ResolvableLibrary library in _librariesInCycle) { |
8678 for (ResolvableCompilationUnit unit | 8900 for (ResolvableCompilationUnit unit |
8679 in library.resolvableCompilationUnits) { | 8901 in library.resolvableCompilationUnits) { |
8680 CompilationUnit ast = unit.compilationUnit; | 8902 CompilationUnit ast = unit.compilationUnit; |
8681 ErrorReporter errorReporter = | 8903 ErrorReporter errorReporter = |
8682 new ErrorReporter(_errorListener, unit.source); | 8904 new ErrorReporter(_errorListener, unit.source); |
8683 ConstantVerifier constantVerifier = new ConstantVerifier( | 8905 ConstantVerifier constantVerifier = new ConstantVerifier( |
8684 errorReporter, library.libraryElement, _typeProvider, | 8906 errorReporter, |
| 8907 library.libraryElement, |
| 8908 _typeProvider, |
8685 analysisContext.declaredVariables); | 8909 analysisContext.declaredVariables); |
8686 ast.accept(constantVerifier); | 8910 ast.accept(constantVerifier); |
8687 } | 8911 } |
8688 } | 8912 } |
8689 }); | 8913 }); |
8690 } | 8914 } |
8691 | 8915 |
8692 /** | 8916 /** |
8693 * Resolve the identifiers and perform type analysis in the libraries in the c
urrent cycle. | 8917 * Resolve the identifiers and perform type analysis in the libraries in the c
urrent cycle. |
8694 * | 8918 * |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8744 * @param coreLibrarySource the source representing the core library | 8968 * @param coreLibrarySource the source representing the core library |
8745 * @throws AnalysisException always | 8969 * @throws AnalysisException always |
8746 */ | 8970 */ |
8747 static void missingCoreLibrary( | 8971 static void missingCoreLibrary( |
8748 AnalysisContext analysisContext, Source coreLibrarySource) { | 8972 AnalysisContext analysisContext, Source coreLibrarySource) { |
8749 throw new AnalysisException("Could not resolve dart:core"); | 8973 throw new AnalysisException("Could not resolve dart:core"); |
8750 } | 8974 } |
8751 } | 8975 } |
8752 | 8976 |
8753 /** | 8977 /** |
8754 * Instances of the class `TypeAliasInfo` hold information about a [TypeAlias]. | |
8755 */ | |
8756 class LibraryResolver2_TypeAliasInfo { | |
8757 final ResolvableLibrary _library; | |
8758 | |
8759 final Source _source; | |
8760 | |
8761 final FunctionTypeAlias _typeAlias; | |
8762 | |
8763 /** | |
8764 * Initialize a newly created information holder with the given information. | |
8765 * | |
8766 * @param library the library containing the type alias | |
8767 * @param source the source of the file containing the type alias | |
8768 * @param typeAlias the type alias being remembered | |
8769 */ | |
8770 LibraryResolver2_TypeAliasInfo(this._library, this._source, this._typeAlias); | |
8771 } | |
8772 | |
8773 /** | |
8774 * Instances of the class `TypeAliasInfo` hold information about a [TypeAlias]. | |
8775 */ | |
8776 class LibraryResolver_TypeAliasInfo { | |
8777 final Library _library; | |
8778 | |
8779 final Source _source; | |
8780 | |
8781 final FunctionTypeAlias _typeAlias; | |
8782 | |
8783 /** | |
8784 * Initialize a newly created information holder with the given information. | |
8785 * | |
8786 * @param library the library containing the type alias | |
8787 * @param source the source of the file containing the type alias | |
8788 * @param typeAlias the type alias being remembered | |
8789 */ | |
8790 LibraryResolver_TypeAliasInfo(this._library, this._source, this._typeAlias); | |
8791 } | |
8792 | |
8793 /** | |
8794 * Instances of the class `LibraryScope` implement a scope containing all of the
names defined | 8978 * Instances of the class `LibraryScope` implement a scope containing all of the
names defined |
8795 * in a given library. | 8979 * in a given library. |
8796 */ | 8980 */ |
8797 class LibraryScope extends EnclosedScope { | 8981 class LibraryScope extends EnclosedScope { |
8798 /** | 8982 /** |
8799 * Initialize a newly created scope representing the names defined in the give
n library. | 8983 * Initialize a newly created scope representing the names defined in the give
n library. |
8800 * | 8984 * |
8801 * @param definingLibrary the element representing the library represented by
this scope | 8985 * @param definingLibrary the element representing the library represented by
this scope |
8802 * @param errorListener the listener that is to be informed when an error is e
ncountered | 8986 * @param errorListener the listener that is to be informed when an error is e
ncountered |
8803 */ | 8987 */ |
8804 LibraryScope( | 8988 LibraryScope( |
8805 LibraryElement definingLibrary, AnalysisErrorListener errorListener) | 8989 LibraryElement definingLibrary, AnalysisErrorListener errorListener) |
8806 : super(new LibraryImportScope(definingLibrary, errorListener)) { | 8990 : super(new LibraryImportScope(definingLibrary, errorListener)) { |
8807 _defineTopLevelNames(definingLibrary); | 8991 _defineTopLevelNames(definingLibrary); |
8808 } | 8992 } |
8809 | 8993 |
8810 @override | 8994 @override |
8811 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 8995 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
8812 if (existing is PrefixElement) { | 8996 if (existing is PrefixElement) { |
8813 // TODO(scheglov) consider providing actual 'nameOffset' from the | 8997 // TODO(scheglov) consider providing actual 'nameOffset' from the |
8814 // synthetic accessor | 8998 // synthetic accessor |
8815 int offset = duplicate.nameOffset; | 8999 int offset = duplicate.nameOffset; |
8816 if (duplicate is PropertyAccessorElement) { | 9000 if (duplicate is PropertyAccessorElement) { |
8817 PropertyAccessorElement accessor = duplicate; | 9001 PropertyAccessorElement accessor = duplicate; |
8818 if (accessor.isSynthetic) { | 9002 if (accessor.isSynthetic) { |
8819 offset = accessor.variable.nameOffset; | 9003 offset = accessor.variable.nameOffset; |
8820 } | 9004 } |
8821 } | 9005 } |
8822 return new AnalysisError(duplicate.source, offset, | 9006 return new AnalysisError( |
8823 duplicate.displayName.length, | 9007 duplicate.source, |
| 9008 offset, |
| 9009 duplicate.nameLength, |
8824 CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, | 9010 CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, |
8825 [existing.displayName]); | 9011 [existing.displayName]); |
8826 } | 9012 } |
8827 return super.getErrorForDuplicate(existing, duplicate); | 9013 return super.getErrorForDuplicate(existing, duplicate); |
8828 } | 9014 } |
8829 | 9015 |
8830 /** | 9016 /** |
8831 * Add to this scope all of the public top-level names that are defined in the
given compilation | 9017 * Add to this scope all of the public top-level names that are defined in the
given compilation |
8832 * unit. | 9018 * unit. |
8833 * | 9019 * |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9075 * @param definedNames the mapping from names that are defined in this namespa
ce to the | 9261 * @param definedNames the mapping from names that are defined in this namespa
ce to the |
9076 * corresponding elements | 9262 * corresponding elements |
9077 */ | 9263 */ |
9078 Namespace(this._definedNames); | 9264 Namespace(this._definedNames); |
9079 | 9265 |
9080 /** | 9266 /** |
9081 * Return a table containing the same mappings as those defined by this namesp
ace. | 9267 * Return a table containing the same mappings as those defined by this namesp
ace. |
9082 * | 9268 * |
9083 * @return a table containing the same mappings as those defined by this names
pace | 9269 * @return a table containing the same mappings as those defined by this names
pace |
9084 */ | 9270 */ |
9085 Map<String, Element> get definedNames => | 9271 Map<String, Element> get definedNames => _definedNames; |
9086 new HashMap<String, Element>.from(_definedNames); | |
9087 | 9272 |
9088 /** | 9273 /** |
9089 * Return the element in this namespace that is available to the containing sc
ope using the given | 9274 * Return the element in this namespace that is available to the containing sc
ope using the given |
9090 * name. | 9275 * name. |
9091 * | 9276 * |
9092 * @param name the name used to reference the | 9277 * @param name the name used to reference the |
9093 * @return the element represented by the given identifier | 9278 * @return the element represented by the given identifier |
9094 */ | 9279 */ |
9095 Element get(String name) => _definedNames[name]; | 9280 Element get(String name) => _definedNames[name]; |
9096 } | 9281 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9226 * Apply the given combinators to all of the names in the given mapping table. | 9411 * Apply the given combinators to all of the names in the given mapping table. |
9227 * | 9412 * |
9228 * @param definedNames the mapping table to which the namespace operations are
to be applied | 9413 * @param definedNames the mapping table to which the namespace operations are
to be applied |
9229 * @param combinators the combinators to be applied | 9414 * @param combinators the combinators to be applied |
9230 */ | 9415 */ |
9231 HashMap<String, Element> _applyCombinators( | 9416 HashMap<String, Element> _applyCombinators( |
9232 HashMap<String, Element> definedNames, | 9417 HashMap<String, Element> definedNames, |
9233 List<NamespaceCombinator> combinators) { | 9418 List<NamespaceCombinator> combinators) { |
9234 for (NamespaceCombinator combinator in combinators) { | 9419 for (NamespaceCombinator combinator in combinators) { |
9235 if (combinator is HideElementCombinator) { | 9420 if (combinator is HideElementCombinator) { |
9236 _hide(definedNames, combinator.hiddenNames); | 9421 definedNames = _hide(definedNames, combinator.hiddenNames); |
9237 } else if (combinator is ShowElementCombinator) { | 9422 } else if (combinator is ShowElementCombinator) { |
9238 definedNames = _show(definedNames, combinator.shownNames); | 9423 definedNames = _show(definedNames, combinator.shownNames); |
9239 } else { | 9424 } else { |
9240 // Internal error. | 9425 // Internal error. |
9241 AnalysisEngine.instance.logger | 9426 AnalysisEngine.instance.logger |
9242 .logError("Unknown type of combinator: ${combinator.runtimeType}"); | 9427 .logError("Unknown type of combinator: ${combinator.runtimeType}"); |
9243 } | 9428 } |
9244 } | 9429 } |
9245 return definedNames; | 9430 return definedNames; |
9246 } | 9431 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9294 // | 9479 // |
9295 // The exported library will be null if the URI does not reference a | 9480 // The exported library will be null if the URI does not reference a |
9296 // valid library. | 9481 // valid library. |
9297 // | 9482 // |
9298 HashMap<String, Element> exportedNames = | 9483 HashMap<String, Element> exportedNames = |
9299 _createExportMapping(exportedLibrary, visitedElements); | 9484 _createExportMapping(exportedLibrary, visitedElements); |
9300 exportedNames = _applyCombinators(exportedNames, element.combinators); | 9485 exportedNames = _applyCombinators(exportedNames, element.combinators); |
9301 definedNames.addAll(exportedNames); | 9486 definedNames.addAll(exportedNames); |
9302 } | 9487 } |
9303 } | 9488 } |
9304 _addAllFromNamespace(definedNames, | 9489 _addAllFromNamespace( |
| 9490 definedNames, |
9305 (library.context as InternalAnalysisContext) | 9491 (library.context as InternalAnalysisContext) |
9306 .getPublicNamespace(library)); | 9492 .getPublicNamespace(library)); |
9307 return definedNames; | 9493 return definedNames; |
9308 } finally { | 9494 } finally { |
9309 visitedElements.remove(library); | 9495 visitedElements.remove(library); |
9310 } | 9496 } |
9311 } | 9497 } |
9312 | 9498 |
9313 /** | 9499 /** |
9314 * Hide all of the given names by removing them from the given collection of d
efined names. | 9500 * Return a new map of names which has all the names from [definedNames] |
9315 * | 9501 * with exception of [hiddenNames]. |
9316 * @param definedNames the names that were defined before this operation | |
9317 * @param hiddenNames the names to be hidden | |
9318 */ | 9502 */ |
9319 void _hide(HashMap<String, Element> definedNames, List<String> hiddenNames) { | 9503 Map<String, Element> _hide( |
| 9504 HashMap<String, Element> definedNames, List<String> hiddenNames) { |
| 9505 HashMap<String, Element> newNames = |
| 9506 new HashMap<String, Element>.from(definedNames); |
9320 for (String name in hiddenNames) { | 9507 for (String name in hiddenNames) { |
9321 definedNames.remove(name); | 9508 newNames.remove(name); |
9322 definedNames.remove("$name="); | 9509 newNames.remove("$name="); |
9323 } | 9510 } |
| 9511 return newNames; |
9324 } | 9512 } |
9325 | 9513 |
9326 /** | 9514 /** |
9327 * Show only the given names by removing all other names from the given collec
tion of defined | 9515 * Return a new map of names which has only [shownNames] from [definedNames]. |
9328 * names. | |
9329 * | |
9330 * @param definedNames the names that were defined before this operation | |
9331 * @param shownNames the names to be shown | |
9332 */ | 9516 */ |
9333 HashMap<String, Element> _show( | 9517 HashMap<String, Element> _show( |
9334 HashMap<String, Element> definedNames, List<String> shownNames) { | 9518 HashMap<String, Element> definedNames, List<String> shownNames) { |
9335 HashMap<String, Element> newNames = new HashMap<String, Element>(); | 9519 HashMap<String, Element> newNames = new HashMap<String, Element>(); |
9336 for (String name in shownNames) { | 9520 for (String name in shownNames) { |
9337 Element element = definedNames[name]; | 9521 Element element = definedNames[name]; |
9338 if (element != null) { | 9522 if (element != null) { |
9339 newNames[name] = element; | 9523 newNames[name] = element; |
9340 } | 9524 } |
9341 String setterName = "$name="; | 9525 String setterName = "$name="; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9415 /** | 9599 /** |
9416 * Return `true` if the given element has an override annotation associated wi
th it. | 9600 * Return `true` if the given element has an override annotation associated wi
th it. |
9417 * | 9601 * |
9418 * @param element the element being tested | 9602 * @param element the element being tested |
9419 * @return `true` if the element has an override annotation associated with it | 9603 * @return `true` if the element has an override annotation associated with it |
9420 */ | 9604 */ |
9421 bool _isOverride(Element element) => element != null && element.isOverride; | 9605 bool _isOverride(Element element) => element != null && element.isOverride; |
9422 } | 9606 } |
9423 | 9607 |
9424 /** | 9608 /** |
| 9609 * An AST visitor that is used to resolve the some of the nodes within a single |
| 9610 * compilation unit. The nodes that are skipped are those that are within |
| 9611 * function bodies. |
| 9612 */ |
| 9613 class PartialResolverVisitor extends ResolverVisitor { |
| 9614 /** |
| 9615 * A flag indicating whether the resolver is being run in strong mode. |
| 9616 */ |
| 9617 final bool strongMode; |
| 9618 |
| 9619 /** |
| 9620 * The static variables and fields that have an initializer. These are the |
| 9621 * variables that need to be re-resolved after static variables have their |
| 9622 * types inferred. A subset of these variables are those whose types should |
| 9623 * be inferred. The list will be empty unless the resolver is being run in |
| 9624 * strong mode. |
| 9625 */ |
| 9626 final List<VariableElement> variablesAndFields = <VariableElement>[]; |
| 9627 |
| 9628 /** |
| 9629 * A flag indicating whether we should discard errors while resolving the |
| 9630 * initializer for variable declarations. We do this for top-level variables |
| 9631 * and fields because their initializer will be re-resolved at a later time. |
| 9632 */ |
| 9633 bool discardErrorsInInitializer = false; |
| 9634 |
| 9635 /** |
| 9636 * Initialize a newly created visitor to resolve the nodes in an AST node. |
| 9637 * |
| 9638 * The [definingLibrary] is the element for the library containing the node |
| 9639 * being visited. The [source] is the source representing the compilation unit |
| 9640 * containing the node being visited. The [typeProvider] is the object used to |
| 9641 * access the types from the core library. The [errorListener] is the error |
| 9642 * listener that will be informed of any errors that are found during |
| 9643 * resolution. The [nameScope] is the scope used to resolve identifiers in the |
| 9644 * node that will first be visited. If `null` or unspecified, a new |
| 9645 * [LibraryScope] will be created based on [definingLibrary] and |
| 9646 * [typeProvider]. The [inheritanceManager] is used to perform inheritance |
| 9647 * lookups. If `null` or unspecified, a new [InheritanceManager] will be |
| 9648 * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to |
| 9649 * create the type analyzer. If `null` or unspecified, a type analyzer of |
| 9650 * type [StaticTypeAnalyzer] will be created. |
| 9651 */ |
| 9652 PartialResolverVisitor(LibraryElement definingLibrary, Source source, |
| 9653 TypeProvider typeProvider, AnalysisErrorListener errorListener, |
| 9654 {Scope nameScope, |
| 9655 InheritanceManager inheritanceManager, |
| 9656 StaticTypeAnalyzerFactory typeAnalyzerFactory}) |
| 9657 : strongMode = definingLibrary.context.analysisOptions.strongMode, |
| 9658 super(definingLibrary, source, typeProvider, |
| 9659 new DisablableErrorListener(errorListener)); |
| 9660 |
| 9661 @override |
| 9662 Object visitBlockFunctionBody(BlockFunctionBody node) { |
| 9663 if (_shouldBeSkipped(node)) { |
| 9664 return null; |
| 9665 } |
| 9666 return super.visitBlockFunctionBody(node); |
| 9667 } |
| 9668 |
| 9669 @override |
| 9670 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 9671 if (_shouldBeSkipped(node)) { |
| 9672 return null; |
| 9673 } |
| 9674 return super.visitExpressionFunctionBody(node); |
| 9675 } |
| 9676 |
| 9677 @override |
| 9678 Object visitFieldDeclaration(FieldDeclaration node) { |
| 9679 if (strongMode && node.isStatic) { |
| 9680 _addVariables(node.fields.variables); |
| 9681 bool wasDiscarding = discardErrorsInInitializer; |
| 9682 discardErrorsInInitializer = true; |
| 9683 try { |
| 9684 return super.visitFieldDeclaration(node); |
| 9685 } finally { |
| 9686 discardErrorsInInitializer = wasDiscarding; |
| 9687 } |
| 9688 } |
| 9689 return super.visitFieldDeclaration(node); |
| 9690 } |
| 9691 |
| 9692 @override |
| 9693 Object visitNode(AstNode node) { |
| 9694 if (discardErrorsInInitializer) { |
| 9695 AstNode parent = node.parent; |
| 9696 if (parent is VariableDeclaration && parent.initializer == node) { |
| 9697 DisablableErrorListener listener = errorListener; |
| 9698 return listener.disableWhile(() => super.visitNode(node)); |
| 9699 } |
| 9700 } |
| 9701 return super.visitNode(node); |
| 9702 } |
| 9703 |
| 9704 @override |
| 9705 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 9706 if (strongMode) { |
| 9707 _addVariables(node.variables.variables); |
| 9708 bool wasDiscarding = discardErrorsInInitializer; |
| 9709 discardErrorsInInitializer = true; |
| 9710 try { |
| 9711 return super.visitTopLevelVariableDeclaration(node); |
| 9712 } finally { |
| 9713 discardErrorsInInitializer = wasDiscarding; |
| 9714 } |
| 9715 } |
| 9716 return super.visitTopLevelVariableDeclaration(node); |
| 9717 } |
| 9718 |
| 9719 /** |
| 9720 * Add all of the [variables] with initializers to the list of variables whose |
| 9721 * type can be inferred. Technically, we only infer the types of variables |
| 9722 * that do not have a static type, but all variables with initializers |
| 9723 * potentially need to be re-resolved after inference because they might |
| 9724 * refer to a field whose type was inferred. |
| 9725 */ |
| 9726 void _addVariables(NodeList<VariableDeclaration> variables) { |
| 9727 for (VariableDeclaration variable in variables) { |
| 9728 if (variable.initializer != null) { |
| 9729 variablesAndFields.add(variable.element); |
| 9730 } |
| 9731 } |
| 9732 } |
| 9733 |
| 9734 /** |
| 9735 * Return `true` if the given function body should be skipped because it is |
| 9736 * the body of a top-level function, method or constructor. |
| 9737 */ |
| 9738 bool _shouldBeSkipped(FunctionBody body) { |
| 9739 AstNode parent = body.parent; |
| 9740 if (parent is MethodDeclaration) { |
| 9741 return parent.body == body; |
| 9742 } |
| 9743 if (parent is ConstructorDeclaration) { |
| 9744 return parent.body == body; |
| 9745 } |
| 9746 if (parent is FunctionExpression) { |
| 9747 AstNode parent2 = parent.parent; |
| 9748 if (parent2 is FunctionDeclaration && |
| 9749 parent2.parent is! FunctionDeclarationStatement) { |
| 9750 return parent.body == body; |
| 9751 } |
| 9752 } |
| 9753 return false; |
| 9754 } |
| 9755 } |
| 9756 |
| 9757 /** |
9425 * Instances of the class `PubVerifier` traverse an AST structure looking for de
viations from | 9758 * Instances of the class `PubVerifier` traverse an AST structure looking for de
viations from |
9426 * pub best practices. | 9759 * pub best practices. |
9427 */ | 9760 */ |
9428 class PubVerifier extends RecursiveAstVisitor<Object> { | 9761 class PubVerifier extends RecursiveAstVisitor<Object> { |
9429 // static String _PUBSPEC_YAML = "pubspec.yaml"; | 9762 // static String _PUBSPEC_YAML = "pubspec.yaml"; |
9430 | 9763 |
9431 /** | 9764 /** |
9432 * The analysis context containing the sources to be analyzed | 9765 * The analysis context containing the sources to be analyzed |
9433 */ | 9766 */ |
9434 final AnalysisContext _context; | 9767 final AnalysisContext _context; |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9947 /** | 10280 /** |
9948 * The object used to resolve the element associated with the current node. | 10281 * The object used to resolve the element associated with the current node. |
9949 */ | 10282 */ |
9950 ElementResolver elementResolver; | 10283 ElementResolver elementResolver; |
9951 | 10284 |
9952 /** | 10285 /** |
9953 * The object used to compute the type associated with the current node. | 10286 * The object used to compute the type associated with the current node. |
9954 */ | 10287 */ |
9955 StaticTypeAnalyzer typeAnalyzer; | 10288 StaticTypeAnalyzer typeAnalyzer; |
9956 | 10289 |
| 10290 /* |
| 10291 * The type system in use during resolution. |
| 10292 */ |
| 10293 TypeSystem typeSystem; |
| 10294 |
9957 /** | 10295 /** |
9958 * The class element representing the class containing the current node, | 10296 * The class element representing the class containing the current node, |
9959 * or `null` if the current node is not contained in a class. | 10297 * or `null` if the current node is not contained in a class. |
9960 */ | 10298 */ |
9961 ClassElement enclosingClass = null; | 10299 ClassElement enclosingClass = null; |
9962 | 10300 |
9963 /** | 10301 /** |
9964 * The class declaration representing the class containing the current node, o
r `null` if | 10302 * The class declaration representing the class containing the current node, o
r `null` if |
9965 * the current node is not contained in a class. | 10303 * the current node is not contained in a class. |
9966 */ | 10304 */ |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10000 * resolve the whole function. | 10338 * resolve the whole function. |
10001 * | 10339 * |
10002 * So, this flag is set to `true`, when just context of the function should | 10340 * So, this flag is set to `true`, when just context of the function should |
10003 * be built and the comment resolved. | 10341 * be built and the comment resolved. |
10004 */ | 10342 */ |
10005 bool resolveOnlyCommentInFunctionBody = false; | 10343 bool resolveOnlyCommentInFunctionBody = false; |
10006 | 10344 |
10007 /** | 10345 /** |
10008 * Initialize a newly created visitor to resolve the nodes in an AST node. | 10346 * Initialize a newly created visitor to resolve the nodes in an AST node. |
10009 * | 10347 * |
10010 * [definingLibrary] is the element for the library containing the node being | 10348 * The [definingLibrary] is the element for the library containing the node |
10011 * visited. | 10349 * being visited. The [source] is the source representing the compilation unit |
10012 * [source] is the source representing the compilation unit containing the | 10350 * containing the node being visited. The [typeProvider] is the object used to |
10013 * node being visited. | 10351 * access the types from the core library. The [errorListener] is the error |
10014 * [typeProvider] the object used to access the types from the core library. | 10352 * listener that will be informed of any errors that are found during |
10015 * [errorListener] the error listener that will be informed of any errors | 10353 * resolution. The [nameScope] is the scope used to resolve identifiers in the |
10016 * that are found during resolution. | 10354 * node that will first be visited. If `null` or unspecified, a new |
10017 * [nameScope] is the scope used to resolve identifiers in the node that will | 10355 * [LibraryScope] will be created based on [definingLibrary] and |
10018 * first be visited. If `null` or unspecified, a new [LibraryScope] will be | 10356 * [typeProvider]. The [inheritanceManager] is used to perform inheritance |
10019 * created based on [definingLibrary] and [typeProvider]. | 10357 * lookups. If `null` or unspecified, a new [InheritanceManager] will be |
10020 * [inheritanceManager] is used to perform inheritance lookups. If `null` or | 10358 * created based on [definingLibrary]. The [typeAnalyzerFactory] is used to |
10021 * unspecified, a new [InheritanceManager] will be created based on | 10359 * create the type analyzer. If `null` or unspecified, a type analyzer of |
10022 * [definingLibrary]. | 10360 * type [StaticTypeAnalyzer] will be created. |
10023 * [typeAnalyzerFactory] is used to create the type analyzer. If `null` or | |
10024 * unspecified, a type analyzer of type [StaticTypeAnalyzer] will be created. | |
10025 */ | 10361 */ |
10026 ResolverVisitor(LibraryElement definingLibrary, Source source, | 10362 ResolverVisitor(LibraryElement definingLibrary, Source source, |
10027 TypeProvider typeProvider, AnalysisErrorListener errorListener, | 10363 TypeProvider typeProvider, AnalysisErrorListener errorListener, |
10028 {Scope nameScope, InheritanceManager inheritanceManager, | 10364 {Scope nameScope, |
| 10365 InheritanceManager inheritanceManager, |
10029 StaticTypeAnalyzerFactory typeAnalyzerFactory}) | 10366 StaticTypeAnalyzerFactory typeAnalyzerFactory}) |
10030 : super(definingLibrary, source, typeProvider, errorListener, | 10367 : super(definingLibrary, source, typeProvider, errorListener, |
10031 nameScope: nameScope) { | 10368 nameScope: nameScope) { |
10032 if (inheritanceManager == null) { | 10369 if (inheritanceManager == null) { |
10033 this._inheritanceManager = new InheritanceManager(definingLibrary); | 10370 this._inheritanceManager = new InheritanceManager(definingLibrary); |
10034 } else { | 10371 } else { |
10035 this._inheritanceManager = inheritanceManager; | 10372 this._inheritanceManager = inheritanceManager; |
10036 } | 10373 } |
10037 this.elementResolver = new ElementResolver(this); | 10374 this.elementResolver = new ElementResolver(this); |
| 10375 this.typeSystem = definingLibrary.context.typeSystem; |
10038 if (typeAnalyzerFactory == null) { | 10376 if (typeAnalyzerFactory == null) { |
10039 this.typeAnalyzer = new StaticTypeAnalyzer(this); | 10377 this.typeAnalyzer = new StaticTypeAnalyzer(this); |
10040 } else { | 10378 } else { |
10041 this.typeAnalyzer = typeAnalyzerFactory(this); | 10379 this.typeAnalyzer = typeAnalyzerFactory(this); |
10042 } | 10380 } |
10043 } | 10381 } |
10044 | 10382 |
10045 /** | 10383 /** |
10046 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. | 10384 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. |
10047 * | 10385 * |
10048 * @param library the library containing the compilation unit being resolved | 10386 * @param library the library containing the compilation unit being resolved |
10049 * @param source the source representing the compilation unit being visited | 10387 * @param source the source representing the compilation unit being visited |
10050 * @param typeProvider the object used to access the types from the core libra
ry | 10388 * @param typeProvider the object used to access the types from the core libra
ry |
10051 * | 10389 * |
10052 * Deprecated. Please use unnamed constructor instead. | 10390 * Deprecated. Please use unnamed constructor instead. |
10053 */ | 10391 */ |
10054 @deprecated | 10392 @deprecated |
10055 ResolverVisitor.con1( | 10393 ResolverVisitor.con1( |
10056 Library library, Source source, TypeProvider typeProvider, | 10394 Library library, Source source, TypeProvider typeProvider, |
10057 {StaticTypeAnalyzerFactory typeAnalyzerFactory}) | 10395 {StaticTypeAnalyzerFactory typeAnalyzerFactory}) |
10058 : this( | 10396 : this( |
10059 library.libraryElement, source, typeProvider, library.errorListener, | 10397 library.libraryElement, source, typeProvider, library.errorListener, |
10060 nameScope: library.libraryScope, | 10398 nameScope: library.libraryScope, |
10061 inheritanceManager: library.inheritanceManager, | 10399 inheritanceManager: library.inheritanceManager, |
10062 typeAnalyzerFactory: typeAnalyzerFactory); | 10400 typeAnalyzerFactory: typeAnalyzerFactory); |
10063 | 10401 |
10064 /** | 10402 /** |
10065 * Return the element representing the function containing the current node, o
r `null` if | 10403 * Return the element representing the function containing the current node, o
r `null` if |
10066 * the current node is not contained in a function. | 10404 * the current node is not contained in a function. |
10067 * | 10405 * |
10068 * @return the element representing the function containing the current node | 10406 * @return the element representing the function containing the current node |
10069 */ | 10407 */ |
10070 ExecutableElement get enclosingFunction => _enclosingFunction; | 10408 ExecutableElement get enclosingFunction => _enclosingFunction; |
10071 | 10409 |
10072 /** | 10410 /** |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10152 } | 10490 } |
10153 if (kind == ElementKind.PARAMETER) { | 10491 if (kind == ElementKind.PARAMETER) { |
10154 return element as VariableElement; | 10492 return element as VariableElement; |
10155 } | 10493 } |
10156 return null; | 10494 return null; |
10157 } | 10495 } |
10158 | 10496 |
10159 /** | 10497 /** |
10160 * Prepares this [ResolverVisitor] to using it for incremental resolution. | 10498 * Prepares this [ResolverVisitor] to using it for incremental resolution. |
10161 */ | 10499 */ |
10162 void initForIncrementalResolution() { | 10500 void initForIncrementalResolution([Declaration declaration = null]) { |
| 10501 if (declaration != null) { |
| 10502 Element element = declaration.element; |
| 10503 if (element is ExecutableElement) { |
| 10504 _enclosingFunction = element; |
| 10505 } |
| 10506 _commentBeforeFunction = declaration.documentationComment; |
| 10507 } |
10163 _overrideManager.enterScope(); | 10508 _overrideManager.enterScope(); |
10164 } | 10509 } |
10165 | 10510 |
10166 /** | 10511 /** |
10167 * If it is appropriate to do so, override the current type of the static and
propagated elements | 10512 * If it is appropriate to do so, override the current type of the static and
propagated elements |
10168 * associated with the given expression with the given type. Generally speakin
g, it is appropriate | 10513 * associated with the given expression with the given type. Generally speakin
g, it is appropriate |
10169 * if the given type is more specific than the current type. | 10514 * if the given type is more specific than the current type. |
10170 * | 10515 * |
10171 * @param expression the expression used to access the static and propagated e
lements whose types | 10516 * @param expression the expression used to access the static and propagated e
lements whose types |
10172 * might be overridden | 10517 * might be overridden |
(...skipping 23 matching lines...) Expand all Loading... |
10196 * @param element the element whose type might be overridden | 10541 * @param element the element whose type might be overridden |
10197 * @param potentialType the potential type of the element | 10542 * @param potentialType the potential type of the element |
10198 * @param allowPrecisionLoss true if `potentialType` is allowed to be less pre
cise than the | 10543 * @param allowPrecisionLoss true if `potentialType` is allowed to be less pre
cise than the |
10199 * current best type | 10544 * current best type |
10200 * | 10545 * |
10201 * Return a new better [DartType], or `null` if [potentialType] is not better | 10546 * Return a new better [DartType], or `null` if [potentialType] is not better |
10202 * than the current [element] type. | 10547 * than the current [element] type. |
10203 */ | 10548 */ |
10204 DartType overrideVariable(VariableElement element, DartType potentialType, | 10549 DartType overrideVariable(VariableElement element, DartType potentialType, |
10205 bool allowPrecisionLoss) { | 10550 bool allowPrecisionLoss) { |
| 10551 // TODO(scheglov) type propagation for instance/top-level fields |
| 10552 // was disabled because it depends on the order or visiting. |
| 10553 // If both field and its client are in the same unit, and we visit |
| 10554 // the client before the field, then propagated type is not set yet. |
| 10555 if (element is PropertyInducingElement) { |
| 10556 return null; |
| 10557 } |
| 10558 |
10206 if (potentialType == null || potentialType.isBottom) { | 10559 if (potentialType == null || potentialType.isBottom) { |
10207 return null; | 10560 return null; |
10208 } | 10561 } |
10209 DartType currentType = _overrideManager.getBestType(element); | 10562 DartType currentType = _overrideManager.getBestType(element); |
10210 | 10563 |
10211 if (potentialType == currentType) { | 10564 if (potentialType == currentType) { |
10212 return null; | 10565 return null; |
10213 } | 10566 } |
10214 | 10567 |
10215 // If we aren't allowing precision loss then the third and fourth conditions | 10568 // If we aren't allowing precision loss then the third and fourth conditions |
(...skipping 12 matching lines...) Expand all Loading... |
10228 // It also covers an important case that is not applicable in the spec: | 10581 // It also covers an important case that is not applicable in the spec: |
10229 // for union types, we want an is-check to promote from an union type to | 10582 // for union types, we want an is-check to promote from an union type to |
10230 // (a subtype of) any of its members. | 10583 // (a subtype of) any of its members. |
10231 // | 10584 // |
10232 // The first check, that [! (C << P)], covers the case where [P] and [C] are | 10585 // The first check, that [! (C << P)], covers the case where [P] and [C] are |
10233 // unrelated types; This case is not addressed in the spec for static types. | 10586 // unrelated types; This case is not addressed in the spec for static types. |
10234 if (currentType == null || | 10587 if (currentType == null || |
10235 allowPrecisionLoss || | 10588 allowPrecisionLoss || |
10236 !currentType.isMoreSpecificThan(potentialType) || | 10589 !currentType.isMoreSpecificThan(potentialType) || |
10237 potentialType.isMoreSpecificThan(currentType)) { | 10590 potentialType.isMoreSpecificThan(currentType)) { |
10238 // TODO(scheglov) type propagation for instance/top-level fields | |
10239 // was disabled because it depends on the order or visiting. | |
10240 // If both field and its client are in the same unit, and we visit | |
10241 // the client before the field, then propagated type is not set yet. | |
10242 // if (element is PropertyInducingElement) { | |
10243 // PropertyInducingElement variable = element; | |
10244 // if (!variable.isConst && !variable.isFinal) { | |
10245 // return; | |
10246 // } | |
10247 // (variable as PropertyInducingElementImpl).propagatedType = | |
10248 // potentialType; | |
10249 // } | |
10250 _overrideManager.setType(element, potentialType); | 10591 _overrideManager.setType(element, potentialType); |
10251 return potentialType; | 10592 return potentialType; |
10252 } | 10593 } |
10253 return null; | 10594 return null; |
10254 } | 10595 } |
10255 | 10596 |
10256 /** | 10597 /** |
| 10598 * A client is about to resolve a member in the given class declaration. |
| 10599 */ |
| 10600 void prepareToResolveMembersInClass(ClassDeclaration node) { |
| 10601 _enclosingClassDeclaration = node; |
| 10602 enclosingClass = node.element; |
| 10603 typeAnalyzer.thisType = enclosingClass == null ? null : enclosingClass.type; |
| 10604 } |
| 10605 |
| 10606 /** |
10257 * If the given [type] is valid, strongly more specific than the | 10607 * If the given [type] is valid, strongly more specific than the |
10258 * existing static type of the given [expression], record it as a propagated | 10608 * existing static type of the given [expression], record it as a propagated |
10259 * type of the given [expression]. Otherwise, reset it to `null`. | 10609 * type of the given [expression]. Otherwise, reset it to `null`. |
10260 * | 10610 * |
10261 * If [hasOldPropagatedType] is `true` then the existing propagated type | 10611 * If [hasOldPropagatedType] is `true` then the existing propagated type |
10262 * should also is checked. | 10612 * should also is checked. |
10263 */ | 10613 */ |
10264 void recordPropagatedTypeIfBetter(Expression expression, DartType type, | 10614 void recordPropagatedTypeIfBetter(Expression expression, DartType type, |
10265 [bool hasOldPropagatedType = false]) { | 10615 [bool hasOldPropagatedType = false]) { |
10266 // Ensure that propagated type invalid. | 10616 // Ensure that propagated type invalid. |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10597 // of the statement. | 10947 // of the statement. |
10598 // | 10948 // |
10599 node.accept(elementResolver); | 10949 node.accept(elementResolver); |
10600 node.accept(typeAnalyzer); | 10950 node.accept(typeAnalyzer); |
10601 return null; | 10951 return null; |
10602 } | 10952 } |
10603 | 10953 |
10604 @override | 10954 @override |
10605 Object visitDefaultFormalParameter(DefaultFormalParameter node) { | 10955 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
10606 super.visitDefaultFormalParameter(node); | 10956 super.visitDefaultFormalParameter(node); |
| 10957 ParameterElement element = node.element; |
| 10958 if (element.initializer != null && node.defaultValue != null) { |
| 10959 (element.initializer as FunctionElementImpl).returnType = |
| 10960 node.defaultValue.staticType; |
| 10961 } |
10607 FormalParameterList parent = node.parent; | 10962 FormalParameterList parent = node.parent; |
10608 AstNode grandparent = parent.parent; | 10963 AstNode grandparent = parent.parent; |
10609 if (grandparent is ConstructorDeclaration && | 10964 if (grandparent is ConstructorDeclaration && |
10610 grandparent.constKeyword != null) { | 10965 grandparent.constKeyword != null) { |
10611 // For const constructors, we need to clone the ASTs for default formal | 10966 // For const constructors, we need to clone the ASTs for default formal |
10612 // parameters, so that we can use them during constant evaluation. | 10967 // parameters, so that we can use them during constant evaluation. |
10613 ParameterElement element = node.element; | 10968 ParameterElement element = node.element; |
10614 (element as ConstVariableElement).constantInitializer = | 10969 (element as ConstVariableElement).constantInitializer = |
10615 new ConstantAstCloner().cloneNode(node.defaultValue); | 10970 new ConstantAstCloner().cloneNode(node.defaultValue); |
10616 } | 10971 } |
(...skipping 26 matching lines...) Expand all Loading... |
10643 Object visitEnumDeclaration(EnumDeclaration node) { | 10998 Object visitEnumDeclaration(EnumDeclaration node) { |
10644 // | 10999 // |
10645 // Resolve the metadata in the library scope | 11000 // Resolve the metadata in the library scope |
10646 // and associate the annotations with the element. | 11001 // and associate the annotations with the element. |
10647 // | 11002 // |
10648 if (node.metadata != null) { | 11003 if (node.metadata != null) { |
10649 node.metadata.accept(this); | 11004 node.metadata.accept(this); |
10650 ElementResolver.setMetadata(node.element, node); | 11005 ElementResolver.setMetadata(node.element, node); |
10651 } | 11006 } |
10652 // | 11007 // |
10653 // There is nothing else to do because everything else was resolved by the | 11008 // Continue the enum resolution. |
10654 // element builder. | |
10655 // | 11009 // |
| 11010 ClassElement outerType = enclosingClass; |
| 11011 try { |
| 11012 enclosingClass = node.element; |
| 11013 typeAnalyzer.thisType = |
| 11014 enclosingClass == null ? null : enclosingClass.type; |
| 11015 super.visitEnumDeclaration(node); |
| 11016 node.accept(elementResolver); |
| 11017 node.accept(typeAnalyzer); |
| 11018 } finally { |
| 11019 typeAnalyzer.thisType = outerType == null ? null : outerType.type; |
| 11020 enclosingClass = outerType; |
| 11021 _enclosingClassDeclaration = null; |
| 11022 } |
10656 return null; | 11023 return null; |
10657 } | 11024 } |
10658 | 11025 |
10659 @override | 11026 @override |
10660 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { | 11027 Object visitExpressionFunctionBody(ExpressionFunctionBody node) { |
10661 safelyVisit(_commentBeforeFunction); | 11028 safelyVisit(_commentBeforeFunction); |
10662 if (resolveOnlyCommentInFunctionBody) { | 11029 if (resolveOnlyCommentInFunctionBody) { |
10663 return null; | 11030 return null; |
10664 } | 11031 } |
10665 _overrideManager.enterScope(); | 11032 _overrideManager.enterScope(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10708 SimpleIdentifier identifier = node.identifier; | 11075 SimpleIdentifier identifier = node.identifier; |
10709 safelyVisit(loopVariable); | 11076 safelyVisit(loopVariable); |
10710 safelyVisit(identifier); | 11077 safelyVisit(identifier); |
10711 Statement body = node.body; | 11078 Statement body = node.body; |
10712 if (body != null) { | 11079 if (body != null) { |
10713 _overrideManager.enterScope(); | 11080 _overrideManager.enterScope(); |
10714 try { | 11081 try { |
10715 if (loopVariable != null && iterable != null) { | 11082 if (loopVariable != null && iterable != null) { |
10716 LocalVariableElement loopElement = loopVariable.element; | 11083 LocalVariableElement loopElement = loopVariable.element; |
10717 if (loopElement != null) { | 11084 if (loopElement != null) { |
10718 DartType iteratorElementType = _getIteratorElementType(iterable); | 11085 DartType propagatedType = null; |
10719 overrideVariable(loopElement, iteratorElementType, true); | 11086 if (node.awaitKeyword == null) { |
10720 _recordPropagatedType(loopVariable.identifier, iteratorElementType); | 11087 propagatedType = _getIteratorElementType(iterable); |
| 11088 } else { |
| 11089 propagatedType = _getStreamElementType(iterable); |
| 11090 } |
| 11091 if (propagatedType != null) { |
| 11092 overrideVariable(loopElement, propagatedType, true); |
| 11093 recordPropagatedTypeIfBetter( |
| 11094 loopVariable.identifier, propagatedType); |
| 11095 } |
10721 } | 11096 } |
10722 } else if (identifier != null && iterable != null) { | 11097 } else if (identifier != null && iterable != null) { |
10723 Element identifierElement = identifier.staticElement; | 11098 Element identifierElement = identifier.staticElement; |
10724 if (identifierElement is VariableElement) { | 11099 if (identifierElement is VariableElement) { |
10725 DartType iteratorElementType = _getIteratorElementType(iterable); | 11100 DartType iteratorElementType = _getIteratorElementType(iterable); |
10726 overrideVariable(identifierElement, iteratorElementType, true); | 11101 overrideVariable(identifierElement, iteratorElementType, true); |
10727 _recordPropagatedType(identifier, iteratorElementType); | 11102 recordPropagatedTypeIfBetter(identifier, iteratorElementType); |
10728 } | 11103 } |
10729 } | 11104 } |
10730 visitStatementInScope(body); | 11105 visitStatementInScope(body); |
10731 } finally { | 11106 } finally { |
10732 _overrideManager.exitScope(); | 11107 _overrideManager.exitScope(); |
10733 } | 11108 } |
10734 } | 11109 } |
10735 node.accept(elementResolver); | 11110 node.accept(elementResolver); |
10736 node.accept(typeAnalyzer); | 11111 node.accept(typeAnalyzer); |
10737 } | 11112 } |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11015 return null; | 11390 return null; |
11016 } | 11391 } |
11017 | 11392 |
11018 @override | 11393 @override |
11019 Object visitTypeName(TypeName node) => null; | 11394 Object visitTypeName(TypeName node) => null; |
11020 | 11395 |
11021 @override | 11396 @override |
11022 Object visitVariableDeclaration(VariableDeclaration node) { | 11397 Object visitVariableDeclaration(VariableDeclaration node) { |
11023 super.visitVariableDeclaration(node); | 11398 super.visitVariableDeclaration(node); |
11024 VariableElement element = node.element; | 11399 VariableElement element = node.element; |
| 11400 if (element.initializer != null && node.initializer != null) { |
| 11401 (element.initializer as FunctionElementImpl).returnType = |
| 11402 node.initializer.staticType; |
| 11403 } |
11025 // Note: in addition to cloning the initializers for const variables, we | 11404 // Note: in addition to cloning the initializers for const variables, we |
11026 // have to clone the initializers for non-static final fields (because if | 11405 // have to clone the initializers for non-static final fields (because if |
11027 // they occur in a class with a const constructor, they will be needed to | 11406 // they occur in a class with a const constructor, they will be needed to |
11028 // evaluate the const constructor). | 11407 // evaluate the const constructor). |
11029 if ((element.isConst || | 11408 if ((element.isConst || |
11030 (element is FieldElement && | 11409 (element is FieldElement && |
11031 element.isFinal && | 11410 element.isFinal && |
11032 !element.isStatic)) && | 11411 !element.isStatic)) && |
11033 node.initializer != null) { | 11412 node.initializer != null) { |
11034 (element as ConstVariableElement).constantInitializer = | 11413 (element as ConstVariableElement).constantInitializer = |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11092 */ | 11471 */ |
11093 void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) { | 11472 void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) { |
11094 for (Element element in _promoteManager.promotedElements) { | 11473 for (Element element in _promoteManager.promotedElements) { |
11095 if (_isVariablePotentiallyMutatedIn(element, target)) { | 11474 if (_isVariablePotentiallyMutatedIn(element, target)) { |
11096 _promoteManager.setType(element, null); | 11475 _promoteManager.setType(element, null); |
11097 } | 11476 } |
11098 } | 11477 } |
11099 } | 11478 } |
11100 | 11479 |
11101 /** | 11480 /** |
11102 * The given expression is the expression used to compute the iterator for a f
or-each statement. | 11481 * The given expression is the expression used to compute the iterator for a |
11103 * Attempt to compute the type of objects that will be assigned to the loop va
riable and return | 11482 * for-each statement. Attempt to compute the type of objects that will be |
11104 * that type. Return `null` if the type could not be determined. | 11483 * assigned to the loop variable and return that type. Return `null` if the |
11105 * | 11484 * type could not be determined. The [iteratorExpression] is the expression |
11106 * @param iterator the iterator for a for-each statement | 11485 * that will return the Iterable being iterated over. |
11107 * @return the type of objects that will be assigned to the loop variable | |
11108 */ | 11486 */ |
11109 DartType _getIteratorElementType(Expression iteratorExpression) { | 11487 DartType _getIteratorElementType(Expression iteratorExpression) { |
11110 DartType expressionType = iteratorExpression.bestType; | 11488 DartType expressionType = iteratorExpression.bestType; |
11111 if (expressionType is InterfaceType) { | 11489 if (expressionType is InterfaceType) { |
11112 InterfaceType interfaceType = expressionType; | 11490 InterfaceType interfaceType = expressionType; |
11113 FunctionType iteratorFunction = | 11491 FunctionType iteratorFunction = |
11114 _inheritanceManager.lookupMemberType(interfaceType, "iterator"); | 11492 _inheritanceManager.lookupMemberType(interfaceType, "iterator"); |
11115 if (iteratorFunction == null) { | 11493 if (iteratorFunction == null) { |
11116 // TODO(brianwilkerson) Should we report this error? | 11494 // TODO(brianwilkerson) Should we report this error? |
11117 return null; | 11495 return null; |
11118 } | 11496 } |
11119 DartType iteratorType = iteratorFunction.returnType; | 11497 DartType iteratorType = iteratorFunction.returnType; |
11120 if (iteratorType is InterfaceType) { | 11498 if (iteratorType is InterfaceType) { |
11121 InterfaceType iteratorInterfaceType = iteratorType; | 11499 InterfaceType iteratorInterfaceType = iteratorType; |
11122 FunctionType currentFunction = _inheritanceManager.lookupMemberType( | 11500 FunctionType currentFunction = _inheritanceManager.lookupMemberType( |
11123 iteratorInterfaceType, "current"); | 11501 iteratorInterfaceType, "current"); |
11124 if (currentFunction == null) { | 11502 if (currentFunction == null) { |
11125 // TODO(brianwilkerson) Should we report this error? | 11503 // TODO(brianwilkerson) Should we report this error? |
11126 return null; | 11504 return null; |
11127 } | 11505 } |
11128 return currentFunction.returnType; | 11506 return currentFunction.returnType; |
11129 } | 11507 } |
11130 } | 11508 } |
11131 return null; | 11509 return null; |
11132 } | 11510 } |
11133 | 11511 |
11134 /** | 11512 /** |
| 11513 * The given expression is the expression used to compute the stream for an |
| 11514 * asyncronous for-each statement. Attempt to compute the type of objects that |
| 11515 * will be assigned to the loop variable and return that type. Return `null` |
| 11516 * if the type could not be determined. The [streamExpression] is the |
| 11517 * expression that will return the stream being iterated over. |
| 11518 */ |
| 11519 DartType _getStreamElementType(Expression streamExpression) { |
| 11520 DartType streamType = streamExpression.bestType; |
| 11521 if (streamType is InterfaceType) { |
| 11522 FunctionType listenFunction = |
| 11523 _inheritanceManager.lookupMemberType(streamType, "listen"); |
| 11524 if (listenFunction == null) { |
| 11525 return null; |
| 11526 } |
| 11527 List<ParameterElement> listenParameters = listenFunction.parameters; |
| 11528 if (listenParameters == null || listenParameters.length < 1) { |
| 11529 return null; |
| 11530 } |
| 11531 DartType onDataType = listenParameters[0].type; |
| 11532 if (onDataType is FunctionType) { |
| 11533 List<ParameterElement> onDataParameters = onDataType.parameters; |
| 11534 if (onDataParameters == null || onDataParameters.length < 1) { |
| 11535 return null; |
| 11536 } |
| 11537 DartType eventType = onDataParameters[0].type; |
| 11538 // TODO(paulberry): checking that typeParameters.isNotEmpty is a |
| 11539 // band-aid fix for dartbug.com/24191. Figure out what the correct |
| 11540 // logic should be. |
| 11541 if (streamType.typeParameters.isNotEmpty && |
| 11542 eventType.element == streamType.typeParameters[0]) { |
| 11543 return streamType.typeArguments[0]; |
| 11544 } |
| 11545 } |
| 11546 } |
| 11547 return null; |
| 11548 } |
| 11549 |
| 11550 /** |
11135 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its | 11551 * If given "mayBeClosure" is [FunctionExpression] without explicit parameters
types and its |
11136 * required type is [FunctionType], then infer parameters types from [Function
Type]. | 11552 * required type is [FunctionType], then infer parameters types from [Function
Type]. |
11137 */ | 11553 */ |
11138 void _inferFunctionExpressionParametersTypes( | 11554 void _inferFunctionExpressionParametersTypes( |
11139 Expression mayBeClosure, DartType mayByFunctionType) { | 11555 Expression mayBeClosure, DartType mayByFunctionType) { |
11140 // prepare closure | 11556 // prepare closure |
11141 if (mayBeClosure is! FunctionExpression) { | 11557 if (mayBeClosure is! FunctionExpression) { |
11142 return; | 11558 return; |
11143 } | 11559 } |
11144 FunctionExpression closure = mayBeClosure as FunctionExpression; | 11560 FunctionExpression closure = mayBeClosure as FunctionExpression; |
11145 // prepare expected closure type | 11561 // prepare expected closure type |
11146 if (mayByFunctionType is! FunctionType) { | 11562 if (mayByFunctionType is! FunctionType) { |
11147 return; | 11563 return; |
11148 } | 11564 } |
11149 FunctionType expectedClosureType = mayByFunctionType as FunctionType; | 11565 FunctionType expectedClosureType = mayByFunctionType as FunctionType; |
11150 // If the expectedClosureType is not more specific than the static type, | 11566 // If the expectedClosureType is not more specific than the static type, |
11151 // return. | 11567 // return. |
11152 DartType staticClosureType = | 11568 DartType staticClosureType = |
11153 (closure.element != null ? closure.element.type : null) as DartType; | 11569 closure.element != null ? closure.element.type : null; |
11154 if (staticClosureType != null && | 11570 if (staticClosureType != null && |
11155 !expectedClosureType.isMoreSpecificThan(staticClosureType)) { | 11571 !expectedClosureType.isMoreSpecificThan(staticClosureType)) { |
11156 return; | 11572 return; |
11157 } | 11573 } |
11158 // set propagated type for the closure | 11574 // set propagated type for the closure |
11159 closure.propagatedType = expectedClosureType; | 11575 closure.propagatedType = expectedClosureType; |
11160 // set inferred types for parameters | 11576 // set inferred types for parameters |
11161 NodeList<FormalParameter> parameters = closure.parameters.parameters; | 11577 NodeList<FormalParameter> parameters = closure.parameters.parameters; |
11162 List<ParameterElement> expectedParameters = expectedClosureType.parameters; | 11578 List<ParameterElement> expectedParameters = expectedClosureType.parameters; |
11163 for (int i = 0; | 11579 for (int i = 0; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11416 } | 11832 } |
11417 } else if (condition is PrefixExpression) { | 11833 } else if (condition is PrefixExpression) { |
11418 PrefixExpression prefix = condition; | 11834 PrefixExpression prefix = condition; |
11419 if (prefix.operator.type == sc.TokenType.BANG) { | 11835 if (prefix.operator.type == sc.TokenType.BANG) { |
11420 _propagateFalseState(prefix.operand); | 11836 _propagateFalseState(prefix.operand); |
11421 } | 11837 } |
11422 } else if (condition is ParenthesizedExpression) { | 11838 } else if (condition is ParenthesizedExpression) { |
11423 _propagateTrueState(condition.expression); | 11839 _propagateTrueState(condition.expression); |
11424 } | 11840 } |
11425 } | 11841 } |
11426 | |
11427 /** | |
11428 * Record that the propagated type of the given node is the given type. | |
11429 * | |
11430 * @param expression the node whose type is to be recorded | |
11431 * @param type the propagated type of the node | |
11432 */ | |
11433 void _recordPropagatedType(Expression expression, DartType type) { | |
11434 if (type != null && !type.isDynamic) { | |
11435 expression.propagatedType = type; | |
11436 } | |
11437 } | |
11438 } | 11842 } |
11439 | 11843 |
11440 /** | 11844 /** |
11441 * The abstract class `Scope` defines the behavior common to name scopes used by
the resolver | 11845 * The abstract class `Scope` defines the behavior common to name scopes used by
the resolver |
11442 * to determine which names are visible at any given point in the code. | 11846 * to determine which names are visible at any given point in the code. |
11443 */ | 11847 */ |
11444 abstract class Scope { | 11848 abstract class Scope { |
11445 /** | 11849 /** |
11446 * The prefix used to mark an identifier as being private to its library. | 11850 * The prefix used to mark an identifier as being private to its library. |
11447 */ | 11851 */ |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11533 * @param existing the first element to be declared with the conflicting name | 11937 * @param existing the first element to be declared with the conflicting name |
11534 * @param duplicate another element declared with the conflicting name | 11938 * @param duplicate another element declared with the conflicting name |
11535 * @return the error code used to report duplicate names within a scope | 11939 * @return the error code used to report duplicate names within a scope |
11536 */ | 11940 */ |
11537 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { | 11941 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { |
11538 // TODO(brianwilkerson) Customize the error message based on the types of | 11942 // TODO(brianwilkerson) Customize the error message based on the types of |
11539 // elements that share the same name. | 11943 // elements that share the same name. |
11540 // TODO(jwren) There are 4 error codes for duplicate, but only 1 is being | 11944 // TODO(jwren) There are 4 error codes for duplicate, but only 1 is being |
11541 // generated. | 11945 // generated. |
11542 Source source = duplicate.source; | 11946 Source source = duplicate.source; |
11543 return new AnalysisError(source, duplicate.nameOffset, | 11947 return new AnalysisError(source, duplicate.nameOffset, duplicate.nameLength, |
11544 duplicate.displayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, | 11948 CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName]); |
11545 [existing.displayName]); | |
11546 } | 11949 } |
11547 | 11950 |
11548 /** | 11951 /** |
11549 * Return the source that contains the given identifier, or the source associa
ted with this scope | 11952 * Return the source that contains the given identifier, or the source associa
ted with this scope |
11550 * if the source containing the identifier could not be determined. | 11953 * if the source containing the identifier could not be determined. |
11551 * | 11954 * |
11552 * @param identifier the identifier whose source is to be returned | 11955 * @param identifier the identifier whose source is to be returned |
11553 * @return the source that contains the given identifier | 11956 * @return the source that contains the given identifier |
11554 */ | 11957 */ |
11555 Source getSource(AstNode node) { | 11958 Source getSource(AstNode node) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11633 } | 12036 } |
11634 | 12037 |
11635 /** | 12038 /** |
11636 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is | 12039 * The abstract class `ScopedVisitor` maintains name and label scopes as an AST
structure is |
11637 * being visited. | 12040 * being visited. |
11638 */ | 12041 */ |
11639 abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { | 12042 abstract class ScopedVisitor extends UnifyingAstVisitor<Object> { |
11640 /** | 12043 /** |
11641 * The element for the library containing the compilation unit being visited. | 12044 * The element for the library containing the compilation unit being visited. |
11642 */ | 12045 */ |
11643 LibraryElement _definingLibrary; | 12046 final LibraryElement definingLibrary; |
11644 | 12047 |
11645 /** | 12048 /** |
11646 * The source representing the compilation unit being visited. | 12049 * The source representing the compilation unit being visited. |
11647 */ | 12050 */ |
11648 final Source source; | 12051 final Source source; |
11649 | 12052 |
11650 /** | 12053 /** |
11651 * The error listener that will be informed of any errors that are found durin
g resolution. | 12054 * The error listener that will be informed of any errors that are found durin
g resolution. |
11652 */ | 12055 */ |
11653 AnalysisErrorListener _errorListener; | 12056 final AnalysisErrorListener errorListener; |
11654 | 12057 |
11655 /** | 12058 /** |
11656 * The scope used to resolve identifiers. | 12059 * The scope used to resolve identifiers. |
11657 */ | 12060 */ |
11658 Scope nameScope; | 12061 Scope nameScope; |
11659 | 12062 |
11660 /** | 12063 /** |
11661 * The object used to access the types from the core library. | 12064 * The object used to access the types from the core library. |
11662 */ | 12065 */ |
11663 final TypeProvider typeProvider; | 12066 final TypeProvider typeProvider; |
(...skipping 23 matching lines...) Expand all Loading... |
11687 * compilation unit being visited. | 12090 * compilation unit being visited. |
11688 * [source] is the source representing the compilation unit being visited. | 12091 * [source] is the source representing the compilation unit being visited. |
11689 * [typeProvider] is the object used to access the types from the core | 12092 * [typeProvider] is the object used to access the types from the core |
11690 * library. | 12093 * library. |
11691 * [errorListener] is the error listener that will be informed of any errors | 12094 * [errorListener] is the error listener that will be informed of any errors |
11692 * that are found during resolution. | 12095 * that are found during resolution. |
11693 * [nameScope] is the scope used to resolve identifiers in the node that will | 12096 * [nameScope] is the scope used to resolve identifiers in the node that will |
11694 * first be visited. If `null` or unspecified, a new [LibraryScope] will be | 12097 * first be visited. If `null` or unspecified, a new [LibraryScope] will be |
11695 * created based on [definingLibrary] and [typeProvider]. | 12098 * created based on [definingLibrary] and [typeProvider]. |
11696 */ | 12099 */ |
11697 ScopedVisitor(LibraryElement definingLibrary, this.source, this.typeProvider, | 12100 ScopedVisitor( |
11698 AnalysisErrorListener errorListener, {Scope nameScope}) { | 12101 this.definingLibrary, this.source, this.typeProvider, this.errorListener, |
11699 this._definingLibrary = definingLibrary; | 12102 {Scope nameScope}) { |
11700 this._errorListener = errorListener; | |
11701 if (nameScope == null) { | 12103 if (nameScope == null) { |
11702 this.nameScope = new LibraryScope(definingLibrary, errorListener); | 12104 this.nameScope = new LibraryScope(definingLibrary, errorListener); |
11703 } else { | 12105 } else { |
11704 this.nameScope = nameScope; | 12106 this.nameScope = nameScope; |
11705 } | 12107 } |
11706 } | 12108 } |
11707 | 12109 |
11708 /** | 12110 /** |
11709 * Return the library element for the library containing the compilation unit
being resolved. | |
11710 * | |
11711 * @return the library element for the library containing the compilation unit
being resolved | |
11712 */ | |
11713 LibraryElement get definingLibrary => _definingLibrary; | |
11714 | |
11715 /** | |
11716 * Return the implicit label scope in which the current node is being | 12111 * Return the implicit label scope in which the current node is being |
11717 * resolved. | 12112 * resolved. |
11718 */ | 12113 */ |
11719 ImplicitLabelScope get implicitLabelScope => _implicitLabelScope; | 12114 ImplicitLabelScope get implicitLabelScope => _implicitLabelScope; |
11720 | 12115 |
11721 /** | 12116 /** |
11722 * Replaces the current [Scope] with the enclosing [Scope]. | 12117 * Replaces the current [Scope] with the enclosing [Scope]. |
11723 * | 12118 * |
11724 * @return the enclosing [Scope]. | 12119 * @return the enclosing [Scope]. |
11725 */ | 12120 */ |
(...skipping 15 matching lines...) Expand all Loading... |
11741 | 12136 |
11742 /** | 12137 /** |
11743 * Report an error with the given error code and arguments. | 12138 * Report an error with the given error code and arguments. |
11744 * | 12139 * |
11745 * @param errorCode the error code of the error to be reported | 12140 * @param errorCode the error code of the error to be reported |
11746 * @param node the node specifying the location of the error | 12141 * @param node the node specifying the location of the error |
11747 * @param arguments the arguments to the error, used to compose the error mess
age | 12142 * @param arguments the arguments to the error, used to compose the error mess
age |
11748 */ | 12143 */ |
11749 void reportErrorForNode(ErrorCode errorCode, AstNode node, | 12144 void reportErrorForNode(ErrorCode errorCode, AstNode node, |
11750 [List<Object> arguments]) { | 12145 [List<Object> arguments]) { |
11751 _errorListener.onError(new AnalysisError( | 12146 errorListener.onError(new AnalysisError( |
11752 source, node.offset, node.length, errorCode, arguments)); | 12147 source, node.offset, node.length, errorCode, arguments)); |
11753 } | 12148 } |
11754 | 12149 |
11755 /** | 12150 /** |
11756 * Report an error with the given error code and arguments. | 12151 * Report an error with the given error code and arguments. |
11757 * | 12152 * |
11758 * @param errorCode the error code of the error to be reported | 12153 * @param errorCode the error code of the error to be reported |
11759 * @param offset the offset of the location of the error | 12154 * @param offset the offset of the location of the error |
11760 * @param length the length of the location of the error | 12155 * @param length the length of the location of the error |
11761 * @param arguments the arguments to the error, used to compose the error mess
age | 12156 * @param arguments the arguments to the error, used to compose the error mess
age |
11762 */ | 12157 */ |
11763 void reportErrorForOffset(ErrorCode errorCode, int offset, int length, | 12158 void reportErrorForOffset(ErrorCode errorCode, int offset, int length, |
11764 [List<Object> arguments]) { | 12159 [List<Object> arguments]) { |
11765 _errorListener.onError( | 12160 errorListener.onError( |
11766 new AnalysisError(source, offset, length, errorCode, arguments)); | 12161 new AnalysisError(source, offset, length, errorCode, arguments)); |
11767 } | 12162 } |
11768 | 12163 |
11769 /** | 12164 /** |
11770 * Report an error with the given error code and arguments. | 12165 * Report an error with the given error code and arguments. |
11771 * | 12166 * |
11772 * @param errorCode the error code of the error to be reported | 12167 * @param errorCode the error code of the error to be reported |
11773 * @param token the token specifying the location of the error | 12168 * @param token the token specifying the location of the error |
11774 * @param arguments the arguments to the error, used to compose the error mess
age | 12169 * @param arguments the arguments to the error, used to compose the error mess
age |
11775 */ | 12170 */ |
11776 void reportErrorForToken(ErrorCode errorCode, sc.Token token, | 12171 void reportErrorForToken(ErrorCode errorCode, sc.Token token, |
11777 [List<Object> arguments]) { | 12172 [List<Object> arguments]) { |
11778 _errorListener.onError(new AnalysisError( | 12173 errorListener.onError(new AnalysisError( |
11779 source, token.offset, token.length, errorCode, arguments)); | 12174 source, token.offset, token.length, errorCode, arguments)); |
11780 } | 12175 } |
11781 | 12176 |
11782 /** | 12177 /** |
11783 * Visit the given AST node if it is not null. | 12178 * Visit the given AST node if it is not null. |
11784 * | 12179 * |
11785 * @param node the node to be visited | 12180 * @param node the node to be visited |
11786 */ | 12181 */ |
11787 void safelyVisit(AstNode node) { | 12182 void safelyVisit(AstNode node) { |
11788 if (node != null) { | 12183 if (node != null) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11939 _implicitLabelScope = _implicitLabelScope.nest(node); | 12334 _implicitLabelScope = _implicitLabelScope.nest(node); |
11940 visitStatementInScope(node.body); | 12335 visitStatementInScope(node.body); |
11941 safelyVisit(node.condition); | 12336 safelyVisit(node.condition); |
11942 } finally { | 12337 } finally { |
11943 _implicitLabelScope = outerImplicitScope; | 12338 _implicitLabelScope = outerImplicitScope; |
11944 } | 12339 } |
11945 return null; | 12340 return null; |
11946 } | 12341 } |
11947 | 12342 |
11948 @override | 12343 @override |
| 12344 Object visitEnumDeclaration(EnumDeclaration node) { |
| 12345 ClassElement classElement = node.element; |
| 12346 Scope outerScope = nameScope; |
| 12347 try { |
| 12348 if (classElement == null) { |
| 12349 AnalysisEngine.instance.logger.logInformation( |
| 12350 "Missing element for enum declaration ${node.name.name} in ${definin
gLibrary.source.fullName}", |
| 12351 new CaughtException(new AnalysisException(), null)); |
| 12352 super.visitEnumDeclaration(node); |
| 12353 } else { |
| 12354 ClassElement outerClass = enclosingClass; |
| 12355 try { |
| 12356 enclosingClass = node.element; |
| 12357 nameScope = new ClassScope(nameScope, classElement); |
| 12358 visitEnumMembersInScope(node); |
| 12359 } finally { |
| 12360 enclosingClass = outerClass; |
| 12361 } |
| 12362 } |
| 12363 } finally { |
| 12364 nameScope = outerScope; |
| 12365 } |
| 12366 return null; |
| 12367 } |
| 12368 |
| 12369 void visitEnumMembersInScope(EnumDeclaration node) { |
| 12370 safelyVisit(node.documentationComment); |
| 12371 node.metadata.accept(this); |
| 12372 node.constants.accept(this); |
| 12373 } |
| 12374 |
| 12375 @override |
11949 Object visitForEachStatement(ForEachStatement node) { | 12376 Object visitForEachStatement(ForEachStatement node) { |
11950 Scope outerNameScope = nameScope; | 12377 Scope outerNameScope = nameScope; |
11951 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; | 12378 ImplicitLabelScope outerImplicitScope = _implicitLabelScope; |
11952 try { | 12379 try { |
11953 nameScope = new EnclosedScope(nameScope); | 12380 nameScope = new EnclosedScope(nameScope); |
11954 _implicitLabelScope = _implicitLabelScope.nest(node); | 12381 _implicitLabelScope = _implicitLabelScope.nest(node); |
11955 visitForEachStatementInScope(node); | 12382 visitForEachStatementInScope(node); |
11956 } finally { | 12383 } finally { |
11957 nameScope = outerNameScope; | 12384 nameScope = outerNameScope; |
11958 _implicitLabelScope = outerImplicitScope; | 12385 _implicitLabelScope = outerImplicitScope; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12289 } | 12716 } |
12290 } else if (statement is FunctionDeclarationStatement) { | 12717 } else if (statement is FunctionDeclarationStatement) { |
12291 FunctionDeclarationStatement fds = statement; | 12718 FunctionDeclarationStatement fds = statement; |
12292 scope.hide(fds.functionDeclaration.element); | 12719 scope.hide(fds.functionDeclaration.element); |
12293 } | 12720 } |
12294 } | 12721 } |
12295 } | 12722 } |
12296 } | 12723 } |
12297 | 12724 |
12298 /** | 12725 /** |
| 12726 * Implementation of [TypeSystem] using the strong mode rules. |
| 12727 * https://github.com/dart-lang/dev_compiler/blob/master/STRONG_MODE.md |
| 12728 */ |
| 12729 class StrongTypeSystemImpl implements TypeSystem { |
| 12730 final _specTypeSystem = new TypeSystemImpl(); |
| 12731 |
| 12732 StrongTypeSystemImpl(); |
| 12733 |
| 12734 @override |
| 12735 DartType getLeastUpperBound( |
| 12736 TypeProvider typeProvider, DartType type1, DartType type2) { |
| 12737 // TODO(leafp): Implement a strong mode version of this. |
| 12738 return _specTypeSystem.getLeastUpperBound(typeProvider, type1, type2); |
| 12739 } |
| 12740 |
| 12741 // TODO(leafp): Document the rules in play here |
| 12742 @override |
| 12743 bool isAssignableTo(DartType fromType, DartType toType) { |
| 12744 // An actual subtype |
| 12745 if (isSubtypeOf(fromType, toType)) { |
| 12746 return true; |
| 12747 } |
| 12748 |
| 12749 // Don't allow implicit downcasts between function types |
| 12750 // and call method objects, as these will almost always fail. |
| 12751 if ((fromType is FunctionType && _getCallMethodType(toType) != null) || |
| 12752 (toType is FunctionType && _getCallMethodType(fromType) != null)) { |
| 12753 return false; |
| 12754 } |
| 12755 |
| 12756 // If the subtype relation goes the other way, allow the implicit downcast. |
| 12757 // TODO(leafp): Emit warnings and hints for these in some way. |
| 12758 // TODO(leafp): Consider adding a flag to disable these? Or just rely on |
| 12759 // --warnings-as-errors? |
| 12760 if (isSubtypeOf(toType, fromType) || |
| 12761 _specTypeSystem.isAssignableTo(toType, fromType)) { |
| 12762 // TODO(leafp): error if type is known to be exact (literal, |
| 12763 // instance creation). |
| 12764 // TODO(leafp): Warn on composite downcast. |
| 12765 // TODO(leafp): hint on object/dynamic downcast. |
| 12766 // TODO(leafp): Consider allowing assignment casts. |
| 12767 return true; |
| 12768 } |
| 12769 |
| 12770 return false; |
| 12771 } |
| 12772 |
| 12773 @override |
| 12774 bool isSubtypeOf(DartType leftType, DartType rightType) { |
| 12775 return _isSubtypeOf(leftType, rightType, null); |
| 12776 } |
| 12777 |
| 12778 FunctionType _getCallMethodType(DartType t) { |
| 12779 if (t is InterfaceType) { |
| 12780 ClassElement element = t.element; |
| 12781 InheritanceManager manager = new InheritanceManager(element.library); |
| 12782 FunctionType callType = manager.lookupMemberType(t, "call"); |
| 12783 return callType; |
| 12784 } |
| 12785 return null; |
| 12786 } |
| 12787 |
| 12788 // Given a type t, if t is an interface type with a call method |
| 12789 // defined, return the function type for the call method, otherwise |
| 12790 // return null. |
| 12791 _GuardedSubtypeChecker<DartType> _guard( |
| 12792 _GuardedSubtypeChecker<DartType> check) { |
| 12793 return (DartType t1, DartType t2, Set<Element> visited) { |
| 12794 Element element = t1.element; |
| 12795 if (visited == null) { |
| 12796 visited = new HashSet<Element>(); |
| 12797 } |
| 12798 if (element == null || !visited.add(element)) { |
| 12799 return false; |
| 12800 } |
| 12801 try { |
| 12802 return check(t1, t2, visited); |
| 12803 } finally { |
| 12804 visited.remove(element); |
| 12805 } |
| 12806 }; |
| 12807 } |
| 12808 |
| 12809 bool _isBottom(DartType t, {bool dynamicIsBottom: false}) { |
| 12810 return (t.isDynamic && dynamicIsBottom) || t.isBottom; |
| 12811 } |
| 12812 |
| 12813 // Guard against loops in the class hierarchy |
| 12814 /** |
| 12815 * Check that [f1] is a subtype of [f2]. |
| 12816 * [fuzzyArrows] indicates whether or not the f1 and f2 should be |
| 12817 * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated |
| 12818 * as bottom). |
| 12819 */ |
| 12820 bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2, |
| 12821 {bool fuzzyArrows: true}) { |
| 12822 final r1s = f1.normalParameterTypes; |
| 12823 final o1s = f1.optionalParameterTypes; |
| 12824 final n1s = f1.namedParameterTypes; |
| 12825 final r2s = f2.normalParameterTypes; |
| 12826 final o2s = f2.optionalParameterTypes; |
| 12827 final n2s = f2.namedParameterTypes; |
| 12828 final ret1 = f1.returnType; |
| 12829 final ret2 = f2.returnType; |
| 12830 |
| 12831 // A -> B <: C -> D if C <: A and |
| 12832 // either D is void or B <: D |
| 12833 if (!ret2.isVoid && !isSubtypeOf(ret1, ret2)) { |
| 12834 return false; |
| 12835 } |
| 12836 |
| 12837 // Reject if one has named and the other has optional |
| 12838 if (n1s.length > 0 && o2s.length > 0) { |
| 12839 return false; |
| 12840 } |
| 12841 if (n2s.length > 0 && o1s.length > 0) { |
| 12842 return false; |
| 12843 } |
| 12844 |
| 12845 // Rebind _isSubtypeOf for convenience |
| 12846 _SubtypeChecker<DartType> parameterSubtype = (DartType t1, DartType t2) => |
| 12847 _isSubtypeOf(t1, t2, null, dynamicIsBottom: fuzzyArrows); |
| 12848 |
| 12849 // f2 has named parameters |
| 12850 if (n2s.length > 0) { |
| 12851 // Check that every named parameter in f2 has a match in f1 |
| 12852 for (String k2 in n2s.keys) { |
| 12853 if (!n1s.containsKey(k2)) { |
| 12854 return false; |
| 12855 } |
| 12856 if (!parameterSubtype(n2s[k2], n1s[k2])) { |
| 12857 return false; |
| 12858 } |
| 12859 } |
| 12860 } |
| 12861 // If we get here, we either have no named parameters, |
| 12862 // or else the named parameters match and we have no optional |
| 12863 // parameters |
| 12864 |
| 12865 // If f1 has more required parameters, reject |
| 12866 if (r1s.length > r2s.length) { |
| 12867 return false; |
| 12868 } |
| 12869 |
| 12870 // If f2 has more required + optional parameters, reject |
| 12871 if (r2s.length + o2s.length > r1s.length + o1s.length) { |
| 12872 return false; |
| 12873 } |
| 12874 |
| 12875 // The parameter lists must look like the following at this point |
| 12876 // where rrr is a region of required, and ooo is a region of optionals. |
| 12877 // f1: rrr ooo ooo ooo |
| 12878 // f2: rrr rrr ooo |
| 12879 int rr = r1s.length; // required in both |
| 12880 int or = r2s.length - r1s.length; // optional in f1, required in f2 |
| 12881 int oo = o2s.length; // optional in both |
| 12882 |
| 12883 for (int i = 0; i < rr; ++i) { |
| 12884 if (!parameterSubtype(r2s[i], r1s[i])) { |
| 12885 return false; |
| 12886 } |
| 12887 } |
| 12888 for (int i = 0, j = rr; i < or; ++i, ++j) { |
| 12889 if (!parameterSubtype(r2s[j], o1s[i])) { |
| 12890 return false; |
| 12891 } |
| 12892 } |
| 12893 for (int i = or, j = 0; i < oo; ++i, ++j) { |
| 12894 if (!parameterSubtype(o2s[j], o1s[i])) { |
| 12895 return false; |
| 12896 } |
| 12897 } |
| 12898 return true; |
| 12899 } |
| 12900 |
| 12901 bool _isInterfaceSubtypeOf( |
| 12902 InterfaceType i1, InterfaceType i2, Set<Element> visited) { |
| 12903 // Guard recursive calls |
| 12904 _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype = |
| 12905 _guard(_isInterfaceSubtypeOf); |
| 12906 |
| 12907 if (i1 == i2) { |
| 12908 return true; |
| 12909 } |
| 12910 |
| 12911 if (i1.element == i2.element) { |
| 12912 List<DartType> tArgs1 = i1.typeArguments; |
| 12913 List<DartType> tArgs2 = i2.typeArguments; |
| 12914 |
| 12915 assert(tArgs1.length == tArgs2.length); |
| 12916 |
| 12917 for (int i = 0; i < tArgs1.length; i++) { |
| 12918 DartType t1 = tArgs1[i]; |
| 12919 DartType t2 = tArgs2[i]; |
| 12920 if (!isSubtypeOf(t1, t2)) { |
| 12921 return false; |
| 12922 } |
| 12923 } |
| 12924 return true; |
| 12925 } |
| 12926 |
| 12927 if (i2.isDartCoreFunction && i1.element.getMethod("call") != null) { |
| 12928 return true; |
| 12929 } |
| 12930 |
| 12931 if (i1.isObject) { |
| 12932 return false; |
| 12933 } |
| 12934 |
| 12935 if (guardedInterfaceSubtype(i1.superclass, i2, visited)) { |
| 12936 return true; |
| 12937 } |
| 12938 |
| 12939 for (final parent in i1.interfaces) { |
| 12940 if (guardedInterfaceSubtype(parent, i2, visited)) { |
| 12941 return true; |
| 12942 } |
| 12943 } |
| 12944 |
| 12945 for (final parent in i1.mixins) { |
| 12946 if (guardedInterfaceSubtype(parent, i2, visited)) { |
| 12947 return true; |
| 12948 } |
| 12949 } |
| 12950 |
| 12951 return false; |
| 12952 } |
| 12953 |
| 12954 bool _isSubtypeOf(DartType t1, DartType t2, Set<Element> visited, |
| 12955 {bool dynamicIsBottom: false}) { |
| 12956 // Guard recursive calls |
| 12957 _GuardedSubtypeChecker<DartType> guardedSubtype = _guard(_isSubtypeOf); |
| 12958 |
| 12959 if (t1 == t2) { |
| 12960 return true; |
| 12961 } |
| 12962 |
| 12963 // The types are void, dynamic, bottom, interface types, function types |
| 12964 // and type parameters. We proceed by eliminating these different classes |
| 12965 // from consideration. |
| 12966 |
| 12967 // Trivially true. |
| 12968 if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) || |
| 12969 _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) { |
| 12970 return true; |
| 12971 } |
| 12972 |
| 12973 // Trivially false. |
| 12974 if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) || |
| 12975 _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) { |
| 12976 return false; |
| 12977 } |
| 12978 |
| 12979 // S <: T where S is a type variable |
| 12980 // T is not dynamic or object (handled above) |
| 12981 // S != T (handled above) |
| 12982 // So only true if bound of S is S' and |
| 12983 // S' <: T |
| 12984 if (t1 is TypeParameterType) { |
| 12985 DartType bound = t1.element.bound; |
| 12986 if (bound == null) return false; |
| 12987 return guardedSubtype(bound, t2, visited); |
| 12988 } |
| 12989 |
| 12990 if (t2 is TypeParameterType) { |
| 12991 return false; |
| 12992 } |
| 12993 |
| 12994 if (t1.isVoid || t2.isVoid) { |
| 12995 return false; |
| 12996 } |
| 12997 |
| 12998 // We've eliminated void, dynamic, bottom, and type parameters. The only |
| 12999 // cases are the combinations of interface type and function type. |
| 13000 |
| 13001 // A function type can only subtype an interface type if |
| 13002 // the interface type is Function |
| 13003 if (t1 is FunctionType && t2 is InterfaceType) { |
| 13004 return t2.isDartCoreFunction; |
| 13005 } |
| 13006 |
| 13007 // An interface type can only subtype a function type if |
| 13008 // the interface type declares a call method with a type |
| 13009 // which is a super type of the function type. |
| 13010 if (t1 is InterfaceType && t2 is FunctionType) { |
| 13011 var callType = _getCallMethodType(t1); |
| 13012 return (callType != null) && _isFunctionSubtypeOf(callType, t2); |
| 13013 } |
| 13014 |
| 13015 // Two interface types |
| 13016 if (t1 is InterfaceType && t2 is InterfaceType) { |
| 13017 return _isInterfaceSubtypeOf(t1, t2, visited); |
| 13018 } |
| 13019 |
| 13020 return _isFunctionSubtypeOf(t1 as FunctionType, t2 as FunctionType); |
| 13021 } |
| 13022 |
| 13023 // TODO(leafp): Document the rules in play here |
| 13024 bool _isTop(DartType t, {bool dynamicIsBottom: false}) { |
| 13025 return (t.isDynamic && !dynamicIsBottom) || t.isObject; |
| 13026 } |
| 13027 } |
| 13028 |
| 13029 /** |
12299 * Instances of this class manage the knowledge of what the set of subtypes are
for a given type. | 13030 * Instances of this class manage the knowledge of what the set of subtypes are
for a given type. |
12300 */ | 13031 */ |
12301 class SubtypeManager { | 13032 class SubtypeManager { |
12302 /** | 13033 /** |
12303 * A map between [ClassElement]s and a set of [ClassElement]s that are subtype
s of the | 13034 * A map between [ClassElement]s and a set of [ClassElement]s that are subtype
s of the |
12304 * key. | 13035 * key. |
12305 */ | 13036 */ |
12306 HashMap<ClassElement, HashSet<ClassElement>> _subtypeMap = | 13037 HashMap<ClassElement, HashSet<ClassElement>> _subtypeMap = |
12307 new HashMap<ClassElement, HashSet<ClassElement>>(); | 13038 new HashMap<ClassElement, HashSet<ClassElement>>(); |
12308 | 13039 |
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13236 InterfaceType get iterableType => _iterableType; | 13967 InterfaceType get iterableType => _iterableType; |
13237 | 13968 |
13238 @override | 13969 @override |
13239 InterfaceType get listType => _listType; | 13970 InterfaceType get listType => _listType; |
13240 | 13971 |
13241 @override | 13972 @override |
13242 InterfaceType get mapType => _mapType; | 13973 InterfaceType get mapType => _mapType; |
13243 | 13974 |
13244 @override | 13975 @override |
13245 List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[ | 13976 List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[ |
13246 nullType, | 13977 nullType, |
13247 numType, | 13978 numType, |
13248 intType, | 13979 intType, |
13249 doubleType, | 13980 doubleType, |
13250 boolType, | 13981 boolType, |
13251 stringType | 13982 stringType |
13252 ]; | 13983 ]; |
13253 | 13984 |
13254 @override | 13985 @override |
13255 DartObjectImpl get nullObject { | 13986 DartObjectImpl get nullObject { |
13256 if (_nullObject == null) { | 13987 if (_nullObject == null) { |
13257 _nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE); | 13988 _nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE); |
13258 } | 13989 } |
13259 return _nullObject; | 13990 return _nullObject; |
13260 } | 13991 } |
13261 | 13992 |
13262 @override | 13993 @override |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13373 * [errorListener] is the error listener that will be informed of any errors | 14104 * [errorListener] is the error listener that will be informed of any errors |
13374 * that are found during resolution. | 14105 * that are found during resolution. |
13375 * [nameScope] is the scope used to resolve identifiers in the node that will | 14106 * [nameScope] is the scope used to resolve identifiers in the node that will |
13376 * first be visited. If `null` or unspecified, a new [LibraryScope] will be | 14107 * first be visited. If `null` or unspecified, a new [LibraryScope] will be |
13377 * created based on [definingLibrary] and [typeProvider]. | 14108 * created based on [definingLibrary] and [typeProvider]. |
13378 */ | 14109 */ |
13379 TypeResolverVisitor(LibraryElement definingLibrary, Source source, | 14110 TypeResolverVisitor(LibraryElement definingLibrary, Source source, |
13380 TypeProvider typeProvider, AnalysisErrorListener errorListener, | 14111 TypeProvider typeProvider, AnalysisErrorListener errorListener, |
13381 {Scope nameScope}) | 14112 {Scope nameScope}) |
13382 : super(definingLibrary, source, typeProvider, errorListener, | 14113 : super(definingLibrary, source, typeProvider, errorListener, |
13383 nameScope: nameScope) { | 14114 nameScope: nameScope) { |
13384 _dynamicType = typeProvider.dynamicType; | 14115 _dynamicType = typeProvider.dynamicType; |
13385 _undefinedType = typeProvider.undefinedType; | 14116 _undefinedType = typeProvider.undefinedType; |
13386 } | 14117 } |
13387 | 14118 |
13388 @override | 14119 @override |
13389 Object visitAnnotation(Annotation node) { | 14120 Object visitAnnotation(Annotation node) { |
13390 // | 14121 // |
13391 // Visit annotations, if the annotation is @proxy, on a class, and "proxy" | 14122 // Visit annotations, if the annotation is @proxy, on a class, and "proxy" |
13392 // resolves to the proxy annotation in dart.core, then create create the | 14123 // resolves to the proxy annotation in dart.core, then create create the |
13393 // ElementAnnotationImpl and set it as the metadata on the enclosing class. | 14124 // ElementAnnotationImpl and set it as the metadata on the enclosing class. |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13578 Object visitFieldFormalParameter(FieldFormalParameter node) { | 14309 Object visitFieldFormalParameter(FieldFormalParameter node) { |
13579 super.visitFieldFormalParameter(node); | 14310 super.visitFieldFormalParameter(node); |
13580 Element element = node.identifier.staticElement; | 14311 Element element = node.identifier.staticElement; |
13581 if (element is ParameterElementImpl) { | 14312 if (element is ParameterElementImpl) { |
13582 ParameterElementImpl parameter = element; | 14313 ParameterElementImpl parameter = element; |
13583 FormalParameterList parameterList = node.parameters; | 14314 FormalParameterList parameterList = node.parameters; |
13584 if (parameterList == null) { | 14315 if (parameterList == null) { |
13585 DartType type; | 14316 DartType type; |
13586 TypeName typeName = node.type; | 14317 TypeName typeName = node.type; |
13587 if (typeName == null) { | 14318 if (typeName == null) { |
| 14319 element.hasImplicitType = true; |
13588 type = _dynamicType; | 14320 type = _dynamicType; |
13589 if (parameter is FieldFormalParameterElement) { | 14321 if (parameter is FieldFormalParameterElement) { |
13590 FieldElement fieldElement = | 14322 FieldElement fieldElement = |
13591 (parameter as FieldFormalParameterElement).field; | 14323 (parameter as FieldFormalParameterElement).field; |
13592 if (fieldElement != null) { | 14324 if (fieldElement != null) { |
13593 type = fieldElement.type; | 14325 type = fieldElement.type; |
13594 } | 14326 } |
13595 } | 14327 } |
13596 } else { | 14328 } else { |
13597 type = _getType(typeName); | 14329 type = _getType(typeName); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13769 if (name.name == null) { | 14501 if (name.name == null) { |
13770 PrefixedIdentifier prefixedIdentifier = | 14502 PrefixedIdentifier prefixedIdentifier = |
13771 typeName as PrefixedIdentifier; | 14503 typeName as PrefixedIdentifier; |
13772 SimpleIdentifier prefix = prefixedIdentifier.prefix; | 14504 SimpleIdentifier prefix = prefixedIdentifier.prefix; |
13773 element = nameScope.lookup(prefix, definingLibrary); | 14505 element = nameScope.lookup(prefix, definingLibrary); |
13774 if (element is PrefixElement) { | 14506 if (element is PrefixElement) { |
13775 if (parent.parent is InstanceCreationExpression && | 14507 if (parent.parent is InstanceCreationExpression && |
13776 (parent.parent as InstanceCreationExpression).isConst) { | 14508 (parent.parent as InstanceCreationExpression).isConst) { |
13777 // If, if this is a const expression, then generate a | 14509 // If, if this is a const expression, then generate a |
13778 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. | 14510 // CompileTimeErrorCode.CONST_WITH_NON_TYPE error. |
13779 reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE, | 14511 reportErrorForNode( |
| 14512 CompileTimeErrorCode.CONST_WITH_NON_TYPE, |
13780 prefixedIdentifier.identifier, | 14513 prefixedIdentifier.identifier, |
13781 [prefixedIdentifier.identifier.name]); | 14514 [prefixedIdentifier.identifier.name]); |
13782 } else { | 14515 } else { |
13783 // Else, if this expression is a new expression, report a | 14516 // Else, if this expression is a new expression, report a |
13784 // NEW_WITH_NON_TYPE warning. | 14517 // NEW_WITH_NON_TYPE warning. |
13785 reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE, | 14518 reportErrorForNode( |
| 14519 StaticWarningCode.NEW_WITH_NON_TYPE, |
13786 prefixedIdentifier.identifier, | 14520 prefixedIdentifier.identifier, |
13787 [prefixedIdentifier.identifier.name]); | 14521 [prefixedIdentifier.identifier.name]); |
13788 } | 14522 } |
13789 _setElement(prefix, element); | 14523 _setElement(prefix, element); |
13790 return null; | 14524 return null; |
13791 } else if (element != null) { | 14525 } else if (element != null) { |
13792 // | 14526 // |
13793 // Rewrite the constructor name. The parser, when it sees a | 14527 // Rewrite the constructor name. The parser, when it sees a |
13794 // constructor named "a.b", cannot tell whether "a" is a prefix and | 14528 // constructor named "a.b", cannot tell whether "a" is a prefix and |
13795 // "b" is a class name, or whether "a" is a class name and "b" is a | 14529 // "b" is a class name, or whether "a" is a class name and "b" is a |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13953 if (argumentCount == parameterCount) { | 14687 if (argumentCount == parameterCount) { |
13954 for (int i = 0; i < parameterCount; i++) { | 14688 for (int i = 0; i < parameterCount; i++) { |
13955 TypeName argumentTypeName = arguments[i]; | 14689 TypeName argumentTypeName = arguments[i]; |
13956 DartType argumentType = _getType(argumentTypeName); | 14690 DartType argumentType = _getType(argumentTypeName); |
13957 if (argumentType == null) { | 14691 if (argumentType == null) { |
13958 argumentType = _dynamicType; | 14692 argumentType = _dynamicType; |
13959 } | 14693 } |
13960 typeArguments[i] = argumentType; | 14694 typeArguments[i] = argumentType; |
13961 } | 14695 } |
13962 } else { | 14696 } else { |
13963 reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node, [ | 14697 reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node, |
13964 typeName.name, | 14698 [typeName.name, parameterCount, argumentCount]); |
13965 parameterCount, | |
13966 argumentCount | |
13967 ]); | |
13968 for (int i = 0; i < parameterCount; i++) { | 14699 for (int i = 0; i < parameterCount; i++) { |
13969 typeArguments[i] = _dynamicType; | 14700 typeArguments[i] = _dynamicType; |
13970 } | 14701 } |
13971 } | 14702 } |
13972 if (type is InterfaceTypeImpl) { | 14703 if (type is InterfaceTypeImpl) { |
13973 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl; | 14704 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl; |
13974 type = interfaceType.substitute4(typeArguments); | 14705 type = interfaceType.substitute4(typeArguments); |
13975 } else if (type is FunctionTypeImpl) { | 14706 } else if (type is FunctionTypeImpl) { |
13976 FunctionTypeImpl functionType = type as FunctionTypeImpl; | 14707 FunctionTypeImpl functionType = type as FunctionTypeImpl; |
13977 type = functionType.substitute3(typeArguments); | 14708 type = functionType.substitute3(typeArguments); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14321 * given class element. | 15052 * given class element. |
14322 * | 15053 * |
14323 * @param classElement the class element with which the mixin and interface ty
pes are to be | 15054 * @param classElement the class element with which the mixin and interface ty
pes are to be |
14324 * associated | 15055 * associated |
14325 * @param withClause the with clause to be resolved | 15056 * @param withClause the with clause to be resolved |
14326 * @param implementsClause the implements clause to be resolved | 15057 * @param implementsClause the implements clause to be resolved |
14327 */ | 15058 */ |
14328 void _resolve(ClassElementImpl classElement, WithClause withClause, | 15059 void _resolve(ClassElementImpl classElement, WithClause withClause, |
14329 ImplementsClause implementsClause) { | 15060 ImplementsClause implementsClause) { |
14330 if (withClause != null) { | 15061 if (withClause != null) { |
14331 List<InterfaceType> mixinTypes = _resolveTypes(withClause.mixinTypes, | 15062 List<InterfaceType> mixinTypes = _resolveTypes( |
| 15063 withClause.mixinTypes, |
14332 CompileTimeErrorCode.MIXIN_OF_NON_CLASS, | 15064 CompileTimeErrorCode.MIXIN_OF_NON_CLASS, |
14333 CompileTimeErrorCode.MIXIN_OF_ENUM, | 15065 CompileTimeErrorCode.MIXIN_OF_ENUM, |
14334 CompileTimeErrorCode.MIXIN_OF_NON_CLASS); | 15066 CompileTimeErrorCode.MIXIN_OF_NON_CLASS); |
14335 if (classElement != null) { | 15067 if (classElement != null) { |
14336 classElement.mixins = mixinTypes; | 15068 classElement.mixins = mixinTypes; |
14337 classElement.withClauseRange = | 15069 classElement.withClauseRange = |
14338 new SourceRange(withClause.offset, withClause.length); | 15070 new SourceRange(withClause.offset, withClause.length); |
14339 } | 15071 } |
14340 } | 15072 } |
14341 if (implementsClause != null) { | 15073 if (implementsClause != null) { |
14342 NodeList<TypeName> interfaces = implementsClause.interfaces; | 15074 NodeList<TypeName> interfaces = implementsClause.interfaces; |
14343 List<InterfaceType> interfaceTypes = _resolveTypes(interfaces, | 15075 List<InterfaceType> interfaceTypes = _resolveTypes( |
| 15076 interfaces, |
14344 CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, | 15077 CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, |
14345 CompileTimeErrorCode.IMPLEMENTS_ENUM, | 15078 CompileTimeErrorCode.IMPLEMENTS_ENUM, |
14346 CompileTimeErrorCode.IMPLEMENTS_DYNAMIC); | 15079 CompileTimeErrorCode.IMPLEMENTS_DYNAMIC); |
14347 if (classElement != null) { | 15080 if (classElement != null) { |
14348 classElement.interfaces = interfaceTypes; | 15081 classElement.interfaces = interfaceTypes; |
14349 } | 15082 } |
14350 // TODO(brianwilkerson) Move the following checks to ErrorVerifier. | 15083 // TODO(brianwilkerson) Move the following checks to ErrorVerifier. |
14351 int count = interfaces.length; | 15084 int count = interfaces.length; |
14352 List<bool> detectedRepeatOnIndex = new List<bool>.filled(count, false); | 15085 List<bool> detectedRepeatOnIndex = new List<bool>.filled(count, false); |
14353 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { | 15086 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14408 /** | 15141 /** |
14409 * Resolve the types in the given list of type names. | 15142 * Resolve the types in the given list of type names. |
14410 * | 15143 * |
14411 * @param typeNames the type names to be resolved | 15144 * @param typeNames the type names to be resolved |
14412 * @param nonTypeError the error to produce if the type name is defined to be
something other than | 15145 * @param nonTypeError the error to produce if the type name is defined to be
something other than |
14413 * a type | 15146 * a type |
14414 * @param enumTypeError the error to produce if the type name is defined to be
an enum | 15147 * @param enumTypeError the error to produce if the type name is defined to be
an enum |
14415 * @param dynamicTypeError the error to produce if the type name is "dynamic" | 15148 * @param dynamicTypeError the error to produce if the type name is "dynamic" |
14416 * @return an array containing all of the types that were resolved. | 15149 * @return an array containing all of the types that were resolved. |
14417 */ | 15150 */ |
14418 List<InterfaceType> _resolveTypes(NodeList<TypeName> typeNames, | 15151 List<InterfaceType> _resolveTypes( |
14419 ErrorCode nonTypeError, ErrorCode enumTypeError, | 15152 NodeList<TypeName> typeNames, |
| 15153 ErrorCode nonTypeError, |
| 15154 ErrorCode enumTypeError, |
14420 ErrorCode dynamicTypeError) { | 15155 ErrorCode dynamicTypeError) { |
14421 List<InterfaceType> types = new List<InterfaceType>(); | 15156 List<InterfaceType> types = new List<InterfaceType>(); |
14422 for (TypeName typeName in typeNames) { | 15157 for (TypeName typeName in typeNames) { |
14423 InterfaceType type = | 15158 InterfaceType type = |
14424 _resolveType(typeName, nonTypeError, enumTypeError, dynamicTypeError); | 15159 _resolveType(typeName, nonTypeError, enumTypeError, dynamicTypeError); |
14425 if (type != null) { | 15160 if (type != null) { |
14426 types.add(type); | 15161 types.add(type); |
14427 } | 15162 } |
14428 } | 15163 } |
14429 return types; | 15164 return types; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14518 | 15253 |
14519 /** | 15254 /** |
14520 * The interface `TypeSystem` defines the behavior of an object representing | 15255 * The interface `TypeSystem` defines the behavior of an object representing |
14521 * the type system. This provides a common location to put methods that act on | 15256 * the type system. This provides a common location to put methods that act on |
14522 * types but may need access to more global data structures, and it paves the | 15257 * types but may need access to more global data structures, and it paves the |
14523 * way for a possible future where we may wish to make the type system | 15258 * way for a possible future where we may wish to make the type system |
14524 * pluggable. | 15259 * pluggable. |
14525 */ | 15260 */ |
14526 abstract class TypeSystem { | 15261 abstract class TypeSystem { |
14527 /** | 15262 /** |
14528 * Return the [TypeProvider] associated with this [TypeSystem]. | 15263 * Compute the least upper bound of two types. |
14529 */ | 15264 */ |
14530 TypeProvider get typeProvider; | 15265 DartType getLeastUpperBound( |
| 15266 TypeProvider typeProvider, DartType type1, DartType type2); |
14531 | 15267 |
14532 /** | 15268 /** |
14533 * Compute the least upper bound of two types. | 15269 * Return `true` if the [leftType] is assignable to the [rightType] (that is, |
| 15270 * if leftType <==> rightType). |
14534 */ | 15271 */ |
14535 DartType getLeastUpperBound(DartType type1, DartType type2); | 15272 bool isAssignableTo(DartType leftType, DartType rightType); |
| 15273 |
| 15274 /** |
| 15275 * Return `true` if the [leftType] is a subtype of the [rightType] (that is, |
| 15276 * if leftType <: rightType). |
| 15277 */ |
| 15278 bool isSubtypeOf(DartType leftType, DartType rightType); |
| 15279 |
| 15280 /** |
| 15281 * Create either a strong mode or regular type system based on context. |
| 15282 */ |
| 15283 static TypeSystem create(AnalysisContext context) { |
| 15284 return (context.analysisOptions.strongMode) |
| 15285 ? new StrongTypeSystemImpl() |
| 15286 : new TypeSystemImpl(); |
| 15287 } |
14536 } | 15288 } |
14537 | 15289 |
14538 /** | 15290 /** |
14539 * Implementation of [TypeSystem] using the rules in the Dart specification. | 15291 * Implementation of [TypeSystem] using the rules in the Dart specification. |
14540 */ | 15292 */ |
14541 class TypeSystemImpl implements TypeSystem { | 15293 class TypeSystemImpl implements TypeSystem { |
14542 @override | 15294 TypeSystemImpl(); |
14543 final TypeProvider typeProvider; | |
14544 | |
14545 TypeSystemImpl(this.typeProvider); | |
14546 | 15295 |
14547 @override | 15296 @override |
14548 DartType getLeastUpperBound(DartType type1, DartType type2) { | 15297 DartType getLeastUpperBound( |
| 15298 TypeProvider typeProvider, DartType type1, DartType type2) { |
14549 // The least upper bound relation is reflexive. | 15299 // The least upper bound relation is reflexive. |
14550 if (identical(type1, type2)) { | 15300 if (identical(type1, type2)) { |
14551 return type1; | 15301 return type1; |
14552 } | 15302 } |
14553 // The least upper bound of dynamic and any type T is dynamic. | 15303 // The least upper bound of dynamic and any type T is dynamic. |
14554 if (type1.isDynamic) { | 15304 if (type1.isDynamic) { |
14555 return type1; | 15305 return type1; |
14556 } | 15306 } |
14557 if (type2.isDynamic) { | 15307 if (type2.isDynamic) { |
14558 return type2; | 15308 return type2; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14615 if (result == null) { | 15365 if (result == null) { |
14616 return typeProvider.functionType; | 15366 return typeProvider.functionType; |
14617 } | 15367 } |
14618 return result; | 15368 return result; |
14619 } else { | 15369 } else { |
14620 // Should never happen. As a defensive measure, return the dynamic type. | 15370 // Should never happen. As a defensive measure, return the dynamic type. |
14621 assert(false); | 15371 assert(false); |
14622 return typeProvider.dynamicType; | 15372 return typeProvider.dynamicType; |
14623 } | 15373 } |
14624 } | 15374 } |
| 15375 |
| 15376 @override |
| 15377 bool isAssignableTo(DartType leftType, DartType rightType) { |
| 15378 return leftType.isAssignableTo(rightType); |
| 15379 } |
| 15380 |
| 15381 @override |
| 15382 bool isSubtypeOf(DartType leftType, DartType rightType) { |
| 15383 return leftType.isSubtypeOf(rightType); |
| 15384 } |
14625 } | 15385 } |
14626 | 15386 |
14627 /** | 15387 /** |
14628 * Instances of the class [UnusedLocalElementsVerifier] traverse an element | 15388 * Instances of the class [UnusedLocalElementsVerifier] traverse an element |
14629 * structure looking for cases of [HintCode.UNUSED_ELEMENT], | 15389 * structure looking for cases of [HintCode.UNUSED_ELEMENT], |
14630 * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc. | 15390 * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc. |
14631 */ | 15391 */ |
14632 class UnusedLocalElementsVerifier extends RecursiveElementVisitor { | 15392 class UnusedLocalElementsVerifier extends RecursiveElementVisitor { |
14633 /** | 15393 /** |
14634 * The error listener to which errors will be reported. | 15394 * The error listener to which errors will be reported. |
14635 */ | 15395 */ |
14636 final AnalysisErrorListener _errorListener; | 15396 final AnalysisErrorListener _errorListener; |
14637 | 15397 |
14638 /** | 15398 /** |
14639 * The elements know to be used. | 15399 * The elements know to be used. |
14640 */ | 15400 */ |
14641 final UsedLocalElements _usedElements; | 15401 final UsedLocalElements _usedElements; |
14642 | 15402 |
14643 /** | 15403 /** |
14644 * Create a new instance of the [UnusedLocalElementsVerifier]. | 15404 * Create a new instance of the [UnusedLocalElementsVerifier]. |
14645 */ | 15405 */ |
14646 UnusedLocalElementsVerifier(this._errorListener, this._usedElements); | 15406 UnusedLocalElementsVerifier(this._errorListener, this._usedElements); |
14647 | 15407 |
14648 @override | 15408 @override |
14649 visitClassElement(ClassElement element) { | 15409 visitClassElement(ClassElement element) { |
14650 if (!_isUsedElement(element)) { | 15410 if (!_isUsedElement(element)) { |
14651 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ | 15411 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, |
14652 element.kind.displayName, | 15412 [element.kind.displayName, element.displayName]); |
14653 element.displayName | |
14654 ]); | |
14655 } | 15413 } |
14656 super.visitClassElement(element); | 15414 super.visitClassElement(element); |
14657 } | 15415 } |
14658 | 15416 |
14659 @override | 15417 @override |
14660 visitFieldElement(FieldElement element) { | 15418 visitFieldElement(FieldElement element) { |
14661 if (!_isReadMember(element)) { | 15419 if (!_isReadMember(element)) { |
14662 _reportErrorForElement( | 15420 _reportErrorForElement( |
14663 HintCode.UNUSED_FIELD, element, [element.displayName]); | 15421 HintCode.UNUSED_FIELD, element, [element.displayName]); |
14664 } | 15422 } |
14665 super.visitFieldElement(element); | 15423 super.visitFieldElement(element); |
14666 } | 15424 } |
14667 | 15425 |
14668 @override | 15426 @override |
14669 visitFunctionElement(FunctionElement element) { | 15427 visitFunctionElement(FunctionElement element) { |
14670 if (!_isUsedElement(element)) { | 15428 if (!_isUsedElement(element)) { |
14671 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ | 15429 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, |
14672 element.kind.displayName, | 15430 [element.kind.displayName, element.displayName]); |
14673 element.displayName | |
14674 ]); | |
14675 } | 15431 } |
14676 super.visitFunctionElement(element); | 15432 super.visitFunctionElement(element); |
14677 } | 15433 } |
14678 | 15434 |
14679 @override | 15435 @override |
14680 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { | 15436 visitFunctionTypeAliasElement(FunctionTypeAliasElement element) { |
14681 if (!_isUsedElement(element)) { | 15437 if (!_isUsedElement(element)) { |
14682 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ | 15438 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, |
14683 element.kind.displayName, | 15439 [element.kind.displayName, element.displayName]); |
14684 element.displayName | |
14685 ]); | |
14686 } | 15440 } |
14687 super.visitFunctionTypeAliasElement(element); | 15441 super.visitFunctionTypeAliasElement(element); |
14688 } | 15442 } |
14689 | 15443 |
14690 @override | 15444 @override |
14691 visitLocalVariableElement(LocalVariableElement element) { | 15445 visitLocalVariableElement(LocalVariableElement element) { |
14692 if (!_isUsedElement(element) && !_isNamedUnderscore(element)) { | 15446 if (!_isUsedElement(element) && !_isNamedUnderscore(element)) { |
14693 HintCode errorCode; | 15447 HintCode errorCode; |
14694 if (_usedElements.isCatchException(element)) { | 15448 if (_usedElements.isCatchException(element)) { |
14695 errorCode = HintCode.UNUSED_CATCH_CLAUSE; | 15449 errorCode = HintCode.UNUSED_CATCH_CLAUSE; |
14696 } else if (_usedElements.isCatchStackTrace(element)) { | 15450 } else if (_usedElements.isCatchStackTrace(element)) { |
14697 errorCode = HintCode.UNUSED_CATCH_STACK; | 15451 errorCode = HintCode.UNUSED_CATCH_STACK; |
14698 } else { | 15452 } else { |
14699 errorCode = HintCode.UNUSED_LOCAL_VARIABLE; | 15453 errorCode = HintCode.UNUSED_LOCAL_VARIABLE; |
14700 } | 15454 } |
14701 _reportErrorForElement(errorCode, element, [element.displayName]); | 15455 _reportErrorForElement(errorCode, element, [element.displayName]); |
14702 } | 15456 } |
14703 } | 15457 } |
14704 | 15458 |
14705 @override | 15459 @override |
14706 visitMethodElement(MethodElement element) { | 15460 visitMethodElement(MethodElement element) { |
14707 if (!_isUsedMember(element)) { | 15461 if (!_isUsedMember(element)) { |
14708 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ | 15462 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, |
14709 element.kind.displayName, | 15463 [element.kind.displayName, element.displayName]); |
14710 element.displayName | |
14711 ]); | |
14712 } | 15464 } |
14713 super.visitMethodElement(element); | 15465 super.visitMethodElement(element); |
14714 } | 15466 } |
14715 | 15467 |
14716 @override | 15468 @override |
14717 visitPropertyAccessorElement(PropertyAccessorElement element) { | 15469 visitPropertyAccessorElement(PropertyAccessorElement element) { |
14718 if (!_isUsedMember(element)) { | 15470 if (!_isUsedMember(element)) { |
14719 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [ | 15471 _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, |
14720 element.kind.displayName, | 15472 [element.kind.displayName, element.displayName]); |
14721 element.displayName | |
14722 ]); | |
14723 } | 15473 } |
14724 super.visitPropertyAccessorElement(element); | 15474 super.visitPropertyAccessorElement(element); |
14725 } | 15475 } |
14726 | 15476 |
14727 bool _isNamedUnderscore(LocalVariableElement element) { | 15477 bool _isNamedUnderscore(LocalVariableElement element) { |
14728 String name = element.name; | 15478 String name = element.name; |
14729 if (name != null) { | 15479 if (name != null) { |
14730 for (int index = name.length - 1; index >= 0; --index) { | 15480 for (int index = name.length - 1; index >= 0; --index) { |
14731 if (name.codeUnitAt(index) != 0x5F) { | 15481 if (name.codeUnitAt(index) != 0x5F) { |
14732 // 0x5F => '_' | 15482 // 0x5F => '_' |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14773 if (_usedElements.members.contains(element.displayName)) { | 15523 if (_usedElements.members.contains(element.displayName)) { |
14774 return true; | 15524 return true; |
14775 } | 15525 } |
14776 return _usedElements.elements.contains(element); | 15526 return _usedElements.elements.contains(element); |
14777 } | 15527 } |
14778 | 15528 |
14779 void _reportErrorForElement( | 15529 void _reportErrorForElement( |
14780 ErrorCode errorCode, Element element, List<Object> arguments) { | 15530 ErrorCode errorCode, Element element, List<Object> arguments) { |
14781 if (element != null) { | 15531 if (element != null) { |
14782 _errorListener.onError(new AnalysisError(element.source, | 15532 _errorListener.onError(new AnalysisError(element.source, |
14783 element.nameOffset, element.displayName.length, errorCode, | 15533 element.nameOffset, element.nameLength, errorCode, arguments)); |
14784 arguments)); | |
14785 } | 15534 } |
14786 } | 15535 } |
14787 } | 15536 } |
14788 | 15537 |
14789 /** | 15538 /** |
14790 * A container with information about used imports prefixes and used imported | 15539 * A container with information about used imports prefixes and used imported |
14791 * elements. | 15540 * elements. |
14792 */ | 15541 */ |
14793 class UsedImportedElements { | 15542 class UsedImportedElements { |
14794 /** | 15543 /** |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14901 * [errorListener] is the error listener that will be informed of any errors | 15650 * [errorListener] is the error listener that will be informed of any errors |
14902 * that are found during resolution. | 15651 * that are found during resolution. |
14903 * [nameScope] is the scope used to resolve identifiers in the node that will | 15652 * [nameScope] is the scope used to resolve identifiers in the node that will |
14904 * first be visited. If `null` or unspecified, a new [LibraryScope] will be | 15653 * first be visited. If `null` or unspecified, a new [LibraryScope] will be |
14905 * created based on [definingLibrary] and [typeProvider]. | 15654 * created based on [definingLibrary] and [typeProvider]. |
14906 */ | 15655 */ |
14907 VariableResolverVisitor(LibraryElement definingLibrary, Source source, | 15656 VariableResolverVisitor(LibraryElement definingLibrary, Source source, |
14908 TypeProvider typeProvider, AnalysisErrorListener errorListener, | 15657 TypeProvider typeProvider, AnalysisErrorListener errorListener, |
14909 {Scope nameScope}) | 15658 {Scope nameScope}) |
14910 : super(definingLibrary, source, typeProvider, errorListener, | 15659 : super(definingLibrary, source, typeProvider, errorListener, |
14911 nameScope: nameScope); | 15660 nameScope: nameScope); |
14912 | 15661 |
14913 /** | 15662 /** |
14914 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. | 15663 * Initialize a newly created visitor to resolve the nodes in a compilation un
it. |
14915 * | 15664 * |
14916 * @param library the library containing the compilation unit being resolved | 15665 * @param library the library containing the compilation unit being resolved |
14917 * @param source the source representing the compilation unit being visited | 15666 * @param source the source representing the compilation unit being visited |
14918 * @param typeProvider the object used to access the types from the core libra
ry | 15667 * @param typeProvider the object used to access the types from the core libra
ry |
14919 * | 15668 * |
14920 * Deprecated. Please use unnamed constructor instead. | 15669 * Deprecated. Please use unnamed constructor instead. |
14921 */ | 15670 */ |
14922 @deprecated | 15671 @deprecated |
14923 VariableResolverVisitor.con1( | 15672 VariableResolverVisitor.con1( |
14924 Library library, Source source, TypeProvider typeProvider) | 15673 Library library, Source source, TypeProvider typeProvider) |
14925 : this( | 15674 : this( |
14926 library.libraryElement, source, typeProvider, library.errorListener, | 15675 library.libraryElement, source, typeProvider, library.errorListener, |
14927 nameScope: library.libraryScope); | 15676 nameScope: library.libraryScope); |
14928 | 15677 |
14929 @override | 15678 @override |
14930 Object visitExportDirective(ExportDirective node) => null; | 15679 Object visitExportDirective(ExportDirective node) => null; |
14931 | 15680 |
14932 @override | 15681 @override |
14933 Object visitFunctionDeclaration(FunctionDeclaration node) { | 15682 Object visitFunctionDeclaration(FunctionDeclaration node) { |
14934 ExecutableElement outerFunction = _enclosingFunction; | 15683 ExecutableElement outerFunction = _enclosingFunction; |
14935 try { | 15684 try { |
14936 _enclosingFunction = node.element; | 15685 _enclosingFunction = node.element; |
14937 return super.visitFunctionDeclaration(node); | 15686 return super.visitFunctionDeclaration(node); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15026 } | 15775 } |
15027 return null; | 15776 return null; |
15028 } | 15777 } |
15029 } | 15778 } |
15030 | 15779 |
15031 class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor { | 15780 class _ConstantVerifier_validateInitializerExpression extends ConstantVisitor { |
15032 final ConstantVerifier verifier; | 15781 final ConstantVerifier verifier; |
15033 | 15782 |
15034 List<ParameterElement> parameterElements; | 15783 List<ParameterElement> parameterElements; |
15035 | 15784 |
15036 _ConstantVerifier_validateInitializerExpression(TypeProvider typeProvider, | 15785 TypeSystem _typeSystem; |
15037 ErrorReporter errorReporter, this.verifier, this.parameterElements, | 15786 |
15038 DeclaredVariables declaredVariables) | 15787 _ConstantVerifier_validateInitializerExpression( |
15039 : super(new ConstantEvaluationEngine(typeProvider, declaredVariables), | 15788 TypeProvider typeProvider, |
15040 errorReporter); | 15789 ErrorReporter errorReporter, |
| 15790 this.verifier, |
| 15791 this.parameterElements, |
| 15792 DeclaredVariables declaredVariables, |
| 15793 {TypeSystem typeSystem}) |
| 15794 : _typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl(), |
| 15795 super( |
| 15796 new ConstantEvaluationEngine(typeProvider, declaredVariables, |
| 15797 typeSystem: typeSystem), |
| 15798 errorReporter); |
15041 | 15799 |
15042 @override | 15800 @override |
15043 DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) { | 15801 DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) { |
15044 Element element = node.staticElement; | 15802 Element element = node.staticElement; |
15045 for (ParameterElement parameterElement in parameterElements) { | 15803 for (ParameterElement parameterElement in parameterElements) { |
15046 if (identical(parameterElement, element) && parameterElement != null) { | 15804 if (identical(parameterElement, element) && parameterElement != null) { |
15047 DartType type = parameterElement.type; | 15805 DartType type = parameterElement.type; |
15048 if (type != null) { | 15806 if (type != null) { |
15049 if (type.isDynamic) { | 15807 if (type.isDynamic) { |
15050 return new DartObjectImpl( | 15808 return new DartObjectImpl( |
15051 verifier._typeProvider.objectType, DynamicState.DYNAMIC_STATE); | 15809 verifier._typeProvider.objectType, DynamicState.DYNAMIC_STATE); |
15052 } else if (type.isSubtypeOf(verifier._boolType)) { | 15810 } else if (_typeSystem.isSubtypeOf(type, verifier._boolType)) { |
15053 return new DartObjectImpl( | 15811 return new DartObjectImpl( |
15054 verifier._typeProvider.boolType, BoolState.UNKNOWN_VALUE); | 15812 verifier._typeProvider.boolType, BoolState.UNKNOWN_VALUE); |
15055 } else if (type.isSubtypeOf(verifier._typeProvider.doubleType)) { | 15813 } else if (_typeSystem.isSubtypeOf( |
| 15814 type, verifier._typeProvider.doubleType)) { |
15056 return new DartObjectImpl( | 15815 return new DartObjectImpl( |
15057 verifier._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE); | 15816 verifier._typeProvider.doubleType, DoubleState.UNKNOWN_VALUE); |
15058 } else if (type.isSubtypeOf(verifier._intType)) { | 15817 } else if (_typeSystem.isSubtypeOf(type, verifier._intType)) { |
15059 return new DartObjectImpl( | 15818 return new DartObjectImpl( |
15060 verifier._typeProvider.intType, IntState.UNKNOWN_VALUE); | 15819 verifier._typeProvider.intType, IntState.UNKNOWN_VALUE); |
15061 } else if (type.isSubtypeOf(verifier._numType)) { | 15820 } else if (_typeSystem.isSubtypeOf(type, verifier._numType)) { |
15062 return new DartObjectImpl( | 15821 return new DartObjectImpl( |
15063 verifier._typeProvider.numType, NumState.UNKNOWN_VALUE); | 15822 verifier._typeProvider.numType, NumState.UNKNOWN_VALUE); |
15064 } else if (type.isSubtypeOf(verifier._stringType)) { | 15823 } else if (_typeSystem.isSubtypeOf(type, verifier._stringType)) { |
15065 return new DartObjectImpl( | 15824 return new DartObjectImpl( |
15066 verifier._typeProvider.stringType, StringState.UNKNOWN_VALUE); | 15825 verifier._typeProvider.stringType, StringState.UNKNOWN_VALUE); |
15067 } | 15826 } |
15068 // | 15827 // |
15069 // We don't test for other types of objects (such as List, Map, | 15828 // We don't test for other types of objects (such as List, Map, |
15070 // Function or Type) because there are no operations allowed on such | 15829 // Function or Type) because there are no operations allowed on such |
15071 // types other than '==' and '!=', which means that we don't need to | 15830 // types other than '==' and '!=', which means that we don't need to |
15072 // know the type when there is no specific data about the state of | 15831 // know the type when there is no specific data about the state of |
15073 // such objects. | 15832 // such objects. |
15074 // | 15833 // |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15187 nonFields.add(node); | 15946 nonFields.add(node); |
15188 return null; | 15947 return null; |
15189 } | 15948 } |
15190 | 15949 |
15191 @override | 15950 @override |
15192 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 15951 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
15193 | 15952 |
15194 @override | 15953 @override |
15195 Object visitWithClause(WithClause node) => null; | 15954 Object visitWithClause(WithClause node) => null; |
15196 } | 15955 } |
OLD | NEW |