blob: 93a522e7714551a0920e3ea35359b04d592e90aa [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.android.jack.ir.ast;
import com.android.jack.Jack;
import com.android.jack.ir.SourceInfo;
import com.android.jack.ir.SourceOrigin;
import com.android.jack.ir.types.JFloatingPointType;
import com.android.jack.ir.types.JIntegralType32;
import com.android.jack.ir.types.JIntegralType64;
import com.android.jack.lookup.CommonTypes;
import com.android.jack.lookup.CommonTypes.CommonType;
import com.android.jack.lookup.JPhantomLookup;
import com.android.sched.item.Component;
import com.android.sched.item.Description;
import com.android.sched.scheduler.ScheduleInstance;
import com.android.sched.transform.TransformRequest;
import javax.annotation.Nonnull;
/**
* Base class for all Java primitive types.
*/
@Description("Java primitive types")
public abstract class JPrimitiveType extends JNode implements JType {
private static final long serialVersionUID = 1L;
/**
* This enum represents all primitive types.
*/
public enum JPrimitiveTypeEnum {
BOOLEAN(new JPrimitiveType.JBooleanType()),
BYTE(new JPrimitiveType.JByteType()),
CHAR(new JPrimitiveType.JCharType()),
DOUBLE(new JPrimitiveType.JDoubleType()),
FLOAT(new JPrimitiveType.JFloatType()),
INT(new JPrimitiveType.JIntType()),
LONG(new JPrimitiveType.JLongType()),
SHORT(new JPrimitiveType.JShortType()),
VOID(new JPrimitiveType.JVoidType());
@Nonnull
private final JPrimitiveType type;
private JPrimitiveTypeEnum(@Nonnull JPrimitiveType type) {
this.type = type;
}
@Nonnull
public JPrimitiveType getType() {
return type;
}
}
@Nonnull
protected final String name;
private JPrimitiveType(@Nonnull String name, @Nonnull String signatureName) {
super(SourceOrigin.UNKNOWN);
this.name = name;
}
@Nonnull
// Section Unary Numeric Promotion (JLS-7 5.6.1)
public static JType getUnaryPromotion(@Nonnull JType argType) throws AssertionError {
JType promotedType;
if (JPrimitiveTypeEnum.BYTE.getType().isEquivalent(argType)
|| JPrimitiveTypeEnum.CHAR.getType().isEquivalent(argType)
|| JPrimitiveTypeEnum.SHORT.getType().isEquivalent(argType)
|| JPrimitiveTypeEnum.INT.getType().isEquivalent(argType)) {
promotedType = JPrimitiveTypeEnum.INT.getType();
} else if (JPrimitiveTypeEnum.FLOAT.getType().isEquivalent(argType)) {
promotedType = JPrimitiveTypeEnum.FLOAT.getType();
} else if (JPrimitiveTypeEnum.LONG.getType().isEquivalent(argType)) {
promotedType = JPrimitiveTypeEnum.LONG.getType();
} else if (JPrimitiveTypeEnum.DOUBLE.getType().isEquivalent(argType)) {
promotedType = JPrimitiveTypeEnum.DOUBLE.getType();
} else {
throw new AssertionError();
}
return promotedType;
}
@Nonnull
// Section Binary Numeric Promotion (JLS-7 5.6.2)
public static JType getBinaryPromotionType(@Nonnull JType lhsType, @Nonnull JType rhsType) {
JType promotedType;
assert JPrimitiveTypeEnum.BYTE.getType().isEquivalent(lhsType)
|| JPrimitiveTypeEnum.CHAR.getType().isEquivalent(lhsType)
|| JPrimitiveTypeEnum.SHORT.getType().isEquivalent(lhsType)
|| JPrimitiveTypeEnum.INT.getType().isEquivalent(lhsType)
|| JPrimitiveTypeEnum.FLOAT.getType().isEquivalent(lhsType)
|| JPrimitiveTypeEnum.LONG.getType().isEquivalent(lhsType)
|| JPrimitiveTypeEnum.DOUBLE.getType().isEquivalent(lhsType);
assert JPrimitiveTypeEnum.BYTE.getType().isEquivalent(rhsType)
|| JPrimitiveTypeEnum.CHAR.getType().isEquivalent(rhsType)
|| JPrimitiveTypeEnum.SHORT.getType().isEquivalent(rhsType)
|| JPrimitiveTypeEnum.INT.getType().isEquivalent(rhsType)
|| JPrimitiveTypeEnum.FLOAT.getType().isEquivalent(rhsType)
|| JPrimitiveTypeEnum.LONG.getType().isEquivalent(rhsType)
|| JPrimitiveTypeEnum.DOUBLE.getType().isEquivalent(rhsType);
if ((lhsType == JPrimitiveTypeEnum.DOUBLE.getType())
|| (rhsType == JPrimitiveTypeEnum.DOUBLE.getType())
|| CommonTypes.isCommonType(CommonTypes.JAVA_LANG_DOUBLE, lhsType)
|| CommonTypes.isCommonType(CommonTypes.JAVA_LANG_DOUBLE, rhsType)) {
promotedType = JPrimitiveTypeEnum.DOUBLE.getType();
} else if ((lhsType == JPrimitiveTypeEnum.FLOAT.getType())
|| (rhsType == JPrimitiveTypeEnum.FLOAT.getType())
|| CommonTypes.isCommonType(CommonTypes.JAVA_LANG_FLOAT, lhsType)
|| CommonTypes.isCommonType(CommonTypes.JAVA_LANG_FLOAT, rhsType)) {
promotedType = JPrimitiveTypeEnum.FLOAT.getType();
} else if ((lhsType == JPrimitiveTypeEnum.LONG.getType())
|| (rhsType == JPrimitiveTypeEnum.LONG.getType())
|| CommonTypes.isCommonType(CommonTypes.JAVA_LANG_LONG, lhsType)
|| CommonTypes.isCommonType(CommonTypes.JAVA_LANG_LONG, rhsType)) {
promotedType = JPrimitiveTypeEnum.LONG.getType();
} else {
promotedType = JPrimitiveTypeEnum.INT.getType();
}
return promotedType;
}
@Override
public boolean isExternal() {
return false;
}
@Override
public String getName() {
return name;
}
@Nonnull
public final JClass getWrapperType() {
return Jack.getSession().getPhantomLookup().getClass(getWrapperCommonType());
}
public boolean isWrapperType(@Nonnull JType candidate) {
JPhantomLookup lookup = Jack.getSession().getPhantomLookup();
return lookup.getClass(getWrapperCommonType()) == candidate
|| lookup.getType(getWrapperCommonType()) == candidate;
}
@Nonnull
public abstract JPrimitiveTypeEnum getPrimitiveTypeEnum();
public boolean isEquivalent(JType type) {
return this == type || isWrapperType(type);
}
@Override
public void traverse(@Nonnull JVisitor visitor) {
if (visitor.visit(this)) {
}
visitor.endVisit(this);
}
@Override
public void traverse(@Nonnull ScheduleInstance<? super Component> schedule) throws Exception {
schedule.process(this);
}
@Override
@Nonnull
public JArrayType getArray() {
return Jack.getSession().getArrayOf(getPrimitiveTypeEnum());
}
@Nonnull
abstract CommonType getWrapperCommonType();
/**
* Java boolean type
*/
@Description("Java boolean type")
public static class JBooleanType extends JPrimitiveType {
private static final long serialVersionUID = 1L;
private JBooleanType() {
super("boolean", "Z");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.BOOLEAN;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JBooleanLiteral(sourceInfo, false);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_BOOLEAN;
}
}
/**
* Java byte type
*/
@Description("Java byte type")
public static class JByteType extends JPrimitiveType implements JIntegralType32 {
private static final long serialVersionUID = 1L;
private JByteType() {
super("byte", "B");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.BYTE;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JByteLiteral(sourceInfo, (byte) 0);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_BYTE;
}
@Override
public boolean isValidValue(int value) {
return (Byte.MIN_VALUE <= value) && (value <= Byte.MAX_VALUE);
}
}
/**
* Java char type
*/
@Description("Java char type")
public static class JCharType extends JPrimitiveType implements JIntegralType32 {
private static final long serialVersionUID = 1L;
private JCharType() {
super("char", "C");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.CHAR;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JCharLiteral(sourceInfo, (char) 0);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_CHAR;
}
@Override
public boolean isValidValue(int value) {
return (Character.MIN_VALUE <= value) && (value <= Character.MAX_VALUE);
}
}
/**
* Java double type
*/
@Description("Java double type")
public static class JDoubleType extends JPrimitiveType implements JFloatingPointType {
private static final long serialVersionUID = 1L;
private JDoubleType() {
super("double", "D");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.DOUBLE;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JDoubleLiteral(sourceInfo, 0.0);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_DOUBLE;
}
}
/**
* Java float type
*/
@Description("Java float type")
public static class JFloatType extends JPrimitiveType implements JFloatingPointType {
private static final long serialVersionUID = 1L;
private JFloatType() {
super("float", "F");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.FLOAT;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JFloatLiteral(sourceInfo, 0.0f);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_FLOAT;
}
}
/**
* Java int type
*/
@Description("Java int type")
public static class JIntType extends JPrimitiveType implements JIntegralType32 {
private static final long serialVersionUID = 1L;
private JIntType() {
super("int", "I");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.INT;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JIntLiteral(sourceInfo, 0);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_INTEGER;
}
@Override
public boolean isValidValue(int value) {
return true;
}
}
/**
* Java long type
*/
@Description("Java long type")
public static class JLongType extends JPrimitiveType implements JIntegralType64 {
private static final long serialVersionUID = 1L;
private JLongType() {
super("long", "J");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.LONG;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JLongLiteral(sourceInfo, 0L);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_LONG;
}
}
/**
* Java short type
*/
@Description("Java short type")
public static class JShortType extends JPrimitiveType implements JIntegralType32 {
private static final long serialVersionUID = 1L;
private JShortType() {
super("short", "S");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.SHORT;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
return new JShortLiteral(sourceInfo, (short) 0);
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_SHORT;
}
@Override
public boolean isValidValue(int value) {
return (Short.MIN_VALUE <= value) && (value <= Short.MAX_VALUE);
}
}
/**
* Java void type
*/
@Description("Java void type")
public static class JVoidType extends JPrimitiveType {
private static final long serialVersionUID = 1L;
private JVoidType() {
super("void", "V");
}
@Override
@Nonnull
public JPrimitiveTypeEnum getPrimitiveTypeEnum() {
return JPrimitiveTypeEnum.VOID;
}
@Override
public void visit(@Nonnull JVisitor visitor, @Nonnull TransformRequest transformRequest)
throws Exception {
visitor.visit(this, transformRequest);
}
@Nonnull
@Override
public JExpression createDefaultValue(@Nonnull SourceInfo sourceInfo) {
throw new AssertionError();
}
@Override
@Nonnull
CommonType getWrapperCommonType() {
return CommonTypes.JAVA_LANG_VOID;
}
@Override
@Nonnull
public JArrayType getArray() {
// Array of void does not exist.
throw new AssertionError();
}
}
}