use of dyvilx.tools.compiler.ast.expression.CastOperator in project Dyvil by Dyvil.
the class CaseClassMetadata method createUnapplyAnyMethod.
private CodeMethod createUnapplyAnyMethod() {
// static final func unapply<TypeParams...>(value: any) -> (T...)?
final SourcePosition position = this.theClass.position();
final AttributeList attributes = AttributeList.of(Modifiers.PUBLIC | Modifiers.STATIC_FINAL | Modifiers.GENERATED);
final IType type = NullableType.apply(this.getUnapplyReturnType());
final CodeMethod unapply = new CodeMethod(this.theClass, Names.unapply, type, attributes);
unapply.setPosition(position);
unapply.getTypeParameters().addAll(this.theClass.getTypeParameters());
final CodeParameter parameter = new CodeParameter(unapply, position, Names.value, Types.NULLABLE_ANY);
unapply.getParameters().add(parameter);
// = (param is This) ? unapply(param as This) : null
final InstanceOfOperator isOperator = new InstanceOfOperator(new FieldAccess(parameter), this.theClass.getClassType());
final CastOperator castOperator = new CastOperator(new FieldAccess(parameter), this.theClass.getThisType());
final IValue call = new MethodCall(position, null, Names.unapply, new ArgumentList(castOperator));
final IfStatement ifStatement = new IfStatement(isOperator, call, new NullValue());
unapply.setValue(ifStatement);
return unapply;
}
use of dyvilx.tools.compiler.ast.expression.CastOperator in project Dyvil by Dyvil.
the class BindingIfStatement method writeCondition.
@Override
protected void writeCondition(MethodWriter writer, Label elseStart) {
for (IVariable var : this.variables) {
IValue value = getOptionalValue(var);
final CastOperator castOp;
final int localCount = writer.localCount();
final int varIndex;
if (value instanceof CastOperator && (castOp = (CastOperator) value).isOptional()) {
// optimization for optional cast operators
value = castOp.getValue();
varIndex = value.writeStoreLoad(writer, null);
// branch if necessary (also branches if null)
writer.visitTypeInsn(Opcodes.INSTANCEOF, castOp.getType().getInternalName());
writer.visitJumpInsn(Opcodes.IFEQ, elseStart);
} else {
varIndex = value.writeStoreLoad(writer, null);
// branch if necessary
writer.visitJumpInsn(Opcodes.IFNULL, elseStart);
}
// load and unwrap the variable
writer.visitVarInsn(Opcodes.ALOAD, varIndex);
writer.resetLocals(localCount);
value.getType().writeCast(writer, var.getType(), value.lineNumber());
// store, but this time with the right type
var.writeInit(writer, null);
}
super.writeCondition(writer, elseStart);
}
Aggregations