/** * Checks if package is indexed. * * @param packageName package name * @return checking result */ public boolean isKnownPackage(String packageName) { String canonicalPackageName = PerlPackageUtil.getCanonicalPackageName(packageName); if (!indexSnapshotDone) makeIndexSnapshot(); return KNOWN_PACKAGES.contains(canonicalPackageName); }
/** * Makes index snapshot hashsets * * @return result */ public synchronized boolean makeIndexSnapshot() { if (!indexSnapshotDone && !DumbService.isDumb(myProject)) { KNOWN_SUBS.addAll(PerlSubUtil.getDeclaredSubsNames(myProject)); KNOWN_SUBS.addAll(PerlSubUtil.getDefinedSubsNames(myProject)); KNOWN_SUBS.addAll(PerlGlobUtil.getDefinedGlobsNames(myProject)); KNOWN_PACKAGES.addAll(PerlPackageUtil.getDefinedPackageNames(myProject)); indexSnapshotDone = true; } return indexSnapshotDone; }
@Override public String getContextPackageNameHeavy() { // System.err.println("Guessing type for method " + getText() + " at " + getTextOffset()); PsiElement parent = getParent(); PsiElement grandParent = parent == null ? null : parent.getParent(); if (grandParent instanceof PsiPerlDerefExpr) { return ((PsiPerlDerefExpr) grandParent).getPreviousElementType(parent); } return PerlPackageUtil.getContextPackageName(this); }
@Override protected void collectNavigationMarkers( @NotNull PsiElement element, Collection<? super RelatedItemLineMarkerInfo> result) { if (element instanceof PerlNamespaceDefinition) { PsiElement nameIdentifier = ((PerlNamespaceDefinition) element).getNameIdentifier(); if (nameIdentifier == null) nameIdentifier = element; List<PerlNamespaceDefinition> parentNamespaces = ((PerlNamespaceDefinition) element).getParentNamespaceDefinitions(); if (parentNamespaces.size() > 0) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(AllIcons.Gutter.ImplementingMethod) .setTargets(parentNamespaces) .setTooltipText("Parent classes"); result.add(builder.createLineMarkerInfo(nameIdentifier)); } Collection<PerlNamespaceDefinition> childNamespaces = ((PerlNamespaceDefinition) element).getChildNamespaceDefinitions(); if (childNamespaces.size() > 0) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(AllIcons.Gutter.ImplementedMethod) .setTargets(childNamespaces) .setTooltipText("Subclasses"); result.add(builder.createLineMarkerInfo(nameIdentifier)); } } else if (element instanceof PerlSubDefinitionBase && ((PerlSubDefinitionBase) element).isMethod()) { PerlNamespaceDefinition containingNamespace = PsiTreeUtil.getParentOfType(element, PerlNamespaceDefinition.class); if (containingNamespace != null) { final String packageName = ((PerlSubDefinitionBase) element).getPackageName(); final String subName = ((PerlSubDefinitionBase) element).getSubName(); PsiElement nameIdentifier = ((PerlSubDefinitionBase) element).getNameIdentifier(); if (nameIdentifier == null) nameIdentifier = element; if (StringUtil.isNotEmpty(packageName) && StringUtil.isNotEmpty(subName)) { Collection<PsiElement> superMethods = PerlMro.resolveSub(element.getProject(), packageName, subName, true); if (superMethods.size() > 0) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(AllIcons.Gutter.OverridingMethod) .setTargets(superMethods) .setTooltipText("Overriding method"); result.add(builder.createLineMarkerInfo(nameIdentifier)); } final List<PerlSubBase> overridingSubs = new ArrayList<PerlSubBase>(); PerlPackageUtil.processChildNamespacesSubs( containingNamespace, null, new Processor<PerlSubBase>() { @Override public boolean process(PerlSubBase perlSubBase) { String subBaseName = perlSubBase.getSubName(); if (StringUtil.isNotEmpty(subBaseName) && subName.equals(subBaseName) && perlSubBase.isMethod()) { overridingSubs.add(perlSubBase); return false; } return true; } }); if (overridingSubs.size() > 0) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(AllIcons.Gutter.OverridenMethod) .setTargets(overridingSubs) .setTooltipText("Overriden methods"); result.add(builder.createLineMarkerInfo(nameIdentifier)); } } } } }
@Override public String getContextPackageName() { return PerlPackageUtil.getContextPackageName(this); }
/** * Parses invocable method As input we may have: PACKAGE_IDENTIFIER IDENTIFIER Foo::sub IDENTIFIER * PACKAGE_IDENTIFIER sub Foo:: IDENTIFIER IDENTIFIER sub Foo * * @param b PerlBuilder * @param l parsing level * @return parsing result */ public static boolean parseMethod(PsiBuilder b, int l) { IElementType currentTokenType = b.getTokenType(); IElementType nextTokenType = b.lookAhead(1); assert b instanceof PerlBuilder; // can be // Foo::method // Foo::Bar if (PACKAGE_TOKENS.contains(currentTokenType) && CONVERTABLE_TOKENS.contains(nextTokenType)) { PerlTokenData nextTokenData = ((PerlBuilder) b).lookupToken(1); PerlTokenData nextNextTokenData = ((PerlBuilder) b).lookupToken(2); IElementType nextNextTokenType = nextNextTokenData == null ? null : nextNextTokenData.getTokenType(); String canonicalPackageName = PerlPackageUtil.getCanonicalPackageName(b.getTokenText()); String potentialSubName = canonicalPackageName + "::" + nextTokenData.getTokenText(); if (nextNextTokenType == LEFT_PAREN // Package::Identifier( - what can it be? || ((PerlBuilder) b).isKnownSub(potentialSubName) // we know this sub || !((PerlBuilder) b).isKnownPackage(potentialSubName)) // we don't know such package return convertPackageIdentifier(b, l) && convertIdentifier(b, l, SUB); else return false; } // method else if (CONVERTABLE_TOKENS.contains(currentTokenType)) { PerlTokenData prevTokenData = ((PerlBuilder) b).lookupToken(-1); // ->sub if (prevTokenData != null && prevTokenData.getTokenType() == OPERATOR_DEREFERENCE) return convertIdentifier(b, l, SUB); // may be // method Foo:: // method Foo::Bar // method Foo::othermethod else if (PACKAGE_TOKENS.contains(nextTokenType)) { IElementType nextNextTokenType = b.lookAhead(2); // sub Foo::->method if (nextNextTokenType == OPERATOR_DEREFERENCE) return convertIdentifier(b, l, SUB); // identifier Package::identifier else if (CONVERTABLE_TOKENS.contains(nextNextTokenType)) { // identifier Package::identifier-> if (b.lookAhead(3) == OPERATOR_DEREFERENCE) return convertIdentifier(b, l, SUB); PerlTokenData nextTokenData = ((PerlBuilder) b).lookupToken(1); PerlTokenData nextNextTokenData = ((PerlBuilder) b).lookupToken(2); String packageOrSub = PerlPackageUtil.getCanonicalPackageName(nextTokenData.getTokenText()) + "::" + nextNextTokenData.getTokenText(); if (((PerlBuilder) b).isKnownSub(packageOrSub)) return convertIdentifier(b, l, SUB); else if (((PerlBuilder) b).isKnownPackage(packageOrSub)) return convertIdentifier(b, l, SUB) && mergePackageName(b, l); return convertIdentifier(b, l, SUB); } else // it's method Package:: return convertIdentifier(b, l, SUB) && convertPackageIdentifier(b, l); } // may be // method Foo else if (CONVERTABLE_TOKENS.contains(nextTokenType) && b.lookAhead(2) != OPERATOR_DEREFERENCE) { PerlTokenData nextTokenData = ((PerlBuilder) b).lookupToken(1); String potentialSubName = nextTokenData.getTokenText() + "::" + b.getTokenText(); if (((PerlBuilder) b).isKnownSub(potentialSubName)) return convertIdentifier(b, l, SUB) && convertIdentifier(b, l, PACKAGE); else return convertIdentifier(b, l, SUB); } // KnownPackage-> else if (nextTokenType == OPERATOR_DEREFERENCE && ((PerlBuilder) b).isKnownPackage(b.getTokenText())) return false; // it's just sub else return convertIdentifier(b, l, SUB); } return false; }