XSourcePositionImpl (@Nullable PsiElement element) { if (element == null) return null; PsiFile psiFile = element.getContainingFile(); if (psiFile == null) return null; final VirtualFile file = psiFile.getVirtualFile(); if (file == null) return null; final SmartPsiElementPointer<PsiElement> pointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); return new XSourcePositionImpl(file) { private final NotNullLazyValue<XSourcePosition> myDelegate = NotNullLazyValue.atomicLazy(() -> { return ReadAction.compute(() -> { PsiElement elem = pointer.getElement(); return XSourcePositionImpl.createByOffset(pointer.getVirtualFile(), elem != null ? elem.getTextOffset() : -1); }); }); @Override public int getLine() { return myDelegate.getValue().getLine(); } @Override public int getOffset() { return myDelegate.getValue().getOffset(); } @NotNull @Override public Navigatable createNavigatable(@NotNull Project project) { // no need to create delegate here, it may be expensive if (myDelegate.isComputed()) { return myDelegate.getValue().createNavigatable(project); } PsiElement elem = pointer.getElement(); if (elem instanceof Navigatable) { return ((Navigatable)elem); } return NonNavigatable.INSTANCE; } }; }