| 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'; |
| 11 import 'package:analyzer/dart/ast/token.dart'; | 11 import 'package:analyzer/dart/ast/token.dart'; |
| 12 import 'package:analyzer/dart/ast/visitor.dart'; | 12 import 'package:analyzer/dart/ast/visitor.dart'; |
| 13 import 'package:analyzer/dart/constant/value.dart'; | 13 import 'package:analyzer/dart/constant/value.dart'; |
| 14 import 'package:analyzer/dart/element/element.dart'; | 14 import 'package:analyzer/dart/element/element.dart'; |
| 15 import 'package:analyzer/dart/element/type.dart'; | 15 import 'package:analyzer/dart/element/type.dart'; |
| 16 import 'package:analyzer/src/dart/constant/utilities.dart'; | 16 import 'package:analyzer/src/dart/constant/utilities.dart'; |
| 17 import 'package:analyzer/src/dart/constant/value.dart'; | 17 import 'package:analyzer/src/dart/constant/value.dart'; |
| 18 import 'package:analyzer/src/dart/element/element.dart'; | 18 import 'package:analyzer/src/dart/element/element.dart'; |
| 19 import 'package:analyzer/src/dart/element/member.dart'; | 19 import 'package:analyzer/src/dart/element/member.dart'; |
| 20 import 'package:analyzer/src/generated/engine.dart'; | 20 import 'package:analyzer/src/generated/engine.dart'; |
| 21 import 'package:analyzer/src/generated/engine.dart' | 21 import 'package:analyzer/src/generated/engine.dart' |
| 22 show AnalysisEngine, RecordingErrorListener; | 22 show AnalysisEngine, RecordingErrorListener; |
| 23 import 'package:analyzer/src/generated/error.dart'; | 23 import 'package:analyzer/src/generated/error.dart'; |
| 24 import 'package:analyzer/src/generated/java_core.dart'; | |
| 25 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; | 24 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider; |
| 26 import 'package:analyzer/src/generated/type_system.dart' | 25 import 'package:analyzer/src/generated/type_system.dart' |
| 27 show TypeSystem, TypeSystemImpl; | 26 show TypeSystem, TypeSystemImpl; |
| 28 import 'package:analyzer/src/generated/utilities_collection.dart'; | 27 import 'package:analyzer/src/generated/utilities_collection.dart'; |
| 29 import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind; | 28 import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind; |
| 30 import 'package:analyzer/src/task/dart.dart'; | 29 import 'package:analyzer/src/task/dart.dart'; |
| 31 | 30 |
| 32 /** | 31 /** |
| 33 * Helper class encapsulating the methods for evaluating constants and | 32 * Helper class encapsulating the methods for evaluating constants and |
| 34 * constant instance creation expressions. | 33 * constant instance creation expressions. |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 852 return false; | 851 return false; |
| 853 } | 852 } |
| 854 return obj.type.isSubtypeOf(type); | 853 return obj.type.isSubtypeOf(type); |
| 855 } | 854 } |
| 856 | 855 |
| 857 /** | 856 /** |
| 858 * Determine whether the given string is a valid name for a public symbol | 857 * Determine whether the given string is a valid name for a public symbol |
| 859 * (i.e. whether it is allowed for a call to the Symbol constructor). | 858 * (i.e. whether it is allowed for a call to the Symbol constructor). |
| 860 */ | 859 */ |
| 861 static bool isValidPublicSymbol(String name) => | 860 static bool isValidPublicSymbol(String name) => |
| 862 name.isEmpty || | 861 name.isEmpty || name == "void" || _PUBLIC_SYMBOL_PATTERN.hasMatch(name); |
| 863 name == "void" || | |
| 864 _PUBLIC_SYMBOL_PATTERN.hasMatch(name); | |
| 865 } | 862 } |
| 866 | 863 |
| 867 /** | 864 /** |
| 868 * Interface used by unit tests to verify correct dependency analysis during | 865 * Interface used by unit tests to verify correct dependency analysis during |
| 869 * constant evaluation. | 866 * constant evaluation. |
| 870 */ | 867 */ |
| 871 abstract class ConstantEvaluationValidator { | 868 abstract class ConstantEvaluationValidator { |
| 872 /** | 869 /** |
| 873 * This method is called just before computing the constant value associated | 870 * This method is called just before computing the constant value associated |
| 874 * with [constant]. Unit tests will override this method to introduce | 871 * with [constant]. Unit tests will override this method to introduce |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 * Convenience getter to gain access to the [evalationEngine]'s type | 1129 * Convenience getter to gain access to the [evalationEngine]'s type |
| 1133 * provider. | 1130 * provider. |
| 1134 */ | 1131 */ |
| 1135 TypeProvider get _typeProvider => evaluationEngine.typeProvider; | 1132 TypeProvider get _typeProvider => evaluationEngine.typeProvider; |
| 1136 | 1133 |
| 1137 /** | 1134 /** |
| 1138 * Convenience getter to gain access to the [evaluationEngine]'s type system. | 1135 * Convenience getter to gain access to the [evaluationEngine]'s type system. |
| 1139 */ | 1136 */ |
| 1140 TypeSystem get _typeSystem => evaluationEngine.typeSystem; | 1137 TypeSystem get _typeSystem => evaluationEngine.typeSystem; |
| 1141 | 1138 |
| 1139 /** |
| 1140 * Given a [type] that may contain free type variables, evaluate them against |
| 1141 * the current lexical environment and return the substituted type. |
| 1142 */ |
| 1143 DartType evaluateType(DartType type) { |
| 1144 if (type is TypeParameterType) { |
| 1145 // Constants may only refer to type parameters in strong mode. |
| 1146 if (!evaluationEngine.strongMode) { |
| 1147 return null; |
| 1148 } |
| 1149 |
| 1150 String name = type.name; |
| 1151 if (_lexicalEnvironment != null) { |
| 1152 return _lexicalEnvironment[name]?.toTypeValue() ?? type; |
| 1153 } |
| 1154 return type; |
| 1155 } |
| 1156 if (type is ParameterizedType) { |
| 1157 List<DartType> typeArguments; |
| 1158 for (int i = 0; i < type.typeArguments.length; i++) { |
| 1159 DartType ta = type.typeArguments[i]; |
| 1160 DartType t = evaluateType(ta); |
| 1161 if (!identical(t, ta)) { |
| 1162 if (typeArguments == null) { |
| 1163 typeArguments = type.typeArguments.toList(growable: false); |
| 1164 } |
| 1165 typeArguments[i] = t; |
| 1166 } |
| 1167 } |
| 1168 if (typeArguments == null) return type; |
| 1169 return type.substitute2(typeArguments, type.typeArguments); |
| 1170 } |
| 1171 return type; |
| 1172 } |
| 1173 |
| 1174 /** |
| 1175 * Given a [type], returns the constant value that contains that type value. |
| 1176 */ |
| 1177 DartObjectImpl typeConstant(DartType type) { |
| 1178 return new DartObjectImpl(_typeProvider.typeType, new TypeState(type)); |
| 1179 } |
| 1180 |
| 1142 @override | 1181 @override |
| 1143 DartObjectImpl visitAdjacentStrings(AdjacentStrings node) { | 1182 DartObjectImpl visitAdjacentStrings(AdjacentStrings node) { |
| 1144 DartObjectImpl result = null; | 1183 DartObjectImpl result = null; |
| 1145 for (StringLiteral string in node.strings) { | 1184 for (StringLiteral string in node.strings) { |
| 1146 if (result == null) { | 1185 if (result == null) { |
| 1147 result = string.accept(this); | 1186 result = string.accept(this); |
| 1148 } else { | 1187 } else { |
| 1149 result = | 1188 result = |
| 1150 _dartObjectComputer.concatenate(node, result, string.accept(this)); | 1189 _dartObjectComputer.concatenate(node, result, string.accept(this)); |
| 1151 } | 1190 } |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 @override | 1551 @override |
| 1513 DartObjectImpl visitTypeName(TypeName node) { | 1552 DartObjectImpl visitTypeName(TypeName node) { |
| 1514 DartType type = evaluateType(node.type); | 1553 DartType type = evaluateType(node.type); |
| 1515 if (type == null) { | 1554 if (type == null) { |
| 1516 return super.visitTypeName(node); | 1555 return super.visitTypeName(node); |
| 1517 } | 1556 } |
| 1518 return typeConstant(type); | 1557 return typeConstant(type); |
| 1519 } | 1558 } |
| 1520 | 1559 |
| 1521 /** | 1560 /** |
| 1522 * Given a [type], returns the constant value that contains that type value. | |
| 1523 */ | |
| 1524 DartObjectImpl typeConstant(DartType type) { | |
| 1525 return new DartObjectImpl(_typeProvider.typeType, new TypeState(type)); | |
| 1526 } | |
| 1527 | |
| 1528 /** | |
| 1529 * Given a [type] that may contain free type variables, evaluate them against | |
| 1530 * the current lexical environment and return the substituted type. | |
| 1531 */ | |
| 1532 DartType evaluateType(DartType type) { | |
| 1533 if (type is TypeParameterType) { | |
| 1534 // Constants may only refer to type parameters in strong mode. | |
| 1535 if (!evaluationEngine.strongMode) { | |
| 1536 return null; | |
| 1537 } | |
| 1538 | |
| 1539 String name = type.name; | |
| 1540 if (_lexicalEnvironment != null) { | |
| 1541 return _lexicalEnvironment[name]?.toTypeValue() ?? type; | |
| 1542 } | |
| 1543 return type; | |
| 1544 } | |
| 1545 if (type is ParameterizedType) { | |
| 1546 List<DartType> typeArguments; | |
| 1547 for (int i = 0; i < type.typeArguments.length; i++) { | |
| 1548 DartType ta = type.typeArguments[i]; | |
| 1549 DartType t = evaluateType(ta); | |
| 1550 if (!identical(t, ta)) { | |
| 1551 if (typeArguments == null) { | |
| 1552 typeArguments = type.typeArguments.toList(growable: false); | |
| 1553 } | |
| 1554 typeArguments[i] = t; | |
| 1555 } | |
| 1556 } | |
| 1557 if (typeArguments == null) return type; | |
| 1558 return type.substitute2(typeArguments, type.typeArguments); | |
| 1559 } | |
| 1560 return type; | |
| 1561 } | |
| 1562 | |
| 1563 /** | |
| 1564 * Create an error associated with the given [node]. The error will have the | 1561 * Create an error associated with the given [node]. The error will have the |
| 1565 * given error [code]. | 1562 * given error [code]. |
| 1566 */ | 1563 */ |
| 1567 void _error(AstNode node, ErrorCode code) { | 1564 void _error(AstNode node, ErrorCode code) { |
| 1568 _errorReporter.reportErrorForNode( | 1565 _errorReporter.reportErrorForNode( |
| 1569 code ?? CompileTimeErrorCode.INVALID_CONSTANT, node); | 1566 code ?? CompileTimeErrorCode.INVALID_CONSTANT, node); |
| 1570 } | 1567 } |
| 1571 | 1568 |
| 1572 /** | 1569 /** |
| 1573 * Return the constant value of the static constant represented by the given | 1570 * Return the constant value of the static constant represented by the given |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2082 } | 2079 } |
| 2083 | 2080 |
| 2084 @override | 2081 @override |
| 2085 String toString() { | 2082 String toString() { |
| 2086 if (value == null) { | 2083 if (value == null) { |
| 2087 return "error"; | 2084 return "error"; |
| 2088 } | 2085 } |
| 2089 return value.toString(); | 2086 return value.toString(); |
| 2090 } | 2087 } |
| 2091 } | 2088 } |
| OLD | NEW |