| 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...) Expand 10 before | Expand all | Expand 10 after 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 | |
| 81 /** | 78 /** |
| 82 * Initialize a newly created [ConstantEvaluationEngine]. The [typeProvider] | 79 * Initialize a newly created [ConstantEvaluationEngine]. The [typeProvider] |
| 83 * is used to access known types. [_declaredVariables] is the set of | 80 * is used to access known types. [_declaredVariables] is the set of |
| 84 * variables declared on the command line using '-D'. The [validator], if | 81 * variables declared on the command line using '-D'. The [validator], if |
| 85 * given, is used to verify correct dependency analysis when running unit | 82 * given, is used to verify correct dependency analysis when running unit |
| 86 * tests. | 83 * tests. |
| 87 */ | 84 */ |
| 88 ConstantEvaluationEngine(TypeProvider typeProvider, this._declaredVariables, | 85 ConstantEvaluationEngine(this.typeProvider, this._declaredVariables, |
| 89 {ConstantEvaluationValidator validator, TypeSystem typeSystem}) | 86 {ConstantEvaluationValidator validator, TypeSystem typeSystem}) |
| 90 : typeProvider = typeProvider, | 87 : validator = |
| 91 strongMode = | |
| 92 typeProvider.objectType.element.context.analysisOptions.strongMode, | |
| 93 validator = | |
| 94 validator ?? new ConstantEvaluationValidator_ForProduction(), | 88 validator ?? new ConstantEvaluationValidator_ForProduction(), |
| 95 typeSystem = typeSystem ?? new TypeSystemImpl(); | 89 typeSystem = typeSystem ?? new TypeSystemImpl(); |
| 96 | 90 |
| 97 /** | 91 /** |
| 98 * Check that the arguments to a call to fromEnvironment() are correct. The | 92 * Check that the arguments to a call to fromEnvironment() are correct. The |
| 99 * [arguments] are the AST nodes of the arguments. The [argumentValues] are | 93 * [arguments] are the AST nodes of the arguments. The [argumentValues] are |
| 100 * the values of the unnamed arguments. The [namedArgumentValues] are the | 94 * the values of the unnamed arguments. The [namedArgumentValues] are the |
| 101 * values of the named arguments. The [expectedDefaultValueType] is the | 95 * values of the named arguments. The [expectedDefaultValueType] is the |
| 102 * allowed type of the "defaultValue" parameter (if present). Note: | 96 * allowed type of the "defaultValue" parameter (if present). Note: |
| 103 * "defaultValue" is always allowed to be null. Return `true` if the arguments | 97 * "defaultValue" is always allowed to be null. Return `true` if the arguments |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 // The VM would use the built-in default value, but we don't want to do | 402 // The VM would use the built-in default value, but we don't want to do |
| 409 // that for analysis because it's likely to lead to cascading errors. | 403 // that for analysis because it's likely to lead to cascading errors. |
| 410 // So just leave [value] in the unknown state. | 404 // So just leave [value] in the unknown state. |
| 411 } | 405 } |
| 412 } | 406 } |
| 413 return value; | 407 return value; |
| 414 } | 408 } |
| 415 | 409 |
| 416 DartObjectImpl evaluateConstructorCall( | 410 DartObjectImpl evaluateConstructorCall( |
| 417 AstNode node, | 411 AstNode node, |
| 418 List<Expression> arguments, | 412 NodeList<Expression> arguments, |
| 419 ConstructorElement constructor, | 413 ConstructorElement constructor, |
| 420 ConstantVisitor constantVisitor, | 414 ConstantVisitor constantVisitor, |
| 421 ErrorReporter errorReporter) { | 415 ErrorReporter errorReporter) { |
| 422 if (!getConstructorImpl(constructor).isCycleFree) { | 416 if (!getConstructorImpl(constructor).isCycleFree) { |
| 423 // It's not safe to evaluate this constructor, so bail out. | 417 // It's not safe to evaluate this constructor, so bail out. |
| 424 // TODO(paulberry): ensure that a reasonable error message is produced | 418 // TODO(paulberry): ensure that a reasonable error message is produced |
| 425 // in this case, as well as other cases involving constant expression | 419 // in this case, as well as other cases involving constant expression |
| 426 // circularities (e.g. "compile-time constant expression depends on | 420 // circularities (e.g. "compile-time constant expression depends on |
| 427 // itself") | 421 // itself") |
| 428 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); | 422 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 List<ConstructorInitializer> initializers = | 508 List<ConstructorInitializer> initializers = |
| 515 constructorBase.constantInitializers; | 509 constructorBase.constantInitializers; |
| 516 if (initializers == null) { | 510 if (initializers == null) { |
| 517 // This can happen in some cases where there are compile errors in the | 511 // This can happen in some cases where there are compile errors in the |
| 518 // code being analyzed (for example if the code is trying to create a | 512 // code being analyzed (for example if the code is trying to create a |
| 519 // const instance using a non-const constructor, or the node we're | 513 // const instance using a non-const constructor, or the node we're |
| 520 // visiting is involved in a cycle). The error has already been reported, | 514 // visiting is involved in a cycle). The error has already been reported, |
| 521 // so consider it an unknown value to suppress further errors. | 515 // so consider it an unknown value to suppress further errors. |
| 522 return new DartObjectImpl.validWithUnknownValue(definingClass); | 516 return new DartObjectImpl.validWithUnknownValue(definingClass); |
| 523 } | 517 } |
| 524 | 518 HashMap<String, DartObjectImpl> fieldMap = |
| 525 // In strong mode, we allow constants to have type arguments. | 519 new HashMap<String, DartObjectImpl>(); |
| 526 // | |
| 527 // They will be added to the lexical environment when evaluating | |
| 528 // subexpressions. | |
| 529 HashMap<String, DartObjectImpl> typeArgumentMap; | |
| 530 if (strongMode) { | |
| 531 // Instantiate the constructor with the in-scope type arguments. | |
| 532 definingClass = constantVisitor.evaluateType(definingClass); | |
| 533 constructor = ConstructorMember.from(constructorBase, definingClass); | |
| 534 | |
| 535 typeArgumentMap = new HashMap<String, DartObjectImpl>.fromIterables( | |
| 536 definingClass.typeParameters.map((t) => t.name), | |
| 537 definingClass.typeArguments.map(constantVisitor.typeConstant)); | |
| 538 } | |
| 539 | |
| 540 var fieldMap = new HashMap<String, DartObjectImpl>(); | |
| 541 var fieldInitVisitor = new ConstantVisitor(this, errorReporter, | |
| 542 lexicalEnvironment: typeArgumentMap); | |
| 543 // Start with final fields that are initialized at their declaration site. | 520 // Start with final fields that are initialized at their declaration site. |
| 544 List<FieldElement> fields = constructor.enclosingElement.fields; | 521 for (FieldElement field in constructor.enclosingElement.fields) { |
| 545 for (int i = 0; i < fields.length; i++) { | |
| 546 FieldElement field = fields[i]; | |
| 547 if ((field.isFinal || field.isConst) && | 522 if ((field.isFinal || field.isConst) && |
| 548 !field.isStatic && | 523 !field.isStatic && |
| 549 field is ConstFieldElementImpl) { | 524 field is ConstFieldElementImpl) { |
| 550 validator.beforeGetFieldEvaluationResult(field); | 525 validator.beforeGetFieldEvaluationResult(field); |
| 551 | 526 EvaluationResultImpl evaluationResult = field.evaluationResult; |
| 552 DartObjectImpl fieldValue; | |
| 553 if (strongMode) { | |
| 554 fieldValue = field.constantInitializer.accept(fieldInitVisitor); | |
| 555 } else { | |
| 556 fieldValue = field.evaluationResult?.value; | |
| 557 } | |
| 558 // It is possible that the evaluation result is null. | 527 // It is possible that the evaluation result is null. |
| 559 // This happens for example when we have duplicate fields. | 528 // This happens for example when we have duplicate fields. |
| 560 // class Test {final x = 1; final x = 2; const Test();} | 529 // class Test {final x = 1; final x = 2; const Test();} |
| 561 if (fieldValue == null) { | 530 if (evaluationResult == null) { |
| 562 continue; | 531 continue; |
| 563 } | 532 } |
| 564 // Match the value and the type. | 533 // Match the value and the type. |
| 565 DartType fieldType = | 534 DartType fieldType = |
| 566 FieldMember.from(field, constructor.returnType).type; | 535 FieldMember.from(field, constructor.returnType).type; |
| 536 DartObjectImpl fieldValue = evaluationResult.value; |
| 567 if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) { | 537 if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) { |
| 568 errorReporter.reportErrorForNode( | 538 errorReporter.reportErrorForNode( |
| 569 CheckedModeCompileTimeErrorCode | 539 CheckedModeCompileTimeErrorCode |
| 570 .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, | 540 .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, |
| 571 node, | 541 node, |
| 572 [fieldValue.type, field.name, fieldType]); | 542 [fieldValue.type, field.name, fieldType]); |
| 573 } | 543 } |
| 574 fieldMap[field.name] = fieldValue; | 544 fieldMap[field.name] = fieldValue; |
| 575 } | 545 } |
| 576 } | 546 } |
| 577 // Now evaluate the constructor declaration. | 547 // Now evaluate the constructor declaration. |
| 578 HashMap<String, DartObjectImpl> parameterMap = | 548 HashMap<String, DartObjectImpl> parameterMap = |
| 579 new HashMap<String, DartObjectImpl>(); | 549 new HashMap<String, DartObjectImpl>(); |
| 580 List<ParameterElement> parameters = constructor.parameters; | 550 List<ParameterElement> parameters = constructor.parameters; |
| 581 int parameterCount = parameters.length; | 551 int parameterCount = parameters.length; |
| 582 | |
| 583 for (int i = 0; i < parameterCount; i++) { | 552 for (int i = 0; i < parameterCount; i++) { |
| 584 ParameterElement parameter = parameters[i]; | 553 ParameterElement parameter = parameters[i]; |
| 585 ParameterElement baseParameter = parameter; | 554 ParameterElement baseParameter = parameter; |
| 586 while (baseParameter is ParameterMember) { | 555 while (baseParameter is ParameterMember) { |
| 587 baseParameter = (baseParameter as ParameterMember).baseElement; | 556 baseParameter = (baseParameter as ParameterMember).baseElement; |
| 588 } | 557 } |
| 589 DartObjectImpl argumentValue = null; | 558 DartObjectImpl argumentValue = null; |
| 590 AstNode errorTarget = null; | 559 AstNode errorTarget = null; |
| 591 if (baseParameter.parameterKind == ParameterKind.NAMED) { | 560 if (baseParameter.parameterKind == ParameterKind.NAMED) { |
| 592 argumentValue = namedArgumentValues[baseParameter.name]; | 561 argumentValue = namedArgumentValues[baseParameter.name]; |
| 593 errorTarget = namedArgumentNodes[baseParameter.name]; | 562 errorTarget = namedArgumentNodes[baseParameter.name]; |
| 594 } else if (i < argumentCount) { | 563 } else if (i < argumentCount) { |
| 595 argumentValue = argumentValues[i]; | 564 argumentValue = argumentValues[i]; |
| 596 errorTarget = argumentNodes[i]; | 565 errorTarget = argumentNodes[i]; |
| 597 } | 566 } |
| 598 if (errorTarget == null) { | 567 if (errorTarget == null) { |
| 599 // No argument node that we can direct error messages to, because we | 568 // No argument node that we can direct error messages to, because we |
| 600 // are handling an optional parameter that wasn't specified. So just | 569 // are handling an optional parameter that wasn't specified. So just |
| 601 // direct error messages to the constructor call. | 570 // direct error messages to the constructor call. |
| 602 errorTarget = node; | 571 errorTarget = node; |
| 603 } | 572 } |
| 604 if (argumentValue == null && baseParameter is ParameterElementImpl) { | 573 if (argumentValue == null && baseParameter is ParameterElementImpl) { |
| 605 // The parameter is an optional positional parameter for which no value | 574 // The parameter is an optional positional parameter for which no value |
| 606 // was provided, so use the default value. | 575 // was provided, so use the default value. |
| 607 validator.beforeGetParameterDefault(baseParameter); | 576 validator.beforeGetParameterDefault(baseParameter); |
| 608 if (strongMode && baseParameter is ConstVariableElement) { | 577 EvaluationResultImpl evaluationResult = baseParameter.evaluationResult; |
| 609 var defaultValue = | 578 if (evaluationResult == null) { |
| 610 (baseParameter as ConstVariableElement).constantInitializer; | 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 } | |
| 625 } | 583 } |
| 626 } | 584 } |
| 627 if (argumentValue != null) { | 585 if (argumentValue != null) { |
| 628 if (!runtimeTypeMatch(argumentValue, parameter.type)) { | 586 if (!runtimeTypeMatch(argumentValue, parameter.type)) { |
| 629 errorReporter.reportErrorForNode( | 587 errorReporter.reportErrorForNode( |
| 630 CheckedModeCompileTimeErrorCode | 588 CheckedModeCompileTimeErrorCode |
| 631 .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | 589 .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
| 632 errorTarget, | 590 errorTarget, |
| 633 [argumentValue.type, parameter.type]); | 591 [argumentValue.type, parameter.type]); |
| 634 } | 592 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 } | 670 } |
| 713 // Evaluate explicit or implicit call to super(). | 671 // Evaluate explicit or implicit call to super(). |
| 714 InterfaceType superclass = definingClass.superclass; | 672 InterfaceType superclass = definingClass.superclass; |
| 715 if (superclass != null && !superclass.isObject) { | 673 if (superclass != null && !superclass.isObject) { |
| 716 ConstructorElement superConstructor = | 674 ConstructorElement superConstructor = |
| 717 superclass.lookUpConstructor(superName, constructor.library); | 675 superclass.lookUpConstructor(superName, constructor.library); |
| 718 if (superConstructor != null) { | 676 if (superConstructor != null) { |
| 719 if (superArguments == null) { | 677 if (superArguments == null) { |
| 720 superArguments = new NodeList<Expression>(null); | 678 superArguments = new NodeList<Expression>(null); |
| 721 } | 679 } |
| 722 | |
| 723 evaluateSuperConstructorCall(node, fieldMap, superConstructor, | 680 evaluateSuperConstructorCall(node, fieldMap, superConstructor, |
| 724 superArguments, initializerVisitor, errorReporter); | 681 superArguments, initializerVisitor, errorReporter); |
| 725 } | 682 } |
| 726 } | 683 } |
| 727 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); | 684 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); |
| 728 } | 685 } |
| 729 | 686 |
| 730 void evaluateSuperConstructorCall( | 687 void evaluateSuperConstructorCall( |
| 731 AstNode node, | 688 AstNode node, |
| 732 HashMap<String, DartObjectImpl> fieldMap, | 689 HashMap<String, DartObjectImpl> fieldMap, |
| 733 ConstructorElement superConstructor, | 690 ConstructorElement superConstructor, |
| 734 List<Expression> superArguments, | 691 NodeList<Expression> superArguments, |
| 735 ConstantVisitor initializerVisitor, | 692 ConstantVisitor initializerVisitor, |
| 736 ErrorReporter errorReporter) { | 693 ErrorReporter errorReporter) { |
| 737 if (superConstructor != null && superConstructor.isConst) { | 694 if (superConstructor != null && superConstructor.isConst) { |
| 738 DartObjectImpl evaluationResult = evaluateConstructorCall(node, | 695 DartObjectImpl evaluationResult = evaluateConstructorCall(node, |
| 739 superArguments, superConstructor, initializerVisitor, errorReporter); | 696 superArguments, superConstructor, initializerVisitor, errorReporter); |
| 740 if (evaluationResult != null) { | 697 if (evaluationResult != null) { |
| 741 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; | 698 fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult; |
| 742 } | 699 } |
| 743 } | 700 } |
| 744 } | 701 } |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 // TODO(brianwilkerson) Figure out which error to report. | 1224 // TODO(brianwilkerson) Figure out which error to report. |
| 1268 _error(node, null); | 1225 _error(node, null); |
| 1269 return null; | 1226 return null; |
| 1270 } | 1227 } |
| 1271 ConstructorElement constructor = node.staticElement; | 1228 ConstructorElement constructor = node.staticElement; |
| 1272 if (constructor == null) { | 1229 if (constructor == null) { |
| 1273 // Couldn't resolve the constructor so we can't compute a value. No | 1230 // Couldn't resolve the constructor so we can't compute a value. No |
| 1274 // problem - the error has already been reported. | 1231 // problem - the error has already been reported. |
| 1275 return null; | 1232 return null; |
| 1276 } | 1233 } |
| 1277 | |
| 1278 return evaluationEngine.evaluateConstructorCall( | 1234 return evaluationEngine.evaluateConstructorCall( |
| 1279 node, node.argumentList.arguments, constructor, this, _errorReporter); | 1235 node, node.argumentList.arguments, constructor, this, _errorReporter); |
| 1280 } | 1236 } |
| 1281 | 1237 |
| 1282 @override | 1238 @override |
| 1283 DartObjectImpl visitIntegerLiteral(IntegerLiteral node) => | 1239 DartObjectImpl visitIntegerLiteral(IntegerLiteral node) => |
| 1284 new DartObjectImpl(_typeProvider.intType, new IntState(node.value)); | 1240 new DartObjectImpl(_typeProvider.intType, new IntState(node.value)); |
| 1285 | 1241 |
| 1286 @override | 1242 @override |
| 1287 DartObjectImpl visitInterpolationExpression(InterpolationExpression node) { | 1243 DartObjectImpl visitInterpolationExpression(InterpolationExpression node) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1311 if (elementResult == null) { | 1267 if (elementResult == null) { |
| 1312 errorOccurred = true; | 1268 errorOccurred = true; |
| 1313 } else { | 1269 } else { |
| 1314 elements.add(elementResult); | 1270 elements.add(elementResult); |
| 1315 } | 1271 } |
| 1316 } | 1272 } |
| 1317 if (errorOccurred) { | 1273 if (errorOccurred) { |
| 1318 return null; | 1274 return null; |
| 1319 } | 1275 } |
| 1320 DartType elementType = _typeProvider.dynamicType; | 1276 DartType elementType = _typeProvider.dynamicType; |
| 1321 NodeList<TypeName> typeArgs = node.typeArguments?.arguments; | 1277 if (node.typeArguments != null && |
| 1322 if (typeArgs?.length == 1) { | 1278 node.typeArguments.arguments.length == 1) { |
| 1323 DartType type = visitTypeName(typeArgs[0]).toTypeValue(); | 1279 DartType type = node.typeArguments.arguments[0].type; |
| 1324 if (type != null) { | 1280 if (type != null) { |
| 1325 elementType = type; | 1281 elementType = type; |
| 1326 } | 1282 } |
| 1327 } | 1283 } |
| 1328 InterfaceType listType = _typeProvider.listType.instantiate([elementType]); | 1284 InterfaceType listType = _typeProvider.listType.instantiate([elementType]); |
| 1329 return new DartObjectImpl(listType, new ListState(elements)); | 1285 return new DartObjectImpl(listType, new ListState(elements)); |
| 1330 } | 1286 } |
| 1331 | 1287 |
| 1332 @override | 1288 @override |
| 1333 DartObjectImpl visitMapLiteral(MapLiteral node) { | 1289 DartObjectImpl visitMapLiteral(MapLiteral node) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1346 errorOccurred = true; | 1302 errorOccurred = true; |
| 1347 } else { | 1303 } else { |
| 1348 map[keyResult] = valueResult; | 1304 map[keyResult] = valueResult; |
| 1349 } | 1305 } |
| 1350 } | 1306 } |
| 1351 if (errorOccurred) { | 1307 if (errorOccurred) { |
| 1352 return null; | 1308 return null; |
| 1353 } | 1309 } |
| 1354 DartType keyType = _typeProvider.dynamicType; | 1310 DartType keyType = _typeProvider.dynamicType; |
| 1355 DartType valueType = _typeProvider.dynamicType; | 1311 DartType valueType = _typeProvider.dynamicType; |
| 1356 NodeList<TypeName> typeArgs = node.typeArguments?.arguments; | 1312 if (node.typeArguments != null && |
| 1357 if (typeArgs?.length == 2) { | 1313 node.typeArguments.arguments.length == 2) { |
| 1358 DartType keyTypeCandidate = visitTypeName(typeArgs[0]).toTypeValue(); | 1314 DartType keyTypeCandidate = node.typeArguments.arguments[0].type; |
| 1359 if (keyTypeCandidate != null) { | 1315 if (keyTypeCandidate != null) { |
| 1360 keyType = keyTypeCandidate; | 1316 keyType = keyTypeCandidate; |
| 1361 } | 1317 } |
| 1362 DartType valueTypeCandidate = visitTypeName(typeArgs[1]).toTypeValue(); | 1318 DartType valueTypeCandidate = node.typeArguments.arguments[1].type; |
| 1363 if (valueTypeCandidate != null) { | 1319 if (valueTypeCandidate != null) { |
| 1364 valueType = valueTypeCandidate; | 1320 valueType = valueTypeCandidate; |
| 1365 } | 1321 } |
| 1366 } | 1322 } |
| 1367 InterfaceType mapType = | 1323 InterfaceType mapType = |
| 1368 _typeProvider.mapType.instantiate([keyType, valueType]); | 1324 _typeProvider.mapType.instantiate([keyType, valueType]); |
| 1369 return new DartObjectImpl(mapType, new MapState(map)); | 1325 return new DartObjectImpl(mapType, new MapState(map)); |
| 1370 } | 1326 } |
| 1371 | 1327 |
| 1372 @override | 1328 @override |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 for (int i = 0; i < components.length; i++) { | 1458 for (int i = 0; i < components.length; i++) { |
| 1503 if (i > 0) { | 1459 if (i > 0) { |
| 1504 buffer.writeCharCode(0x2E); | 1460 buffer.writeCharCode(0x2E); |
| 1505 } | 1461 } |
| 1506 buffer.write(components[i].lexeme); | 1462 buffer.write(components[i].lexeme); |
| 1507 } | 1463 } |
| 1508 return new DartObjectImpl( | 1464 return new DartObjectImpl( |
| 1509 _typeProvider.symbolType, new SymbolState(buffer.toString())); | 1465 _typeProvider.symbolType, new SymbolState(buffer.toString())); |
| 1510 } | 1466 } |
| 1511 | 1467 |
| 1512 @override | |
| 1513 DartObjectImpl visitTypeName(TypeName node) { | |
| 1514 return typeConstant(evaluateType(node.type)); | |
| 1515 } | |
| 1516 | |
| 1517 /** | |
| 1518 * Given a [type], returns the constant value that contains that type value. | |
| 1519 */ | |
| 1520 DartObjectImpl typeConstant(DartType type) { | |
| 1521 return new DartObjectImpl(_typeProvider.typeType, new TypeState(type)); | |
| 1522 } | |
| 1523 | |
| 1524 /** | |
| 1525 * Given a [type] that may contain free type variables, evaluate them against | |
| 1526 * the current lexical environment and return the substituted type. | |
| 1527 */ | |
| 1528 DartType evaluateType(DartType type) { | |
| 1529 if (type is TypeParameterType) { | |
| 1530 String name = type.name; | |
| 1531 if (_lexicalEnvironment != null) { | |
| 1532 return _lexicalEnvironment[name]?.toTypeValue() ?? type; | |
| 1533 } | |
| 1534 return type; | |
| 1535 } | |
| 1536 if (type is ParameterizedType) { | |
| 1537 List<DartType> typeArguments; | |
| 1538 for (int i = 0; i < type.typeArguments.length; i++) { | |
| 1539 DartType ta = type.typeArguments[i]; | |
| 1540 DartType t = evaluateType(ta); | |
| 1541 if (!identical(t, ta)) { | |
| 1542 if (typeArguments == null) { | |
| 1543 typeArguments = type.typeArguments.toList(growable: false); | |
| 1544 } | |
| 1545 typeArguments[i] = t; | |
| 1546 } | |
| 1547 } | |
| 1548 if (typeArguments == null) return type; | |
| 1549 return type.substitute2(typeArguments, type.typeArguments); | |
| 1550 } | |
| 1551 return type; | |
| 1552 } | |
| 1553 | |
| 1554 /** | 1468 /** |
| 1555 * Create an error associated with the given [node]. The error will have the | 1469 * Create an error associated with the given [node]. The error will have the |
| 1556 * given error [code]. | 1470 * given error [code]. |
| 1557 */ | 1471 */ |
| 1558 void _error(AstNode node, ErrorCode code) { | 1472 void _error(AstNode node, ErrorCode code) { |
| 1559 _errorReporter.reportErrorForNode( | 1473 _errorReporter.reportErrorForNode( |
| 1560 code ?? CompileTimeErrorCode.INVALID_CONSTANT, node); | 1474 code ?? CompileTimeErrorCode.INVALID_CONSTANT, node); |
| 1561 } | 1475 } |
| 1562 | 1476 |
| 1563 /** | 1477 /** |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1576 } | 1490 } |
| 1577 } else if (variableElement is ExecutableElement) { | 1491 } else if (variableElement is ExecutableElement) { |
| 1578 ExecutableElement function = element; | 1492 ExecutableElement function = element; |
| 1579 if (function.isStatic) { | 1493 if (function.isStatic) { |
| 1580 ParameterizedType functionType = function.type; | 1494 ParameterizedType functionType = function.type; |
| 1581 if (functionType == null) { | 1495 if (functionType == null) { |
| 1582 functionType = _typeProvider.functionType; | 1496 functionType = _typeProvider.functionType; |
| 1583 } | 1497 } |
| 1584 return new DartObjectImpl(functionType, new FunctionState(function)); | 1498 return new DartObjectImpl(functionType, new FunctionState(function)); |
| 1585 } | 1499 } |
| 1586 } else if (variableElement is TypeDefiningElement) { | 1500 } else if (variableElement is ClassElement || |
| 1587 return new DartObjectImpl( | 1501 variableElement is FunctionTypeAliasElement || |
| 1588 _typeProvider.typeType, new TypeState(variableElement.type)); | 1502 variableElement is DynamicElementImpl) { |
| 1503 return new DartObjectImpl(_typeProvider.typeType, new TypeState(element)); |
| 1589 } | 1504 } |
| 1590 // TODO(brianwilkerson) Figure out which error to report. | 1505 // TODO(brianwilkerson) Figure out which error to report. |
| 1591 _error(node, null); | 1506 _error(node, null); |
| 1592 return null; | 1507 return null; |
| 1593 } | 1508 } |
| 1594 | 1509 |
| 1595 /** | 1510 /** |
| 1596 * Return `true` if the given [targetResult] represents a string and the | 1511 * Return `true` if the given [targetResult] represents a string and the |
| 1597 * [identifier] is "length". | 1512 * [identifier] is "length". |
| 1598 */ | 1513 */ |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2069 } | 1984 } |
| 2070 | 1985 |
| 2071 @override | 1986 @override |
| 2072 String toString() { | 1987 String toString() { |
| 2073 if (value == null) { | 1988 if (value == null) { |
| 2074 return "error"; | 1989 return "error"; |
| 2075 } | 1990 } |
| 2076 return value.toString(); | 1991 return value.toString(); |
| 2077 } | 1992 } |
| 2078 } | 1993 } |
| OLD | NEW |