use of dyvilx.tools.compiler.ast.expression.access.ConstructorCall 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.expression.access.ConstructorCall in project Dyvil by Dyvil.
the class Template method makeMainMethod.
private void makeMainMethod() {
// func main(args: [String]) -> void = new TemplateName().mainImpl(args)
final ParameterList params = this.mainMethod.getParameters();
final CodeParameter argsParam = new CodeParameter(this.mainMethod, null, Name.fromRaw("args"), new ArrayType(Types.STRING));
params.add(argsParam);
final IValue newTemplate = new ConstructorCall(null, this.templateClass.getClassType(), ArgumentList.EMPTY);
this.mainMethod.setValue(new MethodCall(null, newTemplate, Name.fromRaw("mainImpl"), new ArgumentList(new FieldAccess(argsParam))));
}
use of dyvilx.tools.compiler.ast.expression.access.ConstructorCall in project Dyvil by Dyvil.
the class ObjectClassMetadata method createInstanceField.
private Field createInstanceField() {
final int flags = Modifiers.PUBLIC | Modifiers.CONST | (this.theClass.isImplicit() ? Modifiers.IMPLICIT : 0);
final IType classType = this.theClass.getClassType();
final Field field = new Field(this.theClass, Names.instance, classType, AttributeList.of(flags));
final ConstructorCall call = new ConstructorCall(this.theClass.position(), classType, ArgumentList.EMPTY);
field.setValue(call);
return field;
}
use of dyvilx.tools.compiler.ast.expression.access.ConstructorCall in project Dyvil by Dyvil.
the class CaseClassMetadata method createApplyMethod.
private CodeMethod createApplyMethod() {
// static final func apply<TypeParams...>(classParams...: ClassParamTypes...) -> This
final SourcePosition position = this.theClass.position();
final AttributeList attributes = AttributeList.of(Modifiers.PUBLIC | Modifiers.STATIC_FINAL | Modifiers.GENERATED);
final IType type = this.theClass.getThisType();
final CodeMethod applyMethod = new CodeMethod(this.theClass, Names.apply, type, attributes);
applyMethod.setPosition(position);
applyMethod.getTypeParameters().addAll(this.theClass.getTypeParameters());
this.copyClassParameters(applyMethod);
// = new This<TypeParams...>(classParams...)
final ArgumentList arguments = new ArgumentList();
for (IParameter param : applyMethod.getParameters()) {
// no need to check for override class parameters here, since we are dealing with parameters of the
// apply method
final IValue access;
if (param.isVarargs()) {
access = new VarargsOperator(position, new FieldAccess(param));
} else {
access = new FieldAccess(param);
}
arguments.add(access);
}
// = new This(params...)
applyMethod.setValue(new ConstructorCall(this.theClass.position(), this.theClass.getThisType(), arguments));
return applyMethod;
}
use of dyvilx.tools.compiler.ast.expression.access.ConstructorCall in project Dyvil by Dyvil.
the class ConstructorCallParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case NEW:
if (type != DyvilKeywords.NEW) {
pm.report(token, "constructor.new");
pm.reparse();
}
final ArgumentList arguments = token.next().type() == BaseSymbols.OPEN_PARENTHESIS ? null : ArgumentList.empty();
this.call = new ConstructorCall(token.raw(), arguments);
this.mode = CONSTRUCTOR_PARAMETERS;
pm.pushParser(new TypeParser(this.call));
return;
case CONSTRUCTOR_PARAMETERS:
// ^
if (type == BaseSymbols.OPEN_PARENTHESIS) {
// new ... (
this.mode = CONSTRUCTOR_PARAMETERS_END;
ArgumentListParser.parseArguments(pm, token.next(), this.call);
return;
}
// Fallthrough
case ANONYMOUS_CLASS:
if (type == BaseSymbols.OPEN_CURLY_BRACKET && (this.flags & IGNORE_ANON_CLASS) == 0) {
// new ... ( ... ) { ...
this.parseBody(pm);
return;
}
pm.reparse();
this.end(pm, token.prev());
return;
case CONSTRUCTOR_PARAMETERS_END:
// new ... ( ... )
// ^
this.mode = ANONYMOUS_CLASS;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "constructor.call.close_paren");
}
return;
case ANONYMOUS_CLASS_END:
// new ... { ... } ...
// ^
this.end(pm, token);
if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.reparse();
pm.report(token, "class.anonymous.body.end");
}
}
}
Aggregations