blob: 80e52ef98c6c3c7773611a7da71e445bd1178de7 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library world_builder;
import 'dart:collection';
import '../common.dart';
import '../common/names.dart' show Identifiers;
import '../common/resolution.dart' show Resolution;
import '../common_elements.dart';
import '../constants/values.dart';
import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/resolution_types.dart';
import '../elements/types.dart';
import '../js_backend/backend.dart' show JavaScriptBackend;
import '../js_backend/constant_handler_javascript.dart'
show JavaScriptConstantCompiler;
import '../js_backend/native_data.dart' show NativeBasicData;
import '../universe/class_set.dart';
import '../universe/function_set.dart' show FunctionSetBuilder;
import '../util/enumset.dart';
import '../util/util.dart';
import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld;
import 'selector.dart' show Selector;
import 'use.dart'
part 'codegen_world_builder.dart';
part 'member_usage.dart';
part 'resolution_world_builder.dart';
/// The known constraint on receiver for a dynamic call site.
/// This can for instance be used to constrain this dynamic call to `foo` to
/// 'receivers of the exact instance `Bar`':
/// class Bar {
/// void foo() {}
/// }
/// main() => new Bar().foo();
abstract class ReceiverConstraint {
/// Returns whether [element] is a potential target when being
/// invoked on a receiver with this constraint. [selector] is used to ensure
/// library privacy is taken into account.
bool canHit(MemberElement element, Selector selector, World world);
/// Returns whether this [TypeMask] applied to [selector] can hit a
/// [noSuchMethod].
bool needsNoSuchMethodHandling(Selector selector, World world);
/// The combined constraints on receivers all the dynamic call sites of the same
/// selector.
/// For instance for these calls
/// class A {
/// foo(a, b) {}
/// }
/// class B {
/// foo(a, b) {}
/// }
/// class C {
/// foo(a, b) {}
/// }
/// new A().foo(a, b);
/// new B().foo(0, 42);
/// the selector constraints for dynamic calls to 'foo' with two positional
/// arguments could be 'receiver of exact instance `A` or `B`'.
abstract class SelectorConstraints {
/// Returns `true` if [selector] applies to [element] under these constraints
/// given the closed [world].
/// Consider for instance in this world:
/// class A {
/// foo(a, b) {}
/// }
/// class B {
/// foo(a, b) {}
/// }
/// new A().foo(a, b);
/// Ideally the selector constraints for calls `foo` with two positional
/// arguments apply to `` but ``.
bool applies(MemberElement element, Selector selector, World world);
/// Returns `true` if at least one of the receivers matching these constraints
/// in the closed [world] have no implementation matching [selector].
/// For instance for this code snippet
/// class A {}
/// class B { foo() {} }
/// m(b) => (b ? new A() : new B()).foo();
/// the potential receiver `new A()` has no implementation of `foo` and thus
/// needs to handle the call through its `noSuchMethod` handler.
bool needsNoSuchMethodHandling(Selector selector, World world);
/// A mutable [SelectorConstraints] used in [WorldBuilder].
abstract class UniverseSelectorConstraints extends SelectorConstraints {
/// Adds [constraint] to these selector constraints. Return `true` if the set
/// of potential receivers expanded due to the new constraint.
bool addReceiverConstraint(ReceiverConstraint constraint);
/// Strategy for computing the constraints on potential receivers of dynamic
/// call sites.
abstract class SelectorConstraintsStrategy {
/// Create a [UniverseSelectorConstraints] to represent the global receiver
/// constraints for dynamic call sites with [selector].
UniverseSelectorConstraints createSelectorConstraints(Selector selector);
class OpenWorldStrategy implements SelectorConstraintsStrategy {
const OpenWorldStrategy();
OpenWorldConstraints createSelectorConstraints(Selector selector) {
return new OpenWorldConstraints();
class OpenWorldConstraints extends UniverseSelectorConstraints {
bool isAll = false;
bool applies(Element element, Selector selector, World world) => isAll;
bool needsNoSuchMethodHandling(Selector selector, World world) => isAll;
bool addReceiverConstraint(ReceiverConstraint constraint) {
if (isAll) return false;
isAll = true;
return true;
String toString() {
if (isAll) {
return '<all>';
} else {
return '<none>';
/// The [WorldBuilder] is an auxiliary class used in the process of computing
/// the [ClosedWorld].
// TODO(johnniwinther): Move common implementation to a [WorldBuilderBase] when
// universes and worlds have been unified.
abstract class WorldBuilder {
/// All directly instantiated classes, that is, classes with a generative
/// constructor that has been called directly and not only through a
/// super-call.
// TODO(johnniwinther): Improve semantic precision.
Iterable<ClassEntity> get directlyInstantiatedClasses;
/// All types that are checked either through is, as or checked mode checks.
Iterable<DartType> get isChecks;
/// All directly instantiated types, that is, the types of the directly
/// instantiated classes.
// TODO(johnniwinther): Improve semantic precision.
Iterable<InterfaceType> get instantiatedTypes;
/// Registers that [type] is checked in this world builder. The unaliased type
/// is returned.
void registerIsCheck(DartType type);