Skip to content

Commit

Permalink
Allow methods and lambdas as annotation arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
Gene Gleyzer committed May 20, 2022
1 parent 83f5669 commit cba0799
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,32 @@ public MethodConstant getMethodConstant()
@Override
public ObjectHandle getHandle(Frame frame)
{
// this logic is basically a re-arranged copy of MBind op functionality
GenericHandle hThis = (GenericHandle) frame.getThis();
ObjectHandle hTarget = hThis.getField(frame, GenericHandle.OUTER);
MethodConstant idMethod = m_idMethod;
MethodStructure method = (MethodStructure) idMethod.getComponent();
ObjectHandle hTarget;
CallChain chain;

CallChain chain;
if (method != null && method.getAccess() == Access.PRIVATE)
if (idMethod.isLambda())
{
chain = new CallChain(method);
// the lambda code will get the OUTER handle itself
hTarget = hThis;
chain = new CallChain(method);
}
else
{
Object nid = idMethod.resolveNestedIdentity(
frame.poolContext(), frame.getGenericsResolver(true));
chain = hTarget.getComposition().getMethodCallChain(nid);
hTarget = hThis.getField(frame, GenericHandle.OUTER);

if (method != null && method.getAccess() == Access.PRIVATE)
{
chain = new CallChain(method);
}
else
{
Object nid = idMethod.resolveNestedIdentity(
frame.poolContext(), frame.getGenericsResolver(true));
chain = hTarget.getComposition().getMethodCallChain(nid);
}
}

if (chain.getDepth() == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.xvm.asm.constants.ClassConstant;
import org.xvm.asm.constants.ExpressionConstant;
import org.xvm.asm.constants.IdentityConstant;
import org.xvm.asm.constants.MethodBindingConstant;
import org.xvm.asm.constants.MethodConstant;
import org.xvm.asm.constants.TypeConstant;
import org.xvm.asm.constants.TypeInfo;
Expand Down Expand Up @@ -305,8 +306,8 @@ public void validateContent(StageMgr mgr, ErrorListener errs)
{
Expression exprOld = listArgs.get(iArg);
int iParam = exprOld instanceof LabeledExpression exprLbl
? constructor.getParam(exprLbl.getName()).getIndex()
: iArg;
? constructor.getParam(exprLbl.getName()).getIndex()
: iArg;

Expression exprNew = exprOld.validate(ctx, atypeParams[iParam], errs);
if (exprNew != null)
Expand All @@ -325,15 +326,40 @@ public void validateContent(StageMgr mgr, ErrorListener errs)
// constructed, because we were too early in the compile cycle to resolve
// any constant expressions that refer to anything _by name_
aconstArgs[iParam] = exprNew.toConstant();
continue;
}
else if (exprNew.isNonBinding())

if (exprNew.isNonBinding())
{
fDefaults = true;
continue;
}
else

if (hasThis())
{
exprOld.log(errs, Severity.ERROR, Compiler.CONSTANT_REQUIRED);
MethodStructure method = null;
if (exprNew instanceof NameExpression exprName &&
exprName.getMeaning() == NameExpression.Meaning.Method)
{
MethodConstant idMethod = (MethodConstant)
exprName.resolveRawArgument(ctx, false, ErrorListener.BLACKHOLE);
method = (MethodStructure) idMethod.getComponent();
}
else if (exprNew instanceof LambdaExpression exprLambda)
{
method = exprLambda.getLambda();

exprLambda.calculateBindings(ctx, method.createCode(), errs);
}

if (method != null && method.getParamCount() == 0)
{
aconstArgs[iParam] =
new MethodBindingConstant(pool, method.getIdentityConstant());
continue;
}
}
exprOld.log(errs, Severity.ERROR, Compiler.CONSTANT_REQUIRED);
}
}

Expand Down Expand Up @@ -574,6 +600,12 @@ public boolean isVarDeclaredInThisScope(String sName)
return false;
}

@Override
public boolean isVarReadable(String sName)
{
return sName.equals("this") && hasThis();
}

@Override
public boolean isVarWritable(String sName)
{
Expand All @@ -600,6 +632,26 @@ public Context exit()
return this;
}

@Override
public void requireThis(long lPos, ErrorListener errs)
{
if (!hasThis())
{
// the super call will log the error
super.requireThis(lPos, errs);
}
}

@Override
public TypeConstant getThisType()
{
// within an instance property annotation "this" refers to the containing class
PropertyStructure prop = getAnnotatedProperty();
return prop == null || prop.isStatic()
? null
: prop.getContainingClass().getFormalType();
}

@Override
public Map<String, Assignment> prepareJump(Context ctxDest)
{
Expand Down
24 changes: 10 additions & 14 deletions javatools/src/main/java/org/xvm/compiler/ast/LambdaExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -1405,14 +1405,8 @@ protected void promoteNonCompleting(Context ctxInner)
@Override
public void requireThis(long lPos, ErrorListener errs)
{
if (getOuterContext().isFunction())
{
errs.log(Severity.ERROR, Compiler.NO_THIS, null, getSource(), lPos, lPos);
}
else
{
super.requireThis(lPos, errs);
}
getOuterContext().requireThis(lPos, errs);
captureThis();
}

@Override
Expand All @@ -1430,6 +1424,8 @@ protected void markVarRead(boolean fNested, String sName, Token tokName, boolean
boolean fAllowConstructor = false;
switch (sName)
{
// the only names that we capture _without_ a capture parameter are the
// various "this" references that refer to "this" object
case "this":
case "this:struct":
case "this:class":
Expand All @@ -1439,15 +1435,15 @@ protected void markVarRead(boolean fNested, String sName, Token tokName, boolean
case "this:public":
case "this:protected":
case "this:private":
// the only names that we capture _without_ a capture parameter are the
// various "this" references that refer to "this" object
if (ctxOuter.isMethod() ||
fAllowConstructor && ctxOuter.isConstructor())
if (fAllowConstructor && ctxOuter.isConstructor())
{
captureThis();
return;
}
break;
else
{
requireThis(tokName.getStartPosition(), errs);
}
return;

case "this:service":
case "this:module":
Expand Down
8 changes: 2 additions & 6 deletions javatools_bridge/src/main/x/_native/net/RTNetwork.x
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ service RTNetwork(Boolean secure)
implements Network
{
@Override
// TODO GG: @Lazy(instantiateNameService) NameService nameService;
@Lazy NameService nameService.calc()
{
return instantiateNameService();
}
@Lazy(instantiateNameService) NameService nameService;

@Override
@RO NetworkInterface[] interfaces.get()
Expand Down Expand Up @@ -70,4 +66,4 @@ service RTNetwork(Boolean secure)

conditional ServerSocket nativeListen(Byte[] localAddressBytes, UInt16 localPort)
{TODO("Native");}
}
}
11 changes: 7 additions & 4 deletions manualTests/src/main/x/misc.x
Original file line number Diff line number Diff line change
Expand Up @@ -568,10 +568,10 @@ module TestMisc
console.println("lit=" + lit);

Point point1 = new Point(0, 2);
console.println($"point1={point1}");
console.println($"point1={point1} hypo={point1.hypo}");

NamedPoint point2 = new NamedPoint("top-left", 1, 0);
console.println($"point2={point2}");
console.println($"point2={point2} hypo={point2.hypo}");

Hasher<Point> hasherP = new NaturalHasher<Point>();
Hasher<NamedPoint> hasherN = new NaturalHasher<NamedPoint>();
Expand All @@ -593,7 +593,10 @@ module TestMisc
assert foo == bar;
}

const Point(Int x, Int y);
const Point(Int x, Int y)
{
@Lazy(() -> x*x + y*y) Int hypo;
}

const NamedPoint(String name, Int x, Int y)
extends Point(2*y, x + 1)
Expand Down Expand Up @@ -732,4 +735,4 @@ module TestMisc
}
console.println("We have lift-off!");
}
}
}

0 comments on commit cba0799

Please sign in to comment.