下面列出了com.intellij.psi.PsiRecursiveElementWalkingVisitor#com.jetbrains.php.lang.psi.elements.PhpClass 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static Set<String> getAnnotations(Project project, String className) {
HashSet<String> map = new HashSet<>();
PhpClass phpClass = PhpElementsUtil.getClass(project, className);
if(phpClass == null) {
return map;
}
for(Field field: phpClass.getFields()) {
if(!field.isConstant()) {
map.add(field.getName());
}
}
return map;
}
private boolean isValidForPhpClass(Editor editor, PsiFile file) {
if(!(file instanceof PhpFile)) {
return false;
}
int offset = editor.getCaretModel().getOffset();
if(offset <= 0) {
return false;
}
PsiElement psiElement = file.findElementAt(offset);
if(psiElement == null) {
return false;
}
return PlatformPatterns.psiElement().inside(PhpClass.class).accepts(psiElement);
}
@NotNull
@Override
public StringBuilder getStringBuilder(@NotNull ProblemDescriptor problemDescriptor, @NotNull PhpClass phpClass, @NotNull String functionName) {
String taggedEventMethodParameter = getEventTypeHint(problemDescriptor, phpClass);
String parameter = "";
if(taggedEventMethodParameter != null) {
parameter = taggedEventMethodParameter + " $event";
}
return new StringBuilder()
.append("public function ")
.append(functionName)
.append("(")
.append(parameter)
.append(")\n {\n}\n\n");
}
@Override
protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) {
PsiElement psiElement = parameters.getOriginalPosition();
if(psiElement == null) {
return;
}
PhpDocTag phpDocTag = PsiTreeUtil.getParentOfType(parameters.getOriginalPosition(), PhpDocTag.class);
PhpClass phpClass = AnnotationUtil.getAnnotationReference(phpDocTag);
if(phpClass == null) {
return;
}
AnnotationPropertyParameter annotationPropertyParameter = new AnnotationPropertyParameter(parameters.getOriginalPosition(), phpClass, AnnotationPropertyParameter.Type.DEFAULT);
providerWalker(parameters, context, result, annotationPropertyParameter);
}
public void handleInsert(@NotNull InsertionContext context, @NotNull LookupElement lookupElement) {
Object object = lookupElement.getObject();
if (!(object instanceof PhpClass)) {
return;
}
StringBuilder textToInsertBuilder = new StringBuilder();
PhpClass aClass = (PhpClass)object;
String fqn = aClass.getNamespaceName();
if(fqn.startsWith("\\")) {
fqn = fqn.substring(1);
}
textToInsertBuilder.append(fqn);
context.getDocument().insertString(context.getStartOffset(), textToInsertBuilder);
}
public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) {
if(!Symfony2ProjectComponent.isEnabled(parameters.getPosition())) {
return;
}
PhpIndex phpIndex = PhpIndex.getInstance(parameters.getOriginalFile().getProject());
Map<String, String> entityNamespaces = ServiceXmlParserFactory.getInstance(parameters.getOriginalFile().getProject(), EntityNamesServiceParser.class).getEntityNameMap();
// copied from PhpCompletionUtil::addClassesInNamespace looks the official way to find classes in namespaces
// its a really performance nightmare
Collection<String> names = phpIndex.getAllClassNames(new CamelHumpMatcher(resultSet.getPrefixMatcher().getPrefix()));
for (String name : names) {
Collection<PhpClass> classes = phpIndex.getClassesByName(name);
for(Map.Entry<String, String> entry: entityNamespaces.entrySet()) {
String namespaceFqn = PhpLangUtil.toFQN(entry.getValue());
Collection<PhpClass> filtered = PhpCompletionUtil.filterByNamespace(classes, namespaceFqn);
for (PhpClass phpClass : filtered) {
resultSet.addElement(new PhpClassLookupElement(phpClass, true, PhpClassReferenceInsertHandler.getInstance()));
}
}
}
}
@Override
public Collection<? extends PhpNamedElement> getBySignature(String expression, Set<String> visited, int depth, Project project) {
Collection<PhpNamedElement> phpNamedElementCollections = new ArrayList<>();
PhpIndex phpIndex = PhpIndex.getInstance(project);
CoreServiceParser serviceParser = new CoreServiceParser();
serviceParser.collect(project);
List<TYPO3ServiceDefinition> resolvedServices = serviceParser.resolve(project, expression);
if (resolvedServices == null || resolvedServices.isEmpty()) {
return phpNamedElementCollections;
}
resolvedServices.forEach(serviceDefinition -> {
Collection<PhpClass> classesByFQN = phpIndex.getClassesByFQN(serviceDefinition.getClassName());
phpNamedElementCollections.addAll(classesByFQN);
});
return phpNamedElementCollections;
}
public static @NotNull LattePhpType getReturnType(@NotNull LattePhpMethod element) {
LattePhpType type = element.getPhpType();
Collection<PhpClass> phpClasses = type.getPhpClasses(element.getProject());
String name = element.getMethodName();
if (phpClasses.size() == 0) {
LatteFunctionSettings customFunction = LatteConfiguration.getInstance(element.getProject()).getFunction(name);
return customFunction == null ? LattePhpType.MIXED : LattePhpType.create(customFunction.getFunctionReturnType());
}
List<PhpType> types = new ArrayList<>();
for (PhpClass phpClass : phpClasses) {
for (Method phpMethod : phpClass.getMethods()) {
if (phpMethod.getName().equals(name)) {
types.add(phpMethod.getType());
}
}
}
return types.size() > 0 ? LattePhpType.create(types).withDepth(element.getPhpArrayLevel()) : LattePhpType.MIXED;
}
@NotNull
private Collection<PsiElement> getTagMethodGoto(@NotNull PsiElement psiElement) {
String methodName = PsiElementUtils.trimQuote(psiElement.getText());
if(StringUtils.isBlank(methodName)) {
return Collections.emptyList();
}
String classValue = YamlHelper.getServiceDefinitionClassFromTagMethod(psiElement);
if(classValue == null) {
return Collections.emptyList();
}
PhpClass phpClass = ServiceUtil.getResolvedClassDefinition(psiElement.getProject(), classValue);
if(phpClass == null) {
return Collections.emptyList();
}
Method method = phpClass.findMethodByName(methodName);
if(method != null) {
return Collections.singletonList(method);
}
return Collections.emptyList();
}
private void visitPhpReturn(@NotNull PhpReturn phpReturn) {
PhpClass phpClass = method.getContainingClass();
if (phpClass == null) {
return;
}
HookSubscriberUtil.visitSubscriberEvents(phpReturn, (event, methodName, key) -> {
SubscriberInfo subscriberInfo = SubscriberIndexUtil.getSubscriberInfo(event);
if(subscriberInfo == null) {
return;
}
ServiceResource serviceResource = new ServiceResource(event, subscriberInfo.getEvent().getText(), subscriberInfo.getService())
.setSignature(StringUtils.strip(phpClass.getFQN(), "\\") + '.' + methodName);
String resourceKey = subscriberInfo.getEvent().getText();
if(!serviceMap.containsKey(resourceKey)) {
serviceMap.put(resourceKey, new ArrayList<>());
}
serviceMap.get(resourceKey).add(serviceResource);
});
}
public void testRouteGroups() {
assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
"Route::group(['namespace' => 'Group'], function() {\n" +
" Route::get('/', '<caret>');\n" +
"});",
"[email protected]"
);
assertNavigationMatch(PhpFileType.INSTANCE, "<?php\n" +
"Route::group(['namespace' => 'Group'], function() {\n" +
" Route::get('/', '[email protected]<caret>');\n" +
"});",
PlatformPatterns.psiElement(Method.class).withParent(
PlatformPatterns.psiElement(PhpClass.class).withName("GroupController")
)
);
}
public static boolean isExtendsSuperclass(PsiElement child, String superclass) {
if (child == null) {
return false;
}
try {
PhpClass[] supers = ((PhpClass) child).getSupers();
String className = ((PhpClass) child).getName().toLowerCase();
if (className.equals(superclass.toLowerCase())) {
return true;
}
for (PhpClass cl : supers) {
if (cl.getName().toLowerCase().equals(superclass.toLowerCase())) {
return true;
}
}
} catch (Exception e) {
return false;
}
return false;
}
public static String getTypeDisplayName(Project project, Set<String> types) {
Collection<PhpClass> classFromPhpTypeSet = getClassFromPhpTypeSet(project, types);
if (classFromPhpTypeSet.size() > 0) {
return classFromPhpTypeSet.iterator().next().getPresentableFQN();
}
PhpType phpType = new PhpType();
for (String type : types) {
phpType.add(type);
}
PhpType phpTypeFormatted = PhpIndex.getInstance(project).completeType(project, phpType, new HashSet<>());
if (phpTypeFormatted.getTypes().size() > 0) {
return StringUtils.join(phpTypeFormatted.getTypes(), "|");
}
if (types.size() > 0) {
return types.iterator().next();
}
return "";
}
/**
* 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;
}
// class in same namespace
String className = ((PhpClass) phpClassContext).getFQN() + "Validator";
Collection<PhpClass> phpClasses = new ArrayList<>(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));
}
@Nullable
private String getEventTypeHint(@NotNull ProblemDescriptor problemDescriptor, @NotNull PhpClass phpClass) {
String eventName = EventDispatcherSubscriberUtil.getEventNameFromScope(problemDescriptor.getPsiElement());
if (eventName == null) {
return null;
}
String taggedEventMethodParameter = EventSubscriberUtil.getTaggedEventMethodParameter(problemDescriptor.getPsiElement().getProject(), eventName);
if (taggedEventMethodParameter == null) {
return null;
}
String qualifiedName = AnnotationBackportUtil.getQualifiedName(phpClass, taggedEventMethodParameter);
if (qualifiedName != null && !qualifiedName.equals(StringUtils.stripStart(taggedEventMethodParameter, "\\"))) {
// class already imported
return qualifiedName;
}
return PhpElementsUtil.insertUseIfNecessary(phpClass, taggedEventMethodParameter);
}
private void attachController(Project project, String[] namespaces, List<PsiElement> targets) {
if(namespaces.length < 4) {
return;
}
// only show on some context
if(!Arrays.asList("controller", "store", "model", "view").contains(namespaces[3])) {
return;
}
String controller = namespaces[2];
// build class name
String className = String.format("\\Shopware_Controllers_%s_%s", "Backend", controller);
PhpClass phpClass = PhpElementsUtil.getClassInterface(project, className);
if(phpClass != null) {
targets.add(phpClass);
}
}
@Override
public void update(AnActionEvent event) {
event.getPresentation().setEnabled(false);
event.getPresentation().setVisible(true);
event.getPresentation().setText("atoum - run test");
PhpClass currentTestClass = getCurrentTestClass(event);
if (currentTestClass != null) {
event.getPresentation().setEnabled(true);
Method currentTestMethod = getCurrentTestMethod(event);
if (currentTestMethod != null) {
event.getPresentation().setText("atoum - run " + currentTestClass.getName() + "::" + currentTestMethod.getName(), false);
} else {
event.getPresentation().setText("atoum - run test : " + currentTestClass.getName(), false);
}
} else {
VirtualFile selectedDir = getCurrentTestDirectory(event);
if (selectedDir != null) {
event.getPresentation().setText("atoum - run dir : " + selectedDir.getName(), false);
event.getPresentation().setEnabled(true);
}
}
}
protected void saveFiles(PhpClass currentTestClass, Project project) {
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
Document documentTestClass = fileDocumentManager.getDocument(currentTestClass.getContainingFile().getVirtualFile());
if (documentTestClass != null) {
fileDocumentManager.saveDocument(documentTestClass);
}
PhpClass currentTestedClass = Utils.locateTestedClass(project, currentTestClass);
if (currentTestedClass != null) {
Document documentTestedClass = fileDocumentManager.getDocument(currentTestedClass.getContainingFile().getVirtualFile());
if (documentTestedClass != null) {
fileDocumentManager.saveDocument(documentTestedClass);
}
}
}
private void classNameMarker(PhpClass currentClass, Collection<? super RelatedItemLineMarkerInfo> result, Project project) {
Collection<PhpClass> target;
String tooltip;
if (Utils.isClassAtoumTest(currentClass)) {
target = Utils.locateTestedClasses(project, currentClass);
tooltip = "Navigate to tested class";
} else {
target = Utils.locateTestClasses(project, currentClass);
tooltip = "Navigate to test";
}
if (target.size() == 0) {
return;
}
NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder.create(Icons.ATOUM).
setTargets(target).
setTooltipText(tooltip);
result.add(builder.createLineMarkerInfo(currentClass));
}
/**
* class: FooClass
* tags:
* - [ setFoo, [@args_bar] ]
*/
private void visitCall(PsiElement psiElement) {
PsiElement yamlScalar = psiElement.getContext();
if(!(yamlScalar instanceof YAMLScalar)) {
return;
}
YamlHelper.visitServiceCallArgument((YAMLScalar) yamlScalar, visitor -> {
PhpClass serviceClass = ServiceUtil.getResolvedClassDefinition(psiElement.getProject(), visitor.getClassName(), getLazyServiceCollector(psiElement.getProject()));
if(serviceClass == null) {
return;
}
Method method = serviceClass.findMethodByName(visitor.getMethod());
if (method == null) {
return;
}
YamlXmlServiceInstanceInspection.registerInstanceProblem(psiElement, holder, visitor.getParameterIndex(), method, getLazyServiceCollector(psiElement.getProject()));
});
}
@NotNull
@Override
public Collection<LookupElement> getLookupElements() {
PsiElement parent = getElement().getParent();
if(!(parent instanceof XmlAttributeValue)) {
return Collections.emptyList();
}
Collection<PhpClass> phpClasses = new ArrayList<>();
ContainerUtil.addIfNotNull(phpClasses, XmlHelper.getPhpClassForClassFactory((XmlAttributeValue) parent));
ContainerUtil.addIfNotNull(phpClasses, XmlHelper.getPhpClassForServiceFactory((XmlAttributeValue) parent));
Collection<LookupElement> lookupElements = new ArrayList<>();
for (PhpClass phpClass : phpClasses) {
lookupElements.addAll(PhpElementsUtil.getClassPublicMethod(phpClass).stream()
.map(PhpLookupElement::new)
.collect(Collectors.toList())
);
}
return lookupElements;
}
private static <T extends BaseLattePhpElement> void attachResults(@NotNull List<T> result, String key, List<PsiElement> elements, @Nullable Collection<PhpClass> phpClasses)
{
for (PsiElement element : elements) {
if (!(element instanceof BaseLattePhpElement)) {
continue;
}
if ((phpClasses != null && phpClasses.size() > 0 && !((BaseLattePhpElement) element).getPhpType().hasClass(phpClasses))) {
continue;
}
String varName = ((BaseLattePhpElement) element).getPhpElementName();
if (key.equals(varName)) {
result.add((T) element);
}
}
}
protected boolean isCallTo(Method e, Method[] expectedMethods) {
PhpClass methodClass = e.getContainingClass();
if(methodClass == null) {
return false;
}
for (Method expectedMethod : expectedMethods) {
// @TODO: its stuff from beginning times :)
if(expectedMethod == null) {
continue;
}
PhpClass containingClass = expectedMethod.getContainingClass();
if (containingClass != null && expectedMethod.getName().equalsIgnoreCase(e.getName()) && isInstanceOf(methodClass, containingClass)) {
return true;
}
}
return false;
}
@NotNull
public Collection<LookupElement> getLookupElements(@NotNull PhpToolboxCompletionContributorParameter parameter) {
PhpIndex instance = PhpIndex.getInstance(parameter.getProject());
Collection<LookupElement> lookupElements = new ArrayList<>();
for (String className : getClasses(parameter)) {
// strip double backslash
className = className.replaceAll("\\\\+", "\\\\");
for (PhpClass phpClass : getPhpClassesForLookup(instance, className)) {
lookupElements.add(
LookupElementBuilder.create(phpClass.getPresentableFQN()).withIcon(phpClass.getIcon())
);
}
}
return lookupElements;
}
private void serviceTagCallback(String className, TagCallbackInterface callback) {
PhpClass phpClass = PhpElementsUtil.getClass(project, className);
if(phpClass == null) {
return;
}
List<ServiceTag> serviceTags = new ArrayList<>();
for (String tag : ServiceUtil.getPhpClassServiceTags(phpClass)) {
ServiceTag serviceTag = new ServiceTag(phpClass, tag);
ServiceUtil.decorateServiceTag(serviceTag);
serviceTags.add(serviceTag);
}
if(serviceTags.size() == 0) {
return;
}
callback.onTags(serviceTags);
}
public boolean isInstanceOf(@NotNull PhpClass subjectClass, @NotNull PhpClass expectedClass) {
// we have equal class instance, on non multiple classes with same name fallback to namespace and classname
if (subjectClass == expectedClass || PhpElementsUtil.isEqualClassName(subjectClass, expectedClass)) {
return true;
}
if (expectedClass.isInterface()) {
return isImplementationOfInterface(subjectClass, expectedClass);
}
if (null == subjectClass.getSuperClass()) {
return false;
}
return isInstanceOf(subjectClass.getSuperClass(), expectedClass);
}
@NotNull
public static PsiElement[] getPsiElements(@NotNull Project project, @NotNull String contents) {
Collection<PsiElement> psiElements = new HashSet<>();
contents = contents.replaceAll("\\\\+", "\\\\");
// DateTime
// date
Matcher matcher = Pattern.compile("^([\\w\\\\-]+)$").matcher(contents);
if (matcher.find()) {
PhpIndex phpIndex = PhpIndex.getInstance(project);
ContainerUtil.addAllNotNull(psiElements, phpIndex.getAnyByFQN(contents));
ContainerUtil.addAllNotNull(psiElements, phpIndex.getFunctionsByName(contents));
return psiElements.toArray(new PsiElement[psiElements.size()]);
}
// DateTime:format
// DateTime::format
matcher = Pattern.compile("^([\\w\\\\-]+):+([\\w_\\-]+)$").matcher(contents);
if (matcher.find()) {
for (PhpClass phpClass : PhpIndex.getInstance(project).getAnyByFQN(matcher.group(1))) {
ContainerUtil.addIfNotNull(psiElements, phpClass.findMethodByName(matcher.group(2)));
}
return psiElements.toArray(new PsiElement[psiElements.size()]);
}
return psiElements.toArray(new PsiElement[psiElements.size()]);
}
@Override
public Collection<DoctrineModelProviderParameter.DoctrineModel> collectModels(DoctrineModelProviderParameter parameter) {
if(!ShopwareProjectComponent.isValidForProject(parameter.getProject())) {
return Collections.emptyList();
}
List<DoctrineModelProviderParameter.DoctrineModel> doctrineModels = new ArrayList<>();
for(PhpClass phpClass: PhpIndex.getInstance(parameter.getProject()).getAllSubclasses("\\Shopware\\Components\\Model\\ModelEntity")) {
doctrineModels.add(new DoctrineModelProviderParameter.DoctrineModel(phpClass));
}
return doctrineModels;
}
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement psiElement) throws IncorrectOperationException {
if(!(psiElement.getContainingFile() instanceof PhpFile)) {
return;
}
PhpClass phpClass = PhpBundleFileFactory.getPhpClassForCreateCompilerScope(PsiTreeUtil.getParentOfType(psiElement, PhpClass.class));
if(phpClass == null) {
return;
}
PhpBundleFileFactory.invokeCreateCompilerPass(phpClass, editor);
}
public void testThatPhpDocOfNamespaceProvidesNavigation() {
assertNavigationMatch(PhpFileType.INSTANCE, "<?php\n" +
"namespace Bar;\n" +
"\n" +
"use Foo\\Bar;\n" +
"\n" +
"/**\n" +
" * @B<caret>ar()\n" +
" */\n" +
"class Foo\n" +
"{}\n",
PlatformPatterns.psiElement(PhpClass.class)
);
}