Skip to content

Commit 6f7ac90

Browse files
committed
Implemented definition of java.lang.Object so that it can be used with wildcard generics
1 parent 37f6229 commit 6f7ac90

File tree

11 files changed

+222
-58
lines changed

11 files changed

+222
-58
lines changed

CodeModel/src/main/java/org/openzen/zenscript/codemodel/identifiers/TypeSymbol.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package org.openzen.zenscript.codemodel.identifiers;
22

3+
import org.openzen.zencode.shared.CodePosition;
34
import org.openzen.zenscript.codemodel.Modifiers;
45
import org.openzen.zenscript.codemodel.compilation.ResolvingType;
6+
import org.openzen.zenscript.codemodel.expression.Expression;
57
import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
68
import org.openzen.zenscript.codemodel.type.TypeID;
79

10+
import java.util.List;
811
import java.util.Optional;
912

1013
/**
@@ -33,4 +36,12 @@ default TypeID normalize(TypeID[] typeArguments) {
3336
default Optional<TypeSymbol> asType() {
3437
return Optional.of(this);
3538
}
39+
40+
default Optional<Expression> castImplicitFrom(CodePosition position, TypeID[] typeArguments, Expression value, List<ExpansionSymbol> expansions) {
41+
return Optional.empty();
42+
}
43+
44+
default boolean isObjectRoot() {
45+
return false;
46+
}
3647
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/BasicTypeID.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ public ResolvingType resolve() {
7676
return members;
7777
}
7878

79+
@Override
80+
public boolean isObjectRoot() {
81+
return false;
82+
}
83+
7984
@Override
8085
public boolean hasDefaultValue() {
8186
return true;

CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,6 @@ public boolean hasTypeParameters() {
6565
return typeArguments.length > 0;
6666
}
6767

68-
public Map<TypeParameter, TypeID> getTypeParameterMapping() {
69-
Map<TypeParameter, TypeID> mapping = new HashMap<>();
70-
DefinitionTypeID current = this;
71-
do {
72-
if (current.typeArguments != null) {
73-
if (current.definition.getTypeParameters() != null) {
74-
for (int i = 0; i < current.typeArguments.length; i++)
75-
mapping.put(current.definition.getTypeParameters()[i], current.typeArguments[i]);
76-
}
77-
}
78-
79-
current = current.outer;
80-
} while (current != null && !current.definition.isStatic());
81-
return mapping;
82-
}
83-
8468
@Override
8569
public TypeID instance(GenericMapper mapper) {
8670
if (!hasTypeParameters() && outer == null)
@@ -128,6 +112,11 @@ public Optional<Expression> castImplicitTo(
128112
return Optional.empty();
129113
}
130114

115+
@Override
116+
public Optional<Expression> castImplicitFrom(CodePosition position, Expression value, List<ExpansionSymbol> expansions) {
117+
return definition.castImplicitFrom(position, typeArguments, value, expansions);
118+
}
119+
131120
@Override
132121
public boolean isEquivalentTo(TypeID other, List<ExpansionSymbol> expansions) {
133122
if (other instanceof DefinitionTypeID) {
@@ -240,8 +229,8 @@ public void extractTypeParameters(List<TypeParameter> typeParameters) {
240229
type.extractTypeParameters(typeParameters);
241230
}
242231

243-
/*@Override
244-
public Expression castImplicitFrom(CodePosition position, Expression value) {
245-
return new SubtypeCastExpression(position, value, this);
246-
}*/
232+
@Override
233+
public boolean isObjectRoot() {
234+
return definition.isObjectRoot();
235+
}
247236
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/TypeID.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,8 @@ default boolean isEquivalentTo(TypeID type, List<ExpansionSymbol> expansions) {
171171
default String toStringSuffixed() {
172172
return toString();
173173
}
174+
175+
default boolean isObjectRoot() {
176+
return false;
177+
}
174178
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/WildcardOutTypeID.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public Optional<Expression> castImplicitTo(
5454

5555
@Override
5656
public boolean canCastGenericFrom(TypeID toType, List<ExpansionSymbol> expansions) {
57-
return toType.extendsOrImplements(upperBound, expansions);
57+
return toType.extendsOrImplements(upperBound, expansions) || upperBound.isObjectRoot();
5858
}
5959

6060
@Override

JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.openzen.zenscript.javabytecode.compiler.lambda.capturing.JavaInvalidCapturedExpressionVisitor;
2424
import org.openzen.zenscript.javashared.*;
2525
import org.openzen.zenscript.javashared.expressions.JavaFunctionInterfaceCastExpression;
26+
import org.openzen.zenscript.javashared.expressions.JavaObjectCastExpression;
2627
import org.openzen.zenscript.javashared.types.JavaFunctionalInterfaceTypeID;
2728

2829
import java.util.*;
@@ -869,17 +870,22 @@ private void modify(ModifiableExpression source, Runnable modification, PushOpti
869870

870871
@Override
871872
public Void visitPlatformSpecific(Expression expression) {
872-
if (!(expression instanceof JavaFunctionInterfaceCastExpression)) {
873-
throw new AssertionError("Unrecognized platform expression " + expression.getClass().getName() + ": " + expression);
874-
}
875-
876-
final JavaFunctionInterfaceCastExpression jficExpression = (JavaFunctionInterfaceCastExpression) expression;
873+
if (expression instanceof JavaObjectCastExpression) {
874+
JavaObjectCastExpression castExpression = (JavaObjectCastExpression) expression;
875+
castExpression.value.accept(this);
876+
javaWriter.checkCast(Type.getType(Object.class));
877+
} else if (expression instanceof JavaFunctionInterfaceCastExpression) {
878+
final JavaFunctionInterfaceCastExpression jficExpression = (JavaFunctionInterfaceCastExpression) expression;
879+
880+
if (jficExpression.value.type instanceof JavaFunctionalInterfaceTypeID) {
881+
return jficExpression.value.accept(this);
882+
}
877883

878-
if (jficExpression.value.type instanceof JavaFunctionalInterfaceTypeID) {
879-
return jficExpression.value.accept(this);
884+
this.lambdaIndyCompiler.convertTypeOfFunctionExpressionViaIndy(jficExpression);
885+
} else {
886+
throw new AssertionError("Unrecognized platform expression " + expression.getClass().getName() + ": " + expression);
880887
}
881888

882-
this.lambdaIndyCompiler.convertTypeOfFunctionExpressionViaIndy(jficExpression);
883889
return null;
884890
}
885891

JavaIntegration/src/main/java/org/openzen/zencode/java/impl/conversion/JavaRuntimeTypeConverterImpl.java

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,16 @@
1111
import org.openzen.zencode.shared.LiteralSourceFile;
1212
import org.openzen.zenscript.codemodel.FunctionHeader;
1313
import org.openzen.zenscript.codemodel.GenericMapper;
14-
import org.openzen.zenscript.codemodel.Modifiers;
15-
import org.openzen.zenscript.codemodel.SemanticModule;
1614
import org.openzen.zenscript.codemodel.compilation.CompileContext;
17-
import org.openzen.zenscript.codemodel.definition.ClassDefinition;
18-
import org.openzen.zenscript.codemodel.definition.ZSPackage;
1915
import org.openzen.zenscript.codemodel.generic.ParameterTypeBound;
2016
import org.openzen.zenscript.codemodel.generic.TypeParameter;
21-
import org.openzen.zenscript.codemodel.identifiers.ModuleSymbol;
2217
import org.openzen.zenscript.codemodel.identifiers.TypeSymbol;
2318
import org.openzen.zenscript.codemodel.type.*;
2419
import org.openzen.zenscript.javashared.JavaClass;
2520
import org.openzen.zenscript.javashared.JavaModifiers;
2621
import org.openzen.zenscript.javashared.JavaNativeMethod;
2722
import org.openzen.zenscript.javashared.types.JavaFunctionalInterfaceTypeID;
23+
import org.openzen.zenscript.javashared.types.ObjectTypeSymbol;
2824
import org.openzen.zenscript.lexer.ParseException;
2925
import org.openzen.zenscript.lexer.ZSTokenParser;
3026
import org.openzen.zenscript.lexer.ZSTokenType;
@@ -258,23 +254,9 @@ private TypeSymbol findType(Class<?> cls) {
258254
return typeID.get();
259255
}
260256
if (cls == Object.class) {
261-
TypeSymbol result = packageInfo.getRoot().getImport(Arrays.asList("stdlib", "Object"), 0);
262-
if (result == null) {
263-
264-
Optional<ZSPackage> stdlib = packageInfo.getRoot().getOptional("stdlib");
265-
ZSPackage targetPackage = stdlib.orElseGet(() -> packageInfo.getRoot().getOrCreatePackage("stdlib"));
266-
ModuleSymbol module = Optional.ofNullable(nativeModuleSpace.moduleSpace.getModule("stdlib"))
267-
.map(x -> x.module)
268-
.orElse(packageInfo.getModule());
269-
270-
// registers itself to the package automatically
271-
new ClassDefinition(CodePosition.BUILTIN, module, targetPackage, "Object", Modifiers.PUBLIC, null);
272-
result = packageInfo.getRoot().getImport(Arrays.asList("stdlib", "Object"), 0);
273-
}
274-
return result;
257+
return ObjectTypeSymbol.INSTANCE;
275258
}
276259

277-
278260
JavaNativeModule module = nativeModuleSpace.getModule(cls)
279261
.orElseThrow(() -> new IllegalArgumentException("Could not find module for class " + cls.getName()));
280262
return module.findLocalClass(cls)

JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaBuiltinModule.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.openzen.zenscript.codemodel.FunctionParameter;
44
import org.openzen.zenscript.codemodel.identifiers.ModuleSymbol;
55
import org.openzen.zenscript.codemodel.type.builtin.*;
6+
import org.openzen.zenscript.javashared.types.ObjectTypeSymbol;
67

78
public class JavaBuiltinModule {
89
public static final JavaNativeMethod OBJECT_HASHCODE = JavaNativeMethod.getNativeVirtual(JavaClass.OBJECT, "hashCode", "()I");
@@ -130,6 +131,8 @@ public static JavaCompiledModule generate() {
130131
result.setMethodInfo(builtin, new JavaBuiltinMethod(builtin));
131132
}
132133

134+
result.setClassInfo(ObjectTypeSymbol.INSTANCE, new JavaClass("java.lang", "Object", JavaClass.Kind.CLASS));
135+
133136
result.setMethodInfo(BuiltinMethodSymbol.BOOL_TO_STRING, JavaNativeMethod.getNativeStatic(JavaClass.BOOLEAN, "toString", "(Z)Ljava/lang/String;"));
134137
result.setMethodInfo(BuiltinMethodSymbol.BOOL_PARSE, JavaNativeMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z"));
135138

JavaShared/src/main/java/org/openzen/zenscript/javashared/expressions/JavaSpecificExpression.java renamed to JavaShared/src/main/java/org/openzen/zenscript/javashared/expressions/JavaObjectCastExpression.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,28 @@
66
import org.openzen.zenscript.codemodel.expression.ExpressionVisitor;
77
import org.openzen.zenscript.codemodel.expression.ExpressionVisitorWithContext;
88
import org.openzen.zenscript.codemodel.type.TypeID;
9-
import org.openzen.zenscript.javashared.JavaContext;
109

11-
public abstract class JavaSpecificExpression extends Expression {
12-
public JavaSpecificExpression(CodePosition position, TypeID type, TypeID thrownType) {
13-
super(position, type, thrownType);
14-
}
10+
public class JavaObjectCastExpression extends Expression {
11+
public final Expression value;
12+
13+
public JavaObjectCastExpression(CodePosition position, TypeID type, Expression value) {
14+
super(position, type, value.thrownType);
1515

16-
public abstract void compile(JavaContext context);
16+
this.value = value;
17+
}
1718

1819
@Override
19-
public final <T> T accept(ExpressionVisitor<T> visitor) {
20+
public <T> T accept(ExpressionVisitor<T> visitor) {
2021
return visitor.visitPlatformSpecific(this);
2122
}
2223

2324
@Override
24-
public final <C, R> R accept(C context, ExpressionVisitorWithContext<C, R> visitor) {
25+
public <C, R> R accept(C context, ExpressionVisitorWithContext<C, R> visitor) {
2526
return visitor.visitPlatformSpecific(context, this);
2627
}
2728

2829
@Override
2930
public Expression transform(ExpressionTransformer transformer) {
30-
return this;
31+
return new JavaObjectCastExpression(position, type, transformer.transform(value));
3132
}
3233
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package org.openzen.zenscript.javashared.types;
2+
3+
import org.openzen.zencode.shared.CodePosition;
4+
import org.openzen.zenscript.codemodel.Modifiers;
5+
import org.openzen.zenscript.codemodel.compilation.ResolvingType;
6+
import org.openzen.zenscript.codemodel.expression.Expression;
7+
import org.openzen.zenscript.codemodel.generic.TypeParameter;
8+
import org.openzen.zenscript.codemodel.identifiers.ExpansionSymbol;
9+
import org.openzen.zenscript.codemodel.identifiers.ModuleSymbol;
10+
import org.openzen.zenscript.codemodel.identifiers.TypeSymbol;
11+
import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
12+
import org.openzen.zenscript.codemodel.type.TypeID;
13+
import org.openzen.zenscript.codemodel.type.member.MemberSet;
14+
import org.openzen.zenscript.javashared.expressions.JavaObjectCastExpression;
15+
16+
import java.util.List;
17+
import java.util.Optional;
18+
19+
public class ObjectTypeSymbol implements TypeSymbol {
20+
public static ObjectTypeSymbol INSTANCE = new ObjectTypeSymbol();
21+
22+
private ObjectTypeSymbol() {
23+
}
24+
25+
@Override
26+
public Modifiers getModifiers() {
27+
return Modifiers.PUBLIC;
28+
}
29+
30+
@Override
31+
public boolean isStatic() {
32+
return false;
33+
}
34+
35+
@Override
36+
public boolean isEnum() {
37+
return false;
38+
}
39+
40+
@Override
41+
public String getName() {
42+
return "Object";
43+
}
44+
45+
@Override
46+
public ResolvingType resolve(TypeID[] typeArguments) {
47+
MemberSet.Builder members = MemberSet.create(new DefinitionTypeID(this, typeArguments, null));
48+
return members.build();
49+
}
50+
51+
@Override
52+
public Optional<TypeSymbol> getOuter() {
53+
return Optional.empty();
54+
}
55+
56+
@Override
57+
public Optional<TypeID> getSupertype(TypeID[] typeArguments) {
58+
return Optional.empty();
59+
}
60+
61+
@Override
62+
public ModuleSymbol getModule() {
63+
return ModuleSymbol.BUILTIN;
64+
}
65+
66+
@Override
67+
public String describe() {
68+
return "Object";
69+
}
70+
71+
@Override
72+
public boolean isInterface() {
73+
return false;
74+
}
75+
76+
@Override
77+
public boolean isExpansion() {
78+
return false;
79+
}
80+
81+
@Override
82+
public TypeParameter[] getTypeParameters() {
83+
return TypeParameter.NONE;
84+
}
85+
86+
@Override
87+
public Optional<Expression> castImplicitFrom(CodePosition position, TypeID[] typeArguments, Expression value, List<ExpansionSymbol> expansions) {
88+
TypeID type = DefinitionTypeID.create(this, TypeID.NONE);
89+
if (value.type.equals(type)) {
90+
return Optional.of(value);
91+
} else {
92+
return Optional.of(new JavaObjectCastExpression(position, type, value));
93+
}
94+
}
95+
96+
@Override
97+
public boolean isObjectRoot() {
98+
return true;
99+
}
100+
}

0 commit comments

Comments
 (0)