Skip to content

Commit 68fd0d0

Browse files
committed
implement subtype casting expression
1 parent 6f7ac90 commit 68fd0d0

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/ResolvedType.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.openzen.zenscript.codemodel.OperatorType;
66
import org.openzen.zenscript.codemodel.expression.CallArguments;
77
import org.openzen.zenscript.codemodel.expression.Expression;
8+
import org.openzen.zenscript.codemodel.expression.SubtypeCastExpression;
89
import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
910
import org.openzen.zenscript.codemodel.identifiers.ExpansionSymbol;
1011
import org.openzen.zenscript.codemodel.identifiers.MethodSymbol;
@@ -28,15 +29,22 @@ public interface ResolvedType {
2829
Optional<InstanceCallableMethod> findCaster(TypeID toType);
2930

3031
default Optional<Expression> tryCastExplicit(TypeID target, ExpressionCompiler compiler, CodePosition position, Expression value, boolean optional) {
31-
return findCaster(target)
32+
Optional<Expression> expression = findCaster(target)
3233
.filter(caster -> !caster.getModifiers().isImplicit())
3334
// TODO: remember the type arguments in the caster method instead, so we don't need to infer it again
3435
.flatMap(caster -> MatchedCallArguments.match(compiler, position, Collections.singletonList(caster), target, TypeID.NONE)
3536
.getArguments()
3637
.map(arg -> caster.call(compiler.at(position), value, arg))
3738
);
39+
if (!expression.isPresent()) {
40+
if (target.extendsOrImplements(this.getType(), compiler.getAvailableExpansions())) {
41+
return Optional.of(new SubtypeCastExpression(position, value, target));
42+
}
43+
}
44+
return expression;
3845
}
3946

47+
4048
default Optional<Expression> tryCastImplicit(TypeID target, ExpressionCompiler compiler, CodePosition position, Expression value, boolean optional) {
4149
return findCaster(target)
4250
.filter(caster -> caster.getModifiers().isImplicit())
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#output: baz
2+
3+
virtual class Foo {}
4+
5+
class Bar : Foo {
6+
public baz(): void {
7+
println("baz");
8+
}
9+
}
10+
11+
val foo = new Bar();
12+
13+
if foo is Bar {
14+
val bar = foo as Bar;
15+
bar.baz();
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#output: baz
2+
#output: baz
3+
4+
virtual class Foo {}
5+
6+
class Bar : Foo {}
7+
8+
function baz(foo: Foo): void {
9+
println("baz");
10+
}
11+
12+
val bar = new Bar();
13+
baz(bar);
14+
baz(bar as Foo);

0 commit comments

Comments
 (0)