private static Collection<PhpClass> getPhpClassInsideNamespace( Project project, PhpIndex phpIndex, String namespaceName, int maxDeep) { final Collection<PhpClass> phpClasses = new ArrayList<PhpClass>(); if (maxDeep-- <= 0) { return phpClasses; } StubIndex.getInstance() .process( PhpNamespaceIndex.KEY, namespaceName.toLowerCase(), project, phpIndex.getSearchScope(), new Processor<PhpNamespace>() { @Override public boolean process(PhpNamespace phpNamespace) { phpClasses.addAll( PsiTreeUtil.getChildrenOfTypeAsList( phpNamespace.getStatements(), PhpClass.class)); return true; } }); for (String ns : phpIndex.getChildNamespacesByParentName(namespaceName + "\\")) { phpClasses.addAll( getPhpClassInsideNamespace(project, phpIndex, namespaceName + "\\" + ns, maxDeep)); } return phpClasses; }
public static Collection<PhpClass> getClassFromPhpTypeSetArrayClean( Project project, Set<String> types) { PhpType phpType = new PhpType(); phpType.add(types); ArrayList<PhpClass> phpClasses = new ArrayList<PhpClass>(); for (String typeName : PhpIndex.getInstance(project) .completeType(project, phpType, new HashSet<String>()) .getTypes()) { if (typeName.startsWith("\\")) { // we clean array types \Foo[] if (typeName.endsWith("[]")) { typeName = typeName.substring(0, typeName.length() - 2); } PhpClass phpClass = PhpElementsUtil.getClassInterface(project, typeName); if (phpClass != null) { phpClasses.add(phpClass); } } } return phpClasses; }
@NotNull @Override public Collection<PsiElement> getPsiTargets( @NotNull SourceContributorDeclarationHandlerParameter parameter) { String contents = parameter.getHandlerParameter().getContents(); if (StringUtils.isBlank(contents)) { return Collections.emptyList(); } String sourceParameter = parameter.getSourceParameter(); if (sourceParameter == null) { return Collections.emptyList(); } final Collection<PsiElement> psiElements = new ArrayList<PsiElement>(); for (PhpClass phpClass : PhpIndex.getInstance(parameter.getProject()).getAllSubclasses(sourceParameter)) { if (StringUtils.stripStart(contents, "\\") .equalsIgnoreCase(StringUtils.stripStart(phpClass.getPresentableFQN(), "\\"))) { psiElements.add(phpClass); } } return psiElements; }
@Nullable public static String getControllerMethodShortcut(Method method) { // indexAction String methodName = method.getName(); if (!methodName.endsWith("Action")) { return null; } PhpClass phpClass = method.getContainingClass(); if (null == phpClass) { return null; } // defaultController // default/Folder/FolderController String className = phpClass.getName(); if (!className.endsWith("Controller")) { return null; } SymfonyBundleUtil symfonyBundleUtil = new SymfonyBundleUtil(PhpIndex.getInstance(method.getProject())); SymfonyBundle symfonyBundle = symfonyBundleUtil.getContainingBundle(phpClass); if (symfonyBundle == null) { return null; } // find the bundle name of file PhpClass BundleClass = symfonyBundle.getPhpClass(); if (null == BundleClass) { return null; } // check if files is in <Bundle>/Controller/* if (!phpClass.getNamespaceName().startsWith(BundleClass.getNamespaceName() + "Controller\\")) { return null; } // strip the controller folder name String templateFolderName = phpClass.getNamespaceName().substring(BundleClass.getNamespaceName().length() + 11); // HomeBundle:default:indexes // HomeBundle:default/Test:indexes templateFolderName = templateFolderName.replace("\\", "/"); String shortcutName = symfonyBundle.getName() + ":" + templateFolderName + className.substring(0, className.lastIndexOf("Controller")) + ":" + methodName.substring(0, methodName.lastIndexOf("Action")); // we should support types later on // HomeBundle:default:indexes.html.twig return shortcutName + ".html.twig"; }
public static Collection<PhpClass> getClassesInterface( Project project, @NotNull String className) { // api workaround for at least interfaces if (!className.startsWith("\\")) { className = "\\" + className; } return PhpIndex.getInstance(project).getAnyByFQN(className); }
@Override public Collection<? extends PhpNamedElement> getBySignature(String expression, Project project) { // get back our original call int endIndex = expression.lastIndexOf(TRIM_KEY); if (endIndex == -1) { return Collections.emptySet(); } String originalSignature = expression.substring(0, endIndex); String parameter = expression.substring(endIndex + 1); // search for called method PhpIndex phpIndex = PhpIndex.getInstance(project); Collection<? extends PhpNamedElement> phpNamedElementCollections = phpIndex.getBySignature(originalSignature, null, 0); if (phpNamedElementCollections.size() == 0) { return Collections.emptySet(); } PhpNamedElement phpNamedElement = phpNamedElementCollections.iterator().next(); if (!(phpNamedElement instanceof Method)) { return Arrays.asList(phpNamedElement); } if (!new Symfony2InterfacesUtil() .isCallTo( (Method) phpNamedElement, "\\Doctrine\\Common\\Persistence\\ObjectManager", "find")) { return phpNamedElementCollections; } parameter = PhpTypeProviderUtil.getResolvedParameter(phpIndex, parameter); if (parameter == null) { return phpNamedElementCollections; } PhpClass phpClass = EntityHelper.resolveShortcutName(project, parameter); if (phpClass == null) { return phpNamedElementCollections; } return Arrays.asList(phpClass); }
public static PsiElement[] getPsiElementsBySignature( Project project, @Nullable String signature) { if (signature == null) { return new PsiElement[0]; } Collection<? extends PhpNamedElement> phpNamedElementCollections = PhpIndex.getInstance(project).getBySignature(signature, null, 0); return phpNamedElementCollections.toArray(new PsiElement[phpNamedElementCollections.size()]); }
private void parseTypes2( Map<String, Collection<String>> map, Iterable<ArrayHashElement> elements, String parent) { Collection<String> types = map.get(parent); if (types == null) { types = new ArrayList<String>(); map.put(parent, types); } for (ArrayHashElement element : elements) { PhpPsiElement key = element.getKey(); if (key instanceof StringLiteralExpression) { // key String keyName = ((StringLiteralExpression) key).getContents(); types.add(keyName); String fullKeyName = parent.length() > 0 ? (parent + "." + keyName) : keyName; // value PhpPsiElement val = element.getValue(); if (val instanceof ArrayCreationExpression) { // recursive Iterable<ArrayHashElement> subElements = ((ArrayCreationExpression) val).getHashElements(); parseTypes2(map, subElements, fullKeyName); } else if (val instanceof FieldReference) { // reference to a field, where it's defined String classFqn = ((ClassReference) ((FieldReference) val).getClassReference()).getFQN(); for (PhpClass phpClass : PhpIndex.getInstance(element.getProject()).getClassesByFQN(classFqn)) { Field field = phpClass.findFieldByName(((FieldReference) val).getNameCS(), false); if (field.getDefaultValue() instanceof ArrayCreationExpression) { Iterable<ArrayHashElement> subElements = ((ArrayCreationExpression) field.getDefaultValue()).getHashElements(); parseTypes2(map, subElements, fullKeyName); } } } else { // get value type parseValueType(val); // try annotation PsiElement el2 = element; while (el2 != null && (el2 instanceof LeafPsiElement && ((LeafPsiElement) el2).getElementType() == PhpTokenTypes.opCOMMA || el2 instanceof PsiWhiteSpace)) { el2 = el2.getNextSibling(); } if (el2 instanceof PsiComment) { System.out.println("Comment for " + fullKeyName + ": " + el2.getText()); } } } } }
@Nullable public static PhpClass getClassInterface(Project project, @NotNull String className) { // api workaround for at least interfaces if (!className.startsWith("\\")) { className = "\\" + className; } Collection<PhpClass> phpClasses = PhpIndex.getInstance(project).getAnyByFQN(className); return phpClasses.size() == 0 ? null : phpClasses.iterator().next(); }
@Nullable public static PhpClass getInterface(PhpIndex phpIndex, String className) { // api workaround if (!className.startsWith("\\")) { className = "\\" + className; } Collection<PhpClass> classes = phpIndex.getInterfacesByFQN(className); return classes.isEmpty() ? null : classes.iterator().next(); }
@Override protected void addCompletions( @NotNull CompletionParameters parameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { if (!Symfony2ProjectComponent.isEnabled(parameters.getPosition())) { return; } PhpIndex phpIndex = PhpIndex.getInstance(parameters.getOriginalFile().getProject()); for (PhpClass phpClass : phpIndex.getAllSubclasses("\\Doctrine\\ORM\\EntityRepository")) { String presentableFQN = phpClass.getPresentableFQN(); if (presentableFQN != null) { completionResultSet.addElement( LookupElementBuilder.create(phpClass.getName()) .withTypeText(phpClass.getPresentableFQN(), true) .withIcon(phpClass.getIcon())); } } }
@NotNull public static Collection<SymfonyCommand> getCommands(@NotNull Project project) { Collection<SymfonyCommand> symfonyCommands = new ArrayList<SymfonyCommand>(); for (PhpClass phpClass : PhpIndex.getInstance(project) .getAllSubclasses("\\Symfony\\Component\\Console\\Command\\Command")) { if (PhpElementsUtil.isTestClass(phpClass)) { continue; } Method method = phpClass.findOwnMethodByName("configure"); if (method == null) { continue; } PsiElement[] psiElements = PsiTreeUtil.collectElements( method, new PsiElementFilter() { @Override public boolean isAccepted(PsiElement psiElement) { return psiElement instanceof MethodReference && "setName".equals(((MethodReference) psiElement).getName()); } }); for (PsiElement psiElement : psiElements) { if (!(psiElement instanceof MethodReference)) { continue; } PsiElement psiMethodParameter = PsiElementUtils.getMethodParameterPsiElementAt((MethodReference) psiElement, 0); if (psiMethodParameter == null) { continue; } String stringValue = PhpElementsUtil.getStringValue(psiMethodParameter); if (stringValue == null) { continue; } symfonyCommands.add(new SymfonyCommand(stringValue, psiElement)); } } return symfonyCommands; }
@Nullable public static Method getClassMethod(Project project, String phpClassName, String methodName) { // we need here an each; because eg Command is non unique because phar file for (PhpClass phpClass : PhpIndex.getInstance(project).getClassesByFQN(phpClassName)) { Method method = getClassMethod(phpClass, methodName); if (method != null) { return method; } } return null; }
public static List<ResolveResult> getClassInterfaceResolveResult( Project project, String fqnClassOrInterfaceName) { // api workaround for at least interfaces if (!fqnClassOrInterfaceName.startsWith("\\")) { fqnClassOrInterfaceName = "\\" + fqnClassOrInterfaceName; } List<ResolveResult> results = new ArrayList<ResolveResult>(); for (PhpClass phpClass : PhpIndex.getInstance(project).getAnyByFQN(fqnClassOrInterfaceName)) { results.add(new PsiElementResolveResult(phpClass)); } return results; }
@NotNull @Override public Collection<LookupElement> getLookupElements( @NotNull SourceContributorParameter parameter) { String sourceParameter = parameter.getSourceParameter(); if (sourceParameter == null) { return Collections.emptyList(); } Collection<LookupElement> lookupElements = new ArrayList<LookupElement>(); for (PhpClass phpClass : PhpIndex.getInstance(parameter.getProject()).getAllSubclasses(sourceParameter)) { lookupElements.add( LookupElementBuilder.create(phpClass.getPresentableFQN()).withIcon(phpClass.getIcon())); } return lookupElements; }
public static Collection<PhpClass> getClassFromPhpTypeSet(Project project, Set<String> types) { PhpType phpType = new PhpType(); phpType.add(types); List<PhpClass> phpClasses = new ArrayList<PhpClass>(); for (String typeName : PhpIndex.getInstance(project) .completeType(project, phpType, new HashSet<String>()) .getTypes()) { if (typeName.startsWith("\\")) { PhpClass phpClass = PhpElementsUtil.getClassInterface(project, typeName); if (phpClass != null) { phpClasses.add(phpClass); } } } return phpClasses; }
/** * we can also pipe php references signatures and resolve them here overwrite parameter to get * string value */ @Nullable public static String getResolvedParameter(PhpIndex phpIndex, String parameter) { // PHP 5.5 class constant: "Class\Foo::class" if (parameter.startsWith("#K#C")) { // PhpStorm9: #K#C\Class\Foo.class if (parameter.endsWith(".class")) { return parameter.substring(4, parameter.length() - 6); } // PhpStorm8: #K#C\Class\Foo. // workaround since signature has empty type if (parameter.endsWith(".")) { return parameter.substring(4, parameter.length() - 1); } } // #K#C\Class\Foo.property // #K#C\Class\Foo.CONST if (parameter.startsWith("#")) { // get psi element from signature Collection<? extends PhpNamedElement> signTypes = phpIndex.getBySignature(parameter, null, 0); if (signTypes.size() == 0) { return null; } // get string value parameter = PhpElementsUtil.getStringValue(signTypes.iterator().next()); if (parameter == null) { return null; } } return parameter; }
private Collection<Variable> getVariables(Project project, String key) { return PhpIndex.getInstance(project).getVariablesByName(key); }
/** * Collect PhpClass which are inside current namespace and in sub-namespaces * * @param project current project * @param namespaceName namespace name should start with \ and not end with "\" * @return classes inside namespace and sub-namespace */ public static Collection<PhpClass> getPhpClassInsideNamespace( Project project, String namespaceName) { return getPhpClassInsideNamespace(project, PhpIndex.getInstance(project), namespaceName, 10); }
private Map<String, String> findRootDefinition(Collection<MethodReference> methodReferences) { Map<String, String> roots = new HashMap<String, String>(); if (methodReferences.size() == 0) { return roots; } String rootAlias = null; String repository = null; for (MethodReference methodReference : methodReferences) { String methodReferenceName = methodReference.getName(); // get alias // ->createQueryBuilder('test'); if ("createQueryBuilder".equals(methodReferenceName)) { String possibleAlias = PhpElementsUtil.getStringValue( PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0)); if (possibleAlias != null) { rootAlias = possibleAlias; } } // find repository class // getRepository('Foo')->createQueryBuilder('test'); if ("getRepository".equals(methodReferenceName)) { String possibleRepository = PhpElementsUtil.getStringValue( PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0)); if (possibleRepository != null) { repository = possibleRepository; PhpClass phpClass = EntityHelper.resolveShortcutName(project, repository); if (phpClass != null) { repository = phpClass.getPresentableFQN(); } } } // $qb->from('Foo\Class', 'article') if ("from".equals(methodReferenceName)) { String table = PhpElementsUtil.getStringValue( PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 0)); String alias = PhpElementsUtil.getStringValue( PsiElementUtils.getMethodParameterPsiElementAt(methodReference, 1)); if (table != null && alias != null) { PhpClass phpClass = EntityHelper.resolveShortcutName(project, table); if (phpClass != null) { table = phpClass.getPresentableFQN(); } roots.put(table, alias); } } } // we have a valid root so add it if (rootAlias != null && repository != null) { roots.put(repository, rootAlias); } // we found a alias but not a repository name, so try a scope search if we are inside repository // class // class implements \Doctrine\Common\Persistence\ObjectRepository, so search for model name of // "repositoryClass" if (rootAlias != null && repository == null) { MethodReference methodReference = methodReferences.iterator().next(); PhpClass phpClass = PsiTreeUtil.getParentOfType(methodReference, PhpClass.class); if (new Symfony2InterfacesUtil() .isInstanceOf(phpClass, "\\Doctrine\\Common\\Persistence\\ObjectRepository")) { for (DoctrineModel model : EntityHelper.getModelClasses(project)) { String className = model.getPhpClass().getPresentableFQN(); if (className != null) { PhpClass resolvedRepoName = EntityHelper.getEntityRepositoryClass(project, className); if (PhpElementsUtil.isEqualClassName(resolvedRepoName, phpClass.getPresentableFQN())) { roots.put(className, rootAlias); return roots; } } } } } // search on PhpTypeProvider // $er->createQueryBuilder() if (rootAlias != null && repository == null) { for (MethodReference methodReference : methodReferences) { if ("createQueryBuilder".equals(methodReference.getName())) { String signature = methodReference.getSignature(); int endIndex = signature.lastIndexOf(ObjectRepositoryTypeProvider.TRIM_KEY); if (endIndex != -1) { String parameter = signature.substring(endIndex + 1); int point = parameter.indexOf("."); if (point > -1) { parameter = parameter.substring(0, point); parameter = PhpTypeProviderUtil.getResolvedParameter( PhpIndex.getInstance(project), parameter); if (parameter != null) { PhpClass phpClass = EntityHelper.resolveShortcutName(project, parameter); if (phpClass != null && phpClass.getPresentableFQN() != null) { roots.put(phpClass.getPresentableFQN(), rootAlias); return roots; } } } } } } } return roots; }
@Nullable public static PhpClass getClass(Project project, String className) { return getClass(PhpIndex.getInstance(project), className); }
@Nullable public static PhpClass getClass(PhpIndex phpIndex, String className) { Collection<PhpClass> classes = phpIndex.getClassesByFQN(className); return classes.isEmpty() ? null : classes.iterator().next(); }