void (@NotNull TransformationContext context) { Map<PsiType, PsiAnnotation> declaredTypes = new LinkedHashMap<>(); GrTypeDefinition codeClass = context.getCodeClass(); for (GrField field : context.getFields()) { final PsiAnnotation annotation = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE); if (annotation == null) continue; declaredTypes.putIfAbsent(field.getDeclaredType(), annotation); } for (PsiMethod method : context.getMethods()) { final PsiAnnotation annotation = PsiImplUtil.getAnnotation(method, GroovyCommonClassNames.GROOVY_LANG_DELEGATE); if (annotation == null) continue; if (!method.getParameterList().isEmpty()) continue; declaredTypes.putIfAbsent(method.getReturnType(), annotation); } declaredTypes.forEach((type, annotation) -> { if (!(type instanceof PsiClassType)) return; final PsiClassType.ClassResolveResult delegateResult = ((PsiClassType)type).resolveGenerics(); final PsiClass delegate = delegateResult.getElement(); if (delegate == null) return; DelegateProcessor processor = new DelegateProcessor(context, delegate, annotation); delegate.processDeclarations( processor, ResolveState.initial().put(PsiSubstitutor.KEY, delegateResult.getSubstitutor()), null, codeClass ); if (!processor.myInterfaces) return; Set<PsiClass> visited = new HashSet<>(); Queue<Pair<PsiClass, PsiSubstitutor>> queue = ContainerUtil.newLinkedList(Pair.create(delegate, delegateResult.getSubstitutor())); while (!queue.isEmpty()) { Pair<PsiClass, PsiSubstitutor> pair = queue.poll(); PsiClass currentClass = pair.first; PsiSubstitutor substitutor = pair.second; if (visited.add(currentClass) && currentClass.isInterface()) { context.addInterface(new PsiImmediateClassType(currentClass, substitutor)); continue; } for (PsiClassType superType : currentClass.getSuperTypes()) { PsiClassType.ClassResolveResult resolveResult = superType.resolveGenerics(); PsiClass superClass = resolveResult.getElement(); if (superClass != null) { queue.offer(Pair.create(superClass, TypeConversionUtil.getSuperClassSubstitutor(superClass, currentClass, substitutor))); } } } }); }