use of dyvilx.tools.compiler.ast.type.TypeList 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.type.TypeList in project Dyvil by Dyvil.
the class ExternalClass method visit.
public void visit(int access, String name, String signature, String superName, String[] interfaces) {
this.attributes = readModifiers(access);
this.internalName = name;
this.body = new ClassBody(this);
if (interfaces != null) {
this.interfaces = new TypeList(interfaces.length);
}
int index = name.lastIndexOf('$');
if (index == -1) {
index = name.lastIndexOf('/');
}
if (index == -1) {
this.name = Name.fromQualified(name);
this.thePackage = Package.rootPackage;
this.fullName = name;
} else {
this.name = Name.fromQualified(name.substring(index + 1));
// Do not set 'fullName' here
this.thePackage = Package.rootPackage.resolveInternalPackage(name.substring(0, index));
}
if (signature != null) {
ClassFormat.readClassSignature(signature, this);
} else {
this.superType = superName != null ? ClassFormat.internalToType(superName) : null;
if (interfaces != null) {
for (String internal : interfaces) {
this.interfaces.add(ClassFormat.internalToType(internal));
}
}
}
}
use of dyvilx.tools.compiler.ast.type.TypeList in project Dyvil by Dyvil.
the class UnapplyPattern method writeJumpOnMismatch.
// Compilation
@Override
public void writeJumpOnMismatch(MethodWriter writer, int varIndex, Label target) throws BytecodeException {
Pattern.loadVar(writer, varIndex);
final int lineNumer = this.lineNumber();
final int tupleVarIndex = writer.localCount();
this.unapplyCall.writeExpression(writer, null);
final IType methodType = this.unapplyCall.getType();
final String internalType = methodType.getInternalName();
final TupleType tupleType = NullableType.unapply(methodType).extract(TupleType.class);
final TypeList typeArgs = tupleType.getArguments();
if (// nullable
methodType != tupleType) {
writer.visitInsn(Opcodes.DUP);
writer.visitVarInsn(Opcodes.ASTORE, tupleVarIndex);
writer.visitJumpInsn(Opcodes.IFNULL, target);
} else {
writer.visitVarInsn(Opcodes.ASTORE, tupleVarIndex);
}
for (int i = 0; i < this.patternCount; i++) {
if (this.patterns[i].isWildcard()) {
// Skip wildcard patterns
continue;
}
final IType targetType = typeArgs.get(i);
writer.visitVarInsn(Opcodes.ALOAD, tupleVarIndex);
// Get and cast the tuple element
// FIXME not ready for Tuple.OfN
writer.visitFieldInsn(Opcodes.GETFIELD, internalType, "_" + (i + 1), "Ljava/lang/Object;");
Types.OBJECT.writeCast(writer, targetType, lineNumer);
// Check the pattern
this.patterns[i].writeJumpOnMismatch(writer, -1, target);
}
}
use of dyvilx.tools.compiler.ast.type.TypeList in project Dyvil by Dyvil.
the class UnapplyPattern method withMethod.
protected boolean withMethod(IType matchedType, IValue methodCall, MarkerList markers) {
final IType type = NullableType.unapply(methodCall.getType());
final String className = type.getInternalName();
if (// return type must be a tuple type
!className.startsWith("dyvil/tuple/Tuple$Of")) {
return false;
}
final TupleType tupleType = type.extract(TupleType.class);
final TypeList typeArguments = tupleType.getArguments();
if (this.patternCount != typeArguments.size()) {
final Marker marker = Markers.semanticError(this.position, "pattern.unapply.count", this.type.toString());
marker.addInfo(Markers.getSemantic("pattern.unapply.count.pattern", this.patternCount));
marker.addInfo(Markers.getSemantic("pattern.unapply.count.class", typeArguments.size()));
markers.add(marker);
return true;
}
this.unapplyCall = methodCall;
for (int i = 0; i < this.patternCount; i++) {
final IType subType = typeArguments.get(i);
final Pattern pattern = this.patterns[i];
final Pattern typedPattern = pattern.withType(subType, markers);
if (typedPattern == null) {
final Marker marker = Markers.semanticError(this.position, "pattern.unapply.type");
marker.addInfo(Markers.getSemantic("pattern.type", pattern.getType()));
marker.addInfo(Markers.getSemantic("classparameter.type", subType));
markers.add(marker);
} else {
this.patterns[i] = typedPattern;
}
}
this.switchValue = getSwitchValue(matchedType, this.type);
return true;
}
Aggregations