Skip to content

Commit 3dad734

Browse files
committed
406: added sortting plugin list marker
1 parent 6cb0b5f commit 3dad734

File tree

7 files changed

+301
-50
lines changed

7 files changed

+301
-50
lines changed

src/com/magento/idea/magento2plugin/linemarker/php/PluginLineMarkerProvider.java

Lines changed: 125 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
import com.intellij.psi.search.GlobalSearchScope;
1616
import com.intellij.psi.util.PsiTreeUtil;
1717
import com.intellij.util.indexing.FileBasedIndex;
18-
import com.jetbrains.php.PhpIndex;
1918
import com.jetbrains.php.lang.psi.elements.Method;
2019
import com.jetbrains.php.lang.psi.elements.PhpClass;
2120
import com.magento.idea.magento2plugin.linemarker.SearchGutterIconNavigationHandler;
21+
import com.magento.idea.magento2plugin.linemarker.php.data.PluginMethodData;
2222
import com.magento.idea.magento2plugin.project.Settings;
2323
import com.magento.idea.magento2plugin.stubs.indexes.PluginIndex;
24+
import com.magento.idea.magento2plugin.stubs.indexes.data.PluginData;
2425
import java.util.ArrayList;
2526
import java.util.Collection;
2627
import java.util.HashMap;
@@ -94,12 +95,13 @@ public void collectSlowLineMarkers(
9495
}
9596
}
9697

98+
@SuppressWarnings("checkstyle:LineLength")
9799
private static class PluginClassCache {
98100

99-
private final Map<String, List<PhpClass>> classPluginsMap = new HashMap<>();
101+
private final Map<String, List<PluginData>> classPluginsMap = new HashMap<>();
100102

101-
public List<PhpClass> getPluginsForClass(final @NotNull PhpClass phpClass) {
102-
final List<PhpClass> pluginsForClass = getPluginsForClass(
103+
public List<PluginData> getPluginsForClass(final @NotNull PhpClass phpClass) {
104+
final List<PluginData> pluginsForClass = getPluginsForClass(
103105
phpClass,
104106
phpClass.getPresentableFQN()
105107
);
@@ -114,58 +116,62 @@ public List<PhpClass> getPluginsForClass(final @NotNull PhpClass phpClass) {
114116
return pluginsForClass;
115117
}
116118

117-
public List<PhpClass> getPluginsForClass(
119+
public List<PluginData> getPluginsForClass(
118120
final @NotNull PhpClass phpClass,
119121
final @NotNull String classFQN
120122
) {
121123
if (classPluginsMap.containsKey(classFQN)) {
122124
return classPluginsMap.get(classFQN);
123125
}
124126

125-
final List<Set<String>> plugins = FileBasedIndex.getInstance()
127+
final List<Set<PluginData>> plugins = FileBasedIndex.getInstance()
126128
.getValues(
127129
PluginIndex.KEY,
128130
classFQN,
129131
GlobalSearchScope.allScope(phpClass.getProject())
130132
);
131-
final List<PhpClass> results = new ArrayList<>();
133+
final List<PluginData> results = new ArrayList<>();
132134

133135
if (plugins.isEmpty()) {
134136
classPluginsMap.put(classFQN, results);
135137

136138
return results;
137139
}
138-
final PhpIndex phpIndex = PhpIndex.getInstance(phpClass.getProject());
139140

140-
for (final Set<String> pluginClassNames : plugins) {
141-
for (final String pluginClassName: pluginClassNames) {
142-
results.addAll(phpIndex.getClassesByFQN(pluginClassName));
141+
for (final Set<PluginData> pluginDataList : plugins) {
142+
for (final PluginData pluginData: pluginDataList) {
143+
pluginData.setPhpClass(phpClass);
144+
results.add(pluginData);
143145
}
144146
}
145147
classPluginsMap.put(classFQN, results);
146148

147149
return results;
148150
}
149151

150-
public List<Method> getPluginMethods(final List<PhpClass> plugins) {
151-
final List<Method> methodList = new ArrayList<>();
152+
public List<PluginMethodData> getPluginMethods(final List<PluginData> pluginDataList) {
153+
List<PluginMethodData> result = new ArrayList<>();
152154

153-
for (final PhpClass plugin: plugins) {
154-
methodList.addAll(getPluginMethods(plugin));
155+
for (PluginData pluginData: pluginDataList) {
156+
for (final PhpClass plugin: pluginData.getPhpClassCollection()) {
157+
//@todo add module sequence ID if sortOrder equal zero. It should be negative value.
158+
result.addAll(getPluginMethods(plugin, pluginData.getSortOrder()));
159+
}
155160
}
156161

157-
return methodList;
162+
return result;
158163
}
159164

160-
public List<Method> getPluginMethods(final @NotNull PhpClass pluginClass) {
161-
final List<Method> methodList = new ArrayList<>();
165+
public List<PluginMethodData> getPluginMethods(final @NotNull PhpClass pluginClass, int sortOrder) {
166+
final List<PluginMethodData> methodList = new ArrayList<>();
162167

163168
for (final Method method : pluginClass.getMethods()) {
164169
if (method.getAccess().isPublic()) {
165170
final String pluginMethodName = method.getName();
166171

167172
if (pluginMethodName.length() > MIN_PLUGIN_METHOD_NAME_LENGTH) {
168-
methodList.add(method);
173+
//@todo module sequence value should be set here instead of zero.
174+
methodList.add(new PluginMethodData(method, sortOrder, 0));
169175
}
170176
}
171177
}
@@ -186,41 +192,133 @@ public ClassPluginCollector(
186192

187193
@Override
188194
public List<PhpClass> collect(final @NotNull PhpClass psiElement) {
189-
return pluginClassCache.getPluginsForClass(psiElement);
195+
List<PluginData> pluginDataList = pluginClassCache.getPluginsForClass(psiElement);
196+
List<PhpClass> phpClassList = new ArrayList<>();
197+
198+
for (PluginData pluginData: pluginDataList) {
199+
phpClassList.addAll(pluginData.getPhpClassCollection());
200+
}
201+
202+
return phpClassList;
190203
}
191204
}
192205

193206
private static class MethodPluginCollector implements Collector<Method, Method> {
194207

195208
private final PluginLineMarkerProvider.PluginClassCache pluginClassCache;
209+
private final Map<String, Integer> pluginMethodsSortOrder;
196210

197211
public MethodPluginCollector(
198212
final PluginLineMarkerProvider.PluginClassCache pluginClassCache
199213
) {
200214
this.pluginClassCache = pluginClassCache;
215+
pluginMethodsSortOrder = new HashMap<>();
216+
pluginMethodsSortOrder.put("before", 1);
217+
pluginMethodsSortOrder.put("around", 2);
218+
pluginMethodsSortOrder.put("after", 3);
201219
}
202220

221+
@SuppressWarnings("checkstyle:LineLength")
203222
@Override
204223
public List<Method> collect(final @NotNull Method psiElement) {
205224
final List<Method> results = new ArrayList<>();
206-
207225
final PhpClass methodClass = psiElement.getContainingClass();
208226

209227
if (methodClass == null) {
210228
return results;
211229
}
212-
final List<PhpClass> pluginsList = pluginClassCache.getPluginsForClass(methodClass);
213-
final List<Method> pluginMethods = pluginClassCache.getPluginMethods(pluginsList);
214230

231+
final List<PluginData> pluginDataList = pluginClassCache.getPluginsForClass(methodClass);
232+
final List<PluginMethodData> pluginMethods = pluginClassCache.getPluginMethods(pluginDataList);
215233
final String classMethodName = WordUtils.capitalize(psiElement.getName());
216234

217-
for (final Method pluginMethod: pluginMethods) {
218-
if (isPluginMethodName(pluginMethod.getName(), classMethodName)) {
219-
results.add(pluginMethod);
235+
pluginMethods.removeIf(pluginMethod -> !isPluginMethodName(pluginMethod.getMethodName(), classMethodName));
236+
sortMethods(pluginMethods, results);
237+
238+
return results;
239+
}
240+
241+
@SuppressWarnings({"checkstyle:Indentation", "checkstyle:OperatorWrap", "checkstyle:LineLength"})
242+
private void sortMethods(final @NotNull List<PluginMethodData> methodDataList, List<Method> results) {
243+
List<Integer> bufferSortOrderList = new ArrayList<>();
244+
int biggestSortOrder = 0;
245+
246+
for (PluginMethodData pluginMethodData: methodDataList) {
247+
String methodName = pluginMethodData.getMethodName();
248+
249+
if (methodName.startsWith("around")) {
250+
bufferSortOrderList.add(pluginMethodData.getSortOrder());
251+
}
252+
253+
if (pluginMethodData.getSortOrder() > biggestSortOrder) {
254+
biggestSortOrder = pluginMethodData.getSortOrder();
220255
}
221256
}
222257

223-
return results;
258+
final int biggestSortOrderValue = biggestSortOrder;
259+
260+
methodDataList.sort(
261+
(PluginMethodData method1, PluginMethodData method2) -> {
262+
final String firstMethodName = method1.getMethodName();
263+
final String secondMethodName = method2.getMethodName();
264+
final int firstIndexEnd = firstMethodName.startsWith("after") ? 5 : 6;
265+
final int secondIndexEnd = secondMethodName.startsWith("after") ? 5 : 6;
266+
String firstMethodPrefix = firstMethodName.substring(0,firstIndexEnd);
267+
String secondMethodPrefix = secondMethodName.substring(0,secondIndexEnd);
268+
269+
if (!pluginMethodsSortOrder.containsKey(firstMethodPrefix)
270+
|| !pluginMethodsSortOrder.containsKey(secondMethodPrefix)) {
271+
return firstMethodName.compareTo(secondMethodName);
272+
}
273+
274+
final Integer firstNameSortOrder = pluginMethodsSortOrder.get(firstMethodPrefix);
275+
final Integer secondNameSortOrder = pluginMethodsSortOrder.get(secondMethodPrefix);
276+
277+
if (firstNameSortOrder.compareTo(secondNameSortOrder) != 0) {
278+
return firstNameSortOrder.compareTo(secondNameSortOrder);
279+
}
280+
281+
Integer firstBuffer = 0;
282+
Integer secondBuffer = 0;
283+
Integer firstModuleSequence = (method1.getModuleSequence() + biggestSortOrderValue) * -1;
284+
Integer secondModuleSequence = (method2.getModuleSequence() + biggestSortOrderValue) * -1;
285+
Integer firstSortOrder = method1.getSortOrder() != 0 ?
286+
method1.getSortOrder() :
287+
firstModuleSequence;
288+
Integer secondSortOrder = method2.getSortOrder() != 0 ?
289+
method2.getSortOrder() :
290+
secondModuleSequence;
291+
292+
if (!bufferSortOrderList.isEmpty() && firstMethodPrefix.equals("after")) {
293+
for (Integer bufferSortOrder : bufferSortOrderList) {
294+
if (bufferSortOrder < firstSortOrder && firstBuffer < bufferSortOrder + 1) {
295+
firstBuffer = bufferSortOrder + 1;
296+
}
297+
298+
if (bufferSortOrder < secondSortOrder && secondBuffer < bufferSortOrder + 1) {
299+
secondBuffer = bufferSortOrder + 1;
300+
}
301+
}
302+
}
303+
304+
firstBuffer = firstBuffer.equals(0) ? firstSortOrder : firstBuffer * -1;
305+
secondBuffer = secondBuffer.equals(0) ? secondSortOrder : secondBuffer * -1;
306+
307+
if (firstBuffer.compareTo(secondBuffer) == 0 && firstSortOrder.compareTo(secondSortOrder) != 0) {
308+
return firstSortOrder.compareTo(secondSortOrder);
309+
}
310+
311+
if (firstBuffer.compareTo(secondBuffer) == 0 && firstSortOrder.compareTo(secondSortOrder) == 0) {
312+
return firstModuleSequence.compareTo(secondModuleSequence);
313+
}
314+
315+
return firstBuffer.compareTo(secondBuffer);
316+
}
317+
);
318+
319+
for (PluginMethodData pluginMethodData: methodDataList) {
320+
results.add(pluginMethodData.getMethod());
321+
}
224322
}
225323

226324
private boolean isPluginMethodName(
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
package com.magento.idea.magento2plugin.linemarker.php.data;
7+
8+
import com.jetbrains.php.lang.psi.elements.Method;
9+
10+
public class PluginMethodData {
11+
12+
private final Method method;
13+
private final int sortOrder;
14+
private final int moduleSequence;
15+
16+
/**
17+
* Plugin method data class.
18+
*
19+
* @param method Plugin method
20+
* @param sortOrder Plugin SortOrder integer value
21+
* @param moduleSequence PHP class placed module sequence integer value
22+
*/
23+
public PluginMethodData(final Method method, final int sortOrder, final int moduleSequence) {
24+
this.method = method;
25+
this.sortOrder = sortOrder;
26+
this.moduleSequence = moduleSequence;
27+
}
28+
29+
public Method getMethod() {
30+
return method;
31+
}
32+
33+
public int getSortOrder() {
34+
return sortOrder;
35+
}
36+
37+
public int getModuleSequence() {
38+
return moduleSequence;
39+
}
40+
41+
public String getMethodName() {
42+
return method.getName();
43+
}
44+
}

src/com/magento/idea/magento2plugin/magento/files/ModuleDiXml.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class ModuleDiXml implements ModuleFileInterface {
4646

4747
// attributes
4848
public static String NAME_ATTR = "name";
49+
public static String SORT_ORDER_ATTR = "sortOrder";
4950
public static String TYPE_ATTR = "type";
5051
public static String PREFERENCE_ATTR_FOR = "for";
5152
public static String CLI_COMMAND_ATTR_COMMANDS = "commands";

0 commit comments

Comments
 (0)