private static PsiElement findInside( @NotNull PsiElement element, @NotNull PsiFile hostFile, final int hostOffset, @NotNull final PsiDocumentManager documentManager) { final Ref<PsiElement> out = new Ref<PsiElement>(); enumerate( element, hostFile, true, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) { for (PsiLanguageInjectionHost.Shred place : places) { TextRange hostRange = place.getHost().getTextRange(); if (hostRange.cutOut(place.getRangeInsideHost()).grown(1).contains(hostOffset)) { DocumentWindowImpl document = (DocumentWindowImpl) documentManager.getCachedDocument(injectedPsi); if (document == null) return; int injectedOffset = document.hostToInjected(hostOffset); PsiElement injElement = injectedPsi.findElementAt(injectedOffset); out.set(injElement == null ? injectedPsi : injElement); } } } }); return out.get(); }
public static boolean hasInjections(@NotNull PsiLanguageInjectionHost host) { if (!host.isPhysical()) return false; final Ref<Boolean> result = Ref.create(false); enumerate( host, new PsiLanguageInjectionHost.InjectedPsiVisitor() { @Override public void visit( @NotNull final PsiFile injectedPsi, @NotNull final List<PsiLanguageInjectionHost.Shred> places) { result.set(true); } }); return result.get().booleanValue(); }
@Nullable public static PsiType getQualifiedMemberReferenceType( @Nullable PsiType qualifierType, @NotNull final PsiMember member) { final Ref<PsiSubstitutor> subst = Ref.create(PsiSubstitutor.EMPTY); class MyProcessor extends BaseScopeProcessor implements NameHint, ElementClassHint { @Override public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) { if (element == member) { subst.set(state.get(PsiSubstitutor.KEY)); } return true; } @Override public String getName(@NotNull ResolveState state) { return member.getName(); } @Override public boolean shouldProcess(DeclarationKind kind) { return member instanceof PsiEnumConstant ? kind == DeclarationKind.ENUM_CONST : member instanceof PsiField ? kind == DeclarationKind.FIELD : kind == DeclarationKind.METHOD; } @Override public <T> T getHint(@NotNull Key<T> hintKey) { return hintKey == NameHint.KEY || hintKey == ElementClassHint.KEY ? (T) this : null; } } PsiScopesUtil.processTypeDeclarations(qualifierType, member, new MyProcessor()); PsiType rawType = member instanceof PsiField ? ((PsiField) member).getType() : member instanceof PsiMethod ? ((PsiMethod) member).getReturnType() : JavaPsiFacade.getElementFactory(member.getProject()) .createType((PsiClass) member); return subst.get().substitute(rawType); }