use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.
the class Template method makeGenerateSpecMethod.
private void makeGenerateSpecMethod() {
// func generate(spec: Specialization, writer: java.io.Writer) throws IOException -> void = { ... }
final ParameterList params = this.genMethod.getParameters();
final CodeParameter specParam = new CodeParameter(this.genMethod, null, Name.fromRaw("spec"), Template.LazyTypes.Specialization);
final CodeParameter writerParam = new CodeParameter(this.genMethod, null, Name.fromRaw("writer"), Template.LazyTypes.Writer);
params.add(specParam);
params.add(writerParam);
this.genMethod.getExceptions().add(Template.LazyTypes.IOException);
}
use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.
the class ExternalClass method visitMethod.
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if ((access & Modifiers.SYNTHETIC) != 0) {
return null;
}
switch(name) {
case "<clinit>":
return null;
case "<init>":
if (this.hasModifier(Modifiers.ENUM)) {
return null;
}
final ExternalConstructor ctor = new ExternalConstructor(this, readModifiers(access));
if (signature != null) {
readConstructorType(signature, ctor);
} else {
readConstructorType(desc, ctor);
if (exceptions != null) {
readExceptions(exceptions, ctor.getExceptions());
}
}
if ((access & Modifiers.ACC_VARARGS) != 0) {
final ParameterList parameterList = ctor.getExternalParameterList();
parameterList.get(parameterList.size() - 1).setVarargs();
}
this.body.addConstructor(ctor);
return new SimpleMethodVisitor(ctor);
}
if (this.isAnnotation() && (access & Modifiers.STATIC) == 0) {
final ClassParameter param = new ExternalClassParameter(this, Name.fromQualified(name), desc.substring(2), readReturnType(desc), readModifiers(access));
this.parameters.add(param);
return new AnnotationClassVisitor(param);
}
final ExternalMethod method = new ExternalMethod(this, name, desc, signature, readModifiers(access));
if (signature != null) {
readMethodType(signature, method);
} else {
readMethodType(desc, method);
if (exceptions != null) {
readExceptions(exceptions, method.getExceptions());
}
}
if ((access & Modifiers.ACC_VARARGS) != 0) {
final ParameterList parameterList = method.getExternalParameterList();
parameterList.get(parameterList.size() - 1).setVarargs();
}
this.body.addMethod(method);
return new SimpleMethodVisitor(method);
}
use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.
the class AbstractMethod method checkArguments.
@Override
public IValue checkArguments(MarkerList markers, SourcePosition position, IContext context, IValue receiver, ArgumentList arguments, GenericData genericData) {
final ParameterList parameters = this.getParameters();
if (receiver != null) {
final int mod = this.attributes.flags() & Modifiers.INFIX;
if (mod == Modifiers.INFIX && !receiver.isClassAccess() && !parameters.isEmpty()) {
// infix or extension method, declaring class implicit
final IParameter parameter = parameters.get(0);
final IType paramType = parameter.getCovariantType();
updateReceiverType(receiver, genericData);
receiver = TypeChecker.convertValue(receiver, paramType, genericData, markers, context, TypeChecker.markerSupplier("method.access.infix_type", this.name));
updateReceiverType(receiver, genericData);
for (int i = 1, count = parameters.size(); i < count; i++) {
arguments.checkValue(i - 1, parameters.get(i), genericData, position, markers, context);
}
if (genericData != null) {
this.checkTypeVarsInferred(markers, position, genericData);
}
return receiver;
}
updateReceiverType(receiver, genericData);
if ((mod & Modifiers.STATIC) != 0) {
if (!receiver.isClassAccess()) {
// static method called like instance method -> warning
markers.add(Markers.semanticError(position, "method.access.static", this.name));
} else if (this.getReceiverType().getTheClass() == this.enclosingClass && receiver.getType().getTheClass() != this.enclosingClass) {
// static method called on wrong type -> warning
markers.add(Markers.semantic(position, "method.access.static.type", this.name, this.enclosingClass.getFullName()));
}
receiver = receiver.asIgnoredClassAccess();
} else if (receiver.isClassAccess()) {
if (!receiver.getType().getTheClass().isObject()) {
// declaring class is not an object class -> error
markers.add(Markers.semanticError(position, "method.access.instance", this.name));
}
} else {
// normal instance method access
receiver = TypeChecker.convertValue(receiver, this.getReceiverType(), receiver.getType(), markers, context, TypeChecker.markerSupplier("method.access.receiver_type", this.name));
}
if (receiver != null) {
updateReceiverType(receiver, genericData);
}
} else if (!this.isStatic()) {
if (!context.isThisAvailable()) {
// called from static context -> error
markers.add(Markers.semantic(position, "method.access.instance", this.name));
} else {
// unqualified call
final IType receiverType = this.enclosingClass.getThisType();
receiver = new ThisExpr(position, receiverType, markers, context);
if (genericData != null) {
genericData.setFallbackTypeContext(receiverType);
}
if (!this.isNested() && !this.enclosingClass.isAnonymous()) {
markers.add(Markers.semantic(position, "method.access.unqualified", this.name.unqualified));
}
}
}
for (int i = 0, count = parameters.size(); i < count; i++) {
arguments.checkValue(i, parameters.get(i), genericData, position, markers, context);
}
if (genericData != null) {
this.checkTypeVarsInferred(markers, position, genericData);
}
return receiver;
}
use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.
the class AbstractMethod method overrides.
@Override
public boolean overrides(IMethod candidate, ITypeContext typeContext) {
if (// don't check static final
candidate.hasModifier(Modifiers.STATIC_FINAL) || // different number of type params
this.typeArity() != candidate.typeArity() || // different name
this.name != candidate.getName() && // and different internal name
!candidate.getInternalName().equals(this.getInternalName())) // this means either name or internal name or both must match to consider an override
// if only one matches then there is special code in CodeMethod.filterOverride that produces diagnostics
{
return false;
}
final ParameterList thisParameters = this.getParameters();
final ParameterList candidateParameters = candidate.getParameters();
if (// different number of parameters
candidateParameters.size() != thisParameters.size()) {
return false;
}
// Check the cache
if (this.overrideMethods != null && this.overrideMethods.contains(candidate)) {
return true;
}
// Check Parameter Types
for (int i = 0, count = thisParameters.size(); i < count; i++) {
final IType parType = thisParameters.get(i).getCovariantType().getConcreteType(typeContext);
final IType candidateParType = candidateParameters.get(i).getCovariantType().getConcreteType(typeContext);
if (!Types.isSameType(parType, candidateParType)) {
return false;
}
}
return true;
}
use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.
the class CodeMethod method writeBridgeParameters.
private void writeBridgeParameters(MethodWriter methodWriter, IMethod overrideMethod) {
final int lineNumber = this.lineNumber();
final ParameterList overrideParameterList = overrideMethod.getParameters();
for (int p = 0, count = overrideParameterList.size(); p < count; p++) {
final IParameter overrideParameter = overrideParameterList.get(p);
final IType parameterType = this.parameters.get(p).getCovariantType();
final IType overrideParameterType = overrideParameter.getCovariantType();
overrideParameter.writeParameter(methodWriter);
methodWriter.visitVarInsn(overrideParameterType.getLoadOpcode(), overrideParameter.getLocalIndex());
overrideParameterType.writeCast(methodWriter, parameterType, lineNumber);
}
}
Aggregations