Search in sources :

Example 1 with ThisExpr

use of dyvilx.tools.compiler.ast.expression.ThisExpr in project Dyvil by Dyvil.

the class Field method resolve.

@Override
public void resolve(MarkerList markers, IContext context) {
    super.resolve(markers, context);
    if (this.value != null) {
        final IContext context1 = new CombiningContext(this, context);
        this.value = this.value.resolve(markers, context1);
        boolean inferType = false;
        if (this.type == Types.UNKNOWN) {
            inferType = true;
            this.type = this.value.getType();
        }
        final TypeChecker.MarkerSupplier markerSupplier = TypeChecker.markerSupplier("field.type.incompatible", "field.type", "value.type", this.name);
        this.value = TypeChecker.convertValue(this.value, this.type, this.type, markers, context1, markerSupplier);
        if (inferType) {
            this.type = this.value.getType();
            if (this.type == Types.UNKNOWN && this.value.isResolved()) {
                markers.add(Markers.semantic(this.position, "field.type.infer", this.name.unqualified));
                this.type = Types.ANY;
            }
        }
    } else if (this.type == Types.UNKNOWN) {
        markers.add(Markers.semantic(this.position, "field.type.infer.novalue", this.name.unqualified));
        this.type = Types.ANY;
    }
    if (this.property == null) {
        return;
    }
    this.property.setType(this.type);
    final IMethod getter = this.property.getGetter();
    final IMethod setter = this.property.getSetter();
    final IValue receiver = this.hasModifier(Modifiers.STATIC) ? null : new ThisExpr(this.enclosingClass.getThisType(), VariableThis.DEFAULT);
    if (getter != null) {
        getter.setType(this.type);
        if (getter.getValue() == null) {
            // get: this.FIELD_NAME
            getter.setValue(new FieldAccess(getter.getPosition(), receiver, this));
        }
    }
    if (setter != null) {
        final IParameter setterParameter = setter.getParameters().get(0);
        setterParameter.setType(this.type);
        if (setter.getValue() == null) {
            final SourcePosition setterPosition = setter.getPosition();
            if (this.hasModifier(Modifiers.FINAL)) {
                markers.add(Markers.semanticError(setterPosition, "field.property.setter.final", this.name));
                // avoid abstract method error
                setter.setValue(new VoidValue(setterPosition));
            } else {
                // set: this.FIELD_NAME = newValue
                setter.setValue(new FieldAssignment(setterPosition, receiver, this, new FieldAccess(setterPosition, null, setterParameter)));
            }
        }
    }
    this.property.resolve(markers, context);
}
Also used : VoidValue(dyvilx.tools.compiler.ast.expression.constant.VoidValue) IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) IContext(dyvilx.tools.compiler.ast.context.IContext) TypeChecker(dyvilx.tools.compiler.transform.TypeChecker) CombiningContext(dyvilx.tools.compiler.ast.context.CombiningContext) FieldAssignment(dyvilx.tools.compiler.ast.expression.access.FieldAssignment) IValue(dyvilx.tools.compiler.ast.expression.IValue) SourcePosition(dyvil.source.position.SourcePosition) IMethod(dyvilx.tools.compiler.ast.method.IMethod) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) ThisExpr(dyvilx.tools.compiler.ast.expression.ThisExpr)

Example 2 with ThisExpr

use of dyvilx.tools.compiler.ast.expression.ThisExpr in project Dyvil by Dyvil.

the class ThisSuperParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    final int type = token.type();
    switch(this.mode) {
        case THIS_SUPER:
            switch(type) {
                case DyvilKeywords.THIS:
                    this.mode = TYPE;
                    this.value = new ThisExpr(token.raw());
                    return;
                case DyvilKeywords.SUPER:
                    this.mode = TYPE;
                    this.value = new SuperExpr(token.raw());
                    return;
            }
            pm.popParser(true);
            return;
        case TYPE:
            if (ExpressionParser.isGenericCall(token, type)) {
                this.mode = TYPE_END;
                pm.splitJump(token, 1);
                pm.pushParser(new TypeParser(this.value, true));
                return;
            }
            this.valueConsumer.setValue(this.value);
            pm.popParser(true);
            return;
        case TYPE_END:
            pm.popParser();
            this.valueConsumer.setValue(this.value);
            if (!TypeParser.isGenericEnd(token, type)) {
                pm.reparse();
                pm.report(token, this.value.valueTag() == IValue.SUPER ? "super.close_angle" : "this.close_angle");
                return;
            }
            pm.splitJump(token, 1);
    }
}
Also used : TypeParser(dyvilx.tools.compiler.parser.type.TypeParser) SuperExpr(dyvilx.tools.compiler.ast.expression.SuperExpr) ThisExpr(dyvilx.tools.compiler.ast.expression.ThisExpr)

Example 3 with ThisExpr

use of dyvilx.tools.compiler.ast.expression.ThisExpr 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;
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) FieldAssignment(dyvilx.tools.compiler.ast.expression.access.FieldAssignment) ArgumentList(dyvilx.tools.compiler.ast.parameter.ArgumentList) InitializerCall(dyvilx.tools.compiler.ast.expression.access.InitializerCall) IType(dyvilx.tools.compiler.ast.type.IType) IValue(dyvilx.tools.compiler.ast.expression.IValue) CodeConstructor(dyvilx.tools.compiler.ast.constructor.CodeConstructor) SourcePosition(dyvil.source.position.SourcePosition) StatementList(dyvilx.tools.compiler.ast.statement.StatementList) ParameterList(dyvilx.tools.compiler.ast.parameter.ParameterList) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) ThisExpr(dyvilx.tools.compiler.ast.expression.ThisExpr)

Example 4 with ThisExpr

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

Aggregations

ThisExpr (dyvilx.tools.compiler.ast.expression.ThisExpr)4 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)3 SourcePosition (dyvil.source.position.SourcePosition)2 IValue (dyvilx.tools.compiler.ast.expression.IValue)2 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)2 FieldAssignment (dyvilx.tools.compiler.ast.expression.access.FieldAssignment)2 ParameterList (dyvilx.tools.compiler.ast.parameter.ParameterList)2 IType (dyvilx.tools.compiler.ast.type.IType)2 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)1 CodeConstructor (dyvilx.tools.compiler.ast.constructor.CodeConstructor)1 CombiningContext (dyvilx.tools.compiler.ast.context.CombiningContext)1 IContext (dyvilx.tools.compiler.ast.context.IContext)1 SuperExpr (dyvilx.tools.compiler.ast.expression.SuperExpr)1 InitializerCall (dyvilx.tools.compiler.ast.expression.access.InitializerCall)1 VoidValue (dyvilx.tools.compiler.ast.expression.constant.VoidValue)1 TypeParameterList (dyvilx.tools.compiler.ast.generic.TypeParameterList)1 IMethod (dyvilx.tools.compiler.ast.method.IMethod)1 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)1 StatementList (dyvilx.tools.compiler.ast.statement.StatementList)1 TypeParser (dyvilx.tools.compiler.parser.type.TypeParser)1