ClassReferencePointer (PsiElement parent, int index, @NotNull WeakReference<PsiJavaCodeReferenceElement> ref) { return new ClassReferencePointer() { volatile WeakReference<PsiJavaCodeReferenceElement> myCache = ref; @Override public @Nullable PsiJavaCodeReferenceElement retrieveReference() { PsiJavaCodeReferenceElement result = myCache.get(); if (result == null) { PsiType type = calcTypeByParent(); if (type instanceof PsiClassReferenceType) { result = findReferenceByIndex((PsiClassReferenceType)type); } myCache = new WeakReference<>(result); } return result; } @Nullable private PsiJavaCodeReferenceElement findReferenceByIndex(PsiClassReferenceType type) { PsiTypeElement root = getRootTypeElement(type.getReference()); return root == null ? null : allReferencesInside(root).get(index); } @Nullable private PsiType calcTypeByParent() { if (!parent.isValid()) return null; PsiType type = parent instanceof PsiMethod ? ((PsiMethod)parent).getReturnType() : ((PsiVariable)parent).getType(); if (type instanceof PsiArrayType) { //also, for c-style array, e.g. String args[] return type.getDeepComponentType(); } return type; } @Override public @NotNull PsiJavaCodeReferenceElement retrieveNonNullReference() { PsiJavaCodeReferenceElement result = retrieveReference(); if (result == null) { PsiType type = calcTypeByParent(); if (!(type instanceof PsiClassReferenceType)) { PsiUtilCore.ensureValid(parent); throw new IllegalStateException("No reference type for " + parent.getClass() + "; type: " + (type != null ? type.getClass() : "null")); } result = findReferenceByIndex((PsiClassReferenceType)type); if (result == null) { PsiUtilCore.ensureValid(parent); throw new RuntimeExceptionWithAttachments("Can't retrieve reference by index " + index + " for " + parent.getClass() + "; type: " + type.getClass(), new Attachment("memberType.txt", type.getCanonicalText())); } } return result; } @Override public String toString() { String msg = "Type element reference of " + parent.getClass() + " #" + parent.getClass().getSimpleName() + ", index=" + index; return parent.isValid() ? msg + " #" + parent.getLanguage() : msg + ", invalid"; } }; }