void (AnnotationHolder holder, PsiMethod @NotNull[] constructors) { Map<PsiMethod, PsiMethod> nodes = new HashMap<>(constructors.length); Set<PsiMethod> set = Set.of(constructors); for (PsiMethod constructor : constructors) { if (!(constructor instanceof GrMethod)) continue; final GrOpenBlock block = ((GrMethod)constructor).getBlock(); if (block == null) continue; final GrStatement[] statements = block.getStatements(); if (statements.length <= 0 || !(statements[0] instanceof GrConstructorInvocation)) continue; final PsiMethod resolved = ((GrConstructorInvocation)statements[0]).resolveMethod(); if (resolved == null || !set.contains(resolved)) continue; nodes.put(constructor, resolved); } Set<PsiMethod> checked = new HashSet<>(); Set<PsiMethod> current; for (PsiMethod constructor : constructors) { if (!checked.add(constructor)) continue; current = new HashSet<>(); current.add(constructor); for (constructor = nodes.get(constructor); constructor != null && current.add(constructor); constructor = nodes.get(constructor)) { checked.add(constructor); } if (constructor != null) { PsiMethod circleStart = constructor; do { holder.newAnnotation(HighlightSeverity.ERROR, GroovyBundle.message("recursive.constructor.invocation")).range(GrHighlightUtil.getMethodHeaderTextRange(constructor)).create(); constructor = nodes.get(constructor); } while (constructor != circleStart); } } }