mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 03:32:23 +03:00
Use TypeOfNode.findAllTypes to get all types associated with a value
This commit is contained in:
parent
abf68c0372
commit
87e738b779
@ -68,6 +68,7 @@ public final class EnsoMultiValue extends EnsoObject {
|
|||||||
return types[0];
|
return types[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExportMessage
|
||||||
public final Type[] allTypes() {
|
public final Type[] allTypes() {
|
||||||
return types.clone();
|
return types.clone();
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,7 @@ public final class Type extends EnsoObject {
|
|||||||
* @param ctx contexts to get Any type (common super class) from
|
* @param ctx contexts to get Any type (common super class) from
|
||||||
* @return a compilation constant array with all types this type represents
|
* @return a compilation constant array with all types this type represents
|
||||||
*/
|
*/
|
||||||
|
@ExportMessage.Ignore
|
||||||
public final Type[] allTypes(EnsoContext ctx) {
|
public final Type[] allTypes(EnsoContext ctx) {
|
||||||
var types = new Type[3];
|
var types = new Type[3];
|
||||||
var realCount = fillInTypes(this, types, ctx);
|
var realCount = fillInTypes(this, types, ctx);
|
||||||
|
@ -50,7 +50,12 @@ public abstract class TypeOfNode extends Node {
|
|||||||
* @return either {@link Type} of the value or {@link DataflowError} if there is no such type
|
* @return either {@link Type} of the value or {@link DataflowError} if there is no such type
|
||||||
*/
|
*/
|
||||||
public final Object findTypeOrError(Object value) {
|
public final Object findTypeOrError(Object value) {
|
||||||
return executeSingleType(value);
|
try {
|
||||||
|
var types = executeTypes(value);
|
||||||
|
return types[0];
|
||||||
|
} catch (NonTypeResult plain) {
|
||||||
|
return plain.result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,58 +69,90 @@ public abstract class TypeOfNode extends Node {
|
|||||||
return findTypeOrError(value) instanceof Type type ? type : null;
|
return findTypeOrError(value) instanceof Type type ? type : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Object executeSingleType(Object value);
|
/**
|
||||||
|
* Finds all types associated with a given {@code value} or returns {@code null}. It is guaranteed
|
||||||
|
* that the returned array is going to have at least one element, if it is non-{@code null}.
|
||||||
|
*
|
||||||
|
* @param value the value to check
|
||||||
|
* @return either types associated with the value or {@code null} if there is no such type
|
||||||
|
*/
|
||||||
|
public final Type[] findAllTypes(Object value) {
|
||||||
|
try {
|
||||||
|
var types = executeTypes(value);
|
||||||
|
assert types != null && types.length > 0;
|
||||||
|
return types;
|
||||||
|
} catch (NonTypeResult ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Creates new optimizing instance of this node. */
|
/**
|
||||||
|
* Internal implementation call to delegate to various {@link Specialization} methods.
|
||||||
|
*
|
||||||
|
* @param value the value to find type for
|
||||||
|
* @return array of types with at least one element, but possibly more
|
||||||
|
* @throws NonTypeResult when there is a <em>interop value</em> result, but it is not a {@link
|
||||||
|
* Type}
|
||||||
|
*/
|
||||||
|
abstract Type[] executeTypes(Object value) throws NonTypeResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new optimizing instance of this node.
|
||||||
|
*
|
||||||
|
* @return new instance of this node ready to be <em>specialized</em>
|
||||||
|
*/
|
||||||
@NeverDefault
|
@NeverDefault
|
||||||
public static TypeOfNode create() {
|
public static TypeOfNode create() {
|
||||||
return TypeOfNodeGen.create();
|
return TypeOfNodeGen.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns default, non-optimizing implementation of this node. */
|
/**
|
||||||
|
* Returns default, non-optimizing implementation of this node.
|
||||||
|
*
|
||||||
|
* @return shared singleton instance of this node
|
||||||
|
*/
|
||||||
@NeverDefault
|
@NeverDefault
|
||||||
public static TypeOfNode getUncached() {
|
public static TypeOfNode getUncached() {
|
||||||
return TypeOfNodeGen.getUncached();
|
return TypeOfNodeGen.getUncached();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
private static Type[] fromType(Type single) {
|
||||||
Object doUnresolvedSymbol(UnresolvedSymbol value) {
|
return new Type[] {single};
|
||||||
return EnsoContext.get(this).getBuiltins().function();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doDouble(double value) {
|
Type[] doUnresolvedSymbol(UnresolvedSymbol value) {
|
||||||
return EnsoContext.get(this).getBuiltins().number().getFloat();
|
return fromType(EnsoContext.get(this).getBuiltins().function());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doLong(long value) {
|
Type[] doDouble(double value) {
|
||||||
return EnsoContext.get(this).getBuiltins().number().getInteger();
|
return fromType(EnsoContext.get(this).getBuiltins().number().getFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doBigInteger(EnsoBigInteger value) {
|
Type[] doLong(long value) {
|
||||||
return EnsoContext.get(this).getBuiltins().number().getInteger();
|
return fromType(EnsoContext.get(this).getBuiltins().number().getInteger());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doPanicException(PanicException value) {
|
Type[] doBigInteger(EnsoBigInteger value) {
|
||||||
return EnsoContext.get(this).getBuiltins().panic();
|
return fromType(EnsoContext.get(this).getBuiltins().number().getInteger());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doPanicSentinel(PanicSentinel value) {
|
Type[] doPanicException(PanicException value) {
|
||||||
return EnsoContext.get(this).getBuiltins().panic();
|
return fromType(EnsoContext.get(this).getBuiltins().panic());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doWarning(WithWarnings value, @Cached TypeOfNode withoutWarning) {
|
Type[] doPanicSentinel(PanicSentinel value) {
|
||||||
return withoutWarning.executeSingleType(value.getValue());
|
return fromType(EnsoContext.get(this).getBuiltins().panic());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
Object doEnsoMultiValue(EnsoMultiValue value) {
|
Type[] doWarning(WithWarnings value, @Cached TypeOfNode withoutWarning) throws NonTypeResult {
|
||||||
return value.allTypes()[0];
|
return withoutWarning.executeTypes(value.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isWithType(Object value, TypesLibrary types, InteropLibrary iop) {
|
static boolean isWithType(Object value, TypesLibrary types, InteropLibrary iop) {
|
||||||
@ -139,32 +176,40 @@ public abstract class TypeOfNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Specialization(guards = {"isWithoutType(value, types)"})
|
@Specialization(guards = {"isWithoutType(value, types)"})
|
||||||
Object withoutType(
|
Type[] withoutType(
|
||||||
Object value,
|
Object value,
|
||||||
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop,
|
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop,
|
||||||
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types,
|
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types,
|
||||||
@Cached WithoutType delegate) {
|
@Cached WithoutType delegate)
|
||||||
var type = WithoutType.Interop.resolve(value, interop);
|
throws NonTypeResult {
|
||||||
return delegate.execute(type, value);
|
var kind = WithoutType.Interop.resolve(value, interop);
|
||||||
|
var typeOrPlain = delegate.execute(kind, value);
|
||||||
|
if (typeOrPlain instanceof Type type) {
|
||||||
|
return fromType(type);
|
||||||
|
} else {
|
||||||
|
throw new NonTypeResult(typeOrPlain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization(guards = {"isWithType(value, types, interop)"})
|
@Specialization(guards = {"isWithType(value, types, interop)"})
|
||||||
Object doType(
|
Type[] doType(
|
||||||
Object value,
|
Object value,
|
||||||
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop,
|
@Shared("interop") @CachedLibrary(limit = "3") InteropLibrary interop,
|
||||||
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types) {
|
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types) {
|
||||||
return types.getType(value);
|
return types.allTypes(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Fallback
|
@Fallback
|
||||||
@CompilerDirectives.TruffleBoundary
|
@CompilerDirectives.TruffleBoundary
|
||||||
Object doAny(Object value) {
|
Type[] doAny(Object value) throws NonTypeResult {
|
||||||
return DataflowError.withDefaultTrace(
|
var err =
|
||||||
EnsoContext.get(this)
|
DataflowError.withDefaultTrace(
|
||||||
.getBuiltins()
|
EnsoContext.get(this)
|
||||||
.error()
|
.getBuiltins()
|
||||||
.makeCompileError("unknown type_of for " + value),
|
.error()
|
||||||
this);
|
.makeCompileError("unknown type_of for " + value),
|
||||||
|
this);
|
||||||
|
throw new NonTypeResult(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GenerateUncached
|
@GenerateUncached
|
||||||
@ -352,4 +397,17 @@ public abstract class TypeOfNode extends Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final class NonTypeResult extends Exception {
|
||||||
|
final Object result;
|
||||||
|
|
||||||
|
NonTypeResult(Object result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Throwable fillInStackTrace() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,4 +68,17 @@ public abstract class TypesLibrary extends Library {
|
|||||||
public Type getType(Object receiver) {
|
public Type getType(Object receiver) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the receiver types. Default implementation delegates to {@link
|
||||||
|
* #getType(java.lang.Object)} and returns array with one element of that type
|
||||||
|
*
|
||||||
|
* @param receiver the typed object
|
||||||
|
* @return the corresponding types for the {@code receiver}
|
||||||
|
*/
|
||||||
|
public Type[] allTypes(Object receiver) {
|
||||||
|
var t = getType(receiver);
|
||||||
|
assert t != null : "null type for " + receiver;
|
||||||
|
return new Type[] {t};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user