Skip to content

Commit

Permalink
Fixing expansions on recursive generic types
Browse files Browse the repository at this point in the history
  • Loading branch information
stanhebben committed Oct 25, 2024
1 parent 2bc37d4 commit b8546f9
Show file tree
Hide file tree
Showing 15 changed files with 106 additions and 524 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ default boolean canCastImplicitlyTo(TypeID target) {

List<MethodSymbol> getInterfaceMethodsToImplement();

boolean extendsOrImplements(TypeID type);

interface SwitchMember {
SwitchValue toSwitchValue(List<CompilingVariable> bindings);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.openzen.zencode.shared.CodePosition;
import org.openzen.zencode.shared.Taggable;
import org.openzen.zenscript.codemodel.GenericMapper;
import org.openzen.zenscript.codemodel.type.TypeID;

import java.util.ArrayList;
Expand Down Expand Up @@ -31,9 +32,10 @@ public boolean isObjectType() {
return false;
}

public boolean matches(TypeID type) {
public boolean matches(TypeID type, GenericMapper mapper) {
for (TypeParameterBound bound : bounds) {
if (!bound.matches(type))
TypeParameterBound instanced = bound.instance(mapper);
if (!instanced.matches(type))
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public GenericTypeID(TypeParameter parameter) {
}

public boolean matches(TypeID type) {
return parameter.matches(type);
GenericMapper mapper = GenericMapper.single(parameter, type);
return parameter.matches(type, mapper);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ default ResolvedType resolveWithoutExpansions() {
}

default boolean extendsOrImplements(TypeID type) {
return false;
return resolveWithoutExpansions().extendsOrImplements(type);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,12 @@ public Boolean visitBasic(Matching context, BasicTypeID basic) {

@Override
public Boolean visitArray(Matching context, ArrayTypeID array) {
if (context.type instanceof ArrayTypeID) {
ArrayTypeID arrayType = (ArrayTypeID) context.type;
return context.type.asArray().map(arrayType -> {
if (arrayType.dimension != array.dimension)
return false;

return match(context, arrayType.elementType, array.elementType);
} else {
return false;
}
}).orElse(false);
}

@Override
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,12 @@ public List<MethodSymbol> getInterfaceMethodsToImplement() {
return base.getInterfaceMethodsToImplement();
}

@Override
public boolean extendsOrImplements(TypeID type) {
return base.extendsOrImplements(type)
|| expansions.stream().anyMatch(expansion -> expansion.extendsOrImplements(type));
}

@Override
public Optional<Field> findField(String name) {
return base.findField(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ public List<MethodSymbol> getInterfaceMethodsToImplement() {
return result;
}

@Override
public boolean extendsOrImplements(TypeID type) {
return this.type.equals(type);
}

@Override
public Optional<Field> findField(String name) {
return Optional.ofNullable(fields.get(name));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,9 @@ public Optional<StaticCallable> findStaticOperator(OperatorType operator) {
public List<MethodSymbol> getInterfaceMethodsToImplement() {
return Collections.emptyList();
}

@Override
public boolean extendsOrImplements(TypeID type) {
return this.type.equals(type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ public List<MethodSymbol> getInterfaceMethodsToImplement() {
.collect(Collectors.toList());
}

@Override
public boolean extendsOrImplements(TypeID type) {
return streamAllTypes().anyMatch(t -> t.extendsOrImplements(type));
}

private <T> Optional<T> findFirstInLocalOrBaseTypes(Function<ResolvedType, Optional<T>> mapper) {
return streamAllTypes()
.map(mapper)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ public List<MethodSymbol> getInterfaceMethodsToImplement() {
return template.getInterfaceMethodsToImplement();
}

@Override
public boolean extendsOrImplements(TypeID type) {
return type.equals(this.type); // TODO
}

@Override
public Optional<Field> findField(String name) {
return template.getField(name).map(f -> new RuntimeField(mapper.map(f)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

val a = [5, 1, 2, 4, 3];
a.sort();
println(a);
println(a);
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#disabled: currently broken because ZC cannot infer that the expansion for "<T extends Comparable<T>> T[]" is applicable to TicketNumber[]
#dependency: stdlib
#output: T-2
#output: T-3
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#output: T-5
#output: T-3
#output: T-3
#output: T-4
#output: T-2

interface Comparable<T> {
compareTo(other: T): int;
}

expand <T : Comparable<T>> T[] {
sort(): void {}
}

public class TicketNumber {
private var value as int;

public implements Comparable<TicketNumber> {
compareTo(other) => this.value - other.value;
}

public implicit as string => "T-" + value;
}

val a = [
new TicketNumber(5),
new TicketNumber(3),
new TicketNumber(3),
new TicketNumber(4),
new TicketNumber(2),
];
a.sort();
for ticket in a println(ticket);
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#output: T-5
#output: T-3
#output: T-3
#output: T-4
#output: T-2

interface Comparable<T> {
compareTo(other: T): int;
}

expand <T : Comparable<T>> T[] {
sort(): void {}
}

public class TicketNumber {
private var value as int;

public implicit as string => "T-" + value;
}

expand TicketNumber {
public implements Comparable<TicketNumber> {
compareTo(other) => this.value - other.value;
}
}

val a = [
new TicketNumber(5),
new TicketNumber(3),
new TicketNumber(3),
new TicketNumber(4),
new TicketNumber(2),
];
a.sort();
for ticket in a println(ticket);

0 comments on commit b8546f9

Please sign in to comment.