use of dyvilx.tools.compiler.ast.attribute.AttributeList in project Dyvil by Dyvil.
the class CaseClassMetadata method createUnapplyMethod.
private CodeMethod createUnapplyMethod() {
// static final func unapply<TypeParams...>(value: This) -> (T...)
final SourcePosition position = this.theClass.position();
final AttributeList attributes = AttributeList.of(Modifiers.PUBLIC | Modifiers.STATIC_FINAL | Modifiers.GENERATED);
final IType type = 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, this.theClass.getThisType());
unapply.getParameters().add(parameter);
// = (value.classParams...)
final TupleExpr tupleExpr = new TupleExpr(position);
final ArgumentList arguments = tupleExpr.getValues();
for (IParameter param : this.theClass.getParameters()) {
// value
final FieldAccess thisAccess = new FieldAccess(position, null, parameter);
// value.classParam
final IValue fieldAccess;
if (param.isOverride()) {
// if the class parameter is marked as 'override', we have to resolve it from a super-class
// the easiest way to do this is by name
fieldAccess = new FieldAccess(position, thisAccess, param.getName());
} else {
fieldAccess = new FieldAccess(position, thisAccess, param);
}
arguments.add(fieldAccess);
}
unapply.setValue(tupleExpr);
return unapply;
}
use of dyvilx.tools.compiler.ast.attribute.AttributeList in project Dyvil by Dyvil.
the class ClassMetadata method createDefaultConstructor.
private CodeConstructor createDefaultConstructor() {
// init(classParams...)
final SourcePosition position = this.theClass.position();
final AttributeList attributes = this.theClass.getConstructorAttributes();
attributes.addFlag(Modifiers.GENERATED);
final CodeConstructor constructor = new CodeConstructor(this.theClass, attributes);
constructor.setPosition(position);
this.copyClassParameters(constructor);
// : super(superParams...)
final IType superType = this.theClass.getSuperType();
if (superType != null) {
// Generate the constructor body
ArgumentList arguments = this.theClass.getSuperConstructorArguments();
if (arguments == null) {
arguments = ArgumentList.empty();
}
final InitializerCall init = new InitializerCall(this.theClass.getPosition(), true, arguments, superType);
constructor.setInitializer(init);
}
// { this.classParams... = classParams... }
final ParameterList classParams = this.theClass.getParameters();
final StatementList ctorBody = new StatementList();
final ParameterList ctorParams = constructor.getParameters();
// j is the counter for class parameters, as there may be leading synthetic constructor parameters
for (int i = 0, j = 0, count = ctorParams.size(); i < count; i++) {
final IParameter ctorParam = ctorParams.get(i);
if (ctorParam.hasModifier(Modifiers.SYNTHETIC)) {
continue;
}
final IParameter classParam = classParams.get(j++);
if (classParam.hasModifier(Modifiers.OVERRIDE)) {
continue;
}
final IValue receiver = new ThisExpr(this.theClass);
final FieldAccess access = new FieldAccess(ctorParam);
final FieldAssignment assignment = new FieldAssignment(position, receiver, classParam, access);
ctorBody.add(assignment);
}
constructor.setValue(ctorBody);
return constructor;
}
use of dyvilx.tools.compiler.ast.attribute.AttributeList in project Dyvil by Dyvil.
the class ClassMetadata method copyClassParameters.
protected void copyClassParameters(ICallableMember constructor) {
ParameterList from = this.theClass.getParameters();
final int parameterCount = from.size();
final ParameterList ctrParams = constructor.getParameters();
for (int i = 0; i < parameterCount; i++) {
final IParameter classParameter = from.get(i);
AttributeList attributes = classParameter.getAttributes().filtered(Modifiers.PARAMETER_MODIFIERS);
ctrParams.add(constructor.createParameter(classParameter.getPosition(), classParameter.getName(), classParameter.getType(), attributes));
}
if (ctrParams.isLastVariadic()) {
constructor.getAttributes().addFlag(Modifiers.ACC_VARARGS);
}
}
use of dyvilx.tools.compiler.ast.attribute.AttributeList in project Dyvil by Dyvil.
the class AbstractClass method toString.
@Override
public void toString(@NonNull String indent, @NonNull StringBuilder buffer) {
this.attributes.toString(indent, buffer);
ModifierUtil.writeClassType(this.attributes.flags(), buffer);
buffer.append(this.name);
if (this.typeParameters != null) {
this.typeParameters.toString(indent, buffer);
}
final AttributeList constructorAttributes = this.getConstructorAttributes();
if (constructorAttributes != null && !constructorAttributes.isEmpty()) {
buffer.append(' ');
constructorAttributes.toInlineString(indent, buffer);
if (this.parameters.isEmpty()) {
// when there are constructor modifiers but no parameters, we still display the ()
buffer.append("()");
}
}
if (!this.parameters.isEmpty()) {
this.parameters.toString(indent, buffer);
}
if (this.superType != null && this.superType.getTheClass() != Types.OBJECT_CLASS) {
String extendsPrefix = indent;
if (Formatting.getBoolean("class.extends.newline")) {
extendsPrefix = Formatting.getIndent("class.extends.indent", extendsPrefix);
buffer.append('\n').append(extendsPrefix).append("extends ");
} else {
buffer.append(" extends ");
}
this.superType.toString("", buffer);
}
if (this.interfaces != null && this.interfaces.size() > 0) {
final String itfIndent;
if (Formatting.getBoolean("class.implements.newline")) {
itfIndent = Formatting.getIndent("class.implements.indent", indent);
buffer.append('\n').append(itfIndent);
} else {
itfIndent = indent;
buffer.append(' ');
}
buffer.append(this.isInterface() ? "extends " : "implements ");
Util.astToString(itfIndent, this.interfaces.getTypes(), this.interfaces.size(), Formatting.getSeparator("class.implements.separator", ','), buffer);
}
if (this.body != null) {
this.body.toString(indent, buffer);
} else if (Formatting.getBoolean("class.semicolon")) {
buffer.append(';');
}
}
use of dyvilx.tools.compiler.ast.attribute.AttributeList in project Dyvil by Dyvil.
the class IParameter method writeParameter.
default void writeParameter(MethodWriter writer) {
final AttributeList annotations = this.getAttributes();
final IType type = this.getInternalType();
final long flags = ModifierUtil.getFlags(this);
final int index = this.getIndex();
final int localIndex = writer.localCount();
this.setLocalIndex(localIndex);
// Add the ACC_VARARGS modifier if necessary
final int javaModifiers = ModifierUtil.getJavaModifiers(flags) | (this.isVarargs() ? Modifiers.ACC_VARARGS : 0);
writer.visitParameter(localIndex, this.getQualifiedLabel(), type, javaModifiers);
// Annotations
final AnnotatableVisitor visitor = (desc, visible) -> writer.visitParameterAnnotation(index, desc, visible);
if (annotations != null) {
annotations.write(visitor);
}
ModifierUtil.writeModifiers(visitor, flags);
IType.writeAnnotations(type, writer, TypeReference.newFormalParameterReference(index), "");
}
Aggregations