// Copyright (c) 2014, 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 types.constants;

import '../common.dart';
import '../constants/constant_system.dart' show ConstantSystem;
import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../js_backend/js_backend.dart'
    show JavaScriptBackend, SyntheticConstantKind;
import '../world.dart' show ClosedWorld;
import 'masks.dart';

/// Computes the [TypeMask] for the constant [value].
TypeMask computeTypeMask(ClosedWorld closedWorld, ConstantValue value) {
  return value.accept(const ConstantValueTypeMasks(), closedWorld);
}

class ConstantValueTypeMasks
    extends ConstantValueVisitor<TypeMask, ClosedWorld> {
  const ConstantValueTypeMasks();

  @override
  TypeMask visitConstructed(
      ConstructedConstantValue constant, ClosedWorld closedWorld) {
    if (closedWorld.backendClasses.isInterceptorClass(constant.type.element)) {
      return closedWorld.commonMasks.nonNullType;
    }
    return new TypeMask.nonNullExact(constant.type.element, closedWorld);
  }

  @override
  TypeMask visitDeferred(
      DeferredConstantValue constant, ClosedWorld closedWorld) {
    return constant.referenced.accept(this, closedWorld);
  }

  @override
  TypeMask visitDouble(DoubleConstantValue constant, ClosedWorld closedWorld) {
    // We have to recognize double constants that are 'is int'.
    if (closedWorld.constantSystem.isInt(constant)) {
      if (constant.isMinusZero) {
        return closedWorld.commonMasks.uint31Type;
      } else {
        assert(constant.isPositiveInfinity || constant.isNegativeInfinity);
        return closedWorld.commonMasks.intType;
      }
    }
    return closedWorld.commonMasks.doubleType;
  }

  @override
  TypeMask visitSynthetic(
      SyntheticConstantValue constant, ClosedWorld closedWorld) {
    switch (constant.valueKind) {
      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
        return constant.payload;
      case SyntheticConstantKind.EMPTY_VALUE:
        return constant.payload;
      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
        return closedWorld.commonMasks.intType;
      case SyntheticConstantKind.NAME:
        return closedWorld.commonMasks.stringType;
      default:
        throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
            "Unexpected DummyConstantKind: ${constant.toStructuredText()}.");
    }
  }

  @override
  TypeMask visitBool(BoolConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.boolType;
  }

  @override
  TypeMask visitFunction(
      FunctionConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.functionType;
  }

  @override
  TypeMask visitInt(IntConstantValue constant, ClosedWorld closedWorld) {
    if (constant.isUInt31()) return closedWorld.commonMasks.uint31Type;
    if (constant.isUInt32()) return closedWorld.commonMasks.uint32Type;
    if (constant.isPositive()) return closedWorld.commonMasks.positiveIntType;
    return closedWorld.commonMasks.intType;
  }

  @override
  TypeMask visitInterceptor(
      InterceptorConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.nonNullType;
  }

  @override
  TypeMask visitList(ListConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.constListType;
  }

  @override
  TypeMask visitMap(MapConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.constMapType;
  }

  @override
  TypeMask visitNull(NullConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.nullType;
  }

  @override
  TypeMask visitNonConstant(
      NonConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.nullType;
  }

  @override
  TypeMask visitString(StringConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.stringType;
  }

  @override
  TypeMask visitType(TypeConstantValue constant, ClosedWorld closedWorld) {
    return closedWorld.commonMasks.typeType;
  }
}
