Chromium Code Reviews

Side by Side Diff: pkg/analyzer/lib/src/dart/constant/evaluation.dart

Issue 2167263002: fix #26141, add support for type arguments to constants (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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 }
OLDNEW

Powered by Google App Engine