Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: pkg/analyzer/lib/src/dart/element/element.dart

Issue 1966323002: Add API to force the computation of constant values (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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.element.element; 5 library analyzer.src.dart.element.element;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' show min; 8 import 'dart:math' show min;
9 9
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/constant/value.dart'; 12 import 'package:analyzer/dart/constant/value.dart';
13 import 'package:analyzer/dart/element/element.dart'; 13 import 'package:analyzer/dart/element/element.dart';
14 import 'package:analyzer/dart/element/type.dart'; 14 import 'package:analyzer/dart/element/type.dart';
15 import 'package:analyzer/dart/element/visitor.dart'; 15 import 'package:analyzer/dart/element/visitor.dart';
16 import 'package:analyzer/src/dart/ast/utilities.dart'; 16 import 'package:analyzer/src/dart/ast/utilities.dart';
17 import 'package:analyzer/src/dart/element/handle.dart'; 17 import 'package:analyzer/src/dart/element/handle.dart';
18 import 'package:analyzer/src/dart/element/type.dart'; 18 import 'package:analyzer/src/dart/element/type.dart';
19 import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl; 19 import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl;
20 import 'package:analyzer/src/generated/engine.dart' 20 import 'package:analyzer/src/generated/engine.dart'
21 show AnalysisContext, AnalysisEngine; 21 show AnalysisContext, AnalysisEngine;
22 import 'package:analyzer/src/generated/java_core.dart'; 22 import 'package:analyzer/src/generated/java_core.dart';
23 import 'package:analyzer/src/generated/java_engine.dart'; 23 import 'package:analyzer/src/generated/java_engine.dart';
24 import 'package:analyzer/src/generated/resolver.dart'; 24 import 'package:analyzer/src/generated/resolver.dart';
25 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; 25 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
26 import 'package:analyzer/src/generated/source.dart'; 26 import 'package:analyzer/src/generated/source.dart';
27 import 'package:analyzer/src/generated/utilities_collection.dart'; 27 import 'package:analyzer/src/generated/utilities_collection.dart';
28 import 'package:analyzer/src/generated/utilities_dart.dart'; 28 import 'package:analyzer/src/generated/utilities_dart.dart';
29 import 'package:analyzer/src/generated/utilities_general.dart'; 29 import 'package:analyzer/src/generated/utilities_general.dart';
30 import 'package:analyzer/src/task/dart.dart';
30 31
31 /** 32 /**
32 * For AST nodes that could be in both the getter and setter contexts 33 * For AST nodes that could be in both the getter and setter contexts
33 * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved 34 * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
34 * elements are stored in the AST node, in an [AuxiliaryElements]. Because 35 * elements are stored in the AST node, in an [AuxiliaryElements]. Because
35 * resolved elements are either statically resolved or resolved using propagated 36 * resolved elements are either statically resolved or resolved using propagated
36 * type information, this class is a wrapper for a pair of [ExecutableElement]s, 37 * type information, this class is a wrapper for a pair of [ExecutableElement]s,
37 * not just a single [ExecutableElement]. 38 * not just a single [ExecutableElement].
38 */ 39 */
39 class AuxiliaryElements { 40 class AuxiliaryElements {
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 * 1258 *
1258 * TODO(paulberry): we should rename this class to reflect the fact that it's 1259 * TODO(paulberry): we should rename this class to reflect the fact that it's
1259 * used for both const and final fields. However, we shouldn't do so until 1260 * used for both const and final fields. However, we shouldn't do so until
1260 * we've created an API for reading the values of constants; until that API is 1261 * we've created an API for reading the values of constants; until that API is
1261 * available, clients are likely to read constant values by casting to 1262 * available, clients are likely to read constant values by casting to
1262 * ConstFieldElementImpl, so it would be a breaking change to rename this 1263 * ConstFieldElementImpl, so it would be a breaking change to rename this
1263 * class. 1264 * class.
1264 */ 1265 */
1265 class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement { 1266 class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement {
1266 /** 1267 /**
1267 * The result of evaluating this variable's initializer.
1268 */
1269 EvaluationResultImpl _result;
1270
1271 /**
1272 * Initialize a newly created synthetic field element to have the given 1268 * Initialize a newly created synthetic field element to have the given
1273 * [name] and [offset]. 1269 * [name] and [offset].
1274 */ 1270 */
1275 ConstFieldElementImpl(String name, int offset) : super(name, offset); 1271 ConstFieldElementImpl(String name, int offset) : super(name, offset);
1276 1272
1277 /** 1273 /**
1278 * Initialize a newly created field element to have the given [name]. 1274 * Initialize a newly created field element to have the given [name].
1279 */ 1275 */
1280 ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name); 1276 ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
1281
1282 @override
1283 DartObject get constantValue => _result?.value;
1284
1285 @override
1286 EvaluationResultImpl get evaluationResult => _result;
1287
1288 @override
1289 void set evaluationResult(EvaluationResultImpl result) {
1290 this._result = result;
1291 }
1292 } 1277 }
1293 1278
1294 /** 1279 /**
1295 * A [LocalVariableElement] for a local 'const' variable that has an 1280 * A [LocalVariableElement] for a local 'const' variable that has an
1296 * initializer. 1281 * initializer.
1297 */ 1282 */
1298 class ConstLocalVariableElementImpl extends LocalVariableElementImpl 1283 class ConstLocalVariableElementImpl extends LocalVariableElementImpl
1299 with ConstVariableElement { 1284 with ConstVariableElement {
1300 /** 1285 /**
1301 * The result of evaluating this variable's initializer.
1302 */
1303 EvaluationResultImpl _result;
1304
1305 /**
1306 * Initialize a newly created local variable element to have the given [name] 1286 * Initialize a newly created local variable element to have the given [name]
1307 * and [offset]. 1287 * and [offset].
1308 */ 1288 */
1309 ConstLocalVariableElementImpl(String name, int offset) : super(name, offset); 1289 ConstLocalVariableElementImpl(String name, int offset) : super(name, offset);
1310 1290
1311 /** 1291 /**
1312 * Initialize a newly created local variable element to have the given [name]. 1292 * Initialize a newly created local variable element to have the given [name].
1313 */ 1293 */
1314 ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name); 1294 ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
1315
1316 @override
1317 DartObject get constantValue => _result?.value;
1318
1319 @override
1320 EvaluationResultImpl get evaluationResult => _result;
1321
1322 @override
1323 void set evaluationResult(EvaluationResultImpl result) {
1324 this._result = result;
1325 }
1326 } 1295 }
1327 1296
1328 /** 1297 /**
1329 * A concrete implementation of a [ConstructorElement]. 1298 * A concrete implementation of a [ConstructorElement].
1330 */ 1299 */
1331 class ConstructorElementImpl extends ExecutableElementImpl 1300 class ConstructorElementImpl extends ExecutableElementImpl
1332 implements ConstructorElement { 1301 implements ConstructorElement {
1333 /** 1302 /**
1334 * The constructor to which this constructor is redirecting. 1303 * The constructor to which this constructor is redirecting.
1335 */ 1304 */
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 getNodeMatching((node) => node is ConstructorDeclaration); 1416 getNodeMatching((node) => node is ConstructorDeclaration);
1448 } 1417 }
1449 1418
1450 /** 1419 /**
1451 * A [TopLevelVariableElement] for a top-level 'const' variable that has an 1420 * A [TopLevelVariableElement] for a top-level 'const' variable that has an
1452 * initializer. 1421 * initializer.
1453 */ 1422 */
1454 class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl 1423 class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl
1455 with ConstVariableElement { 1424 with ConstVariableElement {
1456 /** 1425 /**
1457 * The result of evaluating this variable's initializer.
1458 */
1459 EvaluationResultImpl _result;
1460
1461 /**
1462 * Initialize a newly created synthetic top-level variable element to have the 1426 * Initialize a newly created synthetic top-level variable element to have the
1463 * given [name] and [offset]. 1427 * given [name] and [offset].
1464 */ 1428 */
1465 ConstTopLevelVariableElementImpl(String name, int offset) 1429 ConstTopLevelVariableElementImpl(String name, int offset)
1466 : super(name, offset); 1430 : super(name, offset);
1467 1431
1468 /** 1432 /**
1469 * Initialize a newly created top-level variable element to have the given 1433 * Initialize a newly created top-level variable element to have the given
1470 * [name]. 1434 * [name].
1471 */ 1435 */
1472 ConstTopLevelVariableElementImpl.forNode(Identifier name) 1436 ConstTopLevelVariableElementImpl.forNode(Identifier name)
1473 : super.forNode(name); 1437 : super.forNode(name);
1474
1475 @override
1476 DartObject get constantValue => _result?.value;
1477
1478 @override
1479 EvaluationResultImpl get evaluationResult => _result;
1480
1481 @override
1482 void set evaluationResult(EvaluationResultImpl result) {
1483 this._result = result;
1484 }
1485 } 1438 }
1486 1439
1487 /** 1440 /**
1488 * Mixin used by elements that represent constant variables and have 1441 * Mixin used by elements that represent constant variables and have
1489 * initializers. 1442 * initializers.
1490 * 1443 *
1491 * Note that in correct Dart code, all constant variables must have 1444 * Note that in correct Dart code, all constant variables must have
1492 * initializers. However, analyzer also needs to handle incorrect Dart code, 1445 * initializers. However, analyzer also needs to handle incorrect Dart code,
1493 * in which case there might be some constant variables that lack initializers. 1446 * in which case there might be some constant variables that lack initializers.
1494 * This interface is only used for constant variables that have initializers. 1447 * This interface is only used for constant variables that have initializers.
1495 * 1448 *
1496 * This class is not intended to be part of the public API for analyzer. 1449 * This class is not intended to be part of the public API for analyzer.
1497 */ 1450 */
1498 abstract class ConstVariableElement { 1451 abstract class ConstVariableElement implements ConstantEvaluationTarget {
1499 /** 1452 /**
1500 * If this element represents a constant variable, and it has an initializer, 1453 * If this element represents a constant variable, and it has an initializer,
1501 * a copy of the initializer for the constant. Otherwise `null`. 1454 * a copy of the initializer for the constant. Otherwise `null`.
1502 * 1455 *
1503 * Note that in correct Dart code, all constant variables must have 1456 * Note that in correct Dart code, all constant variables must have
1504 * initializers. However, analyzer also needs to handle incorrect Dart code, 1457 * initializers. However, analyzer also needs to handle incorrect Dart code,
1505 * in which case there might be some constant variables that lack 1458 * in which case there might be some constant variables that lack
1506 * initializers. 1459 * initializers.
1507 */ 1460 */
1508 Expression constantInitializer; 1461 Expression constantInitializer;
1462
1463 @override
1464 EvaluationResultImpl evaluationResult;
1465
1466 /**
1467 * Return a representation of the value of this variable, forcing the value
1468 * to be computed if it had not previously been computed, or `null` if either
1469 * this variable was not declared with the 'const' modifier or if the value of
1470 * this variable could not be computed because of errors.
1471 */
1472 DartObject computeConstantValue() {
1473 if (evaluationResult == null) {
1474 context?.computeResult(this, CONSTANT_VALUE);
1475 }
1476 return evaluationResult?.value;
1477 }
1509 } 1478 }
1510 1479
1511 /** 1480 /**
1512 * A [FieldFormalParameterElementImpl] for parameters that have an initializer. 1481 * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
1513 */ 1482 */
1514 class DefaultFieldFormalParameterElementImpl 1483 class DefaultFieldFormalParameterElementImpl
1515 extends FieldFormalParameterElementImpl with ConstVariableElement { 1484 extends FieldFormalParameterElementImpl with ConstVariableElement {
1516 /** 1485 /**
1517 * The result of evaluating this variable's initializer.
1518 */
1519 EvaluationResultImpl _result;
1520
1521 /**
1522 * Initialize a newly created parameter element to have the given [name] and 1486 * Initialize a newly created parameter element to have the given [name] and
1523 * [nameOffset]. 1487 * [nameOffset].
1524 */ 1488 */
1525 DefaultFieldFormalParameterElementImpl(String name, int nameOffset) 1489 DefaultFieldFormalParameterElementImpl(String name, int nameOffset)
1526 : super(name, nameOffset); 1490 : super(name, nameOffset);
1527 1491
1528 /** 1492 /**
1529 * Initialize a newly created parameter element to have the given [name]. 1493 * Initialize a newly created parameter element to have the given [name].
1530 */ 1494 */
1531 DefaultFieldFormalParameterElementImpl.forNode(Identifier name) 1495 DefaultFieldFormalParameterElementImpl.forNode(Identifier name)
1532 : super.forNode(name); 1496 : super.forNode(name);
1533
1534 @override
1535 DartObject get constantValue => _result?.value;
1536
1537 @override
1538 EvaluationResultImpl get evaluationResult => _result;
1539
1540 @override
1541 void set evaluationResult(EvaluationResultImpl result) {
1542 this._result = result;
1543 }
1544 } 1497 }
1545 1498
1546 /** 1499 /**
1547 * A [ParameterElement] for parameters that have an initializer. 1500 * A [ParameterElement] for parameters that have an initializer.
1548 */ 1501 */
1549 class DefaultParameterElementImpl extends ParameterElementImpl 1502 class DefaultParameterElementImpl extends ParameterElementImpl
1550 with ConstVariableElement { 1503 with ConstVariableElement {
1551 /** 1504 /**
1552 * The result of evaluating this variable's initializer.
1553 */
1554 EvaluationResultImpl _result;
1555
1556 /**
1557 * Initialize a newly created parameter element to have the given [name] and 1505 * Initialize a newly created parameter element to have the given [name] and
1558 * [nameOffset]. 1506 * [nameOffset].
1559 */ 1507 */
1560 DefaultParameterElementImpl(String name, int nameOffset) 1508 DefaultParameterElementImpl(String name, int nameOffset)
1561 : super(name, nameOffset); 1509 : super(name, nameOffset);
1562 1510
1563 /** 1511 /**
1564 * Initialize a newly created parameter element to have the given [name]. 1512 * Initialize a newly created parameter element to have the given [name].
1565 */ 1513 */
1566 DefaultParameterElementImpl.forNode(Identifier name) : super.forNode(name); 1514 DefaultParameterElementImpl.forNode(Identifier name) : super.forNode(name);
1567 1515
1568 @override 1516 @override
1569 DartObject get constantValue => _result?.value;
1570
1571 @override
1572 EvaluationResultImpl get evaluationResult => _result;
1573
1574 @override
1575 void set evaluationResult(EvaluationResultImpl result) {
1576 this._result = result;
1577 }
1578
1579 @override
1580 DefaultFormalParameter computeNode() => 1517 DefaultFormalParameter computeNode() =>
1581 getNodeMatching((node) => node is DefaultFormalParameter); 1518 getNodeMatching((node) => node is DefaultFormalParameter);
1582 } 1519 }
1583 1520
1584 /** 1521 /**
1585 * The synthetic element representing the declaration of the type `dynamic`. 1522 * The synthetic element representing the declaration of the type `dynamic`.
1586 */ 1523 */
1587 class DynamicElementImpl extends ElementImpl implements TypeDefiningElement { 1524 class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
1588 /** 1525 /**
1589 * Return the unique instance of this class. 1526 * Return the unique instance of this class.
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 1702
1766 /** 1703 /**
1767 * Get the library containing this annotation. 1704 * Get the library containing this annotation.
1768 */ 1705 */
1769 Source get librarySource => compilationUnit.librarySource; 1706 Source get librarySource => compilationUnit.librarySource;
1770 1707
1771 @override 1708 @override
1772 Source get source => compilationUnit.source; 1709 Source get source => compilationUnit.source;
1773 1710
1774 @override 1711 @override
1712 DartObject computeConstantValue() {
1713 if (evaluationResult == null) {
1714 context?.computeResult(this, CONSTANT_VALUE);
1715 }
1716 return constantValue;
1717 }
1718
1719 @override
1775 String toString() => '@$element'; 1720 String toString() => '@$element';
1776 } 1721 }
1777 1722
1778 /** 1723 /**
1779 * A base class for concrete implementations of an [Element]. 1724 * A base class for concrete implementations of an [Element].
1780 */ 1725 */
1781 abstract class ElementImpl implements Element { 1726 abstract class ElementImpl implements Element {
1782 /** 1727 /**
1783 * An Unicode right arrow. 1728 * An Unicode right arrow.
1784 */ 1729 */
(...skipping 3156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4941 * a copy of the initializer for the constant. Otherwise `null`. 4886 * a copy of the initializer for the constant. Otherwise `null`.
4942 * 4887 *
4943 * Note that in correct Dart code, all constant variables must have 4888 * Note that in correct Dart code, all constant variables must have
4944 * initializers. However, analyzer also needs to handle incorrect Dart code, 4889 * initializers. However, analyzer also needs to handle incorrect Dart code,
4945 * in which case there might be some constant variables that lack 4890 * in which case there might be some constant variables that lack
4946 * initializers. 4891 * initializers.
4947 */ 4892 */
4948 Expression get constantInitializer => null; 4893 Expression get constantInitializer => null;
4949 4894
4950 @override 4895 @override
4951 DartObject get constantValue => null; 4896 DartObject get constantValue => evaluationResult?.value;
4952 4897
4953 /** 4898 /**
4954 * Return the result of evaluating this variable's initializer as a 4899 * Return the result of evaluating this variable's initializer as a
4955 * compile-time constant expression, or `null` if this variable is not a 4900 * compile-time constant expression, or `null` if this variable is not a
4956 * 'const' variable, if it does not have an initializer, or if the compilation 4901 * 'const' variable, if it does not have an initializer, or if the compilation
4957 * unit containing the variable has not been resolved. 4902 * unit containing the variable has not been resolved.
4958 */ 4903 */
4959 EvaluationResultImpl get evaluationResult => null; 4904 EvaluationResultImpl get evaluationResult => null;
4960 4905
4961 /** 4906 /**
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5014 bool get isStatic => hasModifier(Modifier.STATIC); 4959 bool get isStatic => hasModifier(Modifier.STATIC);
5015 4960
5016 @override 4961 @override
5017 void appendTo(StringBuffer buffer) { 4962 void appendTo(StringBuffer buffer) {
5018 buffer.write(type); 4963 buffer.write(type);
5019 buffer.write(" "); 4964 buffer.write(" ");
5020 buffer.write(displayName); 4965 buffer.write(displayName);
5021 } 4966 }
5022 4967
5023 @override 4968 @override
4969 DartObject computeConstantValue() => null;
4970
4971 @override
5024 void visitChildren(ElementVisitor visitor) { 4972 void visitChildren(ElementVisitor visitor) {
5025 super.visitChildren(visitor); 4973 super.visitChildren(visitor);
5026 _initializer?.accept(visitor); 4974 _initializer?.accept(visitor);
5027 } 4975 }
5028 } 4976 }
5029 4977
5030 /** 4978 /**
5031 * A visitor that visit all the elements recursively and fill the given [map]. 4979 * A visitor that visit all the elements recursively and fill the given [map].
5032 */ 4980 */
5033 class _BuildOffsetToElementMap extends GeneralizingElementVisitor { 4981 class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
5034 final Map<int, Element> map; 4982 final Map<int, Element> map;
5035 4983
5036 _BuildOffsetToElementMap(this.map); 4984 _BuildOffsetToElementMap(this.map);
5037 4985
5038 @override 4986 @override
5039 void visitElement(Element element) { 4987 void visitElement(Element element) {
5040 int offset = element.nameOffset; 4988 int offset = element.nameOffset;
5041 if (offset != -1) { 4989 if (offset != -1) {
5042 map[offset] = element; 4990 map[offset] = element;
5043 } 4991 }
5044 super.visitElement(element); 4992 super.visitElement(element);
5045 } 4993 }
5046 } 4994 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/dart/element/element.dart ('k') | pkg/analyzer/lib/src/dart/element/handle.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698