// Copyright (c) 2016, 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 masks;

import '../common.dart';
import '../common/backend_api.dart' show BackendClasses;
import '../compiler.dart' show Compiler;
import '../constants/values.dart' show PrimitiveConstantValue;
import '../elements/elements.dart';
import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
import '../tree/tree.dart';
import '../universe/selector.dart' show Selector;
import '../universe/world_builder.dart'
    show
        ReceiverConstraint,
        UniverseSelectorConstraints,
        SelectorConstraintsStrategy;
import '../util/util.dart';
import '../world.dart' show ClassQuery, ClosedWorld;
import 'abstract_value_domain.dart' show AbstractValue;

part 'container_type_mask.dart';
part 'dictionary_type_mask.dart';
part 'flat_type_mask.dart';
part 'forwarding_type_mask.dart';
part 'map_type_mask.dart';
part 'type_mask.dart';
part 'union_type_mask.dart';
part 'value_type_mask.dart';

class CommonMasks {
  // TODO(sigmund): once we split out the backend common elements, depend
  // directly on those instead.
  final ClosedWorld closedWorld;

  CommonMasks(this.closedWorld);

  BackendClasses get backendClasses => closedWorld.backendClasses;

  TypeMask _dynamicType;
  TypeMask _nonNullType;
  TypeMask _nullType;
  TypeMask _intType;
  TypeMask _uint32Type;
  TypeMask _uint31Type;
  TypeMask _positiveIntType;
  TypeMask _doubleType;
  TypeMask _numType;
  TypeMask _boolType;
  TypeMask _functionType;
  TypeMask _listType;
  TypeMask _constListType;
  TypeMask _fixedListType;
  TypeMask _growableListType;
  TypeMask _mapType;
  TypeMask _constMapType;
  TypeMask _stringType;
  TypeMask _typeType;
  TypeMask _syncStarIterableType;
  TypeMask _asyncFutureType;
  TypeMask _asyncStarStreamType;
  TypeMask _indexablePrimitiveType;
  TypeMask _readableArrayType;
  TypeMask _mutableArrayType;
  TypeMask _fixedArrayType;
  TypeMask _extendableArrayType;
  TypeMask _unmodifiableArrayType;
  TypeMask _interceptorType;

  TypeMask get dynamicType => _dynamicType ??=
      new TypeMask.subclass(closedWorld.coreClasses.objectClass, closedWorld);

  TypeMask get nonNullType => _nonNullType ??= new TypeMask.nonNullSubclass(
      closedWorld.coreClasses.objectClass, closedWorld);

  TypeMask get intType => _intType ??= new TypeMask.nonNullSubclass(
      backendClasses.intImplementation, closedWorld);

  TypeMask get uint32Type => _uint32Type ??= new TypeMask.nonNullSubclass(
      backendClasses.uint32Implementation, closedWorld);

  TypeMask get uint31Type => _uint31Type ??= new TypeMask.nonNullExact(
      backendClasses.uint31Implementation, closedWorld);

  TypeMask get positiveIntType =>
      _positiveIntType ??= new TypeMask.nonNullSubclass(
          backendClasses.positiveIntImplementation, closedWorld);

  TypeMask get doubleType => _doubleType ??= new TypeMask.nonNullExact(
      backendClasses.doubleImplementation, closedWorld);

  TypeMask get numType => _numType ??= new TypeMask.nonNullSubclass(
      backendClasses.numImplementation, closedWorld);

  TypeMask get boolType => _boolType ??=
      new TypeMask.nonNullExact(backendClasses.boolImplementation, closedWorld);

  TypeMask get functionType => _functionType ??= new TypeMask.nonNullSubtype(
      backendClasses.functionImplementation, closedWorld);

  TypeMask get listType => _listType ??=
      new TypeMask.nonNullExact(backendClasses.listImplementation, closedWorld);

  TypeMask get constListType => _constListType ??= new TypeMask.nonNullExact(
      backendClasses.constListImplementation, closedWorld);

  TypeMask get fixedListType => _fixedListType ??= new TypeMask.nonNullExact(
      backendClasses.fixedListImplementation, closedWorld);

  TypeMask get growableListType =>
      _growableListType ??= new TypeMask.nonNullExact(
          backendClasses.growableListImplementation, closedWorld);

  TypeMask get mapType => _mapType ??= new TypeMask.nonNullSubtype(
      backendClasses.mapImplementation, closedWorld);

  TypeMask get constMapType => _constMapType ??= new TypeMask.nonNullSubtype(
      backendClasses.constMapImplementation, closedWorld);

  TypeMask get stringType => _stringType ??= new TypeMask.nonNullExact(
      backendClasses.stringImplementation, closedWorld);

  TypeMask get typeType => _typeType ??=
      new TypeMask.nonNullExact(backendClasses.typeImplementation, closedWorld);

  TypeMask get syncStarIterableType =>
      _syncStarIterableType ??= new TypeMask.nonNullExact(
          backendClasses.syncStarIterableImplementation, closedWorld);

  TypeMask get asyncFutureType =>
      _asyncFutureType ??= new TypeMask.nonNullExact(
          backendClasses.asyncFutureImplementation, closedWorld);

  TypeMask get asyncStarStreamType =>
      _asyncStarStreamType ??= new TypeMask.nonNullExact(
          backendClasses.asyncStarStreamImplementation, closedWorld);

  // TODO(johnniwinther): Assert that the null type has been resolved.
  TypeMask get nullType => _nullType ??= const TypeMask.empty();

  TypeMask get emptyType => const TypeMask.nonNullEmpty();

  TypeMask get indexablePrimitiveType =>
      _indexablePrimitiveType ??= new TypeMask.nonNullSubtype(
          backendClasses.indexableImplementation, closedWorld);

  TypeMask get readableArrayType =>
      _readableArrayType ??= new TypeMask.nonNullSubclass(
          backendClasses.listImplementation, closedWorld);

  TypeMask get mutableArrayType =>
      _mutableArrayType ??= new TypeMask.nonNullSubclass(
          backendClasses.mutableListImplementation, closedWorld);

  TypeMask get fixedArrayType => _fixedArrayType ??= new TypeMask.nonNullExact(
      backendClasses.fixedListImplementation, closedWorld);

  TypeMask get extendableArrayType =>
      _extendableArrayType ??= new TypeMask.nonNullExact(
          backendClasses.growableListImplementation, closedWorld);

  TypeMask get unmodifiableArrayType =>
      _unmodifiableArrayType ??= new TypeMask.nonNullExact(
          backendClasses.constListImplementation, closedWorld);

  TypeMask get interceptorType =>
      _interceptorType ??= new TypeMask.nonNullSubclass(
          backendClasses.interceptorImplementation, closedWorld);

  bool isTypedArray(TypeMask mask) {
    // Just checking for [:TypedData:] is not sufficient, as it is an
    // abstract class any user-defined class can implement. So we also
    // check for the interface [JavaScriptIndexingBehavior].
    ClassElement typedDataClass = closedWorld.commonElements.typedDataClass;
    return typedDataClass != null &&
        closedWorld.isInstantiated(typedDataClass) &&
        mask.satisfies(typedDataClass, closedWorld) &&
        mask.satisfies(
            closedWorld.backendClasses.indexingBehaviorImplementation,
            closedWorld);
  }

  bool couldBeTypedArray(TypeMask mask) {
    bool intersects(TypeMask type1, TypeMask type2) =>
        !type1.intersection(type2, closedWorld).isEmpty;
    // TODO(herhut): Maybe cache the TypeMask for typedDataClass and
    //               jsIndexingBehaviourInterface.
    ClassElement typedDataClass = closedWorld.commonElements.typedDataClass;
    return typedDataClass != null &&
        closedWorld.isInstantiated(typedDataClass) &&
        intersects(mask, new TypeMask.subtype(typedDataClass, closedWorld)) &&
        intersects(
            mask,
            new TypeMask.subtype(
                closedWorld.backendClasses.indexingBehaviorImplementation,
                closedWorld));
  }
}
