下面列出了怎么用com.intellij.psi.PsiRecursiveElementVisitor的API类实例代码及写法,或者点击链接到github查看源代码。
@NotNull
@Override
public Collection<? extends String> getVariants(ConvertContext convertContext) {
if (convertContext == null) return Collections.emptyList();
XmlFile file = convertContext.getFile();
final Set<String> drawableIds = new HashSet<>();
file.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
super.visitElement(element);
if (element instanceof XmlTag) {
String drawableId = ((XmlTag) element).getAttributeValue("drawableId", SdkConstants.AUTO_URI);
if(drawableId != null && !drawableId.isEmpty()) {
drawableIds.add(drawableId);
}
}
}
});
return new ArrayList<>(drawableIds);
}
public GraphQLInjectionIndex() {
myDataIndexer = inputData -> {
final Ref<String> environment = new Ref<>();
inputData.getPsiFile().accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (!GraphQLLanguageInjectionUtil.isJSGraphQLLanguageInjectionTarget(element, environment)) {
// visit deeper until injection found
super.visitElement(element);
}
}
});
return environment.isNull() ? Collections.emptyMap() : INJECTED_KEY;
};
includedFileTypes = GraphQLFindUsagesUtil.getService().getIncludedFileTypes();
}
public static String getEnvironment(PsiFile file) {
if (file instanceof JSFile) {
// for JS Files we have to check the kind of environment being used
final Ref<String> envRef = new Ref<>();
file.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (!isJSGraphQLLanguageInjectionTarget(element, envRef)) {
// no match yet, so keep visiting
super.visitElement(element);
}
}
});
final String environment = envRef.get();
if (environment != null) {
return environment;
}
} else if (file instanceof GraphQLFile) {
final Ref<String> tag = new Ref<>();
if (file.getContext() != null && isJSGraphQLLanguageInjectionTarget(file.getContext(), tag)) {
return tag.get();
}
}
// fallback is traditional GraphQL
return GRAPHQL_ENVIRONMENT;
}
@Test
public void testBasicResolveUnknownGlobalVariable() throws Exception {
final PsiReference psiReference = configure();
//must not resolve because the definition is local due to the previous definition
PsiElement varDef = psiReference.resolve();
Assert.assertNull("The vardef should not be found, because it is undefined", varDef);
//the variable must not be a valid reference to the following var def
final AtomicInteger visited = new AtomicInteger(0);
psiReference.getElement().getContainingFile().acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof BashVarDef) {
visited.incrementAndGet();
Assert.assertFalse("A var def must not be a valid definition for the variable used.",
psiReference.isReferenceTo(element));
}
super.visitElement(element);
}
});
Assert.assertEquals(1, visited.get());
}
@Nonnull
public static UnusedUsingVisitor accept(@Nonnull PsiFile file)
{
final UnusedUsingVisitor unusedUsingVisitor = new UnusedUsingVisitor();
PsiRecursiveElementVisitor visitor = new PsiRecursiveElementVisitor()
{
@Override
public void visitElement(PsiElement element)
{
element.accept(unusedUsingVisitor);
super.visitElement(element);
}
};
file.accept(visitor);
return unusedUsingVisitor;
}
private void phpVisitor(final @NotNull ProblemsHolder holder, @NotNull PsiFile psiFile) {
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
PsiElement parent = element.getParent();
if(!(parent instanceof StringLiteralExpression)) {
super.visitElement(element);
return;
}
MethodReference methodReference = PsiElementUtils.getMethodReferenceWithFirstStringParameter(element);
if (methodReference != null && PhpElementsUtil.isMethodReferenceInstanceOf(methodReference, ServiceContainerUtil.SERVICE_GET_SIGNATURES)) {
String serviceName = ((StringLiteralExpression) parent).getContents();
if(StringUtils.isNotBlank(serviceName) && !serviceName.equals(serviceName.toLowerCase())) {
holder.registerProblem(element, SYMFONY_LOWERCASE_LETTERS_FOR_SERVICE, ProblemHighlightType.WEAK_WARNING);
}
}
super.visitElement(element);
}
});
}
private void yamlVisitor(@NotNull ProblemsHolder holder, @NotNull PsiFile psiFile) {
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement psiElement) {
if(psiElement instanceof YAMLScalar) {
String textValue = ((YAMLScalar) psiElement).getTextValue();
if(textValue.length() > 0 && textValue.startsWith("!php/const:")) {
String constantName = textValue.substring(11);
if(StringUtils.isNotBlank(constantName) && ServiceContainerUtil.getTargetsForConstant(psiElement.getProject(), constantName).size() == 0) {
holder.registerProblem(psiElement, MESSAGE, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
}
}
super.visitElement(psiElement);
}
});
}
protected List<Block> buildChildren() {
final List<Block> result = new ArrayList<Block>();
myNode.getPsi().acceptChildren(new PsiRecursiveElementVisitor() {
public void visitElement(PsiElement psiElement) {
final ASTNode node = psiElement.getNode();
if (node != null) {
final IElementType nodeType = node.getElementType();
if (nodeType == CppTokenTypes.BLOCK || nodeType == CppTokenTypes.LBRACE || nodeType == CppTokenTypes.RBRACE) {
final CppBlock block = new CppBlock(psiElement);
result.add(block);
}
}
super.visitElement(psiElement);
}
});
return result;
}
@Override
public PsiReference getReference() {
final Ref<PsiReference> reference = new Ref<>();
final GraphQLDirectiveLocationPsiElement psiElement = this;
final String locationName = psiElement.getText();
GraphQLPsiSearchHelper.getService(getProject()).getBuiltInSchema().accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(element instanceof GraphQLEnumValue && element.getText().equals(locationName)) {
final GraphQLIdentifier referencedEnumValue = ((GraphQLEnumValue) element).getNameIdentifier();
reference.set(new PsiReferenceBase<PsiElement>(psiElement, new TextRange(0, psiElement.getTextLength())) {
@Nullable
@Override
public PsiElement resolve() {
return referencedEnumValue;
}
@NotNull
@Override
public Object[] getVariants() {
return PsiReference.EMPTY_ARRAY;
}
});
return; // done visiting
}
super.visitElement(element);
}
});
return reference.get();
}
/**
* Uses the {@link GraphQLInjectionIndex} to process injected GraphQL PsiFiles
*
* @param scopedElement the starting point of the enumeration settings the scopedElement of the processing
* @param schemaScope the search scope to use for limiting the schema definitions
* @param consumer a consumer that will be invoked for each injected GraphQL PsiFile
*/
public void processInjectedGraphQLPsiFiles(PsiElement scopedElement, GlobalSearchScope schemaScope, Consumer<PsiFile> consumer) {
try {
final PsiManager psiManager = PsiManager.getInstance(scopedElement.getProject());
final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(scopedElement.getProject());
FileBasedIndex.getInstance().getFilesWithKey(GraphQLInjectionIndex.NAME, Collections.singleton(GraphQLInjectionIndex.DATA_KEY), virtualFile -> {
final PsiFile fileWithInjection = psiManager.findFile(virtualFile);
if (fileWithInjection != null) {
fileWithInjection.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (GraphQLLanguageInjectionUtil.isJSGraphQLLanguageInjectionTarget(element)) {
injectedLanguageManager.enumerate(element, (injectedPsi, places) -> {
consumer.accept(injectedPsi);
});
} else {
// visit deeper until injection found
super.visitElement(element);
}
}
});
}
return true;
}, schemaScope);
} catch (IndexNotReadyException e) {
// can't search yet (e.g. during project startup)
}
}
/**
* Compares the signatures of two fields, ignoring comments, whitespace, and annotations
*/
private boolean hasSameSignature(JSGraphQLEndpointFieldDefinition override, JSGraphQLEndpointFieldDefinition toImplement) {
final StringBuilder toImplementSignature = new StringBuilder();
final StringBuilder overrideSignature = new StringBuilder();
final Ref<StringBuilder> sb = new Ref<>();
final PsiElementVisitor visitor = new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof JSGraphQLEndpointAnnotation) {
return;
}
if (element instanceof PsiWhiteSpace) {
return;
}
if (element instanceof PsiComment) {
return;
}
if (element instanceof LeafPsiElement) {
sb.get().append(element.getText()).append(" ");
}
super.visitElement(element);
}
};
sb.set(overrideSignature);
override.accept(visitor);
sb.set(toImplementSignature);
toImplement.accept(visitor);
return toImplementSignature.toString().equals(overrideSignature.toString());
}
private void highlightVariables(PsiElement containerElement, final AnnotationHolder holder) {
new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof BashVar) {
Annotation infoAnnotation = holder.createInfoAnnotation(element, null);
infoAnnotation.setTextAttributes(BashSyntaxHighlighter.VAR_USE);
}
super.visitElement(element);
}
}.visitElement(containerElement);
}
public static void visitRegisterCoreContainerAliases(@NotNull Project project, @NotNull DicAliasVisitor visitor) {
for (PhpClass phpClass : PhpElementsUtil.getClassesOrInterfaces(project, "Illuminate\\Foundation\\Application")) {
Method registerMethod = phpClass.findMethodByName("registerCoreContainerAliases");
if(registerMethod == null) {
continue;
}
final Collection<Variable> aliases = new HashSet<>();
registerMethod.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(element instanceof Variable && ((Variable) element).isDeclaration() && "aliases".equals(((Variable) element).getName())) {
aliases.add((Variable) element);
}
super.visitElement(element);
}
});
if(aliases.size() == 0) {
continue;
}
for (Variable alias : aliases) {
ArrayCreationExpression arrayCreation = PsiTreeUtil.getNextSiblingOfType(alias, ArrayCreationExpression.class);
if(arrayCreation == null) {
continue;
}
Map<String, PsiElement> arrayCreationKeyMap = PhpElementsUtil.getArrayValueMap(arrayCreation);
for (Map.Entry<String, PsiElement> entry : arrayCreationKeyMap.entrySet()) {
PsiElement value = entry.getValue();
visitor.visit(value, entry.getKey());
}
}
}
}
@NotNull
@Override
public DataIndexer<String, Void, FileContent> getIndexer() {
return fileContent -> {
final Map<String, Void> map = new THashMap<>();
PsiFile psiFile = fileContent.getPsiFile();
if(!(psiFile instanceof BladeFileImpl)) {
return map;
}
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(!(element instanceof BladePsiDirectiveParameter)) {
super.visitElement(element);
return;
}
for (String s : BladePsiUtil.getEachDirectiveTemplateParameter((BladePsiDirectiveParameter) element)) {
map.put(s, null);
}
}
});
return map;
};
}
@NotNull
private List<PsiElement> collectPsiElementsRecursive(@NotNull PsiElement psiElement) {
final List<PsiElement> elements = new ArrayList<PsiElement>();
elements.add(psiElement.getContainingFile());
psiElement.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
elements.add(element);
super.visitElement(element);
}
});
return elements;
}
public static void visitSubscriberEvents(@NotNull Method method, @NotNull SubscriberEventsVisitor visitor) {
method.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(element instanceof PhpReturn) {
visitSubscriberEvents((PhpReturn) element, visitor);
}
super.visitElement(element);
}
});
}
/**
* {s name="foobar" namespace ="foobar/foobar"}{/s}
*/
private static void visitSnippets(@NotNull SmartyFile file, @NotNull Consumer<ShopwareSnippet> consumer) {
LazySmartyFileNamespace lazyFileNamespace = new LazySmartyFileNamespace(file);
file.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(!SmartyPattern.getTagAttributePattern("s", "name").accepts(element)) {
super.visitElement(element);
return;
}
String text = element.getText();
if(StringUtils.isBlank(text)) {
super.visitElement(element);
return;
}
PsiElement parent = element.getParent();
String namespace = TemplateUtil.getTagAttributeValueByName((SmartyTag) parent, "namespace");
if(namespace == null) {
namespace = lazyFileNamespace.getNamespace();
}
if(namespace != null) {
consumer.accept(new ShopwareSnippet(element, namespace, text));
}
super.visitElement(element);
}
});
}
public static String getClassName(@NotNull LattePhpClassUsage classUsage) {
StringBuilder out = new StringBuilder();
classUsage.getParent().acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
IElementType type = element.getNode().getElementType();
if (TokenSet.create(T_PHP_NAMESPACE_REFERENCE, T_PHP_NAMESPACE_RESOLUTION, T_PHP_IDENTIFIER).contains(type)) {
out.append(element.getText());
} else {
super.visitElement(element);
}
}
});
return LattePhpUtil.normalizeClassName(out.toString());
}
@Override
public List<PsiElement> getTargets()
{
final OurVisitor visitor = new OurVisitor(myListChild);
myFile.accept(new PsiRecursiveElementVisitor()
{
@Override
public void visitElement(PsiElement element)
{
element.accept(visitor);
super.visitElement(element);
}
});
return visitor.getElements();
}
private void yamlVisitor(final @NotNull ProblemsHolder holder, @NotNull PsiFile psiFile) {
// usage in service arguments or every other service condition
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement psiElement) {
// @TODO: support key itself
if (YamlElementPatternHelper.getServiceDefinition().accepts(psiElement) && YamlElementPatternHelper.getInsideServiceKeyPattern().accepts(psiElement)) {
// @foo, @=foo, @?foo
String serviceText = PsiElementUtils.trimQuote(psiElement.getText());
if (isValidService(serviceText)) {
String serviceName = YamlHelper.trimSpecialSyntaxServiceName(serviceText);
// dont mark "@", "@?", "@@" escaping and expressions
if (StringUtils.isNotBlank(serviceName) && !serviceName.equals(serviceName.toLowerCase()) && !YamlHelper.isClassServiceId(serviceName)) {
holder.registerProblem(psiElement, SYMFONY_LOWERCASE_LETTERS_FOR_SERVICE, ProblemHighlightType.WEAK_WARNING);
}
}
}
super.visitElement(psiElement);
}
});
// services and parameter
YamlHelper.processKeysAfterRoot(psiFile, yamlKeyValue -> {
String keyText = yamlKeyValue.getKeyText();
if(StringUtils.isNotBlank(keyText) && !keyText.equals(keyText.toLowerCase()) && !YamlHelper.isClassServiceId(keyText)) {
PsiElement firstChild = yamlKeyValue.getFirstChild();
if(firstChild != null) {
holder.registerProblem(firstChild, SYMFONY_LOWERCASE_LETTERS_FOR_SERVICE, ProblemHighlightType.WEAK_WARNING);
}
}
return false;
}, "services", "parameters");
}
private void xmlVisitor(final @NotNull ProblemsHolder holder, @NotNull PsiFile psiFile) {
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement psiElement) {
if(psiElement instanceof XmlAttributeValue && (XmlHelper.getArgumentServiceIdPattern().accepts(psiElement) || XmlHelper.getServiceIdAttributePattern().accepts(psiElement))) {
String serviceName = ((XmlAttributeValue) psiElement).getValue();
if(StringUtils.isNotBlank(serviceName) && !serviceName.equals(serviceName.toLowerCase()) && !YamlHelper.isClassServiceId(serviceName)) {
holder.registerProblem(psiElement, SYMFONY_LOWERCASE_LETTERS_FOR_SERVICE, ProblemHighlightType.WEAK_WARNING);
}
}
super.visitElement(psiElement);
}
});
}
private void xmlVisitor(@NotNull ProblemsHolder holder, @NotNull PsiFile psiFile) {
psiFile.acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement psiElement) {
if(!XmlHelper.getArgumentValueWithTypePattern("constant").accepts(psiElement)) {
super.visitElement(psiElement);
return;
}
PsiElement xmlText = psiElement.getParent();
if(!(xmlText instanceof XmlText)) {
super.visitElement(psiElement);
return;
}
String value = ((XmlText) xmlText).getValue();
if(StringUtils.isBlank(value)) {
super.visitElement(psiElement);
return;
}
if(ServiceContainerUtil.getTargetsForConstant(xmlText.getProject(), value).size() == 0) {
holder.registerProblem(xmlText, MESSAGE, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
super.visitElement(psiElement);
}
});
}
public PsiElementVisitor createVisitor(final DependenciesBuilder.DependencyProcessor processor) {
return new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
super.visitElement(element);
PsiReference[] refs = element.getReferences();
for (PsiReference ref : refs) {
PsiElement resolved = ref.resolve();
if (resolved != null) {
processor.process(ref.getElement(), resolved);
}
}
}
};
}
private void maybeRecomputeEventClasses() {
List<VirtualFile> myFilesToScan;
synchronized (filesToScan) {
if (filesToScan.isEmpty()) return;
myFilesToScan = new ArrayList<VirtualFile>(filesToScan);
filesToScan.clear();
}
for (VirtualFile virtualFile : myFilesToScan) {
synchronized (fileToEventClasses) {
getEventClasses(virtualFile).clear();
}
PsiFile psiFile = PsiManager.getInstance(myProject).findFile(virtualFile);
if (psiFile == null) throw new IllegalStateException("huh? " + virtualFile);
if (psiFile.getFileType() instanceof JavaFileType) {
final long startTime = System.currentTimeMillis();
psiFile.accept(new PsiRecursiveElementVisitor() {
@Override public void visitElement(PsiElement element) {
if (element instanceof PsiMethod
&& SubscriberMetadata.isAnnotatedWithSubscriber((PsiMethod) element)) {
maybeAddSubscriberMethod((PsiMethod) element);
} else {
super.visitElement(element);
}
}
});
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Searched for @Subscribe in %s in %dms",
virtualFile, System.currentTimeMillis() - startTime));
}
}
}
optimizeEventClassIndex();
}
private void runCheckOnFunFunctionContainsEnclosingClassAccess(@NotNull String classFileName) {
myFixture.setTestDataPath("./src/test/resources/testdata/");
myFixture.configureByFile(PATH_TO_TEST_DATA + classFileName);
class Visitor extends PsiRecursiveElementVisitor {
private List<PsiMethod> psiMethods = new ArrayList<>();
@Override
public void visitElement(PsiElement element) {
if (element instanceof PsiMethod) {
psiMethods.add((PsiMethod) element);
}
super.visitElement(element);
}
private List<PsiMethod> getPsiMethods() {
return psiMethods;
}
}
Visitor visitor = new Visitor();
Project project = myFixture.getProject();
PsiFile psiFile = FilenameIndex.getFilesByName(project, classFileName, GlobalSearchScope.allScope(project))[0];
for (int i = 0; i < psiFile.getChildren().length; i++) {
PsiElement psiElement = psiFile.getChildren()[i];
visitor.visitElement(psiElement);
}
PsiMethod psiMethod = null;
for (int i = 0; i < visitor.getPsiMethods().size(); i++) {
PsiMethod psiMethod1 = visitor.getPsiMethods().get(i);
if (psiMethod1.getName().equals("fun")) {
psiMethod = psiMethod1;
}
}
final ConstructorObject constructorObject = new ConstructorObject();
constructorObject.setMethodDeclaration(psiMethod);
constructorObject.setName(psiMethod.getName());
constructorObject.setClassName(psiMethod.getContainingClass().getName());
int methodDeclarationStartPosition = psiMethod.getStartOffsetInParent();
int methodDeclarationEndPosition = methodDeclarationStartPosition + psiMethod.getTextLength();
constructorObject.setAccess(Access.PUBLIC);
constructorObject.setMethodBody(new MethodBodyObject(psiMethod.getBody()));
MethodObject methodObject = new MethodObject(psiMethod, constructorObject);
if (methodObject.containsFieldAccessOfEnclosingClass()) {
System.out.println("true");
} else {
System.out.println("false");
}
}
private static boolean doExecute(PsiElement sourceElement, final Processor<? super PsiElement> consumer) {
// must be an interface definition with a named type to be applicable
final Ref<JSGraphQLEndpointNamedTypeDef> sourceNamedTypeDef = new Ref<>();
final Ref<JSGraphQLEndpointProperty> sourceProperty = new Ref<>();
final Ref<JSGraphQLEndpointInterfaceTypeDefinition> sourceInterfaceDefinition = new Ref<>();
if (sourceElement instanceof JSGraphQLEndpointNamedTypeDef) {
sourceNamedTypeDef.set((JSGraphQLEndpointNamedTypeDef) sourceElement);
sourceInterfaceDefinition.set(PsiTreeUtil.getParentOfType(sourceNamedTypeDef.get(), JSGraphQLEndpointInterfaceTypeDefinition.class));
} else if (sourceElement instanceof JSGraphQLEndpointProperty) {
sourceProperty.set((JSGraphQLEndpointProperty) sourceElement);
sourceInterfaceDefinition.set(PsiTreeUtil.getParentOfType(sourceProperty.get(), JSGraphQLEndpointInterfaceTypeDefinition.class));
if (sourceInterfaceDefinition.get() != null) {
sourceNamedTypeDef.set(sourceInterfaceDefinition.get().getNamedTypeDef());
}
}
if (sourceNamedTypeDef.get() != null && sourceInterfaceDefinition.get() != null) {
final String interfaceName = sourceNamedTypeDef.get().getText();
final JSGraphQLEndpointNamedTypeRegistry typeRegistry = JSGraphQLEndpointNamedTypeRegistry.getService(sourceElement.getProject());
typeRegistry.enumerateTypes(sourceElement, jsGraphQLNamedType -> {
if (jsGraphQLNamedType.definitionElement instanceof JSGraphQLEndpointObjectTypeDefinition) {
final JSGraphQLEndpointObjectTypeDefinition typeDefinition = (JSGraphQLEndpointObjectTypeDefinition) jsGraphQLNamedType.definitionElement;
final JSGraphQLEndpointImplementsInterfaces implementsInterfaces = typeDefinition.getImplementsInterfaces();
if (implementsInterfaces != null) {
for (JSGraphQLEndpointNamedType namedType : implementsInterfaces.getNamedTypeList()) {
if (interfaceName.equals(namedType.getName())) {
if (sourceProperty.get() == null) {
// type implements the interface
consumer.process(typeDefinition.getNamedTypeDef());
} else {
// locate field overrides
final String propertyName = sourceProperty.get().getName();
jsGraphQLNamedType.definitionElement.accept(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof JSGraphQLEndpointProperty) {
if ((Objects.equals(propertyName, ((JSGraphQLEndpointProperty) element).getName()))) {
consumer.process(element);
}
return; // don't visit deeper than properties
}
super.visitElement(element);
}
});
}
break;
}
}
}
}
});
}
return true;
}
public static Map<String, Collection<String>> getServiceProviderMap(@NotNull Project project) {
Map<String, Collection<String>> map = new HashMap<>();
for (PhpClass phpClass : PhpIndex.getInstance(project).getAllSubclasses("\\Illuminate\\Support\\ServiceProvider")) {
Collection<MethodReference> methodReferences = new ArrayList<>();
for (Method method : phpClass.getMethods()) {
method.acceptChildren(new AppDicRecursiveElementVisitor(methodReferences));
}
if(methodReferences.size() == 0) {
continue;
}
for (MethodReference methodReference : methodReferences) {
PsiElement[] parameters = methodReference.getParameters();
if(parameters.length < 2 || !(parameters[0] instanceof StringLiteralExpression) || parameters[1].getNode().getElementType() != PhpElementTypes.CLOSURE) {
continue;
}
String dicName = ((StringLiteralExpression) parameters[0]).getContents();
if(StringUtils.isBlank(dicName)) {
continue;
}
final Set<String> types = new HashSet<>();
parameters[1].acceptChildren(new PsiRecursiveElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if(element instanceof PhpReturn) {
PhpPsiElement firstPsiChild = ((PhpReturn) element).getFirstPsiChild();
if(firstPsiChild instanceof PhpTypedElement) {
for (String s : ((PhpTypedElement) firstPsiChild).getType().getTypes()) {
if(s.startsWith("#")) {
continue;
}
types.add(StringUtils.stripStart(s, "\\"));
}
}
}
super.visitElement(element);
}
});
map.put(dicName, types);
}
}
return map;
}
@Override
public void analyze() {
AnalysisScope scope = myForwardScope;
final DependenciesBuilder builder = new ForwardDependenciesBuilder(getProject(), scope, getScopeOfInterest());
builder.setTotalFileCount(myTotalFileCount);
builder.analyze();
subtractScope(builder, getScope());
final PsiManager psiManager = PsiManager.getInstance(getProject());
psiManager.startBatchFilesProcessingMode();
try {
final int fileCount = getScope().getFileCount();
getScope().accept(new PsiRecursiveElementVisitor() {
@Override public void visitFile(final PsiFile file) {
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
if (indicator != null) {
if (indicator.isCanceled()) {
throw new ProcessCanceledException();
}
indicator.setText(AnalysisScopeBundle.message("package.dependencies.progress.text"));
final VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
indicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, getProject()));
}
if (fileCount > 0) {
indicator.setFraction(((double)++myFileCount) / myTotalFileCount);
}
}
final Map<PsiFile, Set<PsiFile>> dependencies = builder.getDependencies();
for (final PsiFile psiFile : dependencies.keySet()) {
if (dependencies.get(psiFile).contains(file)) {
Set<PsiFile> fileDeps = getDependencies().get(file);
if (fileDeps == null) {
fileDeps = new HashSet<PsiFile>();
getDependencies().put(file, fileDeps);
}
fileDeps.add(psiFile);
}
}
psiManager.dropResolveCaches();
InjectedLanguageManager.getInstance(file.getProject()).dropFileCaches(file);
}
});
}
finally {
psiManager.finishBatchFilesProcessingMode();
}
}