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 |