private void classNameMarker(PsiElement psiElement, Collection<? super RelatedItemLineMarkerInfo> result) { PsiElement phpClassContext = psiElement.getContext(); if(!(phpClassContext instanceof PhpClass)) { return; } ClassServiceDefinitionTargetLazyValue psiElements = ServiceIndexUtil.findServiceDefinitionsLazy((PhpClass) phpClassContext); if(psiElements == null) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.SERVICE_LINE_MARKER). setTargets(psiElements). setTooltipText("Navigate to definition"); result.add(builder.createLineMarkerInfo(psiElement)); }
@Nullable public static NavigationGutterIconBuilder<PsiElement> getLineMarkerForDecoratedServiceId(@NotNull Project project, @NotNull ServiceLineMarker lineMarker, @NotNull Map<String, Collection<ContainerService>> decorated, @NotNull String id) { if(!decorated.containsKey(id)) { return null; } NotNullLazyValue<Collection<? extends PsiElement>> lazy = ServiceIndexUtil.getServiceIdDefinitionLazyValue( project, ContainerUtil.map(decorated.get(id), ContainerService::getName) ); return NavigationGutterIconBuilder.create(PhpIcons.IMPLEMENTS) .setTargets(lazy) .setTooltipText(lineMarker == ServiceLineMarker.DECORATE ? "Navigate to decoration" : "Navigate to parent" ); }
@Override protected void collectNavigationMarkers(@NotNull PsiElement element,@NotNull Collection<? super RelatedItemLineMarkerInfo> result) { boolean naviOpenStatus = PropertiesComponent.getInstance().getBoolean("naviOpenStatus"); if (!naviOpenStatus){ return; } //如果element是PsiNameIdentifierOwner对象,且是接口 if (element instanceof PsiNameIdentifierOwner && JavaUtils.isElementWithinInterface(element)) { //表示ID元素的一个集合列表 CommonProcessors.CollectProcessor<IdDomElement> processor = new CommonProcessors.CollectProcessor<>(); JavaService.getInstance(element.getProject()).process(element, processor); Collection<IdDomElement> results = processor.getResults(); if (!results.isEmpty()) { //构建导航图标的builder NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Icons.MAPPER_LINE_MARKER_ICON) .setAlignment(GutterIconRenderer.Alignment.CENTER) .setTargets(Collections2.transform(results, FUN)) .setTooltipTitle("Navigation to target in mapper xml"); result.add(builder.createLineMarkerInfo(Objects.requireNonNull(((PsiNameIdentifierOwner) element).getNameIdentifier()))); } } }
.create(AllIcons.Gutter.OverridingMethod) .setTarget(parentSub) .setTooltipText("Overriding method"); if (!overridingSubs.isEmpty()) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder .create(AllIcons.Gutter.OverridenMethod) .setTargets(overridingSubs) .setTooltipText("Overriden methods");
NavigationGutterIconBuilder.create(Icons.SPRING_INJECTION_ICON) .setAlignment(GutterIconRenderer.Alignment.CENTER) .setTarget(psiClass) .setTooltipTitle("Data access object found - " + psiClass.getQualifiedName()); result.add(builder.createLineMarkerInfo(field.getNameIdentifier()));
if (!alternativeDoms.isEmpty()) { NavigationGutterIconBuilder .create(AllIcons.Actions.Nextfile, TypeSystemGutterAnnotator::findAlternativeDoms) .setTarget(itemType) .setTooltipText(alternativeDoms.size() > 1 ? "Alternative Definitions" : "Alternative Definition") .setAlignment(GutterIconRenderer.Alignment.RIGHT) .install(annotationHolder, psiElement); if (firstExtender.isPresent()) { NavigationGutterIconBuilder .create( AllIcons.Gutter.OverridenMethod, TypeSystemGutterAnnotator::findAllExtendingXmlAttributes .setTarget(itemType) .setAlignment(GutterIconRenderer.Alignment.LEFT) .setTooltipText("Has subtypes") .install(annotationHolder, psiElement);
result.add(lineMarkerDecorates.createLineMarkerInfo(leafTarget)); result.add(lineMarkerParent.createLineMarkerInfo(leafTarget));
private void addNamespaceMarkers(@NotNull PerlNamespaceDefinitionWithIdentifier element, Collection<? super RelatedItemLineMarkerInfo> result) { PsiElement nameIdentifier = element.getNameIdentifier(); if (nameIdentifier == null) { nameIdentifier = element; } List<PerlNamespaceDefinitionElement> parentNamespaces = element.getParentNamespaceDefinitions(); if (!parentNamespaces.isEmpty()) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder .create(AllIcons.Gutter.ImplementingMethod) .setTargets(parentNamespaces) .setTooltipText("Parent classes"); result.add(getMarkerInfo(builder, nameIdentifier)); } Collection<PerlNamespaceDefinitionElement> childNamespaces = element.getChildNamespaceDefinitions(); if (!childNamespaces.isEmpty()) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder .create(AllIcons.Gutter.ImplementedMethod) .setTargets(childNamespaces) .setTooltipText("Subclasses"); result.add(getMarkerInfo(builder, nameIdentifier)); } }
result.add(decorateLineMarker.createLineMarkerInfo(leafTarget)); result.add(parentLineMarker.createLineMarkerInfo(leafTarget));
private void attachController(@NotNull TwigFile twigFile, @NotNull Collection<? super RelatedItemLineMarkerInfo> result) { Set<Function> methods = new HashSet<>(); methods.addAll(TwigUtil.findTwigFileController(twigFile)); methods.addAll(TwigUtil.getTwigFileMethodUsageOnIndex(twigFile)); if(methods.size() == 0) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.TWIG_CONTROLLER_LINE_MARKER). setTargets(methods). setTooltipText("Navigate to controller"); result.add(builder.createLineMarkerInfo(twigFile)); }
private RelatedItemLineMarkerInfo getMarkerInfo(@NotNull NavigationGutterIconBuilder builder, @NotNull PsiElement element) { while (element.getFirstChild() != null) { element = element.getFirstChild(); } return builder.createLineMarkerInfo(element); }
@Nullable private LineMarkerInfo attachBlockImplements(@NotNull PsiElement psiElement, @NotNull FileImplementsLazyLoader implementsLazyLoader) { if(!TwigBlockUtil.hasBlockImplementations(psiElement, implementsLazyLoader)) { return null; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(PhpIcons.IMPLEMENTED) .setTargets(new BlockImplementationLazyValue(psiElement)) .setTooltipText("Implementations") .setCellRenderer(new MyBlockListCellRenderer()); return builder.createLineMarkerInfo(psiElement); }
@Nullable private LineMarkerInfo attachBlockOverwrites(@NotNull PsiElement psiElement, @NotNull FileOverwritesLazyLoader loader) { if(!TwigBlockUtil.hasBlockOverwrites(psiElement, loader)) { return null; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(PhpIcons.OVERRIDES) .setTargets(new BlockOverwriteLazyValue(psiElement)) .setTooltipText("Overwrites") .setCellRenderer(new MyBlockListCellRenderer()); return builder.createLineMarkerInfo(psiElement); }
/** * Provides a lazy linemarker based on the given id eg for "decorated" or "parent" services: * * <service id="foo_bar_main" decorates="app.mailer"/> */ @NotNull public static RelatedItemLineMarkerInfo<PsiElement> getLineMarkerForDecoratesServiceId(@NotNull PsiElement psiElement, @NotNull ServiceLineMarker lineMarker, @NotNull String foreignId) { return NavigationGutterIconBuilder.create(PhpIcons.OVERRIDEN) .setTargets(ServiceIndexUtil.getServiceIdDefinitionLazyValue(psiElement.getProject(), Collections.singletonList(foreignId))) .setTooltipText(lineMarker == ServiceLineMarker.DECORATE ? "Navigate to decorated service" : "Navigate to parent service") .createLineMarkerInfo(psiElement); } }
private void attachXmlRelationMarker(@NotNull PsiElement target, @NotNull XmlAttributeValue psiElement, @NotNull Collection<LineMarkerInfo> results) { String value = psiElement.getValue(); if(StringUtils.isBlank(value)) { return; } Collection<PhpClass> classesInterface = DoctrineMetadataUtil.getClassInsideScope(psiElement, value); if(classesInterface.size() == 0) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.DOCTRINE_LINE_MARKER). setTargets(classesInterface). setTooltipText("Navigate to class"); results.add(builder.createLineMarkerInfo(target)); }
private void visitRootElements(@NotNull Collection<LineMarkerInfo> result, @NotNull PsiElement psiElement, @NotNull LazyConfigTreeSignatures function) { PsiElement parent = psiElement.getParent(); if(!(parent instanceof YAMLKeyValue)) { return; } String keyText = ((YAMLKeyValue) parent).getKeyText(); Map<String, Collection<String>> treeSignatures = function.value(); if(!treeSignatures.containsKey(keyText)) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.SYMFONY_LINE_MARKER) .setTargets(new MyClassIdLazyValue(psiElement.getProject(), treeSignatures.get(keyText), keyText)) .setTooltipText("Navigate to configuration"); result.add(builder.createLineMarkerInfo(psiElement)); }
@Nullable public static RelatedItemLineMarkerInfo<PsiElement> getFileImplementsLineMarker(@NotNull PsiFile psiFile) { final Project project = psiFile.getProject(); VirtualFile virtualFile = psiFile.getVirtualFile(); if(virtualFile == null) { return null; } String bundleLocateName = FileResourceUtil.getBundleLocateName(project, virtualFile); if(bundleLocateName == null) { return null; } if(FileResourceUtil.getFileResourceRefers(project, bundleLocateName).size() == 0) { return null; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(PhpIcons.IMPLEMENTS). setTargets(new FileResourceUtil.FileResourceNotNullLazyValue(project, bundleLocateName)). setTooltipText("Navigate to resource"); return builder.createLineMarkerInfo(psiFile); }
/** * Constraints in same namespace and validateBy service name */ private void validatorClassMarker(PsiElement psiElement, Collection<LineMarkerInfo> results) { PsiElement phpClassContext = psiElement.getContext(); if(!(phpClassContext instanceof PhpClass) || !PhpElementsUtil.isInstanceOf((PhpClass) phpClassContext, "\\Symfony\\Component\\Validator\\Constraint")) { return; } Collection<PhpClass> phpClasses = new ArrayList<>(); // class in same namespace String className = ((PhpClass) phpClassContext).getFQN() + "Validator"; phpClasses.addAll( PhpElementsUtil.getClassesInterface(psiElement.getProject(), className) ); // @TODO: validateBy alias if(phpClasses.size() == 0) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.SYMFONY_LINE_MARKER). setTargets(phpClasses). setTooltipText("Navigate to validator"); results.add(builder.createLineMarkerInfo(psiElement)); }
private void attachRouteActions(@NotNull PsiElement psiElement, @NotNull Collection<LineMarkerInfo> lineMarkerInfos) { PsiElement xmlTag = psiElement.getParent(); if(!(xmlTag instanceof XmlTag) || !Pattern.getRouteTag().accepts(xmlTag)) { return; } String controller = RouteHelper.getXmlController((XmlTag) xmlTag); if(controller != null) { PsiElement[] methods = RouteHelper.getMethodsOnControllerShortcut(xmlTag.getProject(), controller); if(methods.length > 0) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.TWIG_CONTROLLER_LINE_MARKER). setTargets(methods). setTooltipText("Navigate to action"); lineMarkerInfos.add(builder.createLineMarkerInfo(psiElement)); } } }
/** * "FooValidator" back to "Foo" constraint */ private void constraintValidatorClassMarker(PsiElement psiElement, Collection<LineMarkerInfo> results) { PsiElement phpClass = psiElement.getContext(); if(!(phpClass instanceof PhpClass) || !PhpElementsUtil.isInstanceOf((PhpClass) phpClass, "Symfony\\Component\\Validator\\ConstraintValidatorInterface")) { return; } String fqn = ((PhpClass) phpClass).getFQN(); if(!fqn.endsWith("Validator")) { return; } Collection<PhpClass> phpClasses = new ArrayList<>( PhpElementsUtil.getClassesInterface(psiElement.getProject(), fqn.substring(0, fqn.length() - "Validator".length())) ); if(phpClasses.size() == 0) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.SYMFONY_LINE_MARKER). setTargets(phpClasses). setTooltipText("Navigate to constraint"); results.add(builder.createLineMarkerInfo(psiElement)); } }