@Override protected Location locationForValueUpcast(Object value, Location oldLocation) { assert !(value instanceof Class); if (oldLocation instanceof DualLocation) { DualLocation dualLocation = (DualLocation) oldLocation; if (dualLocation.getType() == null) { if (value instanceof Integer) { return dualLocation.changeType(int.class); } else if (value instanceof Double) { return dualLocation.changeType(double.class); } else if (value instanceof Long) { return dualLocation.changeType(long.class); } else if (value instanceof Boolean) { return dualLocation.changeType(boolean.class); } else { return dualLocation.changeType(Object.class); } } else if (dualLocation.getType().isPrimitive()) { return dualLocation.changeType(Object.class); } else { throw new UnsupportedOperationException(); } } else if (oldLocation instanceof ConstantLocation) { return constantLocation(value); } else { throw new UnsupportedOperationException(); } }
@Override public boolean equals(Object obj) { return super.equals(obj) && Objects.equals(defaultValue, ((DeclaredDualLocation) obj).defaultValue); }
@Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + (getObjectLocation() == null ? 0 : getObjectLocation().hashCode()); result = prime * result + (primitiveLocation == null ? 0 : primitiveLocation.hashCode()); result = prime * result + (type == null ? 0 : type.hashCode()); return result; }
@Override public void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException { if (type == Object.class) { ((LocationImpl) objectLocation).setInternal(store, value); } else { long rawValue; if (type == int.class && value instanceof Integer) { rawValue = (int) value; } else if (type == long.class && value instanceof Long) { rawValue = (long) value; } else if (type == long.class && layout.isAllowedIntToLong() && value instanceof Integer) { rawValue = (int) value; } else if (type == double.class && value instanceof Double) { rawValue = Double.doubleToRawLongBits((double) value); } else if (type == double.class && layout.isAllowedIntToDouble() && value instanceof Integer) { rawValue = Double.doubleToRawLongBits((int) value); } else if (type == boolean.class && value instanceof Boolean) { rawValue = (boolean) value ? 1 : 0; } else { throw incompatibleLocation(); } primitiveLocation.setLongInternal(store, rawValue); } }
@Override protected Location moveLocation(Location oldLocation) { if (oldLocation instanceof DeclaredDualLocation) { return advance(newDeclaredDualLocation(((DeclaredDualLocation) oldLocation).get(null, false))); } else if (oldLocation instanceof DualLocation) { return advance(newDualLocation(((DualLocation) oldLocation).getType())); } else if (oldLocation instanceof LongLocation) { return newLongLocation(oldLocation.isFinal()); } else if (oldLocation instanceof IntLocation) { return newIntLocation(oldLocation.isFinal()); } else if (oldLocation instanceof DoubleLocation) { return newDoubleLocation(oldLocation.isFinal()); } else if (oldLocation instanceof BooleanLocation) { return newBooleanLocation(oldLocation.isFinal()); } else if (oldLocation instanceof ObjectLocation) { return newObjectLocation(oldLocation.isFinal(), ((ObjectLocation) oldLocation).isNonNull()); } else { assert oldLocation instanceof ValueLocation; return advance(oldLocation); } }
protected Location newDualLocation(Class<?> type) { return new DualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), layout, type); }
public DualLocation changeType(Class<?> newType) { return new DualLocation(primitiveLocation, objectLocation, layout, newType); }
@Override public DualLocation changeType(Class<?> newType) { return new DualLocation(primitiveLocation, objectLocation, layout, newType); }
protected DualLocation newDualLocationForValue(Object value) { Class<?> initialType = null; if (value instanceof Integer) { initialType = int.class; } else if (value instanceof Double) { initialType = double.class; } else if (value instanceof Boolean) { initialType = boolean.class; } else { initialType = Object.class; } return new DualLocation((InternalLongLocation) newLongLocation(false), (ObjectLocation) newObjectLocation(false, false), layout, initialType); }
@Override public int hashCode() { return super.hashCode(); }
@Override protected int objectFieldIndex(Location location) { if (location instanceof DualLocation) { return objectFieldIndex((Location) ((DualLocation) location).getObjectLocation()); } else if (location instanceof ObjectFieldLocation) { return ((ObjectFieldLocation) location).getIndex(); } else if (location instanceof SimpleObjectFieldLocation) { return ((SimpleObjectFieldLocation) location).getIndex(); } else { return 0; } } }
@Override public boolean equals(Object obj) { if (!super.equals(obj)) { return false; } DualLocation other = (DualLocation) obj; return getObjectLocation().equals(other.getObjectLocation()) && primitiveLocation.equals(other.primitiveLocation) && layout.equals(other.layout) && Objects.equals(type, other.type); }