2424import org .codehaus .groovy .ast .GenericsType ;
2525import org .codehaus .groovy .ast .MethodNode ;
2626import org .codehaus .groovy .ast .Parameter ;
27+ import org .codehaus .groovy .ast .PropertyNode ;
2728import org .codehaus .groovy .ast .expr .ArgumentListExpression ;
2829import org .codehaus .groovy .ast .expr .ArrayExpression ;
2930import org .codehaus .groovy .ast .expr .ClassExpression ;
@@ -399,6 +400,11 @@ private MethodNode chooseMethodRefMethod(final List<MethodNode> methods, final E
399400
400401 private List <MethodNode > findVisibleMethods (final String name , final ClassNode type ) {
401402 List <MethodNode > methods = type .getMethods (name );
403+ // GROOVY-11618: reference to a property node's method
404+ MethodNode generated = findPropertyMethod (name , type );
405+ if (generated != null && methods .stream ().noneMatch (m -> m .getName ().equals (generated .getName ()))) {
406+ methods .add (generated );
407+ }
402408 // GROOVY-10791, GROOVY-11467: include non-static interface methods
403409 Set <ClassNode > implemented = getInterfacesAndSuperInterfaces (type );
404410 implemented .remove (type );
@@ -413,6 +419,25 @@ private List<MethodNode> findVisibleMethods(final String name, final ClassNode t
413419 return filterMethodsByVisibility (methods , controller .getClassNode ());
414420 }
415421
422+ private MethodNode findPropertyMethod (final String name , final ClassNode type ) {
423+ for (ClassNode cn = type ; cn != null ; cn = cn .getSuperClass ()) {
424+ for (PropertyNode pn : cn .getProperties ()) {
425+ if (name .equals (pn .getGetterNameOrDefault ())) {
426+ MethodNode node = new MethodNode (name , Opcodes .ACC_PUBLIC | (pn .isStatic () ? Opcodes .ACC_STATIC : 0 ), pn .getType (), Parameter .EMPTY_ARRAY , ClassNode .EMPTY_ARRAY , null );
427+ node .setDeclaringClass (pn .getDeclaringClass ());
428+ node .setSynthetic (true );
429+ return node ;
430+ } else if (name .equals (pn .getSetterNameOrDefault ()) && (pn .getModifiers () & Opcodes .ACC_FINAL ) == 0 ) {
431+ MethodNode node = new MethodNode (name , Opcodes .ACC_PUBLIC | (pn .isStatic () ? Opcodes .ACC_STATIC : 0 ), ClassHelper .VOID_TYPE , new Parameter []{new Parameter (pn .getType (), pn .getName ())}, ClassNode .EMPTY_ARRAY , null );
432+ node .setDeclaringClass (pn .getDeclaringClass ());
433+ node .setSynthetic (true );
434+ return node ;
435+ }
436+ }
437+ }
438+ return null ;
439+ }
440+
416441 private void addFatalError (final String msg , final ASTNode node ) {
417442 controller .getSourceUnit ().addFatalError (msg , node );
418443 // GRECLIPSE: addFatalError won't throw for quick parse
0 commit comments