use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class AbstractCall method checkArguments.
// every resolveCall implementation calls this
protected final IValue checkArguments(MarkerList markers, IContext context, IMethod method) {
this.method = method;
final IntrinsicData intrinsicData = method.getIntrinsicData();
final int code;
final IValue intrinsic;
if (// Intrinsic annotation
intrinsicData != null && // compilerCode argument
(code = intrinsicData.getCompilerCode()) != 0 && // valid intrinsic
(intrinsic = Intrinsics.getOperator(code, this.receiver, this.arguments)) != null) {
Deprecation.checkAnnotations(method, this.position, markers);
intrinsic.setPosition(this.position);
return intrinsic;
}
final GenericData genericData;
if (this.genericData != null) {
genericData = this.genericData = method.getGenericData(this.genericData, this.receiver, this.arguments);
} else {
genericData = this.getGenericData();
}
this.receiver = method.checkArguments(markers, this.position, context, this.receiver, this.arguments, genericData);
this.type = null;
this.type = this.getType();
return OptionalChainAware.transform(this);
}
use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class AbstractFieldAccess method resolveAsFieldOrMethod.
private IValue resolveAsFieldOrMethod(MarkerList markers, IContext context) {
IValue value;
if (ICall.privateAccess(context, this.receiver)) {
final IValue implicit;
if (this.receiver == null && (implicit = context.resolveImplicit(null)) != null) {
value = this.resolveAsMethod(implicit, markers, context);
if (value != null) {
return value;
}
value = this.resolveAsField(implicit, markers, context);
if (value != null) {
return value;
}
}
value = this.resolveAsField(this.receiver, markers, context);
if (value != null) {
return value;
}
value = this.resolveAsMethod(this.receiver, markers, context);
if (value != null) {
return value;
}
} else {
value = this.resolveAsMethod(this.receiver, markers, context);
if (value != null) {
return value;
}
value = this.resolveAsField(this.receiver, markers, context);
if (value != null) {
return value;
}
}
return null;
}
use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class ApplyAccess method resolve.
@Override
public IValue resolve(MarkerList markers, IContext context) {
// -> with(x..., { statements })
if (this.arguments.size() == 1 && this.receiver instanceof ICall) {
final ICall call = (ICall) this.receiver;
IValue argument = this.arguments.getFirst();
if (argument instanceof Closure) {
argument = argument.resolve(markers, context);
final ArgumentList oldArgs = call.getArguments();
call.resolveReceiver(markers, context);
call.resolveArguments(markers, context);
call.setArguments(oldArgs.appended(null, argument));
final IValue resolvedCall = call.resolveCall(markers, context, false);
if (resolvedCall != null) {
return resolvedCall;
}
// Revert
call.setArguments(oldArgs);
this.receiver = call.resolveCall(markers, context, true);
return this.resolveCall(markers, context, true);
}
}
return super.resolve(markers, context);
}
use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class ApplyAccess method toCompoundAssignment.
@Override
public IValue toCompoundAssignment(IValue rhs, SourcePosition position, MarkerList markers, IContext context, SideEffectHelper helper) {
// x(y...) (op)= z
// -> x(y...) = x(y...) (op) z
// note that x and y... are each only evaluated once
final IValue applyReceiver = helper.processValue(this.receiver);
final ArgumentList applyArguments = helper.processArguments(this.arguments);
this.arguments = applyArguments;
this.receiver = applyReceiver;
return new ApplyAssignment(position, applyReceiver, applyArguments, rhs).resolveCall(markers, context, true);
}
use of dyvilx.tools.compiler.ast.expression.IValue 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;
}
Aggregations