15
15
import com .intellij .psi .search .GlobalSearchScope ;
16
16
import com .intellij .psi .util .PsiTreeUtil ;
17
17
import com .intellij .util .indexing .FileBasedIndex ;
18
- import com .jetbrains .php .PhpIndex ;
19
18
import com .jetbrains .php .lang .psi .elements .Method ;
20
19
import com .jetbrains .php .lang .psi .elements .PhpClass ;
21
20
import com .magento .idea .magento2plugin .linemarker .SearchGutterIconNavigationHandler ;
21
+ import com .magento .idea .magento2plugin .linemarker .php .data .PluginMethodData ;
22
22
import com .magento .idea .magento2plugin .project .Settings ;
23
23
import com .magento .idea .magento2plugin .stubs .indexes .PluginIndex ;
24
+ import com .magento .idea .magento2plugin .stubs .indexes .data .PluginData ;
24
25
import java .util .ArrayList ;
25
26
import java .util .Collection ;
26
27
import java .util .HashMap ;
@@ -94,12 +95,13 @@ public void collectSlowLineMarkers(
94
95
}
95
96
}
96
97
98
+ @ SuppressWarnings ("checkstyle:LineLength" )
97
99
private static class PluginClassCache {
98
100
99
- private final Map <String , List <PhpClass >> classPluginsMap = new HashMap <>();
101
+ private final Map <String , List <PluginData >> classPluginsMap = new HashMap <>();
100
102
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 (
103
105
phpClass ,
104
106
phpClass .getPresentableFQN ()
105
107
);
@@ -114,64 +116,73 @@ public List<PhpClass> getPluginsForClass(final @NotNull PhpClass phpClass) {
114
116
return pluginsForClass ;
115
117
}
116
118
117
- public List <PhpClass > getPluginsForClass (
119
+ public List <PluginData > getPluginsForClass (
118
120
final @ NotNull PhpClass phpClass ,
119
121
final @ NotNull String classFQN
120
122
) {
121
123
if (classPluginsMap .containsKey (classFQN )) {
122
124
return classPluginsMap .get (classFQN );
123
125
}
124
126
125
- final List <Set <String >> plugins = FileBasedIndex .getInstance ()
127
+ final List <Set <PluginData >> plugins = FileBasedIndex .getInstance ()
126
128
.getValues (
127
129
PluginIndex .KEY ,
128
130
classFQN ,
129
131
GlobalSearchScope .allScope (phpClass .getProject ())
130
132
);
131
- final List <PhpClass > results = new ArrayList <>();
133
+ final List <PluginData > results = new ArrayList <>();
132
134
133
135
if (plugins .isEmpty ()) {
134
136
classPluginsMap .put (classFQN , results );
135
137
136
138
return results ;
137
139
}
138
- final PhpIndex phpIndex = PhpIndex .getInstance (phpClass .getProject ());
139
140
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 );
143
145
}
144
146
}
145
147
classPluginsMap .put (classFQN , results );
146
148
147
149
return results ;
148
150
}
149
151
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
+ final List <PluginMethodData > result = new ArrayList <>();
152
154
153
- for (final PhpClass plugin : plugins ) {
154
- methodList .addAll (getPluginMethods (plugin ));
155
+ for (final 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
+ }
155
160
}
156
161
157
- return methodList ;
162
+ return result ;
158
163
}
159
164
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 , final int sortOrder ) {
166
+ final List <PluginMethodData > methodList = new ArrayList <>();
162
167
163
168
for (final Method method : pluginClass .getMethods ()) {
164
169
if (method .getAccess ().isPublic ()) {
165
170
final String pluginMethodName = method .getName ();
166
171
167
172
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 (getPluginMethodDataObject (method , sortOrder , 0 ));
169
175
}
170
176
}
171
177
}
172
178
173
179
return methodList ;
174
180
}
181
+
182
+ @ NotNull
183
+ private PluginMethodData getPluginMethodDataObject (final Method method , final int sortOrder , final int moduleSequence ) {
184
+ return new PluginMethodData (method , sortOrder , moduleSequence );
185
+ }
175
186
}
176
187
177
188
private static class ClassPluginCollector implements Collector <PhpClass , PhpClass > {
@@ -186,41 +197,134 @@ public ClassPluginCollector(
186
197
187
198
@ Override
188
199
public List <PhpClass > collect (final @ NotNull PhpClass psiElement ) {
189
- return pluginClassCache .getPluginsForClass (psiElement );
200
+ final List <PluginData > pluginDataList = pluginClassCache .getPluginsForClass (psiElement );
201
+ final List <PhpClass > phpClassList = new ArrayList <>();
202
+
203
+ for (final PluginData pluginData : pluginDataList ) {
204
+ phpClassList .addAll (pluginData .getPhpClassCollection ());
205
+ }
206
+
207
+ return phpClassList ;
190
208
}
191
209
}
192
210
193
211
private static class MethodPluginCollector implements Collector <Method , Method > {
194
212
195
213
private final PluginLineMarkerProvider .PluginClassCache pluginClassCache ;
214
+ private final Map <String , Integer > pluginMethodsSortOrder ;
215
+ private static final String AFTER_PLUGIN_PREFIX = "after" ;
196
216
197
217
public MethodPluginCollector (
198
218
final PluginLineMarkerProvider .PluginClassCache pluginClassCache
199
219
) {
200
220
this .pluginClassCache = pluginClassCache ;
221
+ pluginMethodsSortOrder = new HashMap <>();
222
+ pluginMethodsSortOrder .put ("before" , 1 );
223
+ pluginMethodsSortOrder .put ("around" , 2 );
224
+ pluginMethodsSortOrder .put (AFTER_PLUGIN_PREFIX , 3 );
201
225
}
202
226
227
+ @ SuppressWarnings ("checkstyle:LineLength" )
203
228
@ Override
204
229
public List <Method > collect (final @ NotNull Method psiElement ) {
205
230
final List <Method > results = new ArrayList <>();
206
-
207
231
final PhpClass methodClass = psiElement .getContainingClass ();
208
232
209
233
if (methodClass == null ) {
210
234
return results ;
211
235
}
212
- final List <PhpClass > pluginsList = pluginClassCache .getPluginsForClass (methodClass );
213
- final List <Method > pluginMethods = pluginClassCache .getPluginMethods (pluginsList );
214
236
237
+ final List <PluginData > pluginDataList = pluginClassCache .getPluginsForClass (methodClass );
238
+ final List <PluginMethodData > pluginMethods = pluginClassCache .getPluginMethods (pluginDataList );
215
239
final String classMethodName = WordUtils .capitalize (psiElement .getName ());
216
240
217
- for (final Method pluginMethod : pluginMethods ) {
218
- if (isPluginMethodName (pluginMethod .getName (), classMethodName )) {
219
- results .add (pluginMethod );
241
+ pluginMethods .removeIf (pluginMethod -> !isPluginMethodName (pluginMethod .getMethodName (), classMethodName ));
242
+ sortMethods (pluginMethods , results );
243
+
244
+ return results ;
245
+ }
246
+
247
+ @ SuppressWarnings ({"checkstyle:Indentation" , "checkstyle:OperatorWrap" , "checkstyle:LineLength" , "PMD.NPathComplexity" })
248
+ private void sortMethods (final @ NotNull List <PluginMethodData > methodDataList , final List <Method > results ) {
249
+ final List <Integer > bufferSortOrderList = new ArrayList <>();
250
+ int biggestSortOrder = 0 ;
251
+
252
+ for (final PluginMethodData pluginMethodData : methodDataList ) {
253
+ final String methodName = pluginMethodData .getMethodName ();
254
+
255
+ if (methodName .startsWith ("around" )) {
256
+ bufferSortOrderList .add (pluginMethodData .getSortOrder ());
257
+ }
258
+
259
+ if (pluginMethodData .getSortOrder () > biggestSortOrder ) {
260
+ biggestSortOrder = pluginMethodData .getSortOrder ();
220
261
}
221
262
}
222
263
223
- return results ;
264
+ final int biggestSortOrderValue = biggestSortOrder ;
265
+
266
+ methodDataList .sort (
267
+ (PluginMethodData method1 , PluginMethodData method2 ) -> {
268
+ final String firstMethodName = method1 .getMethodName ();
269
+ final String secondMethodName = method2 .getMethodName ();
270
+ final int firstIndexEnd = firstMethodName .startsWith (AFTER_PLUGIN_PREFIX ) ? 5 : 6 ;
271
+ final int secondIndexEnd = secondMethodName .startsWith (AFTER_PLUGIN_PREFIX ) ? 5 : 6 ;
272
+ final String firstMethodPrefix = firstMethodName .substring (0 ,firstIndexEnd );
273
+ final String secondMethodPrefix = secondMethodName .substring (0 ,secondIndexEnd );
274
+
275
+ if (!pluginMethodsSortOrder .containsKey (firstMethodPrefix )
276
+ || !pluginMethodsSortOrder .containsKey (secondMethodPrefix )) {
277
+ return firstMethodName .compareTo (secondMethodName );
278
+ }
279
+
280
+ final Integer firstNameSortOrder = pluginMethodsSortOrder .get (firstMethodPrefix );
281
+ final Integer secondNameSortOrder = pluginMethodsSortOrder .get (secondMethodPrefix );
282
+
283
+ if (firstNameSortOrder .compareTo (secondNameSortOrder ) != 0 ) {
284
+ return firstNameSortOrder .compareTo (secondNameSortOrder );
285
+ }
286
+
287
+ Integer firstBuffer = 0 ;
288
+ Integer secondBuffer = 0 ;
289
+ final Integer firstModuleSequence = (method1 .getModuleSequence () + biggestSortOrderValue ) * -1 ;
290
+ final Integer secondModuleSequence = (method2 .getModuleSequence () + biggestSortOrderValue ) * -1 ;
291
+ final Integer firstSortOrder = method1 .getSortOrder () == 0 ?
292
+ firstModuleSequence :
293
+ method1 .getSortOrder ();
294
+ final Integer secondSortOrder = method2 .getSortOrder () == 0 ?
295
+ secondModuleSequence :
296
+ method2 .getSortOrder ();
297
+
298
+ if (!bufferSortOrderList .isEmpty () && firstMethodPrefix .equals (AFTER_PLUGIN_PREFIX )) {
299
+ for (final Integer bufferSortOrder : bufferSortOrderList ) {
300
+ if (bufferSortOrder < firstSortOrder && firstBuffer < bufferSortOrder + 1 ) {
301
+ firstBuffer = bufferSortOrder + 1 ;
302
+ }
303
+
304
+ if (bufferSortOrder < secondSortOrder && secondBuffer < bufferSortOrder + 1 ) {
305
+ secondBuffer = bufferSortOrder + 1 ;
306
+ }
307
+ }
308
+ }
309
+
310
+ firstBuffer = firstBuffer .equals (0 ) ? firstSortOrder : firstBuffer * -1 ;
311
+ secondBuffer = secondBuffer .equals (0 ) ? secondSortOrder : secondBuffer * -1 ;
312
+
313
+ if (firstBuffer .compareTo (secondBuffer ) == 0 && firstSortOrder .compareTo (secondSortOrder ) != 0 ) {
314
+ return firstSortOrder .compareTo (secondSortOrder );
315
+ }
316
+
317
+ if (firstBuffer .compareTo (secondBuffer ) == 0 && firstSortOrder .compareTo (secondSortOrder ) == 0 ) {
318
+ return firstModuleSequence .compareTo (secondModuleSequence );
319
+ }
320
+
321
+ return firstBuffer .compareTo (secondBuffer );
322
+ }
323
+ );
324
+
325
+ for (final PluginMethodData pluginMethodData : methodDataList ) {
326
+ results .add (pluginMethodData .getMethod ());
327
+ }
224
328
}
225
329
226
330
private boolean isPluginMethodName (
0 commit comments