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 analyzer.src.dart.constant.evaluation; | 5 library analyzer.src.dart.constant.evaluation; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/context/declared_variables.dart'; | 9 import 'package:analyzer/context/declared_variables.dart'; |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
(...skipping 57 matching lines...) Loading... |
68 * The set of variables declared on the command line using '-D'. | 68 * The set of variables declared on the command line using '-D'. |
69 */ | 69 */ |
70 final DeclaredVariables _declaredVariables; | 70 final DeclaredVariables _declaredVariables; |
71 | 71 |
72 /** | 72 /** |
73 * Validator used to verify correct dependency analysis when running unit | 73 * Validator used to verify correct dependency analysis when running unit |
74 * tests. | 74 * tests. |
75 */ | 75 */ |
76 final ConstantEvaluationValidator validator; | 76 final ConstantEvaluationValidator validator; |
77 | 77 |
| 78 /** Whether we are running in strong mode. */ |
| 79 final bool strongMode; |
| 80 |
78 /** | 81 /** |
79 * Initialize a newly created [ConstantEvaluationEngine]. The [typeProvider] | 82 * Initialize a newly created [ConstantEvaluationEngine]. The [typeProvider] |
80 * is used to access known types. [_declaredVariables] is the set of | 83 * is used to access known types. [_declaredVariables] is the set of |
81 * variables declared on the command line using '-D'. The [validator], if | 84 * variables declared on the command line using '-D'. The [validator], if |
82 * given, is used to verify correct dependency analysis when running unit | 85 * given, is used to verify correct dependency analysis when running unit |
83 * tests. | 86 * tests. |
84 */ | 87 */ |
85 ConstantEvaluationEngine(this.typeProvider, this._declaredVariables, | 88 ConstantEvaluationEngine(TypeProvider typeProvider, this._declaredVariables, |
86 {ConstantEvaluationValidator validator, TypeSystem typeSystem}) | 89 {ConstantEvaluationValidator validator, TypeSystem typeSystem}) |
87 : validator = | 90 : typeProvider = typeProvider, |
| 91 strongMode = |
| 92 typeProvider.objectType.element.context.analysisOptions.strongMode, |
| 93 validator = |
88 validator ?? new ConstantEvaluationValidator_ForProduction(), | 94 validator ?? new ConstantEvaluationValidator_ForProduction(), |
89 typeSystem = typeSystem ?? new TypeSystemImpl(); | 95 typeSystem = typeSystem ?? new TypeSystemImpl(); |
90 | 96 |
91 /** | 97 /** |
92 * Check that the arguments to a call to fromEnvironment() are correct. The | 98 * Check that the arguments to a call to fromEnvironment() are correct. The |
93 * [arguments] are the AST nodes of the arguments. The [argumentValues] are | 99 * [arguments] are the AST nodes of the arguments. The [argumentValues] are |
94 * the values of the unnamed arguments. The [namedArgumentValues] are the | 100 * the values of the unnamed arguments. The [namedArgumentValues] are the |
95 * values of the named arguments. The [expectedDefaultValueType] is the | 101 * values of the named arguments. The [expectedDefaultValueType] is the |
96 * allowed type of the "defaultValue" parameter (if present). Note: | 102 * allowed type of the "defaultValue" parameter (if present). Note: |
97 * "defaultValue" is always allowed to be null. Return `true` if the arguments | 103 * "defaultValue" is always allowed to be null. Return `true` if the arguments |
(...skipping 126 matching lines...) Loading... |
224 } else if (element is ConstructorElementImpl && | 230 } else if (element is ConstructorElementImpl && |
225 element.isConst && | 231 element.isConst && |
226 constNode.arguments != null) { | 232 constNode.arguments != null) { |
227 RecordingErrorListener errorListener = new RecordingErrorListener(); | 233 RecordingErrorListener errorListener = new RecordingErrorListener(); |
228 ErrorReporter errorReporter = | 234 ErrorReporter errorReporter = |
229 new ErrorReporter(errorListener, constant.source); | 235 new ErrorReporter(errorListener, constant.source); |
230 ConstantVisitor constantVisitor = | 236 ConstantVisitor constantVisitor = |
231 new ConstantVisitor(this, errorReporter); | 237 new ConstantVisitor(this, errorReporter); |
232 DartObjectImpl result = evaluateConstructorCall( | 238 DartObjectImpl result = evaluateConstructorCall( |
233 constNode, | 239 constNode, |
| 240 [], |
234 constNode.arguments.arguments, | 241 constNode.arguments.arguments, |
235 element, | 242 element, |
236 constantVisitor, | 243 constantVisitor, |
237 errorReporter); | 244 errorReporter); |
238 constant.evaluationResult = | 245 constant.evaluationResult = |
239 new EvaluationResultImpl(result, errorListener.errors); | 246 new EvaluationResultImpl(result, errorListener.errors); |
240 } else { | 247 } else { |
241 // This may happen for invalid code (e.g. failing to pass arguments | 248 // This may happen for invalid code (e.g. failing to pass arguments |
242 // to an annotation which references a const constructor). The error | 249 // to an annotation which references a const constructor). The error |
243 // is detected elsewhere, so just silently ignore it here. | 250 // is detected elsewhere, so just silently ignore it here. |
(...skipping 158 matching lines...) Loading... |
402 // The VM would use the built-in default value, but we don't want to do | 409 // The VM would use the built-in default value, but we don't want to do |
403 // that for analysis because it's likely to lead to cascading errors. | 410 // that for analysis because it's likely to lead to cascading errors. |
404 // So just leave [value] in the unknown state. | 411 // So just leave [value] in the unknown state. |
405 } | 412 } |
406 } | 413 } |
407 return value; | 414 return value; |
408 } | 415 } |
409 | 416 |
410 DartObjectImpl evaluateConstructorCall( | 417 DartObjectImpl evaluateConstructorCall( |
411 AstNode node, | 418 AstNode node, |
412 NodeList<Expression> arguments, | 419 List<DartType> typeArguments, |
| 420 List<Expression> arguments, |
413 ConstructorElement constructor, | 421 ConstructorElement constructor, |
414 ConstantVisitor constantVisitor, | 422 ConstantVisitor constantVisitor, |
415 ErrorReporter errorReporter) { | 423 ErrorReporter errorReporter) { |
416 if (!getConstructorImpl(constructor).isCycleFree) { | 424 if (!getConstructorImpl(constructor).isCycleFree) { |
417 // It's not safe to evaluate this constructor, so bail out. | 425 // It's not safe to evaluate this constructor, so bail out. |
418 // TODO(paulberry): ensure that a reasonable error message is produced | 426 // TODO(paulberry): ensure that a reasonable error message is produced |
419 // in this case, as well as other cases involving constant expression | 427 // in this case, as well as other cases involving constant expression |
420 // circularities (e.g. "compile-time constant expression depends on | 428 // circularities (e.g. "compile-time constant expression depends on |
421 // itself") | 429 // itself") |
422 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); | 430 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); |
(...skipping 85 matching lines...) Loading... |
508 List<ConstructorInitializer> initializers = | 516 List<ConstructorInitializer> initializers = |
509 constructorBase.constantInitializers; | 517 constructorBase.constantInitializers; |
510 if (initializers == null) { | 518 if (initializers == null) { |
511 // This can happen in some cases where there are compile errors in the | 519 // This can happen in some cases where there are compile errors in the |
512 // code being analyzed (for example if the code is trying to create a | 520 // code being analyzed (for example if the code is trying to create a |
513 // const instance using a non-const constructor, or the node we're | 521 // const instance using a non-const constructor, or the node we're |
514 // visiting is involved in a cycle). The error has already been reported, | 522 // visiting is involved in a cycle). The error has already been reported, |
515 // so consider it an unknown value to suppress further errors. | 523 // so consider it an unknown value to suppress further errors. |
516 return new DartObjectImpl.validWithUnknownValue(definingClass); | 524 return new DartObjectImpl.validWithUnknownValue(definingClass); |
517 } | 525 } |
518 HashMap<String, DartObjectImpl> fieldMap = | 526 var fieldMap = new HashMap<String, DartObjectImpl>(); |
519 new HashMap<String, DartObjectImpl>(); | 527 var typeArgumentMap = new HashMap<String, DartObjectImpl>.fromIterables( |
| 528 (constructor.returnType as ParameterizedType) |
| 529 .typeParameters |
| 530 .map((t) => t.name), |
| 531 typeArguments.map((t) => |
| 532 new DartObjectImpl(typeProvider.typeType, new TypeState(t)))); |
| 533 |
| 534 var fieldInitVisitor = new ConstantVisitor(this, errorReporter, |
| 535 lexicalEnvironment: typeArgumentMap); |
520 // Start with final fields that are initialized at their declaration site. | 536 // Start with final fields that are initialized at their declaration site. |
521 for (FieldElement field in constructor.enclosingElement.fields) { | 537 List<FieldElement> fields = constructor.enclosingElement.fields; |
| 538 for (int i = 0; i < fields.length; i++) { |
| 539 FieldElement field = fields[i]; |
522 if ((field.isFinal || field.isConst) && | 540 if ((field.isFinal || field.isConst) && |
523 !field.isStatic && | 541 !field.isStatic && |
524 field is ConstFieldElementImpl) { | 542 field is ConstFieldElementImpl) { |
525 validator.beforeGetFieldEvaluationResult(field); | 543 validator.beforeGetFieldEvaluationResult(field); |
526 EvaluationResultImpl evaluationResult = field.evaluationResult; | 544 |
| 545 DartObjectImpl fieldValue; |
| 546 if (strongMode) { |
| 547 var fieldInit = constructorBase.fieldInitializers[i].initializer; |
| 548 fieldValue = fieldInit.accept(fieldInitVisitor); |
| 549 } else { |
| 550 fieldValue = field.evaluationResult?.value; |
| 551 } |
527 // It is possible that the evaluation result is null. | 552 // It is possible that the evaluation result is null. |
528 // This happens for example when we have duplicate fields. | 553 // This happens for example when we have duplicate fields. |
529 // class Test {final x = 1; final x = 2; const Test();} | 554 // class Test {final x = 1; final x = 2; const Test();} |
530 if (evaluationResult == null) { | 555 if (fieldValue == null) { |
531 continue; | 556 continue; |
532 } | 557 } |
533 // Match the value and the type. | 558 // Match the value and the type. |
534 DartType fieldType = | 559 DartType fieldType = |
535 FieldMember.from(field, constructor.returnType).type; | 560 FieldMember.from(field, constructor.returnType).type; |
536 DartObjectImpl fieldValue = evaluationResult.value; | |
537 if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) { | 561 if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) { |
538 errorReporter.reportErrorForNode( | 562 errorReporter.reportErrorForNode( |
539 CheckedModeCompileTimeErrorCode | 563 CheckedModeCompileTimeErrorCode |
540 .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, | 564 .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, |
541 node, | 565 node, |
542 [fieldValue.type, field.name, fieldType]); | 566 [fieldValue.type, field.name, fieldType]); |
543 } | 567 } |
544 fieldMap[field.name] = fieldValue; | 568 fieldMap[field.name] = fieldValue; |
545 } | 569 } |
546 } | 570 } |
547 // Now evaluate the constructor declaration. | 571 // Now evaluate the constructor declaration. |
548 HashMap<String, DartObjectImpl> parameterMap = | 572 HashMap<String, DartObjectImpl> parameterMap = |
549 new HashMap<String, DartObjectImpl>(); | 573 new HashMap<String, DartObjectImpl>(); |
550 List<ParameterElement> parameters = constructor.parameters; | 574 List<ParameterElement> parameters = constructor.parameters; |
551 int parameterCount = parameters.length; | 575 int parameterCount = parameters.length; |
| 576 |
| 577 HashMap<ParameterElement, DefaultFormalParameter> parameterDefaultMap; |
| 578 if (strongMode) { |
| 579 parameterDefaultMap = new HashMap.fromIterable( |
| 580 constructorBase.parameterInitializers, |
| 581 key: (p) => p.parameter.element); |
| 582 } |
| 583 |
552 for (int i = 0; i < parameterCount; i++) { | 584 for (int i = 0; i < parameterCount; i++) { |
553 ParameterElement parameter = parameters[i]; | 585 ParameterElement parameter = parameters[i]; |
554 ParameterElement baseParameter = parameter; | 586 ParameterElement baseParameter = parameter; |
555 while (baseParameter is ParameterMember) { | 587 while (baseParameter is ParameterMember) { |
556 baseParameter = (baseParameter as ParameterMember).baseElement; | 588 baseParameter = (baseParameter as ParameterMember).baseElement; |
557 } | 589 } |
558 DartObjectImpl argumentValue = null; | 590 DartObjectImpl argumentValue = null; |
559 AstNode errorTarget = null; | 591 AstNode errorTarget = null; |
560 if (baseParameter.parameterKind == ParameterKind.NAMED) { | 592 if (baseParameter.parameterKind == ParameterKind.NAMED) { |
561 argumentValue = namedArgumentValues[baseParameter.name]; | 593 argumentValue = namedArgumentValues[baseParameter.name]; |
562 errorTarget = namedArgumentNodes[baseParameter.name]; | 594 errorTarget = namedArgumentNodes[baseParameter.name]; |
563 } else if (i < argumentCount) { | 595 } else if (i < argumentCount) { |
564 argumentValue = argumentValues[i]; | 596 argumentValue = argumentValues[i]; |
565 errorTarget = argumentNodes[i]; | 597 errorTarget = argumentNodes[i]; |
566 } | 598 } |
567 if (errorTarget == null) { | 599 if (errorTarget == null) { |
568 // No argument node that we can direct error messages to, because we | 600 // No argument node that we can direct error messages to, because we |
569 // are handling an optional parameter that wasn't specified. So just | 601 // are handling an optional parameter that wasn't specified. So just |
570 // direct error messages to the constructor call. | 602 // direct error messages to the constructor call. |
571 errorTarget = node; | 603 errorTarget = node; |
572 } | 604 } |
573 if (argumentValue == null && baseParameter is ParameterElementImpl) { | 605 if (argumentValue == null && baseParameter is ParameterElementImpl) { |
574 // The parameter is an optional positional parameter for which no value | 606 // The parameter is an optional positional parameter for which no value |
575 // was provided, so use the default value. | 607 // was provided, so use the default value. |
576 validator.beforeGetParameterDefault(baseParameter); | 608 validator.beforeGetParameterDefault(baseParameter); |
577 EvaluationResultImpl evaluationResult = baseParameter.evaluationResult; | 609 if (strongMode) { |
578 if (evaluationResult == null) { | 610 var defaultValue = parameterDefaultMap[parameter]?.defaultValue; |
579 // No default was provided, so the default value is null. | 611 if (defaultValue == null) { |
580 argumentValue = typeProvider.nullObject; | 612 argumentValue = typeProvider.nullObject; |
581 } else if (evaluationResult.value != null) { | 613 } else { |
582 argumentValue = evaluationResult.value; | 614 argumentValue = defaultValue.accept(fieldInitVisitor); |
| 615 } |
| 616 } else { |
| 617 EvaluationResultImpl evaluationResult = |
| 618 baseParameter.evaluationResult; |
| 619 if (evaluationResult == null) { |
| 620 // No default was provided, so the default value is null. |
| 621 argumentValue = typeProvider.nullObject; |
| 622 } else if (evaluationResult.value != null) { |
| 623 argumentValue = evaluationResult.value; |
| 624 } |
583 } | 625 } |
584 } | 626 } |
585 if (argumentValue != null) { | 627 if (argumentValue != null) { |
586 if (!runtimeTypeMatch(argumentValue, parameter.type)) { | 628 if (!runtimeTypeMatch(argumentValue, parameter.type)) { |
587 errorReporter.reportErrorForNode( | 629 errorReporter.reportErrorForNode( |
588 CheckedModeCompileTimeErrorCode | 630 CheckedModeCompileTimeErrorCode |
589 .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | 631 .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
590 errorTarget, | 632 errorTarget, |
591 [argumentValue.type, parameter.type]); | 633 [argumentValue.type, parameter.type]); |
592 } | 634 } |
(...skipping 61 matching lines...) Loading... |
654 superName = name.name; | 696 superName = name.name; |
655 } | 697 } |
656 superArguments = initializer.argumentList.arguments; | 698 superArguments = initializer.argumentList.arguments; |
657 } else if (initializer is RedirectingConstructorInvocation) { | 699 } else if (initializer is RedirectingConstructorInvocation) { |
658 // This is a redirecting constructor, so just evaluate the constructor | 700 // This is a redirecting constructor, so just evaluate the constructor |
659 // it redirects to. | 701 // it redirects to. |
660 ConstructorElement constructor = initializer.staticElement; | 702 ConstructorElement constructor = initializer.staticElement; |
661 if (constructor != null && constructor.isConst) { | 703 if (constructor != null && constructor.isConst) { |
662 return evaluateConstructorCall( | 704 return evaluateConstructorCall( |
663 node, | 705 node, |
| 706 typeArguments, |
664 initializer.argumentList.arguments, | 707 initializer.argumentList.arguments, |
665 constructor, | 708 constructor, |
666 initializerVisitor, | 709 initializerVisitor, |
667 errorReporter); | 710 errorReporter); |
668 } | 711 } |
669 } | 712 } |
670 } | 713 } |
671 // Evaluate explicit or implicit call to super(). | 714 // Evaluate explicit or implicit call to super(). |
672 InterfaceType superclass = definingClass.superclass; | 715 InterfaceType superclass = definingClass.superclass; |
673 if (superclass != null && !superclass.isObject) { | 716 if (superclass != null && !superclass.isObject) { |
674 ConstructorElement superConstructor = | 717 ConstructorElement superConstructor = |
675 superclass.lookUpConstructor(superName, constructor.library); | 718 superclass.lookUpConstructor(superName, constructor.library); |
676 if (superConstructor != null) { | 719 if (superConstructor != null) { |
677 if (superArguments == null) { | 720 if (superArguments == null) { |
678 superArguments = new NodeList<Expression>(null); | 721 superArguments = new NodeList<Expression>(null); |
679 } | 722 } |
680 evaluateSuperConstructorCall(node, fieldMap, superConstructor, | 723 |
681 superArguments, initializerVisitor, errorReporter); | 724 evaluateSuperConstructorCall( |
| 725 node, |
| 726 fieldMap, |
| 727 superConstructor, |
| 728 superclass.typeArguments, |
| 729 superArguments, |
| 730 initializerVisitor, |
| 731 errorReporter); |
682 } | 732 } |
683 } | 733 } |
684 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); | 734 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); |
685 } | 735 } |
686 | 736 |
687 void evaluateSuperConstructorCall( | 737 void evaluateSuperConstructorCall( |
688 AstNode node, | 738 AstNode node, |
689 HashMap<String, DartObjectImpl> fieldMap, | 739 HashMap<String, DartObjectImpl> fieldMap, |
690 ConstructorElement superConstructor, | 740 ConstructorElement superConstructor, |
691 NodeList<Expression> superArguments, | 741 List<DartType> superTypeArguments, |
| 742 List<Expression> superArguments, |
692 ConstantVisitor initializerVisitor, | 743 ConstantVisitor initializerVisitor, |
693 ErrorReporter errorReporter) { | 744 ErrorReporter errorReporter) { |
694 if (superConstructor != null && superConstructor.isConst) { | 745 if (superConstructor != null && superConstructor.isConst) { |
695 DartObjectImpl evaluationResult = evaluateConstructorCall(node, | 746 DartObjectImpl evaluationResult = evaluateConstructorCall( |
696 superArguments, superConstructor, initializerVisitor, errorReporter); | 747 node, |
| 748 superTypeArguments, |
| 749 superArguments, |
| 750 superConstructor, |
| 751 initializerVisitor, |
| 752 errorReporter); |
697 if (evaluationResult != null) { | 753 if (evaluationResult != null) { |
698 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; | 754 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; |
699 } | 755 } |
700 } | 756 } |
701 } | 757 } |
702 | 758 |
703 /** | 759 /** |
704 * Attempt to follow the chain of factory redirections until a constructor is | 760 * Attempt to follow the chain of factory redirections until a constructor is |
705 * reached which is not a const factory constructor. Return the constant | 761 * reached which is not a const factory constructor. Return the constant |
706 * constructor which terminates the chain of factory redirections, if the | 762 * constructor which terminates the chain of factory redirections, if the |
(...skipping 517 matching lines...) Loading... |
1224 // TODO(brianwilkerson) Figure out which error to report. | 1280 // TODO(brianwilkerson) Figure out which error to report. |
1225 _error(node, null); | 1281 _error(node, null); |
1226 return null; | 1282 return null; |
1227 } | 1283 } |
1228 ConstructorElement constructor = node.staticElement; | 1284 ConstructorElement constructor = node.staticElement; |
1229 if (constructor == null) { | 1285 if (constructor == null) { |
1230 // Couldn't resolve the constructor so we can't compute a value. No | 1286 // Couldn't resolve the constructor so we can't compute a value. No |
1231 // problem - the error has already been reported. | 1287 // problem - the error has already been reported. |
1232 return null; | 1288 return null; |
1233 } | 1289 } |
1234 return evaluationEngine.evaluateConstructorCall( | 1290 |
1235 node, node.argumentList.arguments, constructor, this, _errorReporter); | 1291 var type = constructor.returnType as ParameterizedType; |
| 1292 var typeArguments = type.typeArguments.map((t) { |
| 1293 if (t is TypeParameterType && _lexicalEnvironment != null) { |
| 1294 return _lexicalEnvironment[t.name]?.toTypeValue() ?? t; |
| 1295 } |
| 1296 return t; |
| 1297 }).toList(); |
| 1298 |
| 1299 if (constructor is ConstructorMember) { |
| 1300 constructor = (constructor as ConstructorMember).baseElement; |
| 1301 } |
| 1302 |
| 1303 constructor = ConstructorMember.from( |
| 1304 constructor, |
| 1305 type.substitute2(typeArguments, type.typeArguments)); |
| 1306 |
| 1307 return evaluationEngine.evaluateConstructorCall(node, typeArguments, |
| 1308 node.argumentList.arguments, constructor, this, _errorReporter); |
1236 } | 1309 } |
1237 | 1310 |
1238 @override | 1311 @override |
1239 DartObjectImpl visitIntegerLiteral(IntegerLiteral node) => | 1312 DartObjectImpl visitIntegerLiteral(IntegerLiteral node) => |
1240 new DartObjectImpl(_typeProvider.intType, new IntState(node.value)); | 1313 new DartObjectImpl(_typeProvider.intType, new IntState(node.value)); |
1241 | 1314 |
1242 @override | 1315 @override |
1243 DartObjectImpl visitInterpolationExpression(InterpolationExpression node) { | 1316 DartObjectImpl visitInterpolationExpression(InterpolationExpression node) { |
1244 DartObjectImpl result = node.expression.accept(this); | 1317 DartObjectImpl result = node.expression.accept(this); |
1245 if (result != null && !result.isBoolNumStringOrNull) { | 1318 if (result != null && !result.isBoolNumStringOrNull) { |
(...skipping 212 matching lines...) Loading... |
1458 for (int i = 0; i < components.length; i++) { | 1531 for (int i = 0; i < components.length; i++) { |
1459 if (i > 0) { | 1532 if (i > 0) { |
1460 buffer.writeCharCode(0x2E); | 1533 buffer.writeCharCode(0x2E); |
1461 } | 1534 } |
1462 buffer.write(components[i].lexeme); | 1535 buffer.write(components[i].lexeme); |
1463 } | 1536 } |
1464 return new DartObjectImpl( | 1537 return new DartObjectImpl( |
1465 _typeProvider.symbolType, new SymbolState(buffer.toString())); | 1538 _typeProvider.symbolType, new SymbolState(buffer.toString())); |
1466 } | 1539 } |
1467 | 1540 |
| 1541 @override |
| 1542 DartObjectImpl visitTypeName(TypeName node) { |
| 1543 // TODO(jmesserly): what to do about type arguments? |
| 1544 String name = node.name.name; |
| 1545 if (_lexicalEnvironment != null && _lexicalEnvironment.containsKey(name)) { |
| 1546 return _lexicalEnvironment[name]; |
| 1547 } |
| 1548 return new DartObjectImpl(_typeProvider.typeType, new TypeState(node.type)); |
| 1549 } |
| 1550 |
1468 /** | 1551 /** |
1469 * Create an error associated with the given [node]. The error will have the | 1552 * Create an error associated with the given [node]. The error will have the |
1470 * given error [code]. | 1553 * given error [code]. |
1471 */ | 1554 */ |
1472 void _error(AstNode node, ErrorCode code) { | 1555 void _error(AstNode node, ErrorCode code) { |
1473 _errorReporter.reportErrorForNode( | 1556 _errorReporter.reportErrorForNode( |
1474 code ?? CompileTimeErrorCode.INVALID_CONSTANT, node); | 1557 code ?? CompileTimeErrorCode.INVALID_CONSTANT, node); |
1475 } | 1558 } |
1476 | 1559 |
1477 /** | 1560 /** |
(...skipping 12 matching lines...) Loading... |
1490 } | 1573 } |
1491 } else if (variableElement is ExecutableElement) { | 1574 } else if (variableElement is ExecutableElement) { |
1492 ExecutableElement function = element; | 1575 ExecutableElement function = element; |
1493 if (function.isStatic) { | 1576 if (function.isStatic) { |
1494 ParameterizedType functionType = function.type; | 1577 ParameterizedType functionType = function.type; |
1495 if (functionType == null) { | 1578 if (functionType == null) { |
1496 functionType = _typeProvider.functionType; | 1579 functionType = _typeProvider.functionType; |
1497 } | 1580 } |
1498 return new DartObjectImpl(functionType, new FunctionState(function)); | 1581 return new DartObjectImpl(functionType, new FunctionState(function)); |
1499 } | 1582 } |
1500 } else if (variableElement is ClassElement || | 1583 } else if (variableElement is TypeDefiningElement) { |
1501 variableElement is FunctionTypeAliasElement || | 1584 return new DartObjectImpl( |
1502 variableElement is DynamicElementImpl) { | 1585 _typeProvider.typeType, new TypeState(variableElement.type)); |
1503 return new DartObjectImpl(_typeProvider.typeType, new TypeState(element)); | |
1504 } | 1586 } |
1505 // TODO(brianwilkerson) Figure out which error to report. | 1587 // TODO(brianwilkerson) Figure out which error to report. |
1506 _error(node, null); | 1588 _error(node, null); |
1507 return null; | 1589 return null; |
1508 } | 1590 } |
1509 | 1591 |
1510 /** | 1592 /** |
1511 * Return `true` if the given [targetResult] represents a string and the | 1593 * Return `true` if the given [targetResult] represents a string and the |
1512 * [identifier] is "length". | 1594 * [identifier] is "length". |
1513 */ | 1595 */ |
(...skipping 470 matching lines...) Loading... |
1984 } | 2066 } |
1985 | 2067 |
1986 @override | 2068 @override |
1987 String toString() { | 2069 String toString() { |
1988 if (value == null) { | 2070 if (value == null) { |
1989 return "error"; | 2071 return "error"; |
1990 } | 2072 } |
1991 return value.toString(); | 2073 return value.toString(); |
1992 } | 2074 } |
1993 } | 2075 } |
OLD | NEW |