use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class AnnotationExpr method writeExpression.
@Override
public void writeExpression(MethodWriter writer, IType type) throws BytecodeException {
final StringBuilder descBuilder = new StringBuilder().append('(');
final ArgumentList arguments = this.annotation.getArguments();
final IClass iclass = this.annotation.getType().getTheClass();
final ParameterList parameterList = iclass.getParameters();
final int count = parameterList.size();
String[] parameterNames = new String[count];
for (int i = 0; i < count; i++) {
final IParameter parameter = parameterList.get(i);
final IType parameterType = parameter.getType();
parameterNames[i] = parameter.getInternalName();
parameterType.appendExtendedName(descBuilder);
arguments.writeValue(i, parameter, writer);
}
descBuilder.append(')');
descBuilder.append('L').append(iclass.getInternalName()).append(';');
writer.visitInvokeDynamicInsn("_", descBuilder.toString(), ANNOTATION_METAFACTORY, (Object[]) parameterNames);
if (type != null) {
this.annotation.getType().writeCast(writer, type, this.lineNumber());
}
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class AbstractConstructor method checkMatch.
@Override
public void checkMatch(MatchList<IConstructor> list, ArgumentList arguments) {
final int parameterCount = this.parameters.size();
if (arguments == null) {
list.add(new Candidate<>(this));
return;
}
final int argumentCount = arguments.size();
if (argumentCount > parameterCount && !this.isVariadic()) {
return;
}
final int[] matchValues = new int[argumentCount];
final IType[] matchTypes = new IType[argumentCount];
int defaults = 0;
int varargs = 0;
for (int i = 0; i < parameterCount; i++) {
final IParameter parameter = this.parameters.get(i);
final int partialVarargs = arguments.checkMatch(matchValues, matchTypes, 0, i, parameter, list);
switch(partialVarargs) {
case ArgumentList.MISMATCH:
return;
case ArgumentList.DEFAULT:
defaults++;
continue;
default:
varargs += partialVarargs;
}
}
for (int matchValue : matchValues) {
if (matchValue == IValue.MISMATCH) {
return;
}
}
list.add(new Candidate<>(this, matchValues, matchTypes, defaults, varargs));
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class Annotation method resolve.
@Override
public void resolve(MarkerList markers, IContext context) {
this.arguments.resolve(markers, context);
final IClass theClass;
if (this.type == null || (theClass = this.type.getTheClass()) == null) {
return;
}
final ParameterList parameterList = theClass.getParameters();
for (int i = 0, count = parameterList.size(); i < count; i++) {
final IParameter parameter = parameterList.get(i);
final IType parameterType = parameter.getType();
final IValue value = this.arguments.get(parameter);
if (value == null) {
if (parameter.getValue() == null) {
markers.add(Markers.semanticError(this.getPosition(), "annotation.parameter.missing", this.type, parameter.getName()));
}
continue;
}
IValue typedValue = value.withType(parameterType, parameterType, markers, context);
if (typedValue == null) {
markers.add(TypeChecker.typeError(value, parameterType, parameterType, "annotation.parameter.type", parameter.getName()));
continue;
}
typedValue = IValue.toAnnotationConstant(typedValue, markers, context);
if (typedValue != value) {
this.arguments.set(i, parameter.getLabel(), typedValue);
}
}
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class Annotation method write.
public void write(AnnotationVisitor writer) {
final IClass iclass = this.type.getTheClass();
final ParameterList parameterList = iclass.getParameters();
for (int i = 0, count = parameterList.size(); i < count; i++) {
final IParameter parameter = parameterList.get(i);
final IValue argument = this.arguments.get(parameter);
if (argument != null) {
argument.writeAnnotationValue(writer, parameter.getName().qualified);
}
}
writer.visitEnd();
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class AbstractMethod method checkMatch.
@Override
public void checkMatch(MatchList<IMethod> list, IValue receiver, Name name, ArgumentList arguments) {
if (name != this.name && name != null) {
return;
}
final ParameterList parameters = this.getParameters();
final int parameterStartIndex;
final int argumentStartIndex;
final int argumentCount;
final int parameterCount = parameters.size();
final int[] matchValues;
final IType[] matchTypes;
boolean invalid = false;
final int mod = this.attributes.flags() & Modifiers.INFIX;
if (receiver == null) {
if (mod == Modifiers.INFIX) {
// disallow non-qualified access to infix methods
invalid = true;
}
if (arguments == null) {
list.add(new Candidate<>(this));
return;
}
argumentCount = arguments.size();
matchValues = new int[argumentCount];
matchTypes = new IType[argumentCount];
argumentStartIndex = 0;
parameterStartIndex = 0;
} else if (mod != 0 && receiver.isClassAccess()) {
// Static access to static method
final IType receiverType = receiver.getType();
if (!Types.isSuperType(this.getReceiverType(), receiverType)) {
// Disallow access from the wrong type
return;
}
if (arguments == null) {
list.add(new Candidate<>(this, IValue.EXACT_MATCH, receiverType, false));
return;
}
parameterStartIndex = 0;
argumentCount = arguments.size();
argumentStartIndex = 1;
matchValues = new int[1 + argumentCount];
matchTypes = new IType[1 + argumentCount];
matchValues[0] = 1;
matchTypes[0] = receiverType;
} else {
if (// a
mod == Modifiers.STATIC && !receiver.isClassAccess() || // b
mod == 0 && receiver.isClassAccess() && !receiver.getType().getTheClass().isObject()) {
// Disallow non-static access to static method (a)
// and static access to instance method (unless it's an object class) (b)
invalid = true;
}
final IType receiverType;
if (mod == Modifiers.INFIX && !parameters.isEmpty()) {
// Infix access to infix method
receiverType = parameters.get(0).getCovariantType();
parameterStartIndex = 1;
} else {
// Infix access to instance method
receiverType = this.getReceiverType();
parameterStartIndex = 0;
}
final int receiverMatch = TypeChecker.getTypeMatch(receiver, receiverType, list);
if (receiverMatch == IValue.MISMATCH) {
return;
}
if (arguments == null) {
list.add(new Candidate<>(this, receiverMatch, receiverType, invalid));
return;
}
argumentCount = arguments.size();
argumentStartIndex = 1;
matchValues = new int[1 + argumentCount];
matchTypes = new IType[1 + argumentCount];
matchValues[0] = receiverMatch;
matchTypes[0] = receiverType;
}
final int parametersLeft = parameterCount - parameterStartIndex;
if (argumentCount > parametersLeft && !this.isVariadic()) {
return;
}
int defaults = 0;
int varargs = 0;
for (int argumentIndex = 0; argumentIndex < parametersLeft; argumentIndex++) {
final IParameter parameter = parameters.get(parameterStartIndex + argumentIndex);
final int partialVarargs = arguments.checkMatch(matchValues, matchTypes, argumentStartIndex, argumentIndex, parameter, list);
switch(partialVarargs) {
case ArgumentList.MISMATCH:
return;
case ArgumentList.DEFAULT:
defaults++;
continue;
default:
varargs += partialVarargs;
}
}
for (int matchValue : matchValues) {
if (matchValue == IValue.MISMATCH) {
// Mismatch
return;
}
}
list.add(new Candidate<>(this, matchValues, matchTypes, defaults, varargs, invalid));
}
Aggregations