Skip to content

Commit c5ef977

Browse files
authored
Merge pull request #221 from cedricziel/index-ajax-routes-correctly
[T3CMS] Index ajax backend routes correctly
2 parents 7d20d42 + 78385ba commit c5ef977

File tree

10 files changed

+150
-54
lines changed

10 files changed

+150
-54
lines changed

typo3-cms/src/main/java/com/cedricziel/idea/typo3/icons/IconReferenceContributor.java

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
import com.cedricziel.idea.typo3.util.PhpLangUtil;
44
import com.intellij.patterns.PlatformPatterns;
55
import com.intellij.psi.*;
6+
import com.intellij.psi.util.PsiTreeUtil;
67
import com.intellij.util.ProcessingContext;
78
import com.jetbrains.php.PhpIndex;
89
import com.jetbrains.php.lang.psi.elements.MethodReference;
910
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
1011
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
1112
import com.jetbrains.php.lang.psi.elements.Variable;
12-
import com.jetbrains.php.lang.psi.resolve.types.PhpType;
1313
import org.jetbrains.annotations.NotNull;
1414

1515
import java.util.Collection;
16-
import java.util.Set;
1716

1817
public class IconReferenceContributor extends PsiReferenceContributor {
1918

@@ -23,54 +22,43 @@ public class IconReferenceContributor extends PsiReferenceContributor {
2322
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
2423
// known method calls
2524
registrar.registerReferenceProvider(
26-
PlatformPatterns.psiElement(StringLiteralExpression.class),
27-
new PsiReferenceProvider() {
28-
@NotNull
29-
@Override
30-
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
31-
StringLiteralExpression stringLiteralExpression = (StringLiteralExpression) element;
25+
PlatformPatterns.psiElement(StringLiteralExpression.class).withSuperParent(2, PlatformPatterns.psiElement(MethodReference.class)),
26+
new PsiReferenceProvider() {
27+
@NotNull
28+
@Override
29+
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
30+
StringLiteralExpression stringLiteralExpression = (StringLiteralExpression) element;
31+
MethodReference methodReference = (MethodReference) PsiTreeUtil.findFirstParent(stringLiteralExpression, p -> p instanceof MethodReference);
3232

33-
PsiElement parent = stringLiteralExpression.getParent();
34-
while (!(parent instanceof MethodReference)) {
35-
36-
if (parent != null) {
37-
parent = parent.getParent();
38-
39-
continue;
40-
}
41-
42-
return new PsiReference[0];
43-
}
44-
45-
MethodReference methodReference = (MethodReference) parent;
46-
String methodName = methodReference.getName();
33+
if (methodReference == null) {
34+
return PsiReference.EMPTY_ARRAY;
35+
}
4736

48-
if (methodReference.getFirstPsiChild() instanceof Variable) {
49-
Variable variable = (Variable) methodReference.getFirstPsiChild();
50-
PhpType inferredType = variable.getInferredType();
51-
Set<String> types = inferredType.getTypes();
52-
for (String type : types) {
53-
try {
54-
Collection<? extends PhpNamedElement> bySignature = PhpIndex.getInstance(element.getProject()).getBySignature(type);
55-
for (PhpNamedElement el : bySignature) {
56-
if (el.getFQN().equals(ICON_FACTORY) && methodName.equals("getIcon")) {
57-
return new PsiReference[]{new IconReference(stringLiteralExpression)};
58-
}
59-
}
60-
} catch (RuntimeException e) {
61-
// invalid index signature, skip
37+
String methodName = methodReference.getName();
38+
if (methodReference.getFirstPsiChild() instanceof Variable) {
39+
Variable variable = (Variable) methodReference.getFirstPsiChild();
40+
String signature = variable.getSignature();
41+
try {
42+
Collection<? extends PhpNamedElement> bySignature = PhpIndex.getInstance(element.getProject()).getBySignature(signature);
43+
for (PhpNamedElement el : bySignature) {
44+
String fqn = el.getFQN();
45+
if (fqn.equals(ICON_FACTORY) && methodName.equals("getIcon")) {
46+
return new PsiReference[]{new IconReference(stringLiteralExpression)};
6247
}
6348
}
49+
} catch (RuntimeException e) {
50+
// invalid index signature, skip
6451
}
52+
}
6553

66-
String className = PhpLangUtil.getClassName(stringLiteralExpression);
67-
if (methodName != null && className != null && methodName.equals("getIcon") && className.equals(ICON_FACTORY)) {
68-
return new PsiReference[]{new IconReference(stringLiteralExpression)};
69-
}
70-
71-
return new PsiReference[0];
54+
String className = PhpLangUtil.getClassName(stringLiteralExpression);
55+
if (methodName != null && className != null && methodName.equals("getIcon") && className.equals(ICON_FACTORY)) {
56+
return new PsiReference[]{new IconReference(stringLiteralExpression)};
7257
}
58+
59+
return PsiReference.EMPTY_ARRAY;
7360
}
61+
}
7462
);
7563
}
7664
}

typo3-cms/src/main/java/com/cedricziel/idea/typo3/index/RouteIndex.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
public class RouteIndex extends FileBasedIndexExtension<String, RouteStub> {
2121

2222
public static final ID<String, RouteStub> KEY = ID.create("com.cedricziel.idea.typo3.index.route");
23+
public static final String AJAX_ROUTES_PHP = "AjaxRoutes.php";
24+
public static final String ROUTES_PHP = "Routes.php";
25+
public static final String EXT_TABLES_PHP = "ext_tables.php";
2326

2427
@NotNull
2528
public static boolean hasRoute(@NotNull Project project, @NotNull String routeName) {
@@ -75,13 +78,13 @@ public DataExternalizer<RouteStub> getValueExternalizer() {
7578

7679
@Override
7780
public int getVersion() {
78-
return 0;
81+
return 1;
7982
}
8083

8184
@NotNull
8285
@Override
8386
public FileBasedIndex.InputFilter getInputFilter() {
84-
return file -> file.getName().equals("Routes.php") || file.getName().equals("AjaxRoutes.php") || file.getName().equals("ext_tables.php");
87+
return file -> file.getName().equals(ROUTES_PHP) || file.getName().equals(AJAX_ROUTES_PHP) || file.getName().equals(EXT_TABLES_PHP);
8588
}
8689

8790
@Override
@@ -107,12 +110,15 @@ public void visitElement(PsiElement element) {
107110
PhpExpression classRefExpr = methodReference.getClassReference();
108111
if (!(classRefExpr instanceof ClassReference)) {
109112
super.visitElement(element);
113+
110114
return;
111115
}
112116

113117
ClassReference classReference = (ClassReference) classRefExpr;
114118

115-
if (classReference.getFQN().equals("\\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility") && methodReference.getName().equals("addModule")) {
119+
String fqn = classReference.getFQN();
120+
String methodName = methodReference.getName();
121+
if (fqn != null && fqn.equals("\\TYPO3\\CMS\\Core\\Utility\\ExtensionManagementUtility") && methodName != null && methodName.equals("addModule")) {
116122
RouteStub e = extractRouteStubFromMethodCall(methodReference);
117123
if (e != null) {
118124
routeStubs.add(e);
@@ -135,7 +141,7 @@ private RouteStub extractRouteStubFromMethodCall(MethodReference methodReference
135141
ArrayCreationExpression routeArray = (ArrayCreationExpression) psiElement;
136142
for (ArrayHashElement arrayHashElement : routeArray.getHashElements()) {
137143
PhpPsiElement key = arrayHashElement.getKey();
138-
if (key == null || !(key instanceof StringLiteralExpression)) {
144+
if (!(key instanceof StringLiteralExpression)) {
139145
continue;
140146
}
141147

typo3-cms/src/main/java/com/cedricziel/idea/typo3/routing/RouteHelper.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@
1818
public class RouteHelper {
1919
@NotNull
2020
public static Collection<RouteStub> routesFromRoutesPhp(@NotNull PsiFile psiFile) {
21+
RouteParserVisitor visitor;
22+
if (psiFile.getName().equals(RouteIndex.AJAX_ROUTES_PHP)) {
23+
visitor = new RouteParserVisitor("ajax_");
24+
} else {
25+
visitor = new RouteParserVisitor();
26+
}
2127

22-
RouteParserVisitor visitor = new RouteParserVisitor();
2328
visitor.visitElement(psiFile);
2429

2530
return visitor.getRouteStubs();
@@ -56,7 +61,7 @@ public static PsiElement[] getRouteDefinitionElements(@NotNull Project project,
5661
return true;
5762
}, GlobalSearchScope.allScope(project));
5863

59-
return results.toArray(new PsiElement[results.size()]);
64+
return results.toArray(new PsiElement[0]);
6065
}
6166

6267
@NotNull
@@ -76,7 +81,7 @@ private static PsiElement[] getTargetMethods(@NotNull Project project, @NotNull
7681
});
7782
}
7883

79-
return result.toArray(new PsiElement[result.size()]);
84+
return result.toArray(new PsiElement[0]);
8085
}
8186

8287
@NotNull

typo3-cms/src/main/java/com/cedricziel/idea/typo3/routing/RouteParserVisitor.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@
1414
*/
1515
public class RouteParserVisitor extends PsiRecursiveElementVisitor {
1616

17+
private final String prefix;
1718
private Collection<RouteStub> routeStubs;
1819

1920
public RouteParserVisitor() {
20-
routeStubs = new ArrayList<>();
21+
this.prefix = "";
22+
this.routeStubs = new ArrayList<>();
23+
}
24+
25+
public RouteParserVisitor(String prefix) {
26+
this.prefix = prefix;
27+
this.routeStubs = new ArrayList<>();
2128
}
2229

2330
@NotNull
@@ -60,7 +67,7 @@ private void visitRouteCreation(ArrayHashElement element) {
6067
if (valueMap instanceof ArrayCreationExpression) {
6168
ArrayCreationExpression propertyArray = (ArrayCreationExpression) valueMap;
6269

63-
routeDefinition.setName(key);
70+
routeDefinition.setName(prefix + key);
6471

6572
for (ArrayHashElement routePropertyHashElement : propertyArray.getHashElements()) {
6673
visitProperty(routeDefinition, routePropertyHashElement);

typo3-cms/src/test/java/com/cedricziel/idea/typo3/icons/IconReferenceProviderTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.cedricziel.idea.typo3.icons;
22

3+
import com.cedricziel.idea.typo3.AbstractTestCase;
34
import com.intellij.psi.PsiElement;
45
import com.intellij.psi.PsiReference;
5-
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
66

77

8-
public class IconReferenceProviderTest extends LightCodeInsightFixtureTestCase {
8+
public class IconReferenceProviderTest extends AbstractTestCase {
99
@Override
1010
protected String getTestDataPath() {
1111
return "testData/com/cedricziel/idea/typo3/icons";
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.cedricziel.idea.typo3.routing;
2+
3+
import com.cedricziel.idea.typo3.AbstractTestCase;
4+
import com.jetbrains.php.lang.PhpFileType;
5+
6+
import java.util.List;
7+
8+
public class RouteHelperTest extends AbstractTestCase {
9+
@Override
10+
protected String getTestDataPath() {
11+
return "testData/com/cedricziel/idea/typo3/routing";
12+
}
13+
14+
public void testCanCorrectlyIdentifyRoutesFromRoutesPhp() {
15+
myFixture.copyFileToProject("classes.php");
16+
myFixture.copyFileToProject("AjaxRoutes.php");
17+
myFixture.copyFileToProject("Routes.php");
18+
19+
myFixture.configureByText(PhpFileType.INSTANCE, "<?php\n" +
20+
"/** @var $uriBuilder \\TYPO3\\CMS\\Backend\\Routing\\UriBuilder */\n" +
21+
"$uriBuilder->buildUriFromRoute('<caret>');"
22+
);
23+
24+
myFixture.completeBasic();
25+
26+
List<String> lookupElementStrings = myFixture.getLookupElementStrings();
27+
assertTrue(lookupElementStrings.contains("ajax_solr_updateConnections"));
28+
assertTrue(lookupElementStrings.contains("ajax_solr_updateConnection"));
29+
assertTrue(lookupElementStrings.contains("xMOD_tximpexp"));
30+
}
31+
}

typo3-cms/testData/com/cedricziel/idea/typo3/icons/general_utility_icon_provider_test.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,19 @@ class IconFactory
77
}
88
}
99

10+
namespace TYPO3\CMS\Core\Utility {
11+
class GeneralUtility
12+
{
13+
public static function makeInstance()
14+
{
15+
}
16+
}
17+
}
18+
1019
namespace {
11-
use TYPO3\CMS\Core\Utility\GeneralUtility;
20+
1221
use TYPO3\CMS\Core\Imaging\IconFactory;
22+
use TYPO3\CMS\Core\Utility\GeneralUtility;
1323

1424
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
1525

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
/**
4+
* Definitions for routes provided by EXT:solr
5+
*/
6+
return [
7+
'solr_updateConnections' => [
8+
'path' => '/solr/updateConnections',
9+
'target' => \ApacheSolrForTypo3\Solr\Controller\Backend\AjaxController::class . '::updateConnections',
10+
],
11+
'solr_updateConnection' => [
12+
'path' => '/solr/updateConnection',
13+
'target' => \ApacheSolrForTypo3\Solr\Controller\Backend\AjaxController::class . '::updateConnection',
14+
],
15+
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
/**
4+
* Definitions for routes provided by EXT:impexp
5+
*/
6+
return [
7+
// Register click menu entry point
8+
'xMOD_tximpexp' => [
9+
'path' => '/record/importexport/',
10+
'target' => \TYPO3\CMS\Impexp\Controller\ImportExportController::class . '::mainAction',
11+
],
12+
];
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace TYPO3\CMS\Backend\Routing {
4+
class UriBuilder
5+
{
6+
public function buildUriFromRoutePath()
7+
{
8+
}
9+
10+
public function buildUriFromRoute()
11+
{
12+
}
13+
14+
public function buildUriFromAjaxId()
15+
{
16+
}
17+
18+
public function getAjaxUrl()
19+
{
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)