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,58 +116,62 @@ 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
+ List <PluginMethodData > result = new ArrayList <>();
152
154
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
+ }
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 , 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 (new PluginMethodData (method , sortOrder , 0 ));
169
175
}
170
176
}
171
177
}
@@ -186,41 +192,133 @@ public ClassPluginCollector(
186
192
187
193
@ Override
188
194
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 ;
190
203
}
191
204
}
192
205
193
206
private static class MethodPluginCollector implements Collector <Method , Method > {
194
207
195
208
private final PluginLineMarkerProvider .PluginClassCache pluginClassCache ;
209
+ private final Map <String , Integer > pluginMethodsSortOrder ;
196
210
197
211
public MethodPluginCollector (
198
212
final PluginLineMarkerProvider .PluginClassCache pluginClassCache
199
213
) {
200
214
this .pluginClassCache = pluginClassCache ;
215
+ pluginMethodsSortOrder = new HashMap <>();
216
+ pluginMethodsSortOrder .put ("before" , 1 );
217
+ pluginMethodsSortOrder .put ("around" , 2 );
218
+ pluginMethodsSortOrder .put ("after" , 3 );
201
219
}
202
220
221
+ @ SuppressWarnings ("checkstyle:LineLength" )
203
222
@ Override
204
223
public List <Method > collect (final @ NotNull Method psiElement ) {
205
224
final List <Method > results = new ArrayList <>();
206
-
207
225
final PhpClass methodClass = psiElement .getContainingClass ();
208
226
209
227
if (methodClass == null ) {
210
228
return results ;
211
229
}
212
- final List <PhpClass > pluginsList = pluginClassCache .getPluginsForClass (methodClass );
213
- final List <Method > pluginMethods = pluginClassCache .getPluginMethods (pluginsList );
214
230
231
+ final List <PluginData > pluginDataList = pluginClassCache .getPluginsForClass (methodClass );
232
+ final List <PluginMethodData > pluginMethods = pluginClassCache .getPluginMethods (pluginDataList );
215
233
final String classMethodName = WordUtils .capitalize (psiElement .getName ());
216
234
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 ();
220
255
}
221
256
}
222
257
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
+ }
224
322
}
225
323
226
324
private boolean isPluginMethodName (
0 commit comments