Search in sources :

Example 66 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class AbstractMethod method writeReceiver.

protected void writeReceiver(MethodWriter writer, IValue receiver) throws BytecodeException {
    if (receiver == null) {
        return;
    }
    if (!this.isStatic()) {
        receiver.writeNullCheckedExpression(writer, this.enclosingClass.getReceiverType());
        return;
    }
    if (receiver.isIgnoredClassAccess()) {
        final IType type = receiver.getType();
        if (type.hasTag(IType.TYPE_VAR)) {
            // Static virtual call
            type.writeClassExpression(writer, true);
        }
        return;
    }
    if (this.hasModifier(Modifiers.INFIX) && !this.parameters.isEmpty()) {
        receiver.writeExpression(writer, this.parameters.get(0).getCovariantType());
        return;
    }
    // static
    receiver.writeExpression(writer, this.enclosingClass.getReceiverType());
    writer.visitInsn(Opcodes.AUTO_POP);
}
Also used : IType(dyvilx.tools.compiler.ast.type.IType)

Example 67 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class AbstractMethod method checkMutating.

private void checkMutating(MarkerList markers, IValue receiver) {
    final IType receiverType = receiver.getType();
    if (receiverType.getMutability() != Mutability.IMMUTABLE) {
        return;
    }
    final Annotation mutatingAnnotation = this.getAnnotation(Types.MUTATING_CLASS);
    if (mutatingAnnotation == null) {
        return;
    }
    final IValue value = mutatingAnnotation.getArguments().get(0, Names.value);
    final String stringValue = value != null ? value.stringValue() : Mutating.DEFAULT_MESSAGE;
    StringBuilder builder = new StringBuilder(stringValue);
    int index = builder.indexOf("{method}");
    if (index >= 0) {
        builder.replace(index, index + 8, this.name.unqualified);
    }
    index = builder.indexOf("{type}");
    if (index >= 0) {
        builder.replace(index, index + 6, receiverType.toString());
    }
    markers.add(new SemanticError(receiver.getPosition(), builder.toString()));
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) SemanticError(dyvilx.tools.parsing.marker.SemanticError) Annotation(dyvilx.tools.compiler.ast.attribute.annotation.Annotation) IType(dyvilx.tools.compiler.ast.type.IType)

Example 68 with IType

use of dyvilx.tools.compiler.ast.type.IType 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 69 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class AbstractMethod method checkTypeVarsInferred.

private void checkTypeVarsInferred(MarkerList markers, SourcePosition position, GenericData genericData) {
    if (this.typeParameters == null) {
        return;
    }
    final int count = this.typeParameters.size();
    genericData.lock(count);
    for (int i = 0; i < count; i++) {
        final ITypeParameter typeParameter = this.typeParameters.get(i);
        final IType typeArgument = genericData.resolveType(typeParameter);
        if (typeArgument == null || typeArgument instanceof CovariantTypeVarType) {
            final IType inferredType = typeParameter.getUpperBound();
            markers.add(Markers.semantic(position, "method.typevar.infer", this.name, typeParameter.getName(), inferredType));
            genericData.addMapping(typeParameter, inferredType);
        } else if (!typeParameter.isAssignableFrom(typeArgument, genericData)) {
            final Marker marker = Markers.semanticError(position, "method.typevar.incompatible", this.name, typeParameter.getName());
            marker.addInfo(Markers.getSemantic("type.generic.argument", typeArgument));
            marker.addInfo(Markers.getSemantic("type_parameter.declaration", typeParameter));
            markers.add(marker);
        }
    }
}
Also used : ITypeParameter(dyvilx.tools.compiler.ast.generic.ITypeParameter) CovariantTypeVarType(dyvilx.tools.compiler.ast.type.typevar.CovariantTypeVarType) Marker(dyvilx.tools.parsing.marker.Marker) IType(dyvilx.tools.compiler.ast.type.IType)

Example 70 with IType

use of dyvilx.tools.compiler.ast.type.IType 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)

Aggregations

IType (dyvilx.tools.compiler.ast.type.IType)159 IClass (dyvilx.tools.compiler.ast.classes.IClass)26 Marker (dyvilx.tools.parsing.marker.Marker)23 IValue (dyvilx.tools.compiler.ast.expression.IValue)21 TypeParameterList (dyvilx.tools.compiler.ast.generic.TypeParameterList)13 ParameterList (dyvilx.tools.compiler.ast.parameter.ParameterList)11 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)10 SourcePosition (dyvil.source.position.SourcePosition)9 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)9 ITypeParameter (dyvilx.tools.compiler.ast.generic.ITypeParameter)9 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)9 TypeList (dyvilx.tools.compiler.ast.type.TypeList)7 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)6 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)6 IVariable (dyvilx.tools.compiler.ast.field.IVariable)6 ArrayType (dyvilx.tools.compiler.ast.type.compound.ArrayType)6 MethodWriter (dyvilx.tools.compiler.backend.MethodWriter)6 CodeMethod (dyvilx.tools.compiler.ast.method.CodeMethod)5 CodeParameter (dyvilx.tools.compiler.ast.parameter.CodeParameter)5 Name (dyvil.lang.Name)4