Search in sources :

Example 11 with ParameterList

use of dyvilx.tools.compiler.ast.parameter.ParameterList 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);
        }
    }
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) IValue(dyvilx.tools.compiler.ast.expression.IValue) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) IClass(dyvilx.tools.compiler.ast.classes.IClass) IType(dyvilx.tools.compiler.ast.type.IType)

Example 12 with ParameterList

use of dyvilx.tools.compiler.ast.parameter.ParameterList 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();
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) IValue(dyvilx.tools.compiler.ast.expression.IValue) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) IClass(dyvilx.tools.compiler.ast.classes.IClass)

Example 13 with ParameterList

use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.

the class AbstractMethod method checkImplicitMatch.

@Override
public void checkImplicitMatch(MatchList<IMethod> list, IValue value, IType type) {
    if (!this.isImplicitConversion()) {
        // The method has to be 'implicit static'
        return;
    }
    final ParameterList parameterList = this.getParameters();
    if (parameterList.size() != 1) {
        // and only take exactly one parameter
        return;
    }
    if (type != null && !Types.isSuperType(type, this.getType().asParameterType())) {
        // The method's return type has to be a sub-type of the target type
        return;
    }
    final IType parType = parameterList.get(0).getCovariantType();
    // Note: this explicitly uses null as the context parameter to avoid nested implicit conversions
    final int match = TypeChecker.getTypeMatch(value, parType, null);
    // >= to allow the "light" conversions that are built in based on type, e.g. primitive widening or (un)boxing
    if (match >= IValue.CONVERSION_MATCH) {
        list.add(new Candidate<>(this, match, parType, false));
    }
}
Also used : ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) TypeParameterList(dyvilx.tools.compiler.ast.generic.TypeParameterList) IType(dyvilx.tools.compiler.ast.type.IType)

Example 14 with ParameterList

use of dyvilx.tools.compiler.ast.parameter.ParameterList 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));
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) TypeParameterList(dyvilx.tools.compiler.ast.generic.TypeParameterList) IType(dyvilx.tools.compiler.ast.type.IType)

Example 15 with ParameterList

use of dyvilx.tools.compiler.ast.parameter.ParameterList in project Dyvil by Dyvil.

the class CodeMethod method filterOverride.

private boolean filterOverride(IMethod candidate, MarkerList markers, ITypeContext typeContext) {
    final String candidateInternalName = candidate.getInternalName();
    final boolean sameName = this.name == candidate.getName();
    final boolean sameInternalName = this.getInternalName().equals(candidateInternalName);
    if (// same name but different internal name
    sameName && !sameInternalName) {
        if (this.name.qualified.equals(this.internalName)) // no AutoMangled or BytecodeName annotation, otherwise the user probably knows what they are doing and
        // doesn't need a warning
        {
            final Marker marker = Markers.semantic(this.position, "method.override.mangled_mismatch", this.name, candidateInternalName);
            marker.addInfo(Markers.getSemantic("method.override.mangled_mismatch.info", candidateInternalName));
            markers.add(marker);
        }
        return true;
    }
    if (!sameName && sameInternalName) {
        final Marker marker = Markers.semanticError(this.position, "method.override.mangled_clash", this.name, candidate.getName(), candidateInternalName);
        marker.addInfo(Markers.getSemantic("method.override.mangled_clash.info"));
        // hard error so it doesn't matter if we remove or not - bytecode will never be generated
        return true;
    }
    // sameName && sameInternalName should be true
    final IClass enclosingClass = candidate.getEnclosingClass();
    boolean errors = true;
    for (IMethod method : this.overrideMethods) {
        if (method != candidate && method.getEnclosingClass() == enclosingClass) {
            // If this method overrides two methods from the same class, we do not produce any parameter label errors
            errors = false;
        }
    }
    final ParameterList params = candidate.getParameters();
    for (int i = 0, count = params.size(); i < count; i++) {
        final IParameter thisParam = this.parameters.get(i);
        final Name thisName = thisParam.getLabel();
        final Name otherName = params.get(i).getLabel();
        if (thisName == otherName || thisName == null || otherName == null) {
            // Parameter labels match
            continue;
        }
        if (errors) {
            final Marker marker = Markers.semantic(thisParam.getPosition(), "method.override.parameter_label", i + 1, thisName, otherName);
            addOverrideInfo(typeContext, candidate, marker);
            markers.add(marker);
        }
        // This method does not properly override the candidate
        return true;
    }
    return false;
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) TypeParameterList(dyvilx.tools.compiler.ast.generic.TypeParameterList) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) Marker(dyvilx.tools.parsing.marker.Marker) IClass(dyvilx.tools.compiler.ast.classes.IClass) Name(dyvil.lang.Name)

Aggregations

ParameterList (dyvilx.tools.compiler.ast.parameter.ParameterList)27 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)12 IType (dyvilx.tools.compiler.ast.type.IType)11 TypeParameterList (dyvilx.tools.compiler.ast.generic.TypeParameterList)7 IClass (dyvilx.tools.compiler.ast.classes.IClass)5 IValue (dyvilx.tools.compiler.ast.expression.IValue)5 IConstructor (dyvilx.tools.compiler.ast.constructor.IConstructor)3 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)3 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)3 CodeParameter (dyvilx.tools.compiler.ast.parameter.CodeParameter)3 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)2 ThisExpr (dyvilx.tools.compiler.ast.expression.ThisExpr)2 IDataMember (dyvilx.tools.compiler.ast.field.IDataMember)2 Name (dyvil.lang.Name)1 SourcePosition (dyvil.source.position.SourcePosition)1 Label (dyvilx.tools.asm.Label)1 IInstruction (dyvilx.tools.compiler.ast.bytecode.IInstruction)1 VarInstruction (dyvilx.tools.compiler.ast.bytecode.VarInstruction)1 ClassBody (dyvilx.tools.compiler.ast.classes.ClassBody)1 CodeConstructor (dyvilx.tools.compiler.ast.constructor.CodeConstructor)1