Index: pkg/compiler/lib/src/types/types.dart |
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart |
index b9f681e30a0c6effec93d2aa799b88bd95f066b4..28dc608cb384ef9bfd2da203f58f908c24909ea9 100644 |
--- a/pkg/compiler/lib/src/types/types.dart |
+++ b/pkg/compiler/lib/src/types/types.dart |
@@ -9,7 +9,6 @@ import '../compiler.dart' show Compiler; |
import '../elements/elements.dart'; |
import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer; |
import '../tree/tree.dart'; |
-import '../resolution/tree_elements.dart'; |
import '../universe/selector.dart' show Selector; |
import 'masks.dart'; |
@@ -20,108 +19,13 @@ abstract class TypesInferrer { |
void analyzeMain(Element element); |
TypeMask getReturnTypeOfElement(Element element); |
TypeMask getTypeOfElement(Element element); |
- TypeMask getTypeForNewList(Element owner, Node node); |
+ TypeMask getTypeOfNode(Element owner, Node node); |
TypeMask getTypeOfSelector(Selector selector, TypeMask mask); |
void clear(); |
bool isCalledOnce(Element element); |
bool isFixedArrayCheckedForGrowable(Node node); |
} |
-/// Results produced by the global type-inference algorithm. |
-/// |
-/// All queries in this class may contain results that assume whole-program |
-/// closed-world semantics. Any [TypeMask] for an element or node that we return |
-/// was inferred to be a "guaranteed type", that means, it is a type that we |
-/// can prove to be correct for all executions of the program. |
-class GlobalTypeInferenceResults { |
- // TODO(sigmund): store relevant data & drop reference to inference engine. |
- final TypesInferrer _inferrer; |
- final Compiler compiler; |
- final TypeMask dynamicType; |
- |
- GlobalTypeInferenceResults(this._inferrer, this.compiler, CommonMasks masks) |
- : dynamicType = masks.dynamicType; |
- |
- /// Returns the type of a parameter or field [element], if any. |
- TypeMask typeOf(Element element) { |
- // TODO(24489): trust some JsInterop types. |
- if (compiler.backend.isJsInterop(element)) return dynamicType; |
- return _inferrer.getTypeOfElement(element); |
- } |
- |
- /// Returns the return type of a method or function [element]. |
- TypeMask returnTypeOf(Element element) { |
- // TODO(24489): trust some JsInterop types. |
- if (compiler.backend.isJsInterop(element)) return dynamicType; |
- return _inferrer.getReturnTypeOfElement(element); |
- } |
- |
- /// Returns the type of a [selector] when applied to a receiver with the given |
- /// type [mask]. |
- TypeMask typeOfSelector(Selector selector, TypeMask mask) => |
- _inferrer.getTypeOfSelector(selector, mask); |
- |
- /// Returns whether the method [element] always throws. |
- bool throwsAlways(Element element) { |
- // We know the element always throws if the return type was inferred to be |
- // non-null empty. |
- TypeMask returnType = returnTypeOf(element); |
- return returnType != null && returnType.isEmpty; |
- } |
- |
- /// Returns whether [element] is only called once in the entire program. |
- bool isCalledOnce(Element element) => _inferrer.isCalledOnce(element); |
- |
- // TODO(sigmund): introduce a new class [ElementInferenceResult] that can be |
- // used to collect any information that is specific about the body within a |
- // single element (basically everything below this line). We could consider |
- // moving some of the functions above too, for example: |
- // results.throwsAlways(element) |
- // could become: |
- // results[element].alwaysThrows; |
- // |
- |
- /// Returns the type of a list allocation [node] occuring within [owner]. |
- /// |
- /// [node] can be a list literal or a list new expression. |
- TypeMask typeOfNewList(Element owner, Node node) => |
- _inferrer.getTypeForNewList(owner, node); |
- |
- /// Returns whether a fixed-length constructor call goes through a growable |
- /// check. |
- bool isFixedArrayCheckedForGrowable(Node ctorCall) => |
- _inferrer.isFixedArrayCheckedForGrowable(ctorCall); |
- |
- /// Returns the type of a send [node]. |
- TypeMask typeOfSend( |
- Node node, |
- // TODO(sigmund): move inference data out of TreeElements |
- TreeElements elements) => |
- elements.getTypeMask(node); |
- |
- /// Returns the type of the operator of a complex send-set [node], for |
- /// example, the type of `+` in `a += b`. |
- TypeMask typeOfOperator(Send node, TreeElements elements) => |
- elements.getOperatorTypeMaskInComplexSendSet(node); |
- |
- /// Returns the type of the getter in a complex send-set [node], for example, |
- /// the type of the `a.f` getter in `a.f += b`. |
- TypeMask typeOfGetter(node, elements) => |
- elements.getOperatorTypeMaskInComplexSendSet(node); |
- |
- /// Returns the type of the iterator in a [loop]. |
- TypeMask typeOfIterator(ForIn loop, elements) => |
- elements.getIteratorTypeMask(loop); |
- |
- /// Returns the type of the `moveNext` call of an iterator in a [loop]. |
- TypeMask typeOfIteratorMoveNext(ForIn loop, elements) => |
- elements.getMoveNextTypeMask(loop); |
- |
- /// Returns the type of the `current` getter of an iterator in a [loop]. |
- TypeMask typeOfIteratorCurrent(ForIn node, elements) => |
- elements.getCurrentTypeMask(node); |
-} |
- |
/// Global analysis that infers concrete types. |
class GlobalTypeInferenceTask extends CompilerTask { |
// TODO(sigmund): rename at the same time as our benchmarking tools. |
@@ -130,7 +34,6 @@ class GlobalTypeInferenceTask extends CompilerTask { |
final Compiler compiler; |
TypesInferrer typesInferrer; |
CommonMasks masks; |
- GlobalTypeInferenceResults results; |
GlobalTypeInferenceTask(Compiler compiler) |
: masks = new CommonMasks(compiler), |
@@ -144,7 +47,59 @@ class GlobalTypeInferenceTask extends CompilerTask { |
measure(() { |
typesInferrer.analyzeMain(mainElement); |
typesInferrer.clear(); |
- results = new GlobalTypeInferenceResults(typesInferrer, compiler, masks); |
}); |
} |
+ |
+ /** |
+ * Return the (inferred) guaranteed type of [element] or null. |
+ */ |
+ TypeMask getGuaranteedTypeOfElement(Element element) { |
+ // TODO(24489): trust some JsInterop types. |
+ if (compiler.backend.isJsInterop(element)) { |
+ return masks.dynamicType; |
+ } |
+ TypeMask guaranteedType = typesInferrer.getTypeOfElement(element); |
+ return guaranteedType; |
+ } |
+ |
+ TypeMask getGuaranteedReturnTypeOfElement(Element element) { |
+ // TODO(24489): trust some JsInterop types. |
+ if (compiler.backend.isJsInterop(element)) { |
+ return masks.dynamicType; |
+ } |
+ |
+ TypeMask guaranteedType = typesInferrer.getReturnTypeOfElement(element); |
+ return guaranteedType; |
+ } |
+ |
+ /// Return whether the global inference algorithm determined that [element] |
+ /// always throws. |
+ bool throwsAlways(Element element) { |
+ // We know the element always throws if the return type was inferred to be |
+ // non-null empty. |
+ TypeMask returnType = getGuaranteedReturnTypeOfElement(element); |
+ return returnType != null && returnType.isEmpty; |
+ } |
+ |
+ bool isFixedArrayCheckedForGrowable(Node send) => |
+ typesInferrer.isFixedArrayCheckedForGrowable(send); |
+ |
+ bool isCalledOnce(Element element) => typesInferrer.isCalledOnce(element); |
+ |
+ /** |
+ * Return the (inferred) guaranteed type of [node] or null. |
+ * [node] must be an AST node of [owner]. |
+ */ |
+ TypeMask getGuaranteedTypeOfNode(owner, node) { |
+ TypeMask guaranteedType = typesInferrer.getTypeOfNode(owner, node); |
+ return guaranteedType; |
+ } |
+ |
+ /** |
+ * Return the (inferred) guaranteed type of [selector] or null. |
+ */ |
+ TypeMask getGuaranteedTypeOfSelector(Selector selector, TypeMask mask) { |
+ TypeMask guaranteedType = typesInferrer.getTypeOfSelector(selector, mask); |
+ return guaranteedType; |
+ } |
} |