Search in sources :

Example 1 with SourcePosition

use of dyvil.source.position.SourcePosition 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 SourcePosition

use of dyvil.source.position.SourcePosition in project Dyvil by Dyvil.

the class OptionalChainAware method nullCoalescing.

static IValue nullCoalescing(IValue lhs, IValue rhs) {
    BindingIfStatement bindingIf;
    if (lhs instanceof BindingIfStatement && (bindingIf = (BindingIfStatement) lhs).getElse() == NullValue.NULL) {
        // safe bet that the rhs used to be an optional chain
        // this branch is actually an optimization and technically not necessary, but it is very common
        // to use the null coalescing operator after an optional chain.
        final IValue then = bindingIf.getThen();
        if (NullableType.isNullable(then.getType())) {
            // Perform the following transformation:
            // if let $0 = oldReceiver { $0.oldAccess } else null
            // becomes
            // if (let $0 = oldReceiver, let $1 = $0.oldAccess) { $1 } else { <rhs> }
            final Variable var = newVar(bindingIf.getPosition(), then);
            bindingIf.addVariable(var);
            bindingIf.setThen(new FieldAccess(var));
        }
        // if the then branch of the old binding if is not nullable, we simply set the rhs
        bindingIf.setElse(rhs);
        return bindingIf;
    }
    // the lhs was not an optional chain, so we set up an impromptu null coalescing inline implementation
    final SourcePosition position = lhs.getPosition();
    // let l = <lhs>
    final Variable var = newVar(position, lhs);
    // if let l = <lhs> { l } else { <rhs> }
    bindingIf = new BindingIfStatement(position);
    bindingIf.addVariable(var);
    bindingIf.setThen(new FieldAccess(var));
    bindingIf.setElse(rhs);
    return bindingIf;
}
Also used : BindingIfStatement(dyvilx.tools.compiler.ast.statement.BindingIfStatement) IValue(dyvilx.tools.compiler.ast.expression.IValue) Variable(dyvilx.tools.compiler.ast.field.Variable) SourcePosition(dyvil.source.position.SourcePosition) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess)

Example 3 with SourcePosition

use of dyvil.source.position.SourcePosition in project Dyvil by Dyvil.

the class ICall method toLambda.

default IValue toLambda(MarkerList markers, IContext context, int wildcards) {
    SourcePosition position = this.getPosition();
    final IParameter[] parameters = new IParameter[wildcards];
    for (int i = 0; i < wildcards; i++) {
        parameters[i] = new CodeParameter(null, position, Name.fromRaw("wildcard$" + i), Types.UNKNOWN, new AttributeList());
    }
    int parIndex = 0;
    final IValue receiver = this.getReceiver();
    if (receiver != null && receiver.isPartialWildcard()) {
        this.setReceiver(receiver.withLambdaParameter(parameters[parIndex++]));
    }
    final ArgumentList arguments = this.getArguments();
    for (int i = 0, size = arguments.size(); i < size; i++) {
        final IValue argument = arguments.get(i, null);
        if (argument.isPartialWildcard()) {
            arguments.set(i, null, argument.withLambdaParameter(parameters[parIndex++]));
        }
    }
    final LambdaExpr lambdaExpr = new LambdaExpr(position, parameters, wildcards);
    lambdaExpr.setImplicitParameters(true);
    lambdaExpr.setValue(this);
    return lambdaExpr.resolve(markers, context);
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) IValue(dyvilx.tools.compiler.ast.expression.IValue) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) SourcePosition(dyvil.source.position.SourcePosition) LambdaExpr(dyvilx.tools.compiler.ast.expression.LambdaExpr) ArgumentList(dyvilx.tools.compiler.ast.parameter.ArgumentList) CodeParameter(dyvilx.tools.compiler.ast.parameter.CodeParameter)

Example 4 with SourcePosition

use of dyvil.source.position.SourcePosition in project Dyvil by Dyvil.

the class ProcessedText method resolve.

@Override
public IValue resolve(MarkerList markers, IContext context) {
    final int startLine = this.position.startLine();
    final int startColumn = this.position.startColumn();
    final StringInterpolationExpr parts = new StringInterpolationExpr();
    final String text = this.text;
    final int length = text.length();
    int prev = 0;
    for (int startIndex = 0; startIndex < length; ) {
        final int c = text.codePointAt(startIndex);
        // advance to an identifier character
        if (!Character.isJavaIdentifierStart(c)) {
            startIndex += Character.charCount(c);
            continue;
        }
        final int endIndex = identifierEnd(text, startIndex + 1, length);
        final String key = text.substring(startIndex, endIndex);
        final IDataMember field = context.resolveField(Name.fromRaw(key));
        if (field != null && (field.isLocal() || field.hasModifier(Modifiers.PUBLIC))) {
            // append contents before this identifier
            parts.append(new StringValue(text.substring(prev, startIndex)));
            final SourcePosition position = SourcePosition.apply(startLine, startColumn + startIndex, startColumn + endIndex);
            parts.append(new FieldAccess(position, null, field));
            // advance to the end of the identifier
            prev = endIndex;
            startIndex = endIndex;
            continue;
        }
        startIndex += Character.charCount(c);
    }
    if (prev != length) {
        parts.append(new StringValue(text.substring(prev, length)));
    }
    return new WriteCall(parts.resolve(markers, context));
}
Also used : SourcePosition(dyvil.source.position.SourcePosition) StringInterpolationExpr(dyvilx.tools.compiler.ast.expression.StringInterpolationExpr) StringValue(dyvilx.tools.compiler.ast.expression.constant.StringValue) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) IDataMember(dyvilx.tools.compiler.ast.field.IDataMember)

Example 5 with SourcePosition

use of dyvil.source.position.SourcePosition in project Dyvil by Dyvil.

the class CaseClassMetadata method createUnapplyMethod.

private CodeMethod createUnapplyMethod() {
    // static final func unapply<TypeParams...>(value: This) -> (T...)
    final SourcePosition position = this.theClass.position();
    final AttributeList attributes = AttributeList.of(Modifiers.PUBLIC | Modifiers.STATIC_FINAL | Modifiers.GENERATED);
    final IType type = this.getUnapplyReturnType();
    final CodeMethod unapply = new CodeMethod(this.theClass, Names.unapply, type, attributes);
    unapply.setPosition(position);
    unapply.getTypeParameters().addAll(this.theClass.getTypeParameters());
    final CodeParameter parameter = new CodeParameter(unapply, position, Names.value, this.theClass.getThisType());
    unapply.getParameters().add(parameter);
    // = (value.classParams...)
    final TupleExpr tupleExpr = new TupleExpr(position);
    final ArgumentList arguments = tupleExpr.getValues();
    for (IParameter param : this.theClass.getParameters()) {
        // value
        final FieldAccess thisAccess = new FieldAccess(position, null, parameter);
        // value.classParam
        final IValue fieldAccess;
        if (param.isOverride()) {
            // if the class parameter is marked as 'override', we have to resolve it from a super-class
            // the easiest way to do this is by name
            fieldAccess = new FieldAccess(position, thisAccess, param.getName());
        } else {
            fieldAccess = new FieldAccess(position, thisAccess, param);
        }
        arguments.add(fieldAccess);
    }
    unapply.setValue(tupleExpr);
    return unapply;
}
Also used : IParameter(dyvilx.tools.compiler.ast.parameter.IParameter) IValue(dyvilx.tools.compiler.ast.expression.IValue) CodeMethod(dyvilx.tools.compiler.ast.method.CodeMethod) AttributeList(dyvilx.tools.compiler.ast.attribute.AttributeList) SourcePosition(dyvil.source.position.SourcePosition) ArgumentList(dyvilx.tools.compiler.ast.parameter.ArgumentList) FieldAccess(dyvilx.tools.compiler.ast.expression.access.FieldAccess) CodeParameter(dyvilx.tools.compiler.ast.parameter.CodeParameter) TupleExpr(dyvilx.tools.compiler.ast.expression.TupleExpr) IType(dyvilx.tools.compiler.ast.type.IType)

Aggregations

SourcePosition (dyvil.source.position.SourcePosition)20 IValue (dyvilx.tools.compiler.ast.expression.IValue)10 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)8 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)8 IType (dyvilx.tools.compiler.ast.type.IType)8 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)7 CodeMethod (dyvilx.tools.compiler.ast.method.CodeMethod)6 CodeParameter (dyvilx.tools.compiler.ast.parameter.CodeParameter)6 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)5 IContext (dyvilx.tools.compiler.ast.context.IContext)2 ThisExpr (dyvilx.tools.compiler.ast.expression.ThisExpr)2 FieldAssignment (dyvilx.tools.compiler.ast.expression.access.FieldAssignment)2 Variable (dyvilx.tools.compiler.ast.field.Variable)2 IMethod (dyvilx.tools.compiler.ast.method.IMethod)2 BindingIfStatement (dyvilx.tools.compiler.ast.statement.BindingIfStatement)2 ArrayType (dyvilx.tools.compiler.ast.type.compound.ArrayType)2 TypeChecker (dyvilx.tools.compiler.transform.TypeChecker)2 NonNull (dyvil.annotation.internal.NonNull)1 BitSet (dyvil.collection.mutable.BitSet)1 Modifiers (dyvil.reflect.Modifiers)1