| 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;
|
| + }
|
| }
|
|
|