use of dyvilx.tools.compiler.ast.expression.access.FieldAccess in project Dyvil by Dyvil.
the class TypeVarType method checkType.
@Override
public void checkType(MarkerList markers, IContext context, int position) {
if ((position & TypePosition.REIFY_FLAG) == 0) {
return;
}
final Reified.Type reifiedKind = this.typeParameter.getReifiedKind();
if (reifiedKind == null) {
return;
}
final IParameter reifyParameter = this.typeParameter.getReifyParameter();
if (reifyParameter == null) {
return;
}
this.reifyVariableAccess = new FieldAccess(reifyParameter).resolve(markers, context);
// ensure proper capture
this.reifyVariableAccess.checkTypes(markers, context);
}
use of dyvilx.tools.compiler.ast.expression.access.FieldAccess 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);
}
use of dyvilx.tools.compiler.ast.expression.access.FieldAccess 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;
}
use of dyvilx.tools.compiler.ast.expression.access.FieldAccess in project Dyvil by Dyvil.
the class CaptureParameter method getDefaultValue.
@Override
public IValue getDefaultValue(IContext context) {
final IValue access = new FieldAccess(this.variable) {
@Override
public void writeExpression(MethodWriter writer, IType type) throws BytecodeException {
this.field.writeGetRaw(writer, this.receiver, this.lineNumber());
}
}.resolve(MarkerList.BLACKHOLE, context);
// ensures proper capture
access.checkTypes(MarkerList.BLACKHOLE, context);
return access;
}
use of dyvilx.tools.compiler.ast.expression.access.FieldAccess in project Dyvil by Dyvil.
the class Template method makeMainMethod.
private void makeMainMethod() {
// func main(args: [String]) -> void = new TemplateName().mainImpl(args)
final ParameterList params = this.mainMethod.getParameters();
final CodeParameter argsParam = new CodeParameter(this.mainMethod, null, Name.fromRaw("args"), new ArrayType(Types.STRING));
params.add(argsParam);
final IValue newTemplate = new ConstructorCall(null, this.templateClass.getClassType(), ArgumentList.EMPTY);
this.mainMethod.setValue(new MethodCall(null, newTemplate, Name.fromRaw("mainImpl"), new ArgumentList(new FieldAccess(argsParam))));
}
Aggregations