@NotNull public static <T extends PsiElement> List<T> getStubChildrenOfTypeAsList( @Nullable PsiElement element, @NotNull Class<T> aClass) { if (element == null) return Collections.emptyList(); StubElement<?> stub = null; if (element instanceof PsiFileImpl) stub = ((PsiFileImpl) element).getStub(); else if (element instanceof StubBasedPsiElement) stub = ((StubBasedPsiElement) element).getStub(); if (stub == null) { return getChildrenOfTypeAsList(element, aClass); } List<T> result = new SmartList<T>(); for (StubElement childStub : stub.getChildrenStubs()) { PsiElement child = childStub.getPsi(); if (aClass.isInstance(child)) { //noinspection unchecked result.add((T) child); } } return result; }
public boolean isCompiled(StubT stub) { StubElement parent = stub; while (!(parent instanceof PsiFileStub)) { parent = parent.getParentStub(); } return ((PsiJavaFileStub) parent).isCompiled(); }
protected final PsiElement getParentByStub() { final StubElement<?> stub = getStub(); if (stub != null) { return stub.getParentStub().getPsi(); } return SharedImplUtil.getParent(getNode()); }
@Nullable public static PsiElement restoreFromStubIndex( PsiFileWithStubSupport fileImpl, int index, @NotNull IStubElementType elementType, boolean throwIfNull) { if (fileImpl == null) { if (throwIfNull) throw new AssertionError("Null file"); return null; } StubTree tree = fileImpl.getStubTree(); boolean foreign = tree == null; if (foreign) { if (fileImpl instanceof PsiFileImpl) { // Note: as far as this is a realization of StubIndexReference // fileImpl#getContentElementType() must be instance of IStubFileElementType tree = ((PsiFileImpl) fileImpl).calcStubTree(); } else { if (throwIfNull) throw new AssertionError("Not PsiFileImpl: " + fileImpl.getClass()); return null; } } List<StubElement<?>> list = tree.getPlainList(); if (index >= list.size()) { if (throwIfNull) throw new AssertionError("Too large index: " + index + ">=" + list.size()); return null; } StubElement stub = list.get(index); if (stub.getStubType() != elementType) { if (throwIfNull) throw new AssertionError( "Element type mismatch: " + stub.getStubType() + "!=" + elementType); return null; } if (foreign) { final PsiElement cachedPsi = ((StubBase) stub).getCachedPsi(); if (cachedPsi != null) return cachedPsi; final ASTNode ast = fileImpl.findTreeForStub(tree, stub); if (ast != null) { return ast.getPsi(); } if (throwIfNull) throw new AssertionError("No AST for stub"); return null; } return stub.getPsi(); }
private static PsiClass findClass(String fqn, StubElement<?> stub) { if (stub instanceof PsiClassStub && Comparing.equal(fqn, ((PsiClassStub) stub).getQualifiedName())) { return (PsiClass) stub.getPsi(); } for (StubElement child : stub.getChildrenStubs()) { PsiClass answer = findClass(fqn, child); if (answer != null) return answer; } return null; }
@Override public boolean isValid() { T stub = myStub; if (stub != null) { StubElement parent = stub.getParentStub(); if (parent == null) { LOG.error("No parent for stub " + stub + " of class " + stub.getClass()); return false; } PsiElement psi = parent.getPsi(); return psi != null && psi.isValid(); } return super.isValid(); }
@Nullable public <Psi extends PsiElement> Psi getStubOrPsiChild( final IStubElementType<? extends StubElement, Psi> elementType) { T stub = myStub; if (stub != null) { final StubElement<Psi> element = stub.findChildStubByType(elementType); if (element != null) { return element.getPsi(); } } else { final ASTNode childNode = getNode().findChildByType(elementType); if (childNode != null) { return (Psi) childNode.getPsi(); } } return null; }
@Nullable public static <T extends PsiElement> T getStubChildOfType( @Nullable PsiElement element, @NotNull Class<T> aClass) { if (element == null) return null; StubElement<?> stub = element instanceof StubBasedPsiElement ? ((StubBasedPsiElement) element).getStub() : null; if (stub == null) { return getChildOfType(element, aClass); } for (StubElement childStub : stub.getChildrenStubs()) { PsiElement child = childStub.getPsi(); if (aClass.isInstance(child)) { //noinspection unchecked return (T) child; } } return null; }
private static void recordClassOrObjectByPackage( StubElement<? extends JetClassOrObject> stub, IndexSink sink) { StubElement parentStub = stub.getParentStub(); if (parentStub instanceof PsiJetFileStub) { PsiJetFileStub jetFileStub = (PsiJetFileStub) parentStub; String packageName = jetFileStub.getPackageName(); if (packageName != null) { sink.occurrence(JetClassByPackageIndex.getInstance().getKey(), packageName); } } }
public static int calcStubIndex(@NotNull StubBasedPsiElement psi) { if (psi instanceof PsiFile) { return 0; } final StubElement liveStub = psi.getStub(); if (liveStub != null) { return ((StubBase) liveStub).id; } PsiFileImpl file = (PsiFileImpl) psi.getContainingFile(); final StubTree stubTree = file.calcStubTree(); for (StubElement<?> stb : stubTree.getPlainList()) { if (stb.getPsi() == psi) { return ((StubBase) stb).id; } } return -1; // it is possible via custom stub builder intentionally not producing stubs for // stubbed elements }
@Override @NotNull public PsiFile getContainingFile() { StubElement stub = myStub; if (stub != null) { while (!(stub instanceof PsiFileStub)) { stub = stub.getParentStub(); } PsiFile psi = (PsiFile) stub.getPsi(); if (psi == null) { throw new PsiInvalidElementAccessException(this, "no psi for file stub " + stub, null); } return psi; } PsiFile file = super.getContainingFile(); if (file == null) { throw new PsiInvalidElementAccessException(this); } return file; }
@Nullable private Modifier getWrappersFromStub() { final StubElement parentStub = getStub().getParentStub(); final List childrenStubs = parentStub.getChildrenStubs(); int index = childrenStubs.indexOf(getStub()); if (index >= 0 && index < childrenStubs.size() - 1) { StubElement nextStub = (StubElement) childrenStubs.get(index + 1); if (nextStub instanceof PyTargetExpressionStub) { final PyTargetExpressionStub targetExpressionStub = (PyTargetExpressionStub) nextStub; if (targetExpressionStub.getInitializerType() == PyTargetExpressionStub.InitializerType.CallExpression) { final QualifiedName qualifiedName = targetExpressionStub.getInitializer(); if (QualifiedName.fromComponents(PyNames.CLASSMETHOD).equals(qualifiedName)) { return CLASSMETHOD; } if (QualifiedName.fromComponents(PyNames.STATICMETHOD).equals(qualifiedName)) { return STATICMETHOD; } } } } return null; }
@Nullable public PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName) { final GrModifierListStub stub = getStub(); if (stub != null) { for (StubElement stubElement : stub.getChildrenStubs()) { final PsiElement child = stubElement.getPsi(); if (child instanceof PsiAnnotation && qualifiedName.equals(((PsiAnnotation) child).getQualifiedName())) { return (PsiAnnotation) child; } } } else { PsiElement child = getFirstChild(); while (child != null) { if (child instanceof PsiAnnotation && qualifiedName.equals(((PsiAnnotation) child).getQualifiedName())) { return (PsiAnnotation) child; } child = child.getNextSibling(); } } return null; }
public static boolean isGroovyStaticMemberStub(StubElement<?> stub) { StubElement<?> modifierOwner = stub instanceof GrMethodStub ? stub : stub.getParentStub(); StubElement<GrModifierList> type = modifierOwner.findChildStubByType(GroovyElementTypes.MODIFIERS); if (!(type instanceof GrModifierListStub)) { return false; } int mask = ((GrModifierListStub) type).getModifiersFlags(); if (GrModifierListImpl.hasMaskExplicitModifier(PsiModifier.PRIVATE, mask)) { return false; } if (GrModifierListImpl.hasMaskExplicitModifier(PsiModifier.STATIC, mask)) { return true; } StubElement parent = modifierOwner.getParentStub(); StubElement classStub = parent == null ? null : parent.getParentStub(); if (classStub instanceof GrTypeDefinitionStub && (((GrTypeDefinitionStub) classStub).isAnnotationType() || ((GrTypeDefinitionStub) classStub).isInterface())) { return true; } return false; }