Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

case of and intersection types #11850

Merged
merged 9 commits into from
Dec 13, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ private String[] typeOf(Object value) {
}

var typeOfNode = TypeOfNode.getUncached();
Type[] allTypes = value == null ? null : typeOfNode.findAllTypesOrNull(value);
Type[] allTypes = value == null ? null : typeOfNode.findAllTypesOrNull(value, true);
if (allTypes != null) {
String[] result = new String[allTypes.length];
for (var i = 0; i < allTypes.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,13 @@ final Object doThatConversionUncached(
InvokeFunctionNode invokeNode) {
var selfType = findType(typeOfNode, self);
if (that instanceof EnsoMultiValue multi) {
var all = typeOfNode.findAllTypesOrNull(multi);
var all = typeOfNode.findAllTypesOrNull(multi, false);
assert all != null;
for (var thatType : all) {
var fn = findSymbol(symbol, thatType);
if (fn != null) {
var thatCasted =
EnsoMultiValue.CastToNode.getUncached()
.findTypeOrNull(thatType, multi, false, false);
if (thatCasted == null) {
continue;
}
var result =
doDispatch(
frame, self, thatCasted, selfType, thatType, fn, convertNode, invokeNode);
doDispatch(frame, self, multi, selfType, thatType, fn, convertNode, invokeNode);
if (result != null) {
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static CatchTypeBranchNode build(
}

public void execute(VirtualFrame frame, Object state, Object value) {
if (profile.profile(isValueOfTypeNode.execute(expectedType, value))) {
if (profile.profile(isValueOfTypeNode.execute(expectedType, value, true))) {
accept(frame, state, new Object[] {value});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private Object executeCallbackOrRethrow(
AbstractTruffleException originalException,
InteropLibrary interopLibrary) {

if (profile.profile(isValueOfTypeNode.execute(panicType, payload))) {
if (profile.profile(isValueOfTypeNode.execute(panicType, payload, true))) {
var builtins = EnsoContext.get(this).getBuiltins();
var cons = builtins.caughtPanic().getUniqueConstructor();
var caughtPanic =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ EqualsAndInfo equalsMultiValue(
@Shared("multiCast") @Cached EnsoMultiValue.CastToNode castNode,
@Shared("multiType") @Cached TypeOfNode typesNode,
@Shared("multiEquals") @Cached EqualsSimpleNode delegate) {
var types = typesNode.findAllTypesOrNull(self);
var types = typesNode.findAllTypesOrNull(self, false);
assert types != null;
for (var t : types) {
var value = castNode.findTypeOrNull(t, self, false, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public class IsANode extends Node {
private @Child IsValueOfTypeNode check = IsValueOfTypeNode.build();

public boolean execute(@AcceptsError Object value, Object type) {
return check.execute(type, value);
return check.execute(type, value, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,62 @@
/** An implementation of the payload check against the expected panic type. */
@NodeInfo(shortName = "IsValueOfTypeNode")
public abstract class IsValueOfTypeNode extends Node {
IsValueOfTypeNode() {}

public static IsValueOfTypeNode build() {
return IsValueOfTypeNodeGen.create();
}

public abstract boolean execute(Object expectedType, Object payload);
/**
* @param expectedType the type to check
* @param obj the object to check
* @param includeExtraTypes specify {@code false} to return only <em>types value has already been
* case to</em>, specify {@code true} to return all <em>types value can be cast to</em>
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
*/
public abstract boolean execute(Object expectedType, Object obj, boolean includeExtraTypes);

@Specialization(guards = {"types.hasType(payload)"})
boolean doTyped(
Object expectedType,
Object payload,
boolean allTypes,
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types,
@Cached Typed typed) {
return typed.execute(expectedType, payload);
return typed.execute(expectedType, payload, allTypes);
}

@Specialization(guards = {"!types.hasType(payload)"})
boolean doPolyglot(
Object expectedType,
Object payload,
boolean allTypes,
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types,
@Cached Untyped untyped) {
return untyped.execute(expectedType, payload);
return untyped.execute(expectedType, payload, allTypes);
}

private static boolean typeAndCheck(
Object payload,
Object expectedType,
boolean allTypes,
TypeOfNode typeOfNode,
IsSameObjectNode isSameObject,
CountingConditionProfile isSameObjectProfile) {
Object tpeOfPayload = typeOfNode.findTypeOrError(payload);
if (isSameObjectProfile.profile(isSameObject.execute(expectedType, tpeOfPayload))) {
return true;
} else if (TypesGen.isType(tpeOfPayload)) {
Type tpe = TypesGen.asType(tpeOfPayload);
var ctx = EnsoContext.get(typeOfNode);
for (var superTpe : tpe.allTypes(ctx)) {
boolean testSuperTpe = isSameObject.execute(expectedType, superTpe);
if (testSuperTpe) {
return true;
var arr = typeOfNode.findAllTypesOrNull(payload, allTypes);
if (arr == null) {
return false;
}
for (var tpeOfPayload : arr) {
if (isSameObjectProfile.profile(isSameObject.execute(expectedType, tpeOfPayload))) {
return true;
} else if (TypesGen.isType(tpeOfPayload)) {
Type tpe = TypesGen.asType(tpeOfPayload);
var ctx = EnsoContext.get(typeOfNode);
for (var superTpe : tpe.allTypes(ctx)) {
boolean testSuperTpe = isSameObject.execute(expectedType, superTpe);
if (testSuperTpe) {
return true;
}
}
}
}
Expand All @@ -73,33 +89,33 @@ abstract static class Typed extends Node {
private @Child TypeOfNode typeOfNode = TypeOfNode.create();
private final CountingConditionProfile profile = CountingConditionProfile.create();

abstract boolean execute(Object expectedType, Object payload);
abstract boolean execute(Object expectedType, Object payload, boolean allTypes);

@Specialization(guards = "isAnyType(expectedType)")
boolean doAnyType(Object expectedType, Object payload) {
boolean doAnyType(Object expectedType, Object payload, boolean allTypes) {
return true;
}

@Specialization
boolean doLongCheck(Type expectedType, long payload) {
boolean doLongCheck(Type expectedType, long payload, boolean allTypes) {
var numbers = EnsoContext.get(this).getBuiltins().number();
return checkParentTypes(numbers.getInteger(), expectedType);
}

@Specialization
boolean doDoubleCheck(Type expectedType, double payload) {
boolean doDoubleCheck(Type expectedType, double payload, boolean allTypes) {
var numbers = EnsoContext.get(this).getBuiltins().number();
return checkParentTypes(numbers.getFloat(), expectedType);
}

@Specialization
boolean doBigIntegerCheck(Type expectedType, EnsoBigInteger value) {
boolean doBigIntegerCheck(Type expectedType, EnsoBigInteger value, boolean allTypes) {
var numbers = EnsoContext.get(this).getBuiltins().number();
return checkParentTypes(numbers.getInteger(), expectedType);
}

@Specialization
boolean doUnresolvedSymbol(Type expectedType, UnresolvedSymbol value) {
boolean doUnresolvedSymbol(Type expectedType, UnresolvedSymbol value, boolean allTypes) {
var funTpe = EnsoContext.get(this).getBuiltins().function();
return expectedType == funTpe;
}
Expand All @@ -119,8 +135,9 @@ private boolean checkParentTypes(Type actual, Type expected) {
boolean doType(
Type expectedType,
Object payload,
boolean allTypes,
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types) {
return typeAndCheck(payload, expectedType, typeOfNode, isSameObject, profile);
return typeAndCheck(payload, expectedType, allTypes, typeOfNode, isSameObject, profile);
}

@Specialization(
Expand All @@ -131,13 +148,14 @@ boolean doType(
public boolean doArrayViaType(
Object expectedType,
Object payload,
boolean allTypes,
@CachedLibrary(limit = "3") InteropLibrary interop,
@Shared("types") @CachedLibrary(limit = "3") TypesLibrary types) {
return EnsoContext.get(this).getBuiltins().array() == types.getType(payload);
}

@Fallback
boolean doOther(Object expectedType, Object payload) {
boolean doOther(Object expectedType, Object payload, boolean allTypes) {
return false;
}

Expand All @@ -155,15 +173,18 @@ abstract static class Untyped extends Node {
private @Child TypeOfNode typeOfNode = TypeOfNode.create();
private final CountingConditionProfile profile = CountingConditionProfile.create();

abstract boolean execute(Object expectedType, Object payload);
abstract boolean execute(Object expectedType, Object payload, boolean allTypes);

@Specialization(
guards = {
"interop.isMetaObject(expectedType)",
"isMetaInstance(interop, expectedType, payload)"
})
boolean doPolyglotType(
Object expectedType, Object payload, @CachedLibrary(limit = "3") InteropLibrary interop) {
Object expectedType,
Object payload,
boolean allTypes,
@CachedLibrary(limit = "3") InteropLibrary interop) {
return true;
}

Expand All @@ -176,8 +197,8 @@ static boolean isMetaInstance(InteropLibrary interop, Object expectedType, Objec
}

@Fallback
public boolean doOther(Object expectedType, Object payload) {
return typeAndCheck(payload, expectedType, typeOfNode, isSameObject, profile);
public boolean doOther(Object expectedType, Object payload, boolean allTypes) {
return typeAndCheck(payload, expectedType, allTypes, typeOfNode, isSameObject, profile);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Object verifyMetaObject(VirtualFrame frame, Object v, @Cached IsValueOfTypeNode
if (isAllFitValue(v)) {
return v;
}
if (isA.execute(expectedSupplier.get(), v)) {
if (isA.execute(expectedSupplier.get(), v, true)) {
return v;
} else {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ final Object findDirectMatch(VirtualFrame frame, Object v) {
return result;
}
}
if (checkType.execute(expectedType, v)) {
if (checkType.execute(expectedType, v, isAllTypes())) {
return v;
}
return null;
Expand Down Expand Up @@ -176,7 +176,7 @@ Type[] findType(TypeOfNode typeOfNode, Object v) {

Type[] findType(TypeOfNode typeOfNode, Object v, Type[] previous) {
if (v instanceof EnsoMultiValue multi) {
var all = typeOfNode.findAllTypesOrNull(multi);
var all = typeOfNode.findAllTypesOrNull(multi, isAllTypes());
assert all != null;
var to = 0;
// only consider methodDispatchTypes and not "all types" of the multi value
Expand Down
Loading
Loading