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" ); }
public void navigate(MouseEvent e, PsiElement elt) { List<GotoRelatedItem> items = this.items; if (items.size() == 1) { items.get(0).navigate(); } else { NavigationUtil.getRelatedItemsPopup(items, "Go to Related Files").show(new RelativePoint(e)); } }
result.add(lineMarkerDecorates.createLineMarkerInfo(leafTarget)); result.add(lineMarkerParent.createLineMarkerInfo(leafTarget));
/** * 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); } }
result.add(decorateLineMarker.createLineMarkerInfo(leafTarget)); result.add(parentLineMarker.createLineMarkerInfo(leafTarget));
@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); }
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)); }
@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); }
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)); }
/** * 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 repositoryClassMarker(PsiElement psiElement, Collection<? super RelatedItemLineMarkerInfo> result) { PsiElement phpClassContext = psiElement.getContext(); if(!(phpClassContext instanceof PhpClass)) { return; } Collection<PsiFile> psiFiles = new ArrayList<>(); for (VirtualFile virtualFile : DoctrineMetadataUtil.findMetadataForRepositoryClass((PhpClass) phpClassContext)) { PsiFile file = PsiManager.getInstance(psiElement.getProject()).findFile(virtualFile); if(file == null) { continue; } psiFiles.add(file); } if(psiFiles.size() == 0) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.DOCTRINE_LINE_MARKER). setTargets(psiFiles). setTooltipText("Navigate to metadata"); 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); }
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)); } }
/** * Find controller definition in yaml structor * * foo: * defaults: { _controller: "Bundle:Foo:Bar" } * controller: "Bundle:Foo:Bar" */ private void attachRouteActions(@NotNull Collection<LineMarkerInfo> lineMarkerInfos, @NotNull PsiElement psiElement) { if(psiElement.getNode().getElementType() != YAMLTokenTypes.SCALAR_KEY) { return; } PsiElement yamlKeyValue = psiElement.getParent(); if(!(yamlKeyValue instanceof YAMLKeyValue)) { return; } String yamlController = RouteHelper.getYamlController((YAMLKeyValue) yamlKeyValue); if(yamlController != null) { PsiElement[] methods = RouteHelper.getMethodsOnControllerShortcut(psiElement.getProject(), yamlController); 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)); } } }
private void formNameMarker(PsiElement psiElement, Collection<? super RelatedItemLineMarkerInfo> result) { if(!(psiElement instanceof StringLiteralExpression)) { return; } Method method = PsiTreeUtil.getParentOfType(psiElement, Method.class); if(method == null) { return; } if(PhpElementsUtil.isMethodInstanceOf(method, "\\Symfony\\Component\\Form\\FormTypeInterface", "getParent")) { // get form string; on blank string we dont need any further action String contents = ((StringLiteralExpression) psiElement).getContents(); if(StringUtils.isBlank(contents)) { return; } PsiElement formPsiTarget = FormUtil.getFormTypeToClass(psiElement.getProject(), contents); if(formPsiTarget != null) { NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.FORM_TYPE_LINE_MARKER). setTargets(formPsiTarget). setTooltipText("Navigate to form type"); result.add(builder.createLineMarkerInfo(psiElement)); } } }
private void entityClassMarker(PsiElement psiElement, Collection<? super RelatedItemLineMarkerInfo> result) { PsiElement phpClassContext = psiElement.getContext(); if(!(phpClassContext instanceof PhpClass)) { return; } Collection<PsiFile> psiFiles = new ArrayList<>(); // @TODO: use DoctrineMetadataUtil, for single resolve; we have collecting overhead here for(DoctrineModel doctrineModel: EntityHelper.getModelClasses(psiElement.getProject())) { PhpClass phpClass = doctrineModel.getPhpClass(); if(!PhpElementsUtil.isEqualClassName(phpClass, (PhpClass) phpClassContext)) { continue; } PsiFile psiFile = EntityHelper.getModelConfigFile(phpClass); // prevent self navigation for line marker if(psiFile == null || psiFile instanceof PhpFile) { continue; } psiFiles.add(psiFile); } if(psiFiles.size() == 0) { return; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Symfony2Icons.DOCTRINE_LINE_MARKER). setTargets(psiFiles). setTooltipText("Navigate to model"); result.add(builder.createLineMarkerInfo(psiElement)); }
private LineMarkerInfo attachIncludes(@NotNull TwigFile twigFile) { Collection<String> templateNames = TwigUtil.getTemplateNamesForFile(twigFile); boolean found = false; for(String templateName: templateNames) { Project project = twigFile.getProject(); Collection<VirtualFile> containingFiles = FileBasedIndex.getInstance().getContainingFiles( TwigIncludeStubIndex.KEY, templateName, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), TwigFileType.INSTANCE) ); // stop on first target, we load them lazily afterwards if(containingFiles.size() > 0) { found = true; break; } } if(!found) { return null; } NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(PhpIcons.IMPLEMENTED) .setTargets(new MyTemplateIncludeLazyValue(twigFile, templateNames)) .setTooltipText("Navigate to includes") .setCellRenderer(new MyFileReferencePsiElementListCellRenderer()); return builder.createLineMarkerInfo(twigFile); }