Skip to content

Commit 5fa863e

Browse files
committed
minor items
1 parent 23780cf commit 5fa863e

2 files changed

Lines changed: 26 additions & 10 deletions

File tree

src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import java.util.Collection;
4949

50+
import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.hasAnnotation;
5051
import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
5152
import static org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression;
5253
import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
@@ -214,6 +215,7 @@ public Expression transform(final Expression exp) {
214215
varX(weaved)
215216
));
216217
mce.setImplicitThis(false);
218+
mce.setMethodTarget(ClassHelper.CLOSURE_TYPE.getMethods("rehydrate").get(0));
217219
mce.setSourcePosition(exp);
218220
boolean oldInClosure = inClosure;
219221
inClosure = true;
@@ -360,22 +362,24 @@ private Expression transformMethodCallOnThis(final MethodCallExpression call) {
360362
MethodNode methodNode = findConcreteMethod(traitClass, call.getMethodAsString());
361363
if (methodNode != null) {
362364
MethodCallExpression newCall;
363-
boolean virtual = !methodNode.getAnnotations(VIRTUAL_TYPE).isEmpty();
364-
if (methodNode.isStatic() && !methodNode.isPrivate() && virtual && !inClosure) {
365+
if (methodNode.isStatic() && !methodNode.isPrivate() && !inClosure && hasAnnotation(methodNode, VIRTUAL_TYPE)) {
365366
// Default dispatch for trait static methods is
366367
// declarer-bound; per-implementer override visibility
367368
// is opt-in via `@Virtual`. Annotating a public trait
368369
// static with @Virtual emits the dynamic-dispatch
369370
// path so the implementer's override (if any) is
370371
// visible from trait code.
371-
Expression implClass = ClassHelper.isClassType(weaved.getOriginType()) ? varX(weaved) : castX(ClassHelper.CLASS_Type.getPlainNodeReference(), callX(varX(weaved), "getClass"));
372-
newCall = callX(implClass, method, transform(arguments));
372+
373+
// GROOVY-11985: this.m(x) --> ($static$self or (Class)$self.getClass()).m(x)
374+
Expression selfClass = ClassHelper.isClassType(weaved.getOriginType()) ? varX(weaved) : castX(ClassHelper.CLASS_Type.getPlainNodeReference(), callX(varX(weaved), "getClass"));
375+
newCall = callX(selfClass, method, transform(arguments));
373376
newCall.setImplicitThis(false);
374377
newCall.putNodeMetaData(TraitASTTransformation.DO_DYNAMIC, methodNode.getReturnType());
375378
} else {
376-
// this.m(x) --> (this or T$Trait$Helper).m($self or $static$self or (Class)$self.getClass(), x)
377379
// Reached for: plain (non-@Virtual) static, private static,
378380
// instance method, or any call inside a closure.
381+
382+
// this.m(x) --> (this or T$Trait$Helper).m($self or $static$self or (Class)$self.getClass(), x)
379383
Expression selfClassOrObject = methodNode.isStatic() && !ClassHelper.isClassType(weaved.getOriginType()) ? castX(ClassHelper.CLASS_Type.getPlainNodeReference(), callX(weaved, "getClass")) : weaved;
380384
newCall = callX(!inClosure ? thisExpr : classX(traitHelper), method, createArgumentList(selfClassOrObject, arguments));
381385
}
@@ -386,7 +390,7 @@ private Expression transformMethodCallOnThis(final MethodCallExpression call) {
386390
}
387391
}
388392

389-
// this.m(x) --> ($self or $static$self).m(x)
393+
// this.m(x) --> (this or $self or $static$self).m(x)
390394
MethodCallExpression newCall = callX(inClosure ? thisExpr : weaved, method, transform(arguments));
391395
newCall.setGenericsTypes(call.getGenericsTypes()); // GROOVY-11302: this.<T>m(x)
392396
newCall.setImplicitThis(inClosure ? call.isImplicitThis() : false);

src/main/java/org/codehaus/groovy/transform/trait/Traits.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,13 @@ public abstract class Traits {
159159
* Prefix fragment used for remapped private trait fields.
160160
*/
161161
static final String PRIVATE_FIELD_PREFIX = "$1";
162-
// TODO decide if we should support VOLATILE
162+
163+
// TODO: decide if we should support VOLATILE
163164
// def hex(s) {new BigInteger(s, 16).intValue()}
164165
// def optionals = [[0, 1], [0, 1], [0, 1], [0, 1]].combinations{ a, b, c, d ->
165166
// (a ? hex('80') : 0) + (b ? hex('10') : 0) + (c ? hex('8') : 0) + (d ? hex('2') : hex('1'))
166167
// }.sort()
168+
167169
/**
168170
* Supported modifier encodings used when remapping trait field names.
169171
*/
@@ -336,6 +338,7 @@ static TraitHelpersTuple findHelpers(final ClassNode trait) {
336338

337339
/**
338340
* Returns true if the specified class node is a trait.
341+
*
339342
* @param cNode a class node to test
340343
* @return true if the classnode represents a trait
341344
*/
@@ -345,6 +348,7 @@ public static boolean isTrait(final ClassNode cNode) {
345348

346349
/**
347350
* Returns true if the specified class is a trait.
351+
*
348352
* @param clazz a class to test
349353
* @return true if the classnode represents a trait
350354
*/
@@ -354,6 +358,7 @@ public static boolean isTrait(final Class<?> clazz) {
354358

355359
/**
356360
* Returns true if the specified class node is annotated with the {@link Trait} interface.
361+
*
357362
* @param cNode a class node
358363
* @return true if the specified class node is annotated with the {@link Trait} interface.
359364
*/
@@ -364,6 +369,7 @@ public static boolean isAnnotatedWithTrait(final ClassNode cNode) {
364369

365370
/**
366371
* Indicates whether a method in a trait interface has a default implementation.
372+
*
367373
* @param method a method node
368374
* @return true if the method has a default implementation in the trait
369375
*/
@@ -373,6 +379,7 @@ public static boolean hasDefaultImplementation(final MethodNode method) {
373379

374380
/**
375381
* Indicates whether a method in a trait interface has a default implementation.
382+
*
376383
* @param method a method node
377384
* @return true if the method has a default implementation in the trait
378385
*/
@@ -418,6 +425,7 @@ public static Method getBridgeMethodTarget(Method someMethod) {
418425
* Converts a class implementing some trait into a target class. If the trait is a dynamic proxy and
419426
* that the target class is assignable to the target object of the proxy, then the target object is
420427
* returned. Otherwise, falls back to {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#asType(java.lang.Object, Class)}
428+
*
421429
* @param self an object to be coerced to some class
422430
* @param clazz the class to be coerced to
423431
* @return the object coerced to the target class, or the proxy instance if it is compatible with the target class.
@@ -453,6 +461,7 @@ public static String[] decomposeSuperCallName(final String methodName) {
453461
* Collects all interfaces of a class node, but reverses the order of the declaration of direct interfaces
454462
* of this class node. This is used to make sure a trait implementing A,B where both A and B have the same
455463
* method will take the method from B (latest), aligning the behavior with categories.
464+
*
456465
* @param cNode a class node
457466
* @param interfaces ordered set of interfaces
458467
*/
@@ -471,6 +480,7 @@ public static LinkedHashSet<ClassNode> collectAllInterfacesReverseOrder(final Cl
471480
/**
472481
* Collects all the self types that a type should extend or implement, given
473482
* the traits is implements. Collects from interfaces and superclasses too.
483+
*
474484
* @param receiver a class node that may implement a trait
475485
* @param selfTypes a set where the self types will be put
476486
* @return the {@code selfTypes} collection
@@ -484,6 +494,7 @@ public static LinkedHashSet<ClassNode> collectSelfTypes(final ClassNode receiver
484494
/**
485495
* Collects all the self types that a type should extend or implement, given
486496
* the traits is implements.
497+
*
487498
* @param receiver a class node that may implement a trait
488499
* @param selfTypes a set where the self types will be put
489500
* @param checkInterfaces should the interfaces that the node implements be collected too
@@ -543,7 +554,7 @@ static String getSuperTraitMethodName(ClassNode trait, String method) {
543554
}
544555

545556
/**
546-
* Find all traits associated with the given type.
557+
* Finds all traits associated with the given type.
547558
*
548559
* @param cNode the given classnode
549560
* @return the list of ordered trait classnodes
@@ -566,15 +577,16 @@ public static List<ClassNode> findTraits(final ClassNode cNode) {
566577
*/
567578
@Retention(RetentionPolicy.RUNTIME)
568579
@Target(ElementType.METHOD)
569-
public @interface Implemented {}
580+
public @interface Implemented {
581+
}
570582

571583
/**
572584
* Internal annotation used to indicate that a method is a bridge method to a trait
573585
* default implementation.
574586
*/
575587
@Retention(RetentionPolicy.RUNTIME)
576588
@Target(ElementType.METHOD)
577-
public @interface TraitBridge {
589+
public @interface TraitBridge {
578590
/**
579591
* @return the trait class
580592
*/

0 commit comments

Comments
 (0)