use of dyvilx.tools.compiler.ast.classes.IClass in project Dyvil by Dyvil.
the class SuperExpr method resolveTypes.
@Override
public void resolveTypes(MarkerList markers, IContext context) {
if (!context.isThisAvailable()) {
markers.add(Markers.semantic(this.position, "super.access.static"));
return;
}
if (this.type != Types.UNKNOWN) {
this.type = this.type.resolveType(markers, context);
if (this.type.isResolved()) {
this.checkSuperType(markers, context);
}
return;
}
final IClass enclosingClass = context.getThisClass();
final IType superType = enclosingClass.getSuperType();
if (superType == null) {
final Marker marker = Markers.semanticError(this.position, "super.access.type");
marker.addInfo(Markers.getSemantic("type.enclosing", enclosingClass.getClassType()));
markers.add(marker);
return;
}
this.type = superType;
}
use of dyvilx.tools.compiler.ast.classes.IClass in project Dyvil by Dyvil.
the class SuperExpr method checkSuperType.
private void checkSuperType(MarkerList markers, IContext context) {
final IClass superClass = this.type.getTheClass();
final IClass enclosingClass = context.getThisClass();
final IType enclosingType = enclosingClass.getClassType();
final String message;
boolean indirectSuperInterface = false;
if (superClass == enclosingClass) {
// The specified type is the same as the enclosing type
message = "super.type.enclosing";
} else if (!Types.isSuperType(this.type, enclosingType)) {
message = "super.type.invalid";
} else {
// Check if the specified type is either the direct super type or a direct super interface
final IType superType = enclosingClass.getSuperType();
if (superType.isSameClass(this.type)) {
this.type = superType;
return;
}
if (superClass.isInterface()) {
final TypeList interfaces = enclosingClass.getInterfaces();
if (interfaces != null) {
for (int i = 0, count = interfaces.size(); i < count; i++) {
final IType interfaceType = interfaces.get(i);
if (interfaceType.isSameClass(this.type)) {
this.type = interfaceType;
return;
}
}
}
indirectSuperInterface = true;
}
message = "super.type.indirect";
}
final Marker marker = Markers.semanticError(this.type.getPosition(), message);
if (indirectSuperInterface) {
marker.addInfo(Markers.getSemantic("super.type.interface.info", this.type, enclosingClass.getName()));
}
marker.addInfo(Markers.getSemantic("type.enclosing", enclosingType));
marker.addInfo(Markers.getSemantic("super.type.requested", this.type));
markers.add(marker);
}
use of dyvilx.tools.compiler.ast.classes.IClass in project Dyvil by Dyvil.
the class TupleExpr method getTypeMatch.
@Override
public int getTypeMatch(IType type, IImplicitContext implicitContext) {
final int arity = this.values.size();
final IClass tupleClass = TupleType.getTupleClass(arity);
if (!Types.isSuperClass(type, tupleClass.getClassType())) {
if (type.getAnnotation(LazyFields.TUPLE_CONVERTIBLE) != null) {
return CONVERSION_MATCH;
}
return MISMATCH;
}
// reset type
this.tupleType = null;
final TypeParameterList typeParameters = typeParameters(tupleClass, arity);
int min = EXACT_MATCH;
for (int i = 0; i < arity; i++) {
final IType elementType = Types.resolveTypeSafely(type, typeParameters.get(i));
final int match = TypeChecker.getTypeMatch(this.values.get(i), elementType, implicitContext);
if (match == MISMATCH) {
return MISMATCH;
}
if (match < min) {
min = match;
}
}
return min;
}
use of dyvilx.tools.compiler.ast.classes.IClass in project Dyvil by Dyvil.
the class TupleExpr method withType.
@Override
public IValue withType(IType type, ITypeContext typeContext, MarkerList markers, IContext context) {
final Annotation annotation = type.getAnnotation(LazyFields.TUPLE_CONVERTIBLE);
if (annotation != null) {
return new LiteralConversion(this, annotation, this.values).withType(type, typeContext, markers, context);
}
final int arity = this.values.size();
final IClass tupleClass = TupleType.getTupleClass(arity);
if (!Types.isSuperClass(type, tupleClass.getClassType())) {
return null;
}
// reset type
this.tupleType = null;
final TypeParameterList typeParameters = typeParameters(tupleClass, arity);
for (int i = 0; i < arity; i++) {
final IType elementType = Types.resolveTypeSafely(type, typeParameters.get(i));
final IValue value = TypeChecker.convertValue(this.values.get(i), elementType, typeContext, markers, context, LazyFields.ELEMENT_MARKER_SUPPLIER);
this.values.set(i, value);
}
return this;
}
use of dyvilx.tools.compiler.ast.classes.IClass in project Dyvil by Dyvil.
the class Variable method writeGet.
@Override
public void writeGet(@NonNull MethodWriter writer, WriteableExpression receiver, int lineNumber) throws BytecodeException {
assert receiver == null;
final IType refType = this.getReferenceType();
if (refType == null) {
writer.visitVarInsn(this.getType().getLoadOpcode(), this.localIndex);
return;
}
final IClass refClass = refType.getTheClass();
refClass.resolveField(Names.value).writeGet(writer, this.asWriteableExpression(), lineNumber);
if (refClass == ReferenceType.LazyFields.OBJECT_SIMPLE_REF_CLASS) {
Types.OBJECT.writeCast(writer, this.getType(), lineNumber);
}
}
Aggregations