use of dyvilx.tools.compiler.ast.constructor.IConstructor in project Dyvil by Dyvil.
the class LambdaExpr method cleanup.
@Override
public IValue cleanup(ICompilableList compilableList, IClassCompilableList classCompilableList) {
this.parameters.cleanup(compilableList, classCompilableList);
if (this.returnType != null && (this.flags & EXPLICIT_RETURN) != 0) {
this.returnType.cleanup(compilableList, classCompilableList);
}
this.value = this.value.cleanup(compilableList, classCompilableList);
if (this.captureHelper == null || !this.captureHelper.hasCaptures()) {
// Check if we can use a direct method reference
if (this.value instanceof AbstractCall) {
final AbstractCall call = (AbstractCall) this.value;
final IMethod method = call.getMethod();
if (method != null && this.checkCall(call.getReceiver(), call.getArguments(), method)) {
this.setHandleType(ClassFormat.insnToHandle(method.getInvokeOpcode()));
this.name = method.getInternalName();
this.owner = method.getEnclosingClass().getInternalName();
this.descriptor = method.getDescriptor();
return this;
}
} else // To avoid trouble with anonymous classes
if (this.value.getClass() == ConstructorCall.class) {
final ConstructorCall call = (ConstructorCall) this.value;
final IConstructor constructor = call.getConstructor();
if (constructor != null && this.checkCall(null, call.getArguments(), constructor)) {
this.setHandleType(ClassFormat.H_NEWINVOKESPECIAL);
this.name = constructor.getInternalName();
this.owner = constructor.getEnclosingClass().getInternalName();
this.descriptor = constructor.getDescriptor();
return this;
}
}
}
this.owner = classCompilableList.getInternalName();
this.name = "lambda$" + classCompilableList.classCompilableCount();
classCompilableList.addClassCompilable(this);
return this;
}
use of dyvilx.tools.compiler.ast.constructor.IConstructor in project Dyvil by Dyvil.
the class ClassConstructorCall method resolveCall.
@Override
public IValue resolveCall(MarkerList markers, IContext context, boolean report) {
if (!this.type.isResolved()) {
return this;
}
final IClass theClass = this.type.getTheClass();
if (theClass == null) {
return this;
}
final IType type = theClass.isInterface() ? Types.OBJECT : this.type;
final MatchList<IConstructor> candidates = this.resolveCandidates(context, type);
if (candidates.hasCandidate()) {
this.checkArguments(markers, context, candidates.getBestMember());
return this;
}
if (report) {
reportResolve(markers, candidates, this.position, type, this.arguments);
return this;
}
return null;
}
use of dyvilx.tools.compiler.ast.constructor.IConstructor in project Dyvil by Dyvil.
the class ClassMetadata method resolveTypesBody.
@Override
public void resolveTypesBody(MarkerList markers, IContext context) {
// Check if a constructor needs to be generated
final ClassBody body = this.theClass.getBody();
if (body == null) {
return;
}
this.checkMembers(body);
if (body.constructorCount() <= 0) {
return;
}
final ParameterList parameters = this.theClass.getParameters();
final IConstructor constructor = body.getConstructor(parameters);
if (constructor != null) {
this.constructor = constructor;
this.members |= CONSTRUCTOR;
return;
}
if (parameters.isEmpty()) {
// Do not generate an empty default constructor if there is any other constructor defined
this.members |= CONSTRUCTOR;
}
}
use of dyvilx.tools.compiler.ast.constructor.IConstructor in project Dyvil by Dyvil.
the class EnumClassMetadata method resolveTypesGenerate.
@Override
public void resolveTypesGenerate(MarkerList markers, IContext context) {
super.resolveTypesGenerate(markers, context);
final ClassBody body = this.theClass.createBody();
body.addDataMember(this.createValuesField());
body.addMethod(this.createValuesMethod());
body.addMethod(this.createFromOrdMethod());
body.addMethod(this.createFromNameMethod());
// Replace super initializer calls from constructors
for (IConstructor ctor : body.constructors()) {
this.updateConstructor(ctor);
}
}
use of dyvilx.tools.compiler.ast.constructor.IConstructor in project Dyvil by Dyvil.
the class AnonymousClassMetadata method write.
@Override
public void write(ClassWriter writer) throws BytecodeException {
final CaptureHelper<CaptureField> captureHelper = this.theClass.captureHelper;
final FieldThis thisField = this.theClass.thisField;
final IConstructor constructor = this.theClass.constructor;
captureHelper.writeCaptureFields(writer);
final MethodWriter initWriter = new MethodWriterImpl(writer, writer.visitMethod(Modifiers.MANDATED, "<init>", this.theClass.getConstructorDesc(), null, null));
final ParameterList parameterList = constructor.getParameters();
final int parameterCount = parameterList.size();
// Signature & Parameter Data
initWriter.setThisType(this.theClass.getInternalName());
parameterList.write(initWriter);
int index = initWriter.localCount();
int thisIndex = index;
if (thisField != null) {
thisField.writeField(writer);
index = initWriter.visitParameter(index, thisField.getName(), thisField.getTargetClass().getThisType(), Modifiers.MANDATED);
}
captureHelper.writeCaptureParameters(initWriter, index);
// Constructor Body
initWriter.visitCode();
initWriter.visitVarInsn(Opcodes.ALOAD, 0);
for (int i = 0; i < parameterCount; i++) {
parameterList.get(i).writeGet(initWriter);
}
constructor.writeInvoke(initWriter, 0);
if (thisField != null) {
initWriter.visitVarInsn(Opcodes.ALOAD, 0);
initWriter.visitVarInsn(Opcodes.ALOAD, thisIndex);
initWriter.visitFieldInsn(Opcodes.PUTFIELD, this.theClass.getInternalName(), thisField.getName(), thisField.getDescriptor());
}
captureHelper.writeFieldAssignments(initWriter);
this.theClass.writeClassInit(initWriter);
initWriter.visitEnd(Types.VOID);
}
Aggregations