From d9f9c064a4921ed69a3c3ce63621c35f98843fb3 Mon Sep 17 00:00:00 2001 From: David Alger Date: Mon, 9 Nov 2015 14:43:38 -0600 Subject: [PATCH 01/51] Added README with installation instructions. --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..c77893b89 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# PhpStorm Magento 2 Plugin + +This is a plugin for Magento 2 development in the PhpStorm IDE. It is available via the [JetBrains Plugin Repository](https://plugins.jetbrains.com/plugin/8024) +## Installation + +1. Go to Settings / Preferences in the PhpStorm IDE + +2. Navigate to "Plugins" + +3. Click the "Browse repositories..." button and search for "Magento2" + +4. Install the plugin and restart PhpStorm + +## License + +Copyright (c) 2015 Dmytro Kvashnin. See LICENSE.md for details. From b44ab8d54bedd22ab76431a4c6bc89d1077ea15c Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 15 Nov 2015 14:25:42 +0200 Subject: [PATCH 02/51] Implemented: - line marker reference to plugins from class/interface Fixed: - Plugin type autocomplete for di.xml - Virtual type autocomplete for virtual type for type node (di.xml) --- META-INF/plugin.xml | 2 + .../idea/magento2plugin/Magento2Icons.java | 12 ++ .../icons/interception_reference.png | Bin 0 -> 1335 bytes .../icons/interception_reference@2x.png | Bin 0 -> 2824 bytes .../linemarker/PluginLineMarkerProvider.java | 169 ++++++++++++++++++ .../ClassCompletionContributor.java | 2 +- .../VirtualTypeCompletionContributor.java | 4 +- .../di/index/PluginToTypeFileBasedIndex.java | 118 ++++++++++++ .../VirtualTypesNamesFileBasedIndex.java | 7 +- .../di/reference/DiReferenceContributor.java | 4 +- .../xml/index/StringSetDataExternalizer.java | 40 +++++ .../index/EventObserverFileBasedIndex.java | 35 +--- 12 files changed, 357 insertions(+), 36 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/Magento2Icons.java create mode 100644 src/com/magento/idea/magento2plugin/icons/interception_reference.png create mode 100644 src/com/magento/idea/magento2plugin/icons/interception_reference@2x.png create mode 100644 src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java create mode 100644 src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java create mode 100644 src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index af68bc2e1..fce9e8094 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -37,6 +37,8 @@ + + diff --git a/src/com/magento/idea/magento2plugin/Magento2Icons.java b/src/com/magento/idea/magento2plugin/Magento2Icons.java new file mode 100644 index 000000000..4d1f8a5e9 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/Magento2Icons.java @@ -0,0 +1,12 @@ +package com.magento.idea.magento2plugin; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * Created by dkvashnin on 11/14/15. + */ +public class Magento2Icons { + public static final Icon PLUGIN = IconLoader.getIcon("icons/interception_reference.png"); +} diff --git a/src/com/magento/idea/magento2plugin/icons/interception_reference.png b/src/com/magento/idea/magento2plugin/icons/interception_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..f6271f132ac0a27bdc4b3a39edd52aef9a2a36a8 GIT binary patch literal 1335 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P{HZUkcg59UmvUF{9L`nl>DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtHP6qmLm5Rd1sY@-CA1Az=#^1qQAi7tkhHMA>m^>YcS^U|?qTba4!^5cHkw zpCKD6a;!f6-I+c6zAUZOzwpe|#A|EBl!WfJS69uDT3a?zFKWeFZNbeUj*c2!p9J3C z5-Zo^I@%f`ur(>VG%#9Gb%zGqNB*UXUjJK6DtRaG^Gkbn_Tw3r)#C5&SeKvsKKFgi z^S%UUd;14Zj!wQ?^#9|DykGC{dtdm>a!Bk=<13NV-ojg!@1J_>i#f983a^k-kHi&}09MQ@T_cF=aQ`i}h55{ZW! z3Z3>OoZQ>6A#Zg`N3fIq66u3eS8hHtzcTV(>b3=K&y?jilqK}|t=Y0%=u=+nvBM9T zo<4KsE?~^+R__$Fe07ieh_zkI$-;|^Z_jhox_?=sB;=K5?QAA9n^idyZA;B!?9zW+ zxUf{b>9g>&I{uk7QM_l z6z}eI=R{ohnfXfFRd;EgIor`b(^Go@#jy&I}cVFGo7&lIxc2lHX&}LrdJgb-YmwmaHEzdJW zJvEFsONrlZ{g+71`adl7b&S{dIjvr{^j8VrO7&kCuW3FxWw1E@xs{F5qOv%NuoL=g zwzJ)lUFrGfxB0{8=Z&82`*QJFYQN3=1MdwtMX1JxSxqcBUNtwOz|eb9)1ebellK-} z^@=#L^2&*e+{+$pyjwA6;jJ$PUqiM^CwzC`B-iU zm5*KsbiaMP@4GK9PdVNGWNqi_|9^d0Jy(a`=$E^@ z^Z2ZifQy2cH*7TFPxHB0d3*j8bG><5k9nL|Fa6J8nC-Y~P?mKG+C z>>aeT_HeV`#HgsR>}@yJ(8dq|YSZ|?p}BUFz7~!)01%}F0C5Qbu*nX^%>zI<3;-6q z0RWK=0Q*DpS{(G)3Eof(cOn2l6m}Lz#I0jw0O07wIk}PCY>p#*@xc(ZAKnK8i3kp5 zR|9}v1cH4G#*omUh~S_QA|gT`{G$TFKJSE~V9<{eQlLKA&Bh*Nj3;0~+7K-W4201wzq;;0ai$Ivfs%!Ze^78fxqcHDY842_2yp zLR9!k@)wT@hUiPcg_3ai5YP@U+6Ny_(g%Zg8vXtJ)Jekm|I;ai_{$dCAao}KRfoW! z{}0AC`?tP-p(4&g^V$gn(deHx^_yyL3?%4e=`#)#!Of+bqX<`0boyw zrHP@F8*gS-AkEoT{4r}QFZ%tncFhNX#)IW6=7TC=M*6Nhdqf0BpdPYPHZ&V4twAHv z6giq@`-sq{rD{Vhx3&^}dq7>s231rg*dQkfs!F39a(O&8P+rPG7p#RnW8P&p@25WV zCSjlD5!X&eSFtv09wQ%rkmx!#EZUmiZb=-=3UBqV9H-A@2&(jXR5Z=$G@ogGd#e~h zZ-_F=48#Xivb0m~ogK(rUHce4T~YzZQ;uvT=|?~JssZ0cbu_UowAT)|dKy2S(4$HNk|t=^bwbO!#8sXg(WO z#WyI$Uk;@zKa1^UAkU=RXn5M}<1m1I=cE~@vBn-%5$=@0rfxMpJQ-G99TopkGGuSj z;Fw+4NM6Hr?n*e2@rUS0AUuVsn|}-r8eJ)jZd!70OfbmS=l6LfMq8Q~m!&=bu;6&3 zp4#a&^0{ruV>d@cX0|Cm$Bohst*psh*L3w}gl>hyD}Jm>UrkvNvGEM!$oJ3Djncgf z4Bo~QniJbl^5*NIa${4+_o@#$-@IY;)%M`GEuxK#HkU4g)ev0`wuQ!CufL| zMzpawh@_p8J&bzy^_MHtukQ?Xh7V<=amGu8&fgvSEN9Kgy>woD=4iN|)|)%SJ@z&u z97a;-UQNGe%EU|w)Q&M6)m3nZ6?;}+rOaaDA0NlPQ^9rQ56y(H$hp1qvQ{2G9eMk7 z`wJ%Of%qV$z0N{-Wy}cM_1344b}}<{^-+1g^$1e8Pop2 zH+s7s9wQ7;W7CoNQN5*mmq&X$7AtL=EZ)SVN zRkeLAEJr3Ll6(tG3yPC3ew4JBM#jS?gQob(e38*BaU6w$D9JMoGTU-yn$SJx@ABO& z_OfbQxpI|AnVYx#I3F_K?frVesdZ-c9i>>*bR%^u?`lw{=S#-OhT+CgrCCtFInxVn zEl%?X7!(De!#o1xt9rL(n$DO(Zh>b+mf<1+^4LXE%n}`aG!QEhm3!dNT16KVrt4HX zp<$Lww|LI8bQj?!G1BZ~uboxwmeO2Lo~lLS!`En~DuDZGeG!+eaRP8cSRg5NfBY_= zMc{UlS#cA*G!+(-yy9fYpQW64)YuJzB2X+;kv!=_)~quQE#!=YC)C<0_EM3*-Tq4L zlv>nMp1_{HsS|H&J5VZ)I+A7yRFaOOL=zsfI^IzW6QzvAW^Xt+b%=U!=3&;N3(|FB zOr?%O^YyxUBg9%*34_CN>yrE7eounhyQ`mYj=B&29yQTR?PJS0Y`K(Fa(U()Q(o$}1@%HgfA~CIp%8(!W_=g6pbuyTd;7lgvV=yqrv1%|8a!8GFiU5GRlIcO=Z{H5-|(>seEg`5yrTZ|$~+ z_8Z*t{=PF%;6Zzb5U~4rQ{o@+2d{d5TVp-<&UL_@%j_j|6%&JKO@0CRj*-k_443U z?yiCP)2ZuiH$9@9)nfKi+snI7?za=&HG`S#ZNmu^>>B!1vJEz`v>NwEOKwWnLCT^| zAQVGERn_WbFrY)C1TfI)YmX6&LVPIU{^0cY*X_Kn0|kM zxlei%Io5NW6srUyT_O}8wv(0TP=3OZF<=&^UvpX39<}S+zTX;%Wpp(y3)M{)|T)zBn$+{KU&fCH-pKck& zoV=>WOid3r8OGk4K_gy9Yzu|hP4Dj~S8rIE$+3h5--*UGo$xhwroHb9EU)itd3d`{ z8lIGNzI!dCP4P>Y=f3{Kh3c$bIdp|{n{AIo_i~+`*5aOcDfS}5buA4)Wkg0MdGlyF zU#d0PGh!HH!zEHz;27TE-W!Vd)L1!QlY`BEA1*#4;he!|JGpcK`85xkrI6W+yjJ;2 zpEU2h`@n literal 0 HcmV?d00001 diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java new file mode 100644 index 000000000..7f481443a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java @@ -0,0 +1,169 @@ +package com.magento.idea.magento2plugin.php.linemarker; + +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.Magento2Icons; +import com.magento.idea.magento2plugin.xml.di.index.PluginToTypeFileBasedIndex; +import org.apache.commons.lang.WordUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Created by dkvashnin on 11/12/15. + */ +public class PluginLineMarkerProvider implements LineMarkerProvider { + @Nullable + @Override + public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { + return null; + } + + @Override + public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { + PluginClassCache pluginClassCache = new PluginClassCache(); + ClassPluginCollector classPluginCollector = new ClassPluginCollector(pluginClassCache); + MethodPluginCollector methodPluginCollector = new MethodPluginCollector(pluginClassCache); + + for (PsiElement psiElement : list) { + if (psiElement instanceof PhpClass || psiElement instanceof Method) { + List results; + + if (psiElement instanceof PhpClass) { + results = classPluginCollector.collect((PhpClass) psiElement); + } else { + results = methodPluginCollector.collect((Method) psiElement); + } + + if (results.size() > 0 ) { + NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. + create(Magento2Icons.PLUGIN). + setTargets(results). + setTooltipText("Navigate Plugin"); + + collection.add(builder.createLineMarkerInfo(psiElement)); + } + } + } + } + + class PluginClassCache { + private HashMap> classPluginsMap = new HashMap>(); + + public List getPluginsForClass(PhpClass phpClass, String classFQN) { + List results = new ArrayList<>(); + + if (classPluginsMap.containsKey(classFQN)) { + return classPluginsMap.get(classFQN); + } + + + List plugins = FileBasedIndex.getInstance() + .getValues( + PluginToTypeFileBasedIndex.NAME, + classFQN, + GlobalSearchScope.allScope(phpClass.getProject()) + ); + + if (plugins.size() == 0) { + classPluginsMap.put(classFQN, results); + return results; + } + + PhpIndex phpIndex = PhpIndex.getInstance(phpClass.getProject()); + + + for (String[] pluginClassNames: plugins) { + for (String pluginClassName: pluginClassNames) { + results.addAll(phpIndex.getClassesByFQN(pluginClassName)); + } + } + classPluginsMap.put(classFQN, results); + return results; + } + + public List getPluginsForClass(PhpClass phpClass) + { + List pluginsForClass = getPluginsForClass(phpClass, phpClass.getPresentableFQN()); + for (PhpClass parent: phpClass.getSupers()) { + pluginsForClass.addAll(getPluginsForClass(parent)); + } + + return pluginsForClass; + } + + public List getPluginMethods(PhpClass plugin) { + List methodList = new ArrayList(); + for (Method method : plugin.getMethods()) { + if (method.getAccess().isPublic()) { + String pluginMethodName = method.getName(); + if (pluginMethodName.length() > 6) { + methodList.add(method); + } + } + } + return methodList; + } + + public List getPluginMethods(List plugins) { + List methodList = new ArrayList(); + for (PhpClass plugin: plugins) { + methodList.addAll(getPluginMethods(plugin)); + } + return methodList; + } + } +} + +interface PluginCollectorI { + public List collect(T psiElement); +} + +class ClassPluginCollector implements PluginCollectorI { + private PluginLineMarkerProvider.PluginClassCache pluginClassCache; + + public ClassPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { + this.pluginClassCache = pluginClassCache; + } + + @Override + public List collect(PhpClass psiElement) { + return pluginClassCache.getPluginsForClass(psiElement); + } +} + +class MethodPluginCollector implements PluginCollectorI { + private PluginLineMarkerProvider.PluginClassCache pluginClassCache; + + public MethodPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { + this.pluginClassCache = pluginClassCache; + } + + @Override + public List collect(Method psiElement) { + List results = new ArrayList<>(); + + List pluginsList = pluginClassCache.getPluginsForClass(psiElement.getContainingClass()); + List pluginMethods = pluginClassCache.getPluginMethods(pluginsList); + + String classMethodName = WordUtils.capitalize(psiElement.getName()); + for (Method pluginMethod: pluginMethods) { + if (isPluginMethodName(pluginMethod.getName(), classMethodName)) { + results.add(pluginMethod); + } + } + return results; + } + + private boolean isPluginMethodName(String pluginMethodName, String classMethodName) { + return pluginMethodName.substring(5).equals(classMethodName) || pluginMethodName.substring(6).equals(classMethodName); + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java index c703cedf0..564a7616a 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java @@ -27,7 +27,7 @@ public ClassCompletionContributor() { XmlHelper.getTagAttributePattern(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE), XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.TYPE_ATTRIBUTE), XmlHelper.getTagAttributePattern(XmlHelper.VIRTUAL_TYPE_TAG, XmlHelper.TYPE_ATTRIBUTE), - XmlHelper.getPluginTypePattern() + XmlHelper.getTagAttributePattern(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE) ), new CompletionProvider() { public void addCompletions(@NotNull CompletionParameters parameters, diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java index 65d7b200b..9934edd79 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java @@ -16,7 +16,9 @@ public VirtualTypeCompletionContributor() { extend(CompletionType.BASIC, XmlPatterns.or( XmlHelper.getArgumentValuePatternForType("object"), - XmlHelper.getItemValuePatternForType("object") + XmlHelper.getItemValuePatternForType("object"), + XmlHelper.getTagAttributePattern(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE), + XmlHelper.getTagAttributePattern(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE) ), new CompletionProvider() { public void addCompletions(@NotNull CompletionParameters parameters, diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java new file mode 100644 index 000000000..5bf74281f --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java @@ -0,0 +1,118 @@ +package com.magento.idea.magento2plugin.xml.di.index; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.xml.XmlDocumentImpl; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.*; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpLangUtil; +import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * Created by dkvashnin on 11/10/15. + */ +public class PluginToTypeFileBasedIndex extends FileBasedIndexExtension { + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.plugin_to_type"); + private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new DataIndexer() { + @NotNull + @Override + public Map map(@NotNull FileContent fileContent) { + Map map = new HashMap<>(); + + PsiFile psiFile = fileContent.getPsiFile(); + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); + if(document == null) { + return map; + } + + XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if(xmlTags == null) { + return map; + } + + for(XmlTag xmlTag: xmlTags) { + if(xmlTag.getName().equals("config")) { + for(XmlTag typeNode: xmlTag.findSubTags("type")) { + String typeName = typeNode.getAttributeValue("name"); + if (typeName != null) { + String[] plugins = getPluginsForType(typeNode); + if (plugins.length != 0) { + map.put( + PhpLangUtil.toPresentableFQN(typeName), + getPluginsForType(typeNode) + ); + } + } + } + } + } + + return map; + } + + private String[] getPluginsForType(XmlTag typeNode) { + List results = new ArrayList(); + + for (XmlTag pluginTag: typeNode.findSubTags("plugin")) { + String pluginType = pluginTag.getAttributeValue("type"); + if (pluginType != null) { + results.add(PhpLangUtil.toPresentableFQN(pluginType)); + } + } + return results.toArray(new String[results.size()]); + } + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public DataExternalizer getValueExternalizer() { + return new StringSetDataExternalizer(); + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return new FileBasedIndex.InputFilter() { + @Override + public boolean acceptInput(@NotNull VirtualFile file) { + return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("di"); + } + }; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java index 447690ef3..4795e033c 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java @@ -17,6 +17,7 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpLangUtil; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -108,7 +109,7 @@ public boolean dependsOnFileContent() { @Override public int getVersion() { - return 1; + return 2; } private class MyDataIndexer implements DataIndexer { @@ -135,8 +136,8 @@ public Map map(@NotNull FileContent fileContent) { if (typeNode.getAttributeValue("name") != null && typeNode.getAttributeValue("type") != null) { map.put( typeNode.getAttributeValue("name"), - typeNode.getAttributeValue("type") - ); + PhpLangUtil.toPresentableFQN(typeNode.getAttributeValue("type")) + ); } } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java index 65986886d..d7381bc19 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java @@ -50,7 +50,9 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelper.getDiTypePattern(), new DiInstanceReferenceProvider( new ResolveResultsFiller[]{ - ClassesResultsFiller.INSTANCE + ClassesResultsFiller.INSTANCE, + InterfacesResultsFiller.INSTANCE, + VirtualTypesResultsFiller.INSTANCE } ) ); diff --git a/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java b/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java new file mode 100644 index 000000000..34798ef46 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java @@ -0,0 +1,40 @@ +package com.magento.idea.magento2plugin.xml.index; + +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import org.jetbrains.annotations.NotNull; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by dkvashnin on 11/10/15. + */ +public class StringSetDataExternalizer implements DataExternalizer { + + private final EnumeratorStringDescriptor myStringEnumerator = new EnumeratorStringDescriptor(); + + public synchronized void save(@NotNull DataOutput out, String[] values) throws IOException { + + out.writeInt(values.length); + for(String value: values) { + this.myStringEnumerator.save(out, value != null ? value : ""); + } + + } + + public synchronized String[] read(@NotNull DataInput in) throws IOException { + List list = new ArrayList(); + int r = in.readInt(); + + while (r > 0) { + list.add(this.myStringEnumerator.read(in)); + r--; + } + + return list.toArray(new String[list.size()]); + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java index eeb4fd308..92cfe9ec4 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java @@ -10,6 +10,8 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpLangUtil; +import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; import org.jetbrains.annotations.NotNull; import java.io.DataInput; @@ -75,7 +77,7 @@ private String[] getObserversForEvent(XmlTag eventNode) { for (XmlTag observerTag: eventNode.findSubTags("observer")) { String name = observerTag.getAttributeValue("instance"); if (name != null) { - observerNames.add(name); + observerNames.add(PhpLangUtil.toPresentableFQN(name)); } } @@ -93,7 +95,7 @@ public KeyDescriptor getKeyDescriptor() { @NotNull @Override public DataExternalizer getValueExternalizer() { - return new MySetDataExternalizer(); + return new StringSetDataExternalizer(); } @NotNull @@ -114,33 +116,6 @@ public boolean dependsOnFileContent() { @Override public int getVersion() { - return 1; - } - - public static class MySetDataExternalizer implements DataExternalizer { - - private final EnumeratorStringDescriptor myStringEnumerator = new EnumeratorStringDescriptor(); - - public synchronized void save(@NotNull DataOutput out, String[] values) throws IOException { - - out.writeInt(values.length); - for(String value: values) { - this.myStringEnumerator.save(out, value != null ? value : ""); - } - - } - - public synchronized String[] read(@NotNull DataInput in) throws IOException { - List list = new ArrayList(); - int r = in.readInt(); - - while (r > 0) { - list.add(this.myStringEnumerator.read(in)); - r--; - } - - return list.toArray(new String[list.size()]); - } - + return 2; } } From d6f9a00586fafeca727c04d2095b3ead9954a7bb Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 15 Nov 2015 17:47:27 +0200 Subject: [PATCH 03/51] Implemented: - GoTo Configuration line merker for php class/interface --- META-INF/plugin.xml | 7 +- .../idea/magento2plugin/Magento2Icons.java | 1 + .../magento2plugin/icons/xml_reference.png | Bin 0 -> 1190 bytes .../magento2plugin/icons/xml_reference@2x.png | Bin 0 -> 2192 bytes .../ClassConfigurationLineMarkerProvider.java | 46 +++++ .../linemarker/PluginLineMarkerProvider.java | 6 +- .../di/index/PluginToTypeFileBasedIndex.java | 26 +-- .../TypeConfigurationFileBasedIndex.java | 176 ++++++++++++++++++ .../VirtualTypesNamesFileBasedIndex.java | 2 +- .../xml/index/StringSetDataExternalizer.java | 18 +- .../index/EventObserverFileBasedIndex.java | 30 ++- .../util/ClassResultsFillerWrapper.java | 5 +- 12 files changed, 270 insertions(+), 47 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/icons/xml_reference.png create mode 100644 src/com/magento/idea/magento2plugin/icons/xml_reference@2x.png create mode 100644 src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java create mode 100644 src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index fce9e8094..3933ae3ce 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -32,14 +32,19 @@ + + + + - + + diff --git a/src/com/magento/idea/magento2plugin/Magento2Icons.java b/src/com/magento/idea/magento2plugin/Magento2Icons.java index 4d1f8a5e9..f9375f957 100644 --- a/src/com/magento/idea/magento2plugin/Magento2Icons.java +++ b/src/com/magento/idea/magento2plugin/Magento2Icons.java @@ -9,4 +9,5 @@ */ public class Magento2Icons { public static final Icon PLUGIN = IconLoader.getIcon("icons/interception_reference.png"); + public static final Icon CONFIGURATION = IconLoader.getIcon("icons/xml_reference.png"); } diff --git a/src/com/magento/idea/magento2plugin/icons/xml_reference.png b/src/com/magento/idea/magento2plugin/icons/xml_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc3822a1521a54de11a7cce3fdd39e14bc71d8b GIT binary patch literal 1190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P{HZUkcg59UmvUF{9L`nl>DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtHP6qmLm5Rd1sY@-CA1Az=#^1qQAi7tkhHMA>m^>YcS^U|=foba4!^5X_x? zI!nY+q;3DJmnU;4P3TZGJXXQT%qGh8N@-WoL#I2hj5`+eKV+6TICn=N$Gg(i(g$0e z3?e(66gvI(s7RI?&3rd+-6#9I!j2vXXRfrX{dan$)!RdlXTR?8^PBjbF?!t(+aJr< zY*^$F)0uI_JejR+*$UZDEeb2_86-5n*W0lui65O;Qm&+y`BX78Y|ixN3Eg`Z8BEY+ z{9Cs!+c!gekH(^oveUacuvI3LS^PVTR^{F9Tx;rfl*1ic-pc;^ z&&Bq7iQMK5TUR-WuGQ~+A^n9T;wo>i&*24gOr8c^e|zZAp5=etu9pi{iB{iY{~BSb zdT~{kT~`Qu)^+g|`|#{-N}QqRBe z@|}2@{o&8R8VR+$L_Ow B)_?#2 literal 0 HcmV?d00001 diff --git a/src/com/magento/idea/magento2plugin/icons/xml_reference@2x.png b/src/com/magento/idea/magento2plugin/icons/xml_reference@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0b919a7aad5b32ef7a0439aedbe7d979c4fce116 GIT binary patch literal 2192 zcmZuzdpy(YAODUYGWv~bLeY?HvCSnrZEX{FTw+4*Oy+)@%{C0(uTHTLxy^K$bO@6= zh|-1TDAax{(uL@Uh?Q&QocV3lIp=qKUa!ydd_JG&{kgn9&p*#ko*vGt!TMkT09L!Y zki6w5Od+dOboKFBdfb5Qo zpwm#)NP2h_ibG?_(Exzw;N&VTicN)aXo*QI9EV{16@ioM3OCvq_7%cTAQ%UbJz5@_ImjfI$+skbC$9#>R?5f3EL+(indhN@9Iy zCFh6cP#I_|lqLHA1+n9z|7!0)q7*mZ!oITlRtzs64bG7nMP<{OK6H8_(Oxk-m@ADM z6XhL6jZDX*{~PgFr+7t5+-_!El$@)A5zz{d{vY3WJRYr}`)~BW&GxHTK3pPLUg?jA zB7za99s&TUhPsmMeFD@wi-NO!eRV}E2^9pJ67G_oG_tf{jcdGss&!n4MAD*6%zEx7 zkRX&Seumb?BA9x$=sbLqY;$VDzBS-%tZC?06Wbf^8__mgeo15Bs^Lz1Z?PBD?2&kfE>Iov@*68}YnDwSgbvNv2Dt>d^4xo--M*N>>cJSPM?w z;o!ZM`#UX^&Ogu2xofelm+=^Ho=~E*zHnbq(^!mYUqyM%58g^E-TK~_{$AjKO<3c- zS@n@acRn;%gOSg!?Qofj=VN3e5Z$xC95o>98zC6-Y#>;~nXNm0Gz-h_uX3u9rJ3)j ze^YjL zZOJKdSnqS{F`%1A07Mf`j@*AN+_#{q?FKL{@f<_}x8C`mjGP-XNDlSHJ8KBAslkH2ZjgM)-f3;t{ ze_C8bFLQ}Qbcv8fsP;4Pq;no#n=0_mk?jTA!O<@_^FWs;ic}ArfC4$vS@qtoTXCC| zik&Yp2X4+BfY^9K$&c2n?qANozOq9TG;z-MRR60fk9CqcE<3h7+F=c3U^N8H4DDdA5hn-W|6z!~l3mrn-$91o~k4(Oh*d*F2lwsPd9fvGr91B$Ea z5Yikab^RAw%Op=-^|{Mu)+|_E%11|oAcEw3n2}pu(?*DJ*n~6 zIk6~9v!URJ*S2pViTN3jnSmc$Bgw8C2o}H5lVj(l(bV6zv z!q)J86H&Tn%+;T$G*DHU-si$H93LYOw|ST)=JpM8s%1Uar6$XjWOVKxrfg1MAFPdP z55Bn&2%bkqBJNq0!$-rU{^Ai|cl`Jk&2o4jZdG?Ju0Cj~TTK96Dqv!1Ez+#(vh<{9 zQvlqvR9Il{WKIF(Uy>6iI0ddR8wx30d z^}=VEwXh+?7`C>#j=?bNxn0Xnj1I90t(a7K55THed;3F&d^|{pyC&bN2T43Oq*l%H z?cgd|FD^V8%2M^6fwj}>c=)DB{(GYoSWd3=Il6tP)hQhWtR+hXgNdNKQ$uX%jPcn*XsIaF@ zNk&1aTiARnIAVURGvxObz}qYIQLgisi@Z8*sRNnZ-VQO9;7;lup|Ehy!XJd literal 0 HcmV?d00001 diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java new file mode 100644 index 000000000..dd06e5ad8 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java @@ -0,0 +1,46 @@ +package com.magento.idea.magento2plugin.php.linemarker; + +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTag; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.Magento2Icons; +import com.magento.idea.magento2plugin.xml.di.index.TypeConfigurationFileBasedIndex; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/15/15. + */ +public class ClassConfigurationLineMarkerProvider implements LineMarkerProvider { + @Nullable + @Override + public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { + return null; + } + + @Override + public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { + for (PsiElement psiElement: list) { + if (psiElement instanceof PhpClass) { + List results = TypeConfigurationFileBasedIndex + .getClassConfigurations((PhpClass) psiElement); + if (results == null || results.size() == 0) { + continue; + } + + NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. + create(Magento2Icons.CONFIGURATION). + setTargets(results). + setTooltipText("Navigate to configuration"); + + collection.add(builder.createLineMarkerInfo(psiElement)); + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java index 7f481443a..d93ba644c 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java @@ -47,7 +47,7 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. create(Magento2Icons.PLUGIN). setTargets(results). - setTooltipText("Navigate Plugin"); + setTooltipText("Navigate to plugins"); collection.add(builder.createLineMarkerInfo(psiElement)); } @@ -66,7 +66,7 @@ public List getPluginsForClass(PhpClass phpClass, String classFQN) { } - List plugins = FileBasedIndex.getInstance() + List> plugins = FileBasedIndex.getInstance() .getValues( PluginToTypeFileBasedIndex.NAME, classFQN, @@ -81,7 +81,7 @@ public List getPluginsForClass(PhpClass phpClass, String classFQN) { PhpIndex phpIndex = PhpIndex.getInstance(phpClass.getProject()); - for (String[] pluginClassNames: plugins) { + for (Set pluginClassNames: plugins) { for (String pluginClassName: pluginClassNames) { results.addAll(phpIndex.getClassesByFQN(pluginClassName)); } diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java index 5bf74281f..9bdb912d7 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java @@ -19,24 +19,24 @@ /** * Created by dkvashnin on 11/10/15. */ -public class PluginToTypeFileBasedIndex extends FileBasedIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.plugin_to_type"); +public class PluginToTypeFileBasedIndex extends FileBasedIndexExtension> { + public static final ID> NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.plugin_to_type"); private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); @NotNull @Override - public ID getName() { + public ID> getName() { return NAME; } @NotNull @Override - public DataIndexer getIndexer() { - return new DataIndexer() { + public DataIndexer, FileContent> getIndexer() { + return new DataIndexer, FileContent>() { @NotNull @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); + public Map> map(@NotNull FileContent fileContent) { + Map> map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); @@ -54,8 +54,8 @@ public Map map(@NotNull FileContent fileContent) { for(XmlTag typeNode: xmlTag.findSubTags("type")) { String typeName = typeNode.getAttributeValue("name"); if (typeName != null) { - String[] plugins = getPluginsForType(typeNode); - if (plugins.length != 0) { + Set plugins = getPluginsForType(typeNode); + if (plugins.size() != 0) { map.put( PhpLangUtil.toPresentableFQN(typeName), getPluginsForType(typeNode) @@ -69,8 +69,8 @@ public Map map(@NotNull FileContent fileContent) { return map; } - private String[] getPluginsForType(XmlTag typeNode) { - List results = new ArrayList(); + private Set getPluginsForType(XmlTag typeNode) { + Set results = new HashSet(); for (XmlTag pluginTag: typeNode.findSubTags("plugin")) { String pluginType = pluginTag.getAttributeValue("type"); @@ -78,7 +78,7 @@ private String[] getPluginsForType(XmlTag typeNode) { results.add(PhpLangUtil.toPresentableFQN(pluginType)); } } - return results.toArray(new String[results.size()]); + return results; } }; } @@ -91,7 +91,7 @@ public KeyDescriptor getKeyDescriptor() { @NotNull @Override - public DataExternalizer getValueExternalizer() { + public DataExternalizer> getValueExternalizer() { return new StringSetDataExternalizer(); } diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java new file mode 100644 index 000000000..f31457bff --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java @@ -0,0 +1,176 @@ +package com.magento.idea.magento2plugin.xml.di.index; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.source.xml.XmlDocumentImpl; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.*; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpLangUtil; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.xml.di.XmlHelper; +import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Created by dkvashnin on 11/15/15. + */ +public class TypeConfigurationFileBasedIndex extends ScalarIndexExtension { + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.type_configuration"); + private final EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + public static final Map TAG_ATTRIBUTE_RELATION = new HashMap() {{ + put(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE); + put(XmlHelper.PREFERENCE_TAG, XmlHelper.FOR_ATTRIBUTE); + put(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE); + put(XmlHelper.VIRTUAL_TYPE_TAG, XmlHelper.TYPE_ATTRIBUTE); + }}; + + @Nullable + public static List getClassConfigurations(PhpClass phpClass) { + String classFqn = phpClass.getPresentableFQN(); + if (classFqn == null) { + return null; + } + + Collection containingFiles = FileBasedIndex + .getInstance() + .getContainingFiles( + NAME, + classFqn, + GlobalSearchScope.allScope(phpClass.getProject()) + ); + + PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); + + List tags = new ArrayList(); + + for (VirtualFile virtualFile: containingFiles) { + XmlFile file = (XmlFile)psiManager.findFile(virtualFile); + + if (file == null) { + continue; + } + + XmlTag rootTag = file.getRootTag(); + fillRelatedTags(classFqn, rootTag, tags); + } + + return tags; + } + + private static void fillRelatedTags(String classFqn, XmlTag parentTag, List tagsReferences) { + for (XmlTag childTag: parentTag.getSubTags()) { + String tagName = childTag.getName(); + String attribute = TAG_ATTRIBUTE_RELATION.get(tagName); + if (attribute == null) { + continue; + } + + String className = childTag.getAttributeValue(attribute); + if (className != null && PhpLangUtil.toPresentableFQN(className).equals(classFqn)) { + tagsReferences.add(childTag); + } + + // type tag has plugin tags + if (tagName.equals(XmlHelper.TYPE_TAG)) { + fillRelatedTags(classFqn, childTag, tagsReferences); + } + } + } + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new DataIndexer() { + @NotNull + @Override + public Map map(@NotNull FileContent fileContent) { + Map map = new HashMap<>(); + + PsiFile psiFile = fileContent.getPsiFile(); + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); + if(document == null) { + return map; + } + + XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if(xmlTags == null) { + return map; + } + + for(XmlTag xmlTag: xmlTags) { + if(xmlTag.getName().equals("config")) { + processConfigurationTags(xmlTag, map); + } + } + + return map; + } + + private void processConfigurationTags(XmlTag parentTag, Map results) { + for (XmlTag childTag: parentTag.getSubTags()) { + String tagName = childTag.getName(); + + String attribute = TAG_ATTRIBUTE_RELATION.get(tagName); + if (attribute == null) { + continue; + } + + String className = childTag.getAttributeValue(attribute); + if (className != null) { + results.put(PhpLangUtil.toPresentableFQN(className), null); + } + + // type tag has plugin tags + if (tagName.equals(XmlHelper.TYPE_TAG)) { + processConfigurationTags(childTag, results); + } + } + } + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return new FileBasedIndex.InputFilter() { + @Override + public boolean acceptInput(@NotNull VirtualFile file) { + return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("di"); + } + }; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 0; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java index 4795e033c..6da1c3390 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java @@ -39,9 +39,9 @@ public static XmlAttributeValue[] getVirtualTypesByName(final Project project, f List xmlAttributeList = new ArrayList(); Collection virtualFileCollection = FileBasedIndex.getInstance().getContainingFiles(NAME, name, scope); + PsiManager psiManager = PsiManager.getInstance(project); for (VirtualFile virtualFile: virtualFileCollection) { - PsiManager psiManager = PsiManager.getInstance(project); XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); if (xmlFile == null) { continue; diff --git a/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java b/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java index 34798ef46..f4102d466 100644 --- a/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java +++ b/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java @@ -7,34 +7,34 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; /** * Created by dkvashnin on 11/10/15. */ -public class StringSetDataExternalizer implements DataExternalizer { +public class StringSetDataExternalizer implements DataExternalizer> { private final EnumeratorStringDescriptor myStringEnumerator = new EnumeratorStringDescriptor(); - public synchronized void save(@NotNull DataOutput out, String[] values) throws IOException { + public synchronized void save(@NotNull DataOutput out, Set values) throws IOException { - out.writeInt(values.length); + out.writeInt(values.size()); for(String value: values) { this.myStringEnumerator.save(out, value != null ? value : ""); } } - public synchronized String[] read(@NotNull DataInput in) throws IOException { - List list = new ArrayList(); + public synchronized Set read(@NotNull DataInput in) throws IOException { + Set set = new HashSet(); int r = in.readInt(); while (r > 0) { - list.add(this.myStringEnumerator.read(in)); + set.add(this.myStringEnumerator.read(in)); r--; } - return list.toArray(new String[list.size()]); + return set; } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java index 92cfe9ec4..13122c269 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java @@ -14,35 +14,29 @@ import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; import org.jetbrains.annotations.NotNull; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Created by dkvashnin on 11/2/15. */ -public class EventObserverFileBasedIndex extends FileBasedIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.observer.index.event_observer"); +public class EventObserverFileBasedIndex extends FileBasedIndexExtension> { + public static final ID> NAME = ID.create("com.magento.idea.magento2plugin.xml.observer.index.event_observer"); private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); @NotNull @Override - public ID getName() { + public ID> getName() { return NAME; } @NotNull @Override - public DataIndexer getIndexer() { - return new DataIndexer() { + public DataIndexer, FileContent> getIndexer() { + return new DataIndexer, FileContent>() { @NotNull @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); + public Map> map(@NotNull FileContent fileContent) { + Map> map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); @@ -71,8 +65,8 @@ public Map map(@NotNull FileContent fileContent) { return map; } - private String[] getObserversForEvent(XmlTag eventNode) { - List observerNames = new ArrayList(); + private Set getObserversForEvent(XmlTag eventNode) { + Set observerNames = new HashSet(); for (XmlTag observerTag: eventNode.findSubTags("observer")) { String name = observerTag.getAttributeValue("instance"); @@ -81,7 +75,7 @@ private String[] getObserversForEvent(XmlTag eventNode) { } } - return observerNames.toArray(new String[observerNames.size()]); + return observerNames; } }; } @@ -94,7 +88,7 @@ public KeyDescriptor getKeyDescriptor() { @NotNull @Override - public DataExternalizer getValueExternalizer() { + public DataExternalizer> getValueExternalizer() { return new StringSetDataExternalizer(); } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java index 1ff51f1b1..28da242c4 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java @@ -10,6 +10,7 @@ import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import java.util.List; +import java.util.Set; /** * Created by dkvashnin on 11/3/15. @@ -19,13 +20,13 @@ public class ClassResultsFillerWrapper implements ResolveResultsFiller { @Override public void fillResults(PsiElement psiElement, List results, String typeName) { - List observersTypesList = FileBasedIndex.getInstance().getValues( + List> observersTypesList = FileBasedIndex.getInstance().getValues( EventObserverFileBasedIndex.NAME, typeName, GlobalSearchScope.allScope(psiElement.getProject()) ); - for (String[] observerTypes: observersTypesList) { + for (Set observerTypes: observersTypesList) { for (String type: observerTypes) { ClassesResultsFiller.INSTANCE.fillResults(psiElement, results, type); VirtualTypesResultsFiller.INSTANCE.fillResults(psiElement, results, type); From 70fb7cc094a6567c4dffc0e1b55ea1a4a538ee90 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 15 Nov 2015 18:40:45 +0200 Subject: [PATCH 04/51] - Version change to v0.0.7 --- META-INF/plugin.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 3933ae3ce..b0561510a 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,7 +1,7 @@ com.magento.idea.magento2plugin Magento2 - 0.0.7 + 0.0.8 Magento v0.0.7 References: to configuration and observers (classes or virtualType), to observers from configuration, to event dispatch from configuration +
+ v0.0.8 Line marker reference for php class/interface to: XML(di.xml) configuration, Plugins ]]> From d5222b7da7919b02f18ee14c19b81b5d4d7e5919 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Wed, 18 Nov 2015 00:02:24 +0200 Subject: [PATCH 05/51] Added completion for observers and events in events.xml --- META-INF/plugin.xml | 4 +- .../xml/{reference => }/XmlHelperUtility.java | 27 +++++++-- .../completion/ClassCompletionProvider.java | 48 +++++++++++++++ .../xml/completion/CompletionProviderI.java | 13 ++++ .../VirtualTypeCompletionProvider.java | 30 ++++++++++ .../idea/magento2plugin/xml/di/XmlHelper.java | 21 +------ ...utor.java => DiCompletionContributor.java} | 36 ++++------- .../VirtualTypeCompletionContributor.java | 38 ------------ .../xml/observer/XmlHelper.java | 24 ++++++++ .../EventCompletionContributor.java | 60 +++++++++++++++++++ .../ObserverReferenceContributor.java | 7 +-- 11 files changed, 217 insertions(+), 91 deletions(-) rename src/com/magento/idea/magento2plugin/xml/{reference => }/XmlHelperUtility.java (59%) create mode 100644 src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java create mode 100644 src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java rename src/com/magento/idea/magento2plugin/xml/di/completion/{ClassCompletionContributor.java => DiCompletionContributor.java} (53%) delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java create mode 100644 src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index b0561510a..55d63fc4f 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -35,8 +35,8 @@ - - + + diff --git a/src/com/magento/idea/magento2plugin/xml/reference/XmlHelperUtility.java b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java similarity index 59% rename from src/com/magento/idea/magento2plugin/xml/reference/XmlHelperUtility.java rename to src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java index 6fa77a046..46a26f8c9 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/XmlHelperUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java @@ -1,9 +1,7 @@ -package com.magento.idea.magento2plugin.xml.reference; +package com.magento.idea.magento2plugin.xml; -import com.intellij.patterns.PsiElementPattern; -import com.intellij.patterns.PsiFilePattern; -import com.intellij.patterns.XmlAttributeValuePattern; -import com.intellij.patterns.XmlPatterns; +import com.intellij.patterns.*; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.xml.XmlTag; @@ -38,4 +36,23 @@ public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagNam getInsideTagPattern(tagName) ).inFile(getXmlFilePattern(fileType)); } + + /** + * + */ + public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName, String fileName) { + return XmlPatterns + .psiElement() + .inside(XmlPatterns + .xmlAttributeValue() + .inside(XmlPatterns + .xmlAttribute() + .withName(attributeName) + .withParent(XmlPatterns + .xmlTag() + .withName(tag) + ) + ) + ).inFile(getXmlFilePattern(fileName)); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java new file mode 100644 index 000000000..f8a699640 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java @@ -0,0 +1,48 @@ +package com.magento.idea.magento2plugin.xml.completion; + +import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.jetbrains.php.PhpIcons; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/17/15. + */ +public class ClassCompletionProvider implements CompletionProviderI { + public final static CompletionProviderI INSTANCE = new ClassCompletionProvider(); + + @Override + public List collectCompletionResult(PsiElement psiElement) { + List result = new ArrayList<>(); + PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); + String prefix = StringUtil.unquoteString(psiElement.getText()); + + Collection classNames = phpIndex.getAllClassNames(new CamelHumpMatcher(prefix)); + + for (String className: classNames) { + Collection classesByName = phpIndex.getClassesByName(className); + for (PhpClass phpClass: classesByName) { + String classFqn = phpClass.getPresentableFQN(); + if (classFqn == null) { + continue; + } + + result.add( + LookupElementBuilder + .create(classFqn) + .withIcon(PhpIcons.CLASS_ICON) + ); + } + } + + return result; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java new file mode 100644 index 000000000..3d347a041 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java @@ -0,0 +1,13 @@ +package com.magento.idea.magento2plugin.xml.completion; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.psi.PsiElement; + +import java.util.List; + +/** + * Created by dkvashnin on 11/17/15. + */ +public interface CompletionProviderI { + public List collectCompletionResult(PsiElement psiElement); +} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java new file mode 100644 index 000000000..1a3b13ab4 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java @@ -0,0 +1,30 @@ +package com.magento.idea.magento2plugin.xml.completion; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by dkvashnin on 11/17/15. + */ +public class VirtualTypeCompletionProvider implements CompletionProviderI { + public final static CompletionProviderI INSTANCE = new VirtualTypeCompletionProvider(); + + @Override + public List collectCompletionResult(PsiElement psiElement) { + List result = new ArrayList<>(); + String[] allVirtualTypesNames = VirtualTypesNamesFileBasedIndex.getAllVirtualTypesNames( + psiElement.getProject() + ); + + for (String name: allVirtualTypesNames) { + result.add(LookupElementBuilder.create(name)); + } + + return result; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java index ea51bc188..fa34de197 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java +++ b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java @@ -3,7 +3,7 @@ import com.intellij.patterns.*; import com.intellij.psi.PsiElement; import com.intellij.psi.xml.XmlTokenType; -import com.magento.idea.magento2plugin.xml.reference.XmlHelperUtility; +import com.magento.idea.magento2plugin.xml.XmlHelperUtility; /** * Created by Warider on 17.08.2015. @@ -103,23 +103,8 @@ public static PsiElementPattern.Capture getItemValuePatternForType(S /** * - * - * @param tag tagname - * @param attributeNames attribute values listen for */ - public static PsiElementPattern.Capture getTagAttributePattern(String tag, String... attributeNames) { - return XmlPatterns - .psiElement() - .inside(XmlPatterns - .xmlAttributeValue() - .inside(XmlPatterns - .xmlAttribute() - .withName(StandardPatterns.string().oneOfIgnoreCase(attributeNames)) - .withParent(XmlPatterns - .xmlTag() - .withName(tag) - ) - ) - ).inFile(getXmlFilePattern(FILE_TYPE)); + public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { + return getTagAttributePattern(tag, attributeName, FILE_TYPE); } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java similarity index 53% rename from src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java rename to src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java index 564a7616a..42bcfba29 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/ClassCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java @@ -1,25 +1,25 @@ package com.magento.idea.magento2plugin.xml.di.completion; import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; -import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; +import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.xml.di.XmlHelper; import org.jetbrains.annotations.NotNull; -import java.util.Collection; - /** * Created by dkvashnin on 10/15/15. */ -public class ClassCompletionContributor extends CompletionContributor { - public ClassCompletionContributor() { +public class DiCompletionContributor extends CompletionContributor { + private CompletionProviderI[] completionProviders = new CompletionProviderI[] { + ClassCompletionProvider.INSTANCE, + VirtualTypeCompletionProvider.INSTANCE + }; + + public DiCompletionContributor() { extend(CompletionType.BASIC, XmlPatterns.or( XmlHelper.getArgumentValuePatternForType("object"), @@ -34,20 +34,8 @@ public void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet resultSet) { PsiElement psiElement = parameters.getOriginalPosition(); - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - String prefix = StringUtil.unquoteString(psiElement.getText()); - - Collection classNames = phpIndex.getAllClassNames(new CamelHumpMatcher(prefix)); - - for (String className: classNames) { - Collection classesByName = phpIndex.getClassesByName(className); - for (PhpClass phpClass: classesByName) { - resultSet.addElement( - LookupElementBuilder - .create(phpClass.getPresentableFQN()) - .withIcon(PhpIcons.CLASS_ICON) - ); - } + for (CompletionProviderI completionProvider: completionProviders) { + resultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); } } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java deleted file mode 100644 index 9934edd79..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/VirtualTypeCompletionContributor.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.patterns.XmlPatterns; -import com.intellij.util.ProcessingContext; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 10/14/15. - */ -public class VirtualTypeCompletionContributor extends CompletionContributor { - public VirtualTypeCompletionContributor() { - extend(CompletionType.BASIC, - XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType("object"), - XmlHelper.getItemValuePatternForType("object"), - XmlHelper.getTagAttributePattern(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE), - XmlHelper.getTagAttributePattern(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE) - ), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - String[] allVirtualTypesNames = VirtualTypesNamesFileBasedIndex.getAllVirtualTypesNames( - parameters.getOriginalPosition().getProject() - ); - - for (String name: allVirtualTypesNames) { - resultSet.addElement(LookupElementBuilder.create(name)); - } - } - } - ); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java new file mode 100644 index 000000000..1a60455e6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java @@ -0,0 +1,24 @@ +package com.magento.idea.magento2plugin.xml.observer; + +import com.intellij.patterns.XmlAttributeValuePattern; +import com.magento.idea.magento2plugin.xml.XmlHelperUtility; + +/** + * Created by dkvashnin on 11/17/15. + */ +public class XmlHelper extends XmlHelperUtility { + public static final String FILE_TYPE = "events"; + + public static final String OBSERVER_TAG = "observer"; + public static final String EVENT_TAG = "event"; + + public static final String NAME_ATTRIBUTE = "name"; + public static final String INSTANCE_ATTRIBUTE = "instance"; + + /** + * + */ + public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagName, String attributeName) { + return getTagAttributeValuePattern(tagName, attributeName, FILE_TYPE); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java new file mode 100644 index 000000000..61d077794 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java @@ -0,0 +1,60 @@ +package com.magento.idea.magento2plugin.xml.observer.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.xml.XmlHelperUtility; +import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; +import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; +import com.magento.idea.magento2plugin.xml.observer.XmlHelper; +import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * Created by dkvashnin on 11/17/15. + */ +public class EventCompletionContributor extends CompletionContributor { + private CompletionProviderI[] typeCompletionProviders = new CompletionProviderI[] { + ClassCompletionProvider.INSTANCE, + VirtualTypeCompletionProvider.INSTANCE + }; + + public EventCompletionContributor() { + extend( + CompletionType.BASIC, + XmlHelperUtility.getTagAttributePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE, XmlHelper.FILE_TYPE), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + PsiElement psiElement = completionParameters.getOriginalPosition(); + for (CompletionProviderI completionProvider: typeCompletionProviders) { + completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); + } + } + } + ); + + extend( + CompletionType.BASIC, + XmlHelperUtility.getTagAttributePattern(XmlHelper.EVENT_TAG, XmlHelper.NAME_ATTRIBUTE, XmlHelper.FILE_TYPE), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + PsiElement psiElement = completionParameters.getOriginalPosition(); + Collection eventNames = FileBasedIndex.getInstance().getAllKeys(EventsDeclarationsFileBasedIndex.NAME, psiElement.getProject()); + + for (String eventName: eventNames) { + completionResultSet.addElement(LookupElementBuilder.create(eventName)); + } + + } + } + ); + } +} + diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java index 330b0fea7..03632b96e 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java @@ -1,10 +1,9 @@ package com.magento.idea.magento2plugin.xml.observer.reference; -import com.intellij.patterns.XmlPatterns; import com.intellij.psi.*; import com.magento.idea.magento2plugin.xml.di.reference.provider.DiInstanceReferenceProvider; +import com.magento.idea.magento2plugin.xml.observer.XmlHelper; import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsDeclarationsFilesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; @@ -18,7 +17,7 @@ public class ObserverReferenceContributor extends PsiReferenceContributor { public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { // psiReferenceRegistrar.registerReferenceProvider( - XmlHelperUtility.getTagAttributeValuePattern("observer", "instance", "events"), + XmlHelper.getTagAttributeValuePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE), new DiInstanceReferenceProvider( new ResolveResultsFiller[]{ ClassesResultsFiller.INSTANCE, @@ -28,7 +27,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen ); psiReferenceRegistrar.registerReferenceProvider( - XmlHelperUtility.getTagAttributeValuePattern("event", "name", "events"), + XmlHelper.getTagAttributeValuePattern(XmlHelper.EVENT_TAG, XmlHelper.NAME_ATTRIBUTE), new DiInstanceReferenceProvider( new ResolveResultsFiller[]{ EventsDeclarationsFilesResultsFiller.INSTANCE From 2579439a40ee7c9704dcfb3df8c9f8c093795a9d Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Wed, 18 Nov 2015 21:05:00 +0200 Subject: [PATCH 06/51] Added references for layouts: - to referenceContainer and referenceBlock - to block class --- META-INF/plugin.xml | 3 + .../magento2plugin/xml/XmlHelperUtility.java | 31 +++++- .../AbstractComponentNameFileBasedIndex.java | 97 +++++++++++++++++++ .../xml/layout/index/BlockFileBasedIndex.java | 22 +++++ .../layout/index/ContainerFileBasedIndex.java | 26 +++++ .../xml/layout/index/LayoutDataIndexer.java | 58 +++++++++++ .../reference/LayoutReferenceContributor.java | 49 ++++++++++ .../fill/ComponentResultsFiller.java | 39 ++++++++ 8 files changed, 324 insertions(+), 1 deletion(-) create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 55d63fc4f..fc1e1e993 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -34,6 +34,7 @@ + @@ -43,6 +44,8 @@ + + diff --git a/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java index 46a26f8c9..5f5e850e4 100644 --- a/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java @@ -4,16 +4,26 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.Nullable; /** * Created by dkvashnin on 11/2/15. */ public class XmlHelperUtility { - public static PsiFilePattern.Capture getXmlFilePattern(String fileName) { + public static PsiFilePattern.Capture getXmlFilePattern(@Nullable String fileName) { + if (fileName == null) { + return getXmlFilePattern(); + } + return XmlPatterns.psiFile() .withName(XmlPatterns.string().equalTo(fileName + ".xml")); } + public static PsiFilePattern.Capture getXmlFilePattern() { + return XmlPatterns.psiFile() + .withName(XmlPatterns.string().endsWith(".xml")); + } + public static PsiElementPattern.Capture getInsideTagPattern(String insideTagName) { return XmlPatterns.psiElement(XmlTag.class).withName(insideTagName); } @@ -37,6 +47,25 @@ public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagNam ).inFile(getXmlFilePattern(fileType)); } + /** + * + */ + public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagName, String attributeName) { + return XmlPatterns + .xmlAttributeValue() + .withParent( + XmlPatterns + .xmlAttribute(attributeName) + .withParent( + XmlPatterns + .xmlTag() + .withName(tagName) + ) + ).inside( + getInsideTagPattern(tagName) + ).inFile(getXmlFilePattern()); + } + /** * */ diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java new file mode 100644 index 000000000..1e0d67f61 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java @@ -0,0 +1,97 @@ +package com.magento.idea.magento2plugin.xml.layout.index; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/18/15. + */ +public abstract class AbstractComponentNameFileBasedIndex extends ScalarIndexExtension { + private EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public DataIndexer getIndexer() { + return new LayoutDataIndexer(getComponentName()); + } + + protected abstract String getComponentName(); + + public static List getComponentDeclarations(String componentName, String componentType, ID id, Project project) { + List results = new ArrayList(); + Collection containingFiles = FileBasedIndex.getInstance() + .getContainingFiles( + id, + componentName, + GlobalSearchScope.allScope(project) + ); + PsiManager psiManager = PsiManager.getInstance(project); + + for (VirtualFile virtualFile: containingFiles) { + XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); + if (xmlFile == null) { + continue; + } + + XmlTag rootTag = xmlFile.getRootTag(); + if (rootTag == null) { + continue; + } + collectComponentDeclarations(rootTag, results, componentName, componentType); + } + + + return results; + } + + public static void collectComponentDeclarations(XmlTag parentTag, List results, String componentName, String componentType) { + for (XmlTag childTag: parentTag.getSubTags()) { + if (componentType.equals(childTag.getName()) && componentName.equals(childTag.getAttributeValue("name"))) { + results.add(childTag); + } else if(childTag.getSubTags().length > 0 ) { + collectComponentDeclarations(childTag, results, componentName, componentType); + } + } + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return new FileBasedIndex.InputFilter() { + @Override + public boolean acceptInput(@NotNull VirtualFile virtualFile) { + VirtualFile parent = virtualFile.getParent(); + return virtualFile.getFileType() == XmlFileType.INSTANCE && parent.isDirectory() && parent.getName().endsWith("layout"); + } + }; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 0; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java new file mode 100644 index 000000000..2c3844bd6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java @@ -0,0 +1,22 @@ +package com.magento.idea.magento2plugin.xml.layout.index; + +import com.intellij.util.indexing.*; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class BlockFileBasedIndex extends AbstractComponentNameFileBasedIndex { + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.layout.index.block_name"); + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @Override + protected String getComponentName() { + return "block"; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java new file mode 100644 index 000000000..e4b10d12a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java @@ -0,0 +1,26 @@ +package com.magento.idea.magento2plugin.xml.layout.index; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class ContainerFileBasedIndex extends AbstractComponentNameFileBasedIndex { + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.layout.index.container_name"); + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @Override + protected String getComponentName() { + return "container"; + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java b/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java new file mode 100644 index 000000000..a7d0151a1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java @@ -0,0 +1,58 @@ +package com.magento.idea.magento2plugin.xml.layout.index; + +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.xml.XmlDocumentImpl; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileContent; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class LayoutDataIndexer implements DataIndexer { + private String indexTag; + + public LayoutDataIndexer(String indexTag) { + this.indexTag = indexTag; + } + + @NotNull + @Override + public Map map(@NotNull FileContent fileContent) { + Map map = new HashMap<>(); + + PsiFile psiFile = fileContent.getPsiFile(); + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); + if(document == null) { + return map; + } + + XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if(xmlTags == null) { + return map; + } + + for (XmlTag xmlTag: xmlTags) { + fillResultMap(xmlTag, map); + } + + return map; + } + + private void fillResultMap(XmlTag parentTag, Map resultMap) { + for (XmlTag childTag: parentTag.getSubTags()) { + if (indexTag.equals(childTag.getName())) { + String blockName = childTag.getAttributeValue("name"); + if (blockName != null) { + resultMap.put(blockName, null); + } + } + fillResultMap(childTag, resultMap); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java new file mode 100644 index 000000000..328872762 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -0,0 +1,49 @@ +package com.magento.idea.magento2plugin.xml.layout.reference; + +import com.intellij.psi.*; +import com.magento.idea.magento2plugin.xml.XmlHelperUtility; +import com.magento.idea.magento2plugin.xml.di.reference.provider.DiInstanceReferenceProvider; +import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.reference.fill.ComponentResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class LayoutReferenceContributor extends PsiReferenceContributor { + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { + // + psiReferenceRegistrar.registerReferenceProvider( + XmlHelperUtility.getTagAttributeValuePattern("block", "class"), + new DiInstanceReferenceProvider( + new ResolveResultsFiller[]{ + ClassesResultsFiller.INSTANCE, + VirtualTypesResultsFiller.INSTANCE + } + ) + ); + + psiReferenceRegistrar.registerReferenceProvider( + XmlHelperUtility.getTagAttributeValuePattern("referenceBlock", "name"), + new DiInstanceReferenceProvider( + new ResolveResultsFiller[]{ + new ComponentResultsFiller(BlockFileBasedIndex.NAME, "block") + } + ) + ); + + psiReferenceRegistrar.registerReferenceProvider( + XmlHelperUtility.getTagAttributeValuePattern("referenceContainer", "name"), + new DiInstanceReferenceProvider( + new ResolveResultsFiller[]{ + new ComponentResultsFiller(ContainerFileBasedIndex.NAME, "container") + } + ) + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java new file mode 100644 index 000000000..29821c175 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java @@ -0,0 +1,39 @@ +package com.magento.idea.magento2plugin.xml.layout.reference.fill; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.ID; +import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; +import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class ComponentResultsFiller implements ResolveResultsFiller { + private ID indexId; + private String componentType; + + public ComponentResultsFiller(ID indexId, String componentType) { + this.indexId = indexId; + this.componentType = componentType; + } + + @Override + public void fillResults(PsiElement psiElement, List results, String typeName) { + List componentDeclarations = AbstractComponentNameFileBasedIndex + .getComponentDeclarations( + typeName, + componentType, + indexId, + psiElement.getProject() + ); + + ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); + results.addAll(Arrays.asList(resolveResults)); + } +} From 60d6c987567adb181f8037fe399b8657d3c7a2bc Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Wed, 18 Nov 2015 22:58:18 +0200 Subject: [PATCH 07/51] Added completion for layout: - referenceBlock and referenceContainer - block class --- META-INF/plugin.xml | 3 + .../magento2plugin/xml/XmlHelperUtility.java | 19 +++++ .../di/reference/DiReferenceContributor.java | 29 ++++---- ...rovider.java => XmlReferenceProvider.java} | 8 +-- .../LayoutCompletionContributor.java | 72 +++++++++++++++++++ .../ReferenceComponentCompletionProvider.java | 38 ++++++++++ .../AbstractComponentNameFileBasedIndex.java | 4 ++ .../reference/LayoutReferenceContributor.java | 16 ++--- .../fill/ComponentResultsFiller.java | 10 ++- .../reference/EventReferenceContributor.java | 4 +- .../reference/EventReferenceProvider.java | 6 +- .../ObserverReferenceContributor.java | 12 ++-- .../util/ClassResultsFillerWrapper.java | 12 ++-- ...EventsConfigurationFilesResultsFiller.java | 8 +-- .../EventsDeclarationsFilesResultsFiller.java | 8 +-- .../xml/reference/TypeReference.java | 14 ++-- .../reference/util/ClassesResultsFiller.java | 6 +- .../util/InterfacesResultsFiller.java | 6 +- ...iller.java => ReferenceResultsFiller.java} | 4 +- .../util/VirtualTypesResultsFiller.java | 6 +- 20 files changed, 211 insertions(+), 74 deletions(-) rename src/com/magento/idea/magento2plugin/xml/di/reference/provider/{DiInstanceReferenceProvider.java => XmlReferenceProvider.java} (70%) create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java rename src/com/magento/idea/magento2plugin/xml/reference/util/{ResolveResultsFiller.java => ReferenceResultsFiller.java} (58%) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index fc1e1e993..317ce927b 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -38,6 +38,9 @@ + + + diff --git a/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java index 5f5e850e4..ecb5e635f 100644 --- a/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java @@ -84,4 +84,23 @@ public static PsiElementPattern.Capture getTagAttributePattern(Strin ) ).inFile(getXmlFilePattern(fileName)); } + + /** + * + */ + public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { + return XmlPatterns + .psiElement() + .inside(XmlPatterns + .xmlAttributeValue() + .inside(XmlPatterns + .xmlAttribute() + .withName(attributeName) + .withParent(XmlPatterns + .xmlTag() + .withName(tag) + ) + ) + ).inFile(getXmlFilePattern()); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java index d7381bc19..2e51f3180 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java @@ -5,11 +5,10 @@ import com.intellij.util.ProcessingContext; import com.magento.idea.magento2plugin.xml.di.XmlHelper; import com.magento.idea.magento2plugin.xml.di.reference.provider.ArgumentNameReferenceProvider; -import com.magento.idea.magento2plugin.xml.di.reference.provider.DiInstanceReferenceProvider; -import com.magento.idea.magento2plugin.xml.reference.TypeReference; +import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.InterfacesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; @@ -26,8 +25,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getDiPreferenceForPattern(), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, InterfacesResultsFiller.INSTANCE } @@ -37,8 +36,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getDiPreferenceTypePattern(), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } @@ -48,8 +47,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getDiTypePattern(), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, InterfacesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE @@ -60,8 +59,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getDiVirtualTypePattern(), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } @@ -74,8 +73,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelper.getArgumentValuePatternForType(OBJECT_TYPE_NAME), XmlHelper.getItemValuePatternForType(OBJECT_TYPE_NAME) ), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } @@ -108,8 +107,8 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @No // psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getPluginTypePattern(), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/DiInstanceReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java similarity index 70% rename from src/com/magento/idea/magento2plugin/xml/di/reference/provider/DiInstanceReferenceProvider.java rename to src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java index 61668dd8f..132dfab7b 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/DiInstanceReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java @@ -5,16 +5,16 @@ import com.intellij.psi.PsiReferenceProvider; import com.intellij.util.ProcessingContext; import com.magento.idea.magento2plugin.xml.reference.TypeReference; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import org.jetbrains.annotations.NotNull; /** * Created by Warider on 17.08.2015. */ -public class DiInstanceReferenceProvider extends PsiReferenceProvider { - private final ResolveResultsFiller[] resultsFillers; +public class XmlReferenceProvider extends PsiReferenceProvider { + private final ReferenceResultsFiller[] resultsFillers; - public DiInstanceReferenceProvider(ResolveResultsFiller[] resultsFillers) { + public XmlReferenceProvider(ReferenceResultsFiller[] resultsFillers) { super(); this.resultsFillers = resultsFillers; } diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java new file mode 100644 index 000000000..37e314488 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java @@ -0,0 +1,72 @@ +package com.magento.idea.magento2plugin.xml.layout.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.xml.XmlHelperUtility; +import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; +import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; +import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class LayoutCompletionContributor extends CompletionContributor { + private CompletionProviderI[] typeCompletionProviders = new CompletionProviderI[] { + ClassCompletionProvider.INSTANCE, + VirtualTypeCompletionProvider.INSTANCE + }; + + private ReferenceComponentCompletionProvider containerCompletionProvider = new ReferenceComponentCompletionProvider(ContainerFileBasedIndex.NAME); + private ReferenceComponentCompletionProvider blockCompletionProvider = new ReferenceComponentCompletionProvider(BlockFileBasedIndex.NAME); + + + public LayoutCompletionContributor() { + extend( + CompletionType.BASIC, + XmlHelperUtility.getTagAttributePattern("block", "class"), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + PsiElement psiElement = completionParameters.getOriginalPosition(); + for (CompletionProviderI completionProvider: typeCompletionProviders) { + completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); + } + } + } + ); + + extend( + CompletionType.BASIC, + XmlHelperUtility.getTagAttributePattern("referenceContainer", "name"), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + PsiElement psiElement = completionParameters.getOriginalPosition(); + completionResultSet.addAllElements(containerCompletionProvider.collectCompletionResult(psiElement)); + } + } + ); + + extend( + CompletionType.BASIC, + XmlHelperUtility.getTagAttributePattern("referenceBlock", "name"), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + PsiElement psiElement = completionParameters.getOriginalPosition(); + completionResultSet.addAllElements(blockCompletionProvider.collectCompletionResult(psiElement)); + } + } + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java new file mode 100644 index 000000000..decea3f6c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java @@ -0,0 +1,38 @@ +package com.magento.idea.magento2plugin.xml.layout.completion; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.indexing.ID; +import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class ReferenceComponentCompletionProvider implements CompletionProviderI { + private ID indexId; + + public ReferenceComponentCompletionProvider(ID indexId) { + this.indexId = indexId; + } + + @Override + public List collectCompletionResult(PsiElement psiElement) { + Collection keys = AbstractComponentNameFileBasedIndex.getAllKeys(indexId, psiElement.getProject()); + + List results = new ArrayList<>(); + for (String key: keys) { + results.add( + LookupElementBuilder.create(key).withIcon(PhpIcons.XML_TAG_ICON) + ); + } + + return results; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java index 1e0d67f61..72e46b785 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java @@ -57,6 +57,10 @@ public static List getComponentDeclarations(String componentName, String return results; } + public static Collection getAllKeys(ID id, Project project) { + return FileBasedIndex.getInstance().getAllKeys(id, project); + } + public static void collectComponentDeclarations(XmlTag parentTag, List results, String componentName, String componentType) { for (XmlTag childTag: parentTag.getSubTags()) { if (componentType.equals(childTag.getName()) && componentName.equals(childTag.getAttributeValue("name"))) { diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index 328872762..95b9ebe14 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -2,12 +2,12 @@ import com.intellij.psi.*; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; -import com.magento.idea.magento2plugin.xml.di.reference.provider.DiInstanceReferenceProvider; +import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.reference.fill.ComponentResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; @@ -20,8 +20,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelperUtility.getTagAttributeValuePattern("block", "class"), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } @@ -30,8 +30,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen psiReferenceRegistrar.registerReferenceProvider( XmlHelperUtility.getTagAttributeValuePattern("referenceBlock", "name"), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ new ComponentResultsFiller(BlockFileBasedIndex.NAME, "block") } ) @@ -39,8 +39,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen psiReferenceRegistrar.registerReferenceProvider( XmlHelperUtility.getTagAttributeValuePattern("referenceContainer", "name"), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ new ComponentResultsFiller(ContainerFileBasedIndex.NAME, "container") } ) diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java index 29821c175..c1edbe709 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java @@ -6,7 +6,7 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.ID; import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import java.util.Arrays; import java.util.List; @@ -14,7 +14,7 @@ /** * Created by dkvashnin on 11/18/15. */ -public class ComponentResultsFiller implements ResolveResultsFiller { +public class ComponentResultsFiller implements ReferenceResultsFiller { private ID indexId; private String componentType; @@ -24,7 +24,7 @@ public ComponentResultsFiller(ID indexId, String componentType) { } @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { List componentDeclarations = AbstractComponentNameFileBasedIndex .getComponentDeclarations( typeName, @@ -36,4 +36,8 @@ public void fillResults(PsiElement psiElement, List results, Stri ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); results.addAll(Arrays.asList(resolveResults)); } + + public void getVariants(PsiElement psiElement, List results) { + results.addAll(AbstractComponentNameFileBasedIndex.getAllKeys(indexId, psiElement.getProject())); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java index d1533b11d..ab84e86b7 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java @@ -4,7 +4,7 @@ import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; import com.magento.idea.magento2plugin.xml.observer.reference.util.ClassResultsFillerWrapper; import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsConfigurationFilesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import org.jetbrains.annotations.NotNull; /** @@ -16,7 +16,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen psiReferenceRegistrar.registerReferenceProvider( PhpPatternsHelper.STRING_METHOD_ARGUMENT, new EventReferenceProvider( - new ResolveResultsFiller[] { + new ReferenceResultsFiller[] { EventsConfigurationFilesResultsFiller.INSTANCE, ClassResultsFillerWrapper.INSTANCE } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java index 107597a7e..f88e4fa31 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java @@ -8,16 +8,16 @@ import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.ParameterList; import com.magento.idea.magento2plugin.xml.reference.TypeReference; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import org.jetbrains.annotations.NotNull; /** * Created by dkvashnin on 11/3/15. */ class EventReferenceProvider extends PsiReferenceProvider { - private final ResolveResultsFiller[] resultsFillers; + private final ReferenceResultsFiller[] resultsFillers; - public EventReferenceProvider(ResolveResultsFiller[] resultsFillers) { + public EventReferenceProvider(ReferenceResultsFiller[] resultsFillers) { this.resultsFillers = resultsFillers; } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java index 03632b96e..c43ef5f20 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java @@ -1,11 +1,11 @@ package com.magento.idea.magento2plugin.xml.observer.reference; import com.intellij.psi.*; -import com.magento.idea.magento2plugin.xml.di.reference.provider.DiInstanceReferenceProvider; +import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.observer.XmlHelper; import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsDeclarationsFilesResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; @@ -18,8 +18,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getTagAttributeValuePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } @@ -28,8 +28,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen psiReferenceRegistrar.registerReferenceProvider( XmlHelper.getTagAttributeValuePattern(XmlHelper.EVENT_TAG, XmlHelper.NAME_ATTRIBUTE), - new DiInstanceReferenceProvider( - new ResolveResultsFiller[]{ + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ EventsDeclarationsFilesResultsFiller.INSTANCE } ) diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java index 28da242c4..df1ab025b 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java @@ -6,7 +6,7 @@ import com.intellij.util.indexing.FileBasedIndex; import com.magento.idea.magento2plugin.xml.observer.index.EventObserverFileBasedIndex; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import java.util.List; @@ -15,11 +15,11 @@ /** * Created by dkvashnin on 11/3/15. */ -public class ClassResultsFillerWrapper implements ResolveResultsFiller { - public static final ResolveResultsFiller INSTANCE = new ClassResultsFillerWrapper(); +public class ClassResultsFillerWrapper implements ReferenceResultsFiller { + public static final ReferenceResultsFiller INSTANCE = new ClassResultsFillerWrapper(); @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { List> observersTypesList = FileBasedIndex.getInstance().getValues( EventObserverFileBasedIndex.NAME, typeName, @@ -28,8 +28,8 @@ public void fillResults(PsiElement psiElement, List results, Stri for (Set observerTypes: observersTypesList) { for (String type: observerTypes) { - ClassesResultsFiller.INSTANCE.fillResults(psiElement, results, type); - VirtualTypesResultsFiller.INSTANCE.fillResults(psiElement, results, type); + ClassesResultsFiller.INSTANCE.fillResolveResults(psiElement, results, type); + VirtualTypesResultsFiller.INSTANCE.fillResolveResults(psiElement, results, type); } } } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java index ee4d41d54..04aeae84d 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java @@ -9,7 +9,7 @@ import com.intellij.util.indexing.FileBasedIndex; import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; import com.magento.idea.magento2plugin.xml.observer.index.EventObserverFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import java.util.Collection; import java.util.List; @@ -17,11 +17,11 @@ /** * Created by dkvashnin on 11/3/15. */ -public class EventsConfigurationFilesResultsFiller implements ResolveResultsFiller { - public static final ResolveResultsFiller INSTANCE = new EventsConfigurationFilesResultsFiller(); +public class EventsConfigurationFilesResultsFiller implements ReferenceResultsFiller { + public static final ReferenceResultsFiller INSTANCE = new EventsConfigurationFilesResultsFiller(); @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { Collection containingFiles = FileBasedIndex .getInstance() .getContainingFiles( diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java index fe28dd9be..bf707e386 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java @@ -11,7 +11,7 @@ import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import java.util.Collection; import java.util.List; @@ -19,11 +19,11 @@ /** * Created by dkvashnin on 11/5/15. */ -public class EventsDeclarationsFilesResultsFiller implements ResolveResultsFiller { - public static final ResolveResultsFiller INSTANCE = new EventsDeclarationsFilesResultsFiller(); +public class EventsDeclarationsFilesResultsFiller implements ReferenceResultsFiller { + public static final ReferenceResultsFiller INSTANCE = new EventsDeclarationsFilesResultsFiller(); @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { Collection containingFiles = FileBasedIndex .getInstance() .getContainingFiles( diff --git a/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java b/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java index 02ffe9901..31dbf5563 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java @@ -4,7 +4,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReferenceBase; import com.intellij.psi.ResolveResult; -import com.magento.idea.magento2plugin.xml.reference.util.ResolveResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -16,15 +16,13 @@ public class TypeReference extends PsiPolyVariantReferenceBase { private final boolean greedy; - private ResolveResultsFiller[] resultsFillers; + private ReferenceResultsFiller[] resultsFillers; - public TypeReference(@NotNull PsiElement element, ResolveResultsFiller[] resultsFillers) { + public TypeReference(@NotNull PsiElement element, ReferenceResultsFiller[] resultsFillers) { this(element, resultsFillers, false); - - this.resultsFillers = resultsFillers; } - public TypeReference(@NotNull PsiElement element, ResolveResultsFiller[] resultsFillers, boolean greedy) { + public TypeReference(@NotNull PsiElement element, ReferenceResultsFiller[] resultsFillers, boolean greedy) { super(element); this.resultsFillers = resultsFillers; @@ -37,8 +35,8 @@ public ResolveResult[] multiResolve(boolean incompleteCode) { List resolveResults = new ArrayList<>(); String typeName = StringUtil.unquoteString(getElement().getText()); - for (ResolveResultsFiller resolveResultsFiller: resultsFillers) { - resolveResultsFiller.fillResults(getElement(), resolveResults, typeName); + for (ReferenceResultsFiller referenceResultsFiller : resultsFillers) { + referenceResultsFiller.fillResolveResults(getElement(), resolveResults, typeName); if (!greedy && resolveResults.size() > 0) { break; } diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java index ad0c86e48..944c973d8 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java @@ -12,13 +12,13 @@ /** * Created by dkvashnin on 11/3/15. */ -public class ClassesResultsFiller implements ResolveResultsFiller { - public static final ResolveResultsFiller INSTANCE = new ClassesResultsFiller(); +public class ClassesResultsFiller implements ReferenceResultsFiller { + public static final ReferenceResultsFiller INSTANCE = new ClassesResultsFiller(); private ClassesResultsFiller() {} @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); for (PhpClass phpClass : phpIndex.getClassesByFQN(PhpLangUtil.toFQN(typeName))) { diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java index b3373a7df..4b53a716c 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java @@ -12,13 +12,13 @@ /** * Created by dkvashnin on 11/3/15. */ -public class InterfacesResultsFiller implements ResolveResultsFiller { - public static final ResolveResultsFiller INSTANCE = new InterfacesResultsFiller(); +public class InterfacesResultsFiller implements ReferenceResultsFiller { + public static final ReferenceResultsFiller INSTANCE = new InterfacesResultsFiller(); private InterfacesResultsFiller() {} @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); for (PhpClass phpClass : phpIndex.getInterfacesByFQN(PhpLangUtil.toFQN(typeName))) { diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ResolveResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java similarity index 58% rename from src/com/magento/idea/magento2plugin/xml/reference/util/ResolveResultsFiller.java rename to src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java index 4376b6134..25bdbbf3c 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ResolveResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java @@ -8,6 +8,6 @@ /** * Created by dkvashnin on 11/3/15. */ -public interface ResolveResultsFiller { - public void fillResults(PsiElement psiElement, List results, String typeName); +public interface ReferenceResultsFiller { + public void fillResolveResults(PsiElement psiElement, List results, String typeName); } diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java index 9850dd6df..77edfd3b5 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java @@ -11,13 +11,13 @@ /** * Created by dkvashnin on 11/3/15. */ -public class VirtualTypesResultsFiller implements ResolveResultsFiller { - public static final ResolveResultsFiller INSTANCE = new VirtualTypesResultsFiller(); +public class VirtualTypesResultsFiller implements ReferenceResultsFiller { + public static final ReferenceResultsFiller INSTANCE = new VirtualTypesResultsFiller(); private VirtualTypesResultsFiller() {} @Override - public void fillResults(PsiElement psiElement, List results, String typeName) { + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { XmlAttributeValue[] virtualTypesByName = VirtualTypesNamesFileBasedIndex.getVirtualTypesByName( psiElement.getProject(), typeName, From a0a9d424d3ae9558e4110d7c65403b4b8b0a1ab2 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 20 Nov 2015 18:39:39 +0200 Subject: [PATCH 08/51] Fixed null pointer exeception as MethodPluginCollector as Method Psi element can have Null containing class --- .../linemarker/PluginLineMarkerProvider.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java index d93ba644c..16ce1f94f 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java @@ -58,7 +58,7 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll class PluginClassCache { private HashMap> classPluginsMap = new HashMap>(); - public List getPluginsForClass(PhpClass phpClass, String classFQN) { + public List getPluginsForClass(@NotNull PhpClass phpClass, @NotNull String classFQN) { List results = new ArrayList<>(); if (classPluginsMap.containsKey(classFQN)) { @@ -90,7 +90,7 @@ public List getPluginsForClass(PhpClass phpClass, String classFQN) { return results; } - public List getPluginsForClass(PhpClass phpClass) + public List getPluginsForClass(@NotNull PhpClass phpClass) { List pluginsForClass = getPluginsForClass(phpClass, phpClass.getPresentableFQN()); for (PhpClass parent: phpClass.getSupers()) { @@ -100,7 +100,7 @@ public List getPluginsForClass(PhpClass phpClass) return pluginsForClass; } - public List getPluginMethods(PhpClass plugin) { + public List getPluginMethods(@NotNull PhpClass plugin) { List methodList = new ArrayList(); for (Method method : plugin.getMethods()) { if (method.getAccess().isPublic()) { @@ -124,7 +124,7 @@ public List getPluginMethods(List plugins) { } interface PluginCollectorI { - public List collect(T psiElement); + public List collect(@NotNull T psiElement); } class ClassPluginCollector implements PluginCollectorI { @@ -135,7 +135,7 @@ public ClassPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClas } @Override - public List collect(PhpClass psiElement) { + public List collect(@NotNull PhpClass psiElement) { return pluginClassCache.getPluginsForClass(psiElement); } } @@ -148,10 +148,15 @@ public MethodPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginCla } @Override - public List collect(Method psiElement) { + public List collect(@NotNull Method psiElement) { List results = new ArrayList<>(); - List pluginsList = pluginClassCache.getPluginsForClass(psiElement.getContainingClass()); + PhpClass methodClass = psiElement.getContainingClass(); + if (methodClass == null) { + return results; + } + + List pluginsList = pluginClassCache.getPluginsForClass(methodClass); List pluginMethods = pluginClassCache.getPluginMethods(pluginsList); String classMethodName = WordUtils.capitalize(psiElement.getName()); From eece6fddb8807bc87a84093548e89625420d28c9 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 22 Nov 2015 17:40:36 +0200 Subject: [PATCH 09/51] Added Layout configuration line marker --- META-INF/plugin.xml | 1 + .../ClassConfigurationLineMarkerProvider.java | 31 +++++- .../php/linemarker/Collector.java | 13 +++ .../linemarker/PluginLineMarkerProvider.java | 8 +- .../ReferenceComponentCompletionProvider.java | 4 +- .../AbstractComponentNameFileBasedIndex.java | 49 ---------- .../index/BlockClassFileBasedIndex.java | 25 +++++ .../xml/layout/index/BlockFileBasedIndex.java | 5 +- .../layout/index/ContainerFileBasedIndex.java | 9 +- .../xml/layout/index/LayoutDataIndexer.java | 11 ++- .../layout/index/util/LayoutIndexUtility.java | 94 +++++++++++++++++++ .../reference/LayoutReferenceContributor.java | 7 +- .../reference/fill/BlockResultsFiller.java | 28 ++++++ .../fill/ComponentResultsFiller.java | 43 --------- .../fill/ContainerResultsFiller.java | 28 ++++++ 15 files changed, 238 insertions(+), 118 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/php/linemarker/Collector.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 317ce927b..3c02caaba 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -49,6 +49,7 @@ + diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java index dd06e5ad8..216e0b4fc 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java @@ -8,9 +8,11 @@ import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.Magento2Icons; import com.magento.idea.magento2plugin.xml.di.index.TypeConfigurationFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -18,6 +20,11 @@ * Created by dkvashnin on 11/15/15. */ public class ClassConfigurationLineMarkerProvider implements LineMarkerProvider { + public static List> COLLECTORS = new ArrayList>() {{ + add(new DiConfigurationCollector()); + add(new LayoutConfigurationCollector()); + }}; + @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { @@ -28,9 +35,12 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { for (PsiElement psiElement: list) { if (psiElement instanceof PhpClass) { - List results = TypeConfigurationFileBasedIndex - .getClassConfigurations((PhpClass) psiElement); - if (results == null || results.size() == 0) { + List results = new ArrayList(); + for (Collector collector: COLLECTORS) { + results.addAll(collector.collect((PhpClass) psiElement)); + } + + if (results.size() == 0) { continue; } @@ -44,3 +54,18 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll } } } + +class DiConfigurationCollector implements Collector { + @Override + public List collect(@NotNull PhpClass psiElement) { + return TypeConfigurationFileBasedIndex + .getClassConfigurations(psiElement); + } +} + +class LayoutConfigurationCollector implements Collector { + @Override + public List collect(@NotNull PhpClass psiElement) { + return LayoutIndexUtility.getBlockClassDeclarations(psiElement, psiElement.getProject()); + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/Collector.java b/src/com/magento/idea/magento2plugin/php/linemarker/Collector.java new file mode 100644 index 000000000..e78d400cb --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/linemarker/Collector.java @@ -0,0 +1,13 @@ +package com.magento.idea.magento2plugin.php.linemarker; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Created by dkvashnin on 11/20/15. + */ +interface Collector { + List collect(@NotNull T psiElement); +} diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java index 16ce1f94f..b38b79d53 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java @@ -123,11 +123,7 @@ public List getPluginMethods(List plugins) { } } -interface PluginCollectorI { - public List collect(@NotNull T psiElement); -} - -class ClassPluginCollector implements PluginCollectorI { +class ClassPluginCollector implements Collector { private PluginLineMarkerProvider.PluginClassCache pluginClassCache; public ClassPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { @@ -140,7 +136,7 @@ public List collect(@NotNull PhpClass psiElement) { } } -class MethodPluginCollector implements PluginCollectorI { +class MethodPluginCollector implements Collector { private PluginLineMarkerProvider.PluginClassCache pluginClassCache; public MethodPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java index decea3f6c..1cbf9fda9 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java @@ -6,7 +6,7 @@ import com.intellij.util.indexing.ID; import com.jetbrains.php.PhpIcons; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; -import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; import java.util.ArrayList; import java.util.Collection; @@ -24,7 +24,7 @@ public ReferenceComponentCompletionProvider(ID indexId) { @Override public List collectCompletionResult(PsiElement psiElement) { - Collection keys = AbstractComponentNameFileBasedIndex.getAllKeys(indexId, psiElement.getProject()); + Collection keys = LayoutIndexUtility.getAllKeys(indexId, psiElement.getProject()); List results = new ArrayList<>(); for (String key: keys) { diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java index 72e46b785..60b3b3b52 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java @@ -22,55 +22,6 @@ public abstract class AbstractComponentNameFileBasedIndex extends ScalarIndexExtension { private EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); - @NotNull - @Override - public DataIndexer getIndexer() { - return new LayoutDataIndexer(getComponentName()); - } - - protected abstract String getComponentName(); - - public static List getComponentDeclarations(String componentName, String componentType, ID id, Project project) { - List results = new ArrayList(); - Collection containingFiles = FileBasedIndex.getInstance() - .getContainingFiles( - id, - componentName, - GlobalSearchScope.allScope(project) - ); - PsiManager psiManager = PsiManager.getInstance(project); - - for (VirtualFile virtualFile: containingFiles) { - XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); - if (xmlFile == null) { - continue; - } - - XmlTag rootTag = xmlFile.getRootTag(); - if (rootTag == null) { - continue; - } - collectComponentDeclarations(rootTag, results, componentName, componentType); - } - - - return results; - } - - public static Collection getAllKeys(ID id, Project project) { - return FileBasedIndex.getInstance().getAllKeys(id, project); - } - - public static void collectComponentDeclarations(XmlTag parentTag, List results, String componentName, String componentType) { - for (XmlTag childTag: parentTag.getSubTags()) { - if (componentType.equals(childTag.getName()) && componentName.equals(childTag.getAttributeValue("name"))) { - results.add(childTag); - } else if(childTag.getSubTags().length > 0 ) { - collectComponentDeclarations(childTag, results, componentName, componentType); - } - } - } - @NotNull @Override public KeyDescriptor getKeyDescriptor() { diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java new file mode 100644 index 000000000..cfc9766f2 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java @@ -0,0 +1,25 @@ +package com.magento.idea.magento2plugin.xml.layout.index; + +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/20/15. + */ +public class BlockClassFileBasedIndex extends AbstractComponentNameFileBasedIndex { + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.layout.index.block_class"); + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new LayoutDataIndexer("block", "class"); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java index 2c3844bd6..7c2063309 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java @@ -15,8 +15,9 @@ public ID getName() { return NAME; } + @NotNull @Override - protected String getComponentName() { - return "block"; + public DataIndexer getIndexer() { + return new LayoutDataIndexer("block", "name"); } } diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java index e4b10d12a..816b4420b 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java @@ -1,10 +1,6 @@ package com.magento.idea.magento2plugin.xml.layout.index; -import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.indexing.*; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; import org.jetbrains.annotations.NotNull; /** @@ -19,8 +15,9 @@ public ID getName() { return NAME; } + @NotNull @Override - protected String getComponentName() { - return "container"; + public DataIndexer getIndexer() { + return new LayoutDataIndexer("block", "name"); } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java b/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java index a7d0151a1..85cf566df 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java @@ -6,6 +6,7 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.DataIndexer; import com.intellij.util.indexing.FileContent; +import com.jetbrains.php.lang.PhpLangUtil; import org.jetbrains.annotations.NotNull; import java.util.HashMap; @@ -16,9 +17,11 @@ */ public class LayoutDataIndexer implements DataIndexer { private String indexTag; + private String indexAttribute; - public LayoutDataIndexer(String indexTag) { + public LayoutDataIndexer(String indexTag, String indexAttribute) { this.indexTag = indexTag; + this.indexAttribute = indexAttribute; } @NotNull @@ -47,9 +50,9 @@ public Map map(@NotNull FileContent fileContent) { private void fillResultMap(XmlTag parentTag, Map resultMap) { for (XmlTag childTag: parentTag.getSubTags()) { if (indexTag.equals(childTag.getName())) { - String blockName = childTag.getAttributeValue("name"); - if (blockName != null) { - resultMap.put(blockName, null); + String attributeValue = childTag.getAttributeValue(this.indexAttribute); + if (attributeValue != null) { + resultMap.put(PhpLangUtil.toPresentableFQN(attributeValue), null); } } fillResultMap(childTag, resultMap); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java new file mode 100644 index 000000000..5d20de1e0 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java @@ -0,0 +1,94 @@ +package com.magento.idea.magento2plugin.xml.layout.index.util; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.ID; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.xml.layout.index.BlockClassFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/20/15. + */ +public class LayoutIndexUtility { + public static List getComponentDeclarations(String componentValue, String componentType, ID id, Project project, ComponentMatcher componentMatcher) { + List results = new ArrayList(); + Collection containingFiles = FileBasedIndex.getInstance() + .getContainingFiles( + id, + componentValue, + GlobalSearchScope.allScope(project) + ); + PsiManager psiManager = PsiManager.getInstance(project); + + for (VirtualFile virtualFile: containingFiles) { + XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); + if (xmlFile == null) { + continue; + } + + XmlTag rootTag = xmlFile.getRootTag(); + if (rootTag == null) { + continue; + } + collectComponentDeclarations(rootTag, results, componentValue, componentType, componentMatcher); + } + + return results; + } + + public static Collection getAllKeys(ID id, Project project) { + return FileBasedIndex.getInstance().getAllKeys(id, project); + } + + public static void collectComponentDeclarations(XmlTag parentTag, List results, String componentName, String componentType, ComponentMatcher componentMatcher) { + for (XmlTag childTag: parentTag.getSubTags()) { + if (componentType.equals(childTag.getName()) && componentMatcher.matches(componentName, childTag)) { + results.add(childTag); + } else if(childTag.getSubTags().length > 0 ) { + collectComponentDeclarations(childTag, results, componentName, componentType, componentMatcher); + } + } + } + + public static List getBlockDeclarations(String componentName, Project project) { + return getComponentDeclarations(componentName, "block", BlockFileBasedIndex.NAME, project, new NameComponentMatcher()); + } + + public static List getContainerDeclarations(String componentName, Project project) { + return getComponentDeclarations(componentName, "container", BlockFileBasedIndex.NAME, project, new NameComponentMatcher()); + } + + public static List getBlockClassDeclarations(PhpClass phpClass, Project project) { + String className = phpClass.getPresentableFQN(); + + return getComponentDeclarations(className, "block", BlockClassFileBasedIndex.NAME, project, new ClassComponentMatcher()); + } +} + +interface ComponentMatcher { + boolean matches(String value, XmlTag tag); +} + +class NameComponentMatcher implements ComponentMatcher { + @Override + public boolean matches(String value, XmlTag tag) { + return value.equals(tag.getAttributeValue("name")); + } +} + +class ClassComponentMatcher implements ComponentMatcher { + @Override + public boolean matches(String value, XmlTag tag) { + return value.equals(tag.getAttributeValue("class")); + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index 95b9ebe14..7d01167ce 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -5,7 +5,8 @@ import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.reference.fill.ComponentResultsFiller; +import com.magento.idea.magento2plugin.xml.layout.reference.fill.BlockResultsFiller; +import com.magento.idea.magento2plugin.xml.layout.reference.fill.ContainerResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; @@ -32,7 +33,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelperUtility.getTagAttributeValuePattern("referenceBlock", "name"), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - new ComponentResultsFiller(BlockFileBasedIndex.NAME, "block") + new BlockResultsFiller() } ) ); @@ -41,7 +42,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelperUtility.getTagAttributeValuePattern("referenceContainer", "name"), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - new ComponentResultsFiller(ContainerFileBasedIndex.NAME, "container") + new ContainerResultsFiller() } ) ); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java new file mode 100644 index 000000000..1071ef103 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java @@ -0,0 +1,28 @@ +package com.magento.idea.magento2plugin.xml.layout.reference.fill; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.xml.XmlTag; +import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by dkvashnin on 11/20/15. + */ +public class BlockResultsFiller implements ReferenceResultsFiller { + @Override + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { + List componentDeclarations = LayoutIndexUtility + .getBlockDeclarations( + typeName, + psiElement.getProject() + ); + + ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); + results.addAll(Arrays.asList(resolveResults)); + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java deleted file mode 100644 index c1edbe709..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ComponentResultsFiller.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.reference.fill; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.indexing.ID; -import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; - -import java.util.Arrays; -import java.util.List; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class ComponentResultsFiller implements ReferenceResultsFiller { - private ID indexId; - private String componentType; - - public ComponentResultsFiller(ID indexId, String componentType) { - this.indexId = indexId; - this.componentType = componentType; - } - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - List componentDeclarations = AbstractComponentNameFileBasedIndex - .getComponentDeclarations( - typeName, - componentType, - indexId, - psiElement.getProject() - ); - - ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); - results.addAll(Arrays.asList(resolveResults)); - } - - public void getVariants(PsiElement psiElement, List results) { - results.addAll(AbstractComponentNameFileBasedIndex.getAllKeys(indexId, psiElement.getProject())); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java new file mode 100644 index 000000000..3cf4d1324 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java @@ -0,0 +1,28 @@ +package com.magento.idea.magento2plugin.xml.layout.reference.fill; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.xml.XmlTag; +import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; + +import java.util.Arrays; +import java.util.List; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class ContainerResultsFiller implements ReferenceResultsFiller { + @Override + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { + List componentDeclarations = LayoutIndexUtility + .getContainerDeclarations( + typeName, + psiElement.getProject() + ); + + ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); + results.addAll(Arrays.asList(resolveResults)); + } +} From 8b35c5fc93a0530f2969dae1a5de1ca5e1914952 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 22 Nov 2015 20:01:31 +0200 Subject: [PATCH 10/51] Added reference/completion for block, move, remove, update layout tags --- .../xml/layout/LayoutUtility.java | 50 +++++++++++++++++++ .../LayoutCompletionContributor.java | 36 ++++++++++++- .../AbstractComponentNameFileBasedIndex.java | 4 +- .../reference/LayoutReferenceContributor.java | 35 ++++++++++++- 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java diff --git a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java new file mode 100644 index 000000000..79015a2f6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java @@ -0,0 +1,50 @@ +package com.magento.idea.magento2plugin.xml.layout; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.xml.XmlFile; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/22/15. + */ +public class LayoutUtility { + public static boolean isLayoutFile(VirtualFile virtualFile) { + VirtualFile parent = virtualFile.getParent(); + return virtualFile.getFileType() == XmlFileType.INSTANCE && parent.isDirectory() && parent.getName().endsWith("layout"); + } + + public static List getLayoutFiles(Project project, @Nullable String fileName) { + List results = new ArrayList(); + Collection xmlFiles = FilenameIndex.getAllFilesByExt(project, "xml"); + + PsiManager psiManager = PsiManager.getInstance(project); + for (VirtualFile xmlFile: xmlFiles) { + if (LayoutUtility.isLayoutFile(xmlFile)) { + if (fileName != null && !xmlFile.getNameWithoutExtension().equals(fileName)) { + continue; + } + + PsiFile file = psiManager.findFile(xmlFile); + if (file != null) { + results.add((XmlFile)file); + } + } + } + + return results; + } + + public static List getLayoutFiles(Project project) { + return getLayoutFiles(project, null); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java index 37e314488..1056e83d0 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java @@ -2,20 +2,26 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.project.Project; +import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; +import com.intellij.util.PlatformIcons; import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.xml.util.XmlIconProvider; import com.jetbrains.php.PhpIcons; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; +import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import org.jetbrains.annotations.NotNull; import java.util.Collection; +import java.util.stream.Collectors; /** * Created by dkvashnin on 11/18/15. @@ -59,7 +65,16 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters extend( CompletionType.BASIC, - XmlHelperUtility.getTagAttributePattern("referenceBlock", "name"), + XmlPatterns.or( + XmlHelperUtility.getTagAttributePattern("referenceBlock", "name"), + XmlHelperUtility.getTagAttributePattern("block", "before"), + XmlHelperUtility.getTagAttributePattern("block", "after"), + XmlHelperUtility.getTagAttributePattern("remove", "name"), + XmlHelperUtility.getTagAttributePattern("move", "element"), + XmlHelperUtility.getTagAttributePattern("move", "destination"), + XmlHelperUtility.getTagAttributePattern("move", "before"), + XmlHelperUtility.getTagAttributePattern("move", "after") + ), new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { @@ -68,5 +83,24 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters } } ); + + extend( + CompletionType.BASIC, + XmlHelperUtility.getTagAttributePattern("update", "handle"), + new CompletionProvider() { + @Override + protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + PsiElement psiElement = completionParameters.getOriginalPosition(); + Project project = psiElement.getProject(); + + completionResultSet.addAllElements( + LayoutUtility.getLayoutFiles(project) + .stream() + .map(e -> LookupElementBuilder.create(e.getVirtualFile().getNameWithoutExtension())) + .collect(Collectors.toList()) + ); + } + } + ); } } diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java index 60b3b3b52..6cb598d14 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java @@ -10,6 +10,7 @@ import com.intellij.util.indexing.*; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -34,8 +35,7 @@ public FileBasedIndex.InputFilter getInputFilter() { return new FileBasedIndex.InputFilter() { @Override public boolean acceptInput(@NotNull VirtualFile virtualFile) { - VirtualFile parent = virtualFile.getParent(); - return virtualFile.getFileType() == XmlFileType.INSTANCE && parent.isDirectory() && parent.getName().endsWith("layout"); + return LayoutUtility.isLayoutFile(virtualFile); } }; } diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index 7d01167ce..dfcd9b164 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -1,8 +1,13 @@ package com.magento.idea.magento2plugin.xml.layout.reference; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.patterns.XmlPatterns; import com.intellij.psi.*; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.util.indexing.FileBasedIndex; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; +import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.reference.fill.BlockResultsFiller; @@ -12,6 +17,10 @@ import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + /** * Created by dkvashnin on 11/18/15. */ @@ -30,7 +39,16 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen ); psiReferenceRegistrar.registerReferenceProvider( - XmlHelperUtility.getTagAttributeValuePattern("referenceBlock", "name"), + XmlPatterns.or( + XmlHelperUtility.getTagAttributeValuePattern("referenceBlock", "name"), + XmlHelperUtility.getTagAttributeValuePattern("block", "before"), + XmlHelperUtility.getTagAttributeValuePattern("block", "after"), + XmlHelperUtility.getTagAttributeValuePattern("remove", "name"), + XmlHelperUtility.getTagAttributeValuePattern("move", "element"), + XmlHelperUtility.getTagAttributeValuePattern("move", "destination"), + XmlHelperUtility.getTagAttributeValuePattern("move", "before"), + XmlHelperUtility.getTagAttributeValuePattern("move", "after") + ), new XmlReferenceProvider( new ReferenceResultsFiller[]{ new BlockResultsFiller() @@ -46,5 +64,20 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen } ) ); + + psiReferenceRegistrar.registerReferenceProvider( + XmlHelperUtility.getTagAttributeValuePattern("update", "handle"), + new XmlReferenceProvider( + new ReferenceResultsFiller[]{ + (psiElement, results, typeName) -> results.addAll( + Arrays.asList( + PsiElementResolveResult.createResults( + LayoutUtility.getLayoutFiles(psiElement.getProject(), typeName) + ) + ) + ) + } + ) + ); } } From 4adbad13975dd84a4c28b69140223e9d19cc141a Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 22 Nov 2015 20:29:27 +0200 Subject: [PATCH 11/51] Version change to 0.0.9 --- META-INF/plugin.xml | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 3c02caaba..cb9bc4390 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,21 +1,48 @@ com.magento.idea.magento2plugin Magento2 - 0.0.8 - Magento + 0.0.9 + Dmytro Kvashnin - v0.0.6 Implemented reference and completion support for virtual types/classes/arguments in DI configuration -
- v0.0.7 References: to configuration and observers (classes or virtualType), to observers from configuration, to event dispatch from configuration -
- v0.0.8 Line marker reference for php class/interface to: XML(di.xml) configuration, Plugins +

0.0.9

+
    +
  • Added Reference and completion support for layouts
    + - block: class, before, after
    + - referenceBlock: name
    + - move: element, destination, before, after
    + - remove: name
    + - update: handle
    + - referenceContainer: name
  • +
  • Line marker reference for php class to Layout configuration
  • +
+ +

0.0.8

+
    +
  • Added Line marker reference for php class/interface to DI configuration
  • +
  • Added Line marker reference to plugins
  • +
+ +

0.0.7

+
    +
  • Added reference to configuration and observers (classes or virtualType)
  • +
  • Added reference to observers from configuration +
  • Added reference to event dispatch from configuration
  • +
+ +

0.0.6

+
    +
  • Added reference and completion support for virtual types/classes/arguments in DI configuration
  • +
+ +

0.0.5

+
    +
  • Added reference support for classes/interfaces in DI configuration
  • +
]]>
From dceeeaa86e133bdab0afe63250fa1762b2e39304 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 27 Nov 2015 23:52:23 +0200 Subject: [PATCH 12/51] Added argument name resolution for virtualType --- .../VirtualTypesNamesFileBasedIndex.java | 39 +++++++++++++++++-- .../provider/resolver/TypeTagResolver.java | 8 ++-- .../resolver/VirtualTypeTagResolver.java | 18 +++++++-- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java index 6da1c3390..d18be7d93 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java @@ -18,6 +18,7 @@ import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; +import com.jetbrains.php.lang.psi.elements.PhpClass; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -30,15 +31,17 @@ public class VirtualTypesNamesFileBasedIndex extends FileBasedIndexExtension allKeys = FileBasedIndex.getInstance().getAllKeys(NAME, project); return ArrayUtil.toStringArray(allKeys); } - public static XmlAttributeValue[] getVirtualTypesByName(final Project project, final String name, final GlobalSearchScope scope) { + public static XmlAttributeValue[] getVirtualTypesByName(final Project project, final String virtualTypeName, final GlobalSearchScope scope) { List xmlAttributeList = new ArrayList(); - Collection virtualFileCollection = FileBasedIndex.getInstance().getContainingFiles(NAME, name, scope); + Collection virtualFileCollection = FileBasedIndex.getInstance().getContainingFiles(NAME, virtualTypeName, scope); PsiManager psiManager = PsiManager.getInstance(project); for (VirtualFile virtualFile: virtualFileCollection) { @@ -56,7 +59,7 @@ public static XmlAttributeValue[] getVirtualTypesByName(final Project project, f if (typeTag.getName().equals("virtualType")) { XmlAttribute nameAttribute = typeTag.getAttribute("name"); if (nameAttribute != null) { - if (nameAttribute.getValue() != null && nameAttribute.getValue().equals(name)) + if (nameAttribute.getValue() != null && nameAttribute.getValue().equals(virtualTypeName)) xmlAttributeList.add(nameAttribute.getValueElement()); } @@ -67,6 +70,36 @@ public static XmlAttributeValue[] getVirtualTypesByName(final Project project, f return xmlAttributeList.toArray(new XmlAttributeValue[xmlAttributeList.size()]); } + public static String getParentTypeName(final Project project, String virtualTypeName) { + List originNames = FileBasedIndex.getInstance().getValues(NAME, virtualTypeName, GlobalSearchScope.allScope(project)); + + if (originNames.size() > 0) { + return originNames.get(0); + } + + return null; + } + + public static String getSuperParentTypeName(final Project project, String inputChildTypeName) { + String superName = null; + String childTypeName = inputChildTypeName; + + for (int index = 0; index < SUPER_MAX_NESTING_LEVEL; index++) { + superName = getParentTypeName(project, childTypeName); + + if (superName == null) { + superName = childTypeName; + break; + } + + childTypeName = superName; + } + + return superName == null + ? (!inputChildTypeName.equals(childTypeName) ? childTypeName : null) + : superName; + } + @NotNull @Override public ID getName() { diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java index b61e70322..4528cf864 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java @@ -1,6 +1,7 @@ package com.magento.idea.magento2plugin.xml.di.reference.provider.resolver; import com.intellij.psi.xml.XmlTag; +import com.magento.idea.magento2plugin.xml.di.XmlHelper; import org.jetbrains.annotations.Nullable; /** @@ -9,19 +10,16 @@ public class TypeTagResolver extends ClassNameResolver { public static final TypeTagResolver INSTANCE = new TypeTagResolver(); - private static final String TAG_NAME = "type"; - private static final String ATTRIBUTE_NAME = "name"; - private TypeTagResolver() {} @Nullable @Override public String resolveTypeName(XmlTag xmlTag) { - return xmlTag.getAttributeValue(ATTRIBUTE_NAME); + return xmlTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); } @Override protected String getTagName() { - return TAG_NAME; + return XmlHelper.TYPE_TAG; } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java index cb631088f..d40a5a246 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java @@ -1,6 +1,9 @@ package com.magento.idea.magento2plugin.xml.di.reference.provider.resolver; import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.xml.di.XmlHelper; +import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; import org.jetbrains.annotations.Nullable; /** @@ -9,18 +12,25 @@ public class VirtualTypeTagResolver extends ClassNameResolver { public static final VirtualTypeTagResolver INSTANCE = new VirtualTypeTagResolver(); - private static final String TAG_NAME = "virtualType"; - private VirtualTypeTagResolver() {} @Nullable @Override public String resolveTypeName(XmlTag xmlTag) { - return xmlTag.getAttributeValue("type"); + String parentTypeName = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); + + if (parentTypeName == null) { + return parentTypeName; + } + + String superParentName = VirtualTypesNamesFileBasedIndex.getSuperParentTypeName(xmlTag.getProject(), parentTypeName); + + return superParentName == null ? parentTypeName : superParentName; + } @Override protected String getTagName() { - return TAG_NAME; + return XmlHelper.VIRTUAL_TYPE_TAG; } } From 65a733a999439739a1ebcb5caef223c8a8da9ce8 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 6 Dec 2015 01:10:02 +0200 Subject: [PATCH 13/51] Added Inspection for not API code usage --- META-INF/plugin.xml | 9 +- .../index/ModulePackageFileBasedIndex.java | 87 +++++++++++ .../php/inspections/MagentoApiInspection.java | 79 ++++++++++ .../php/module/ComposerPackageModel.java | 25 +++ .../php/module/ComposerPackageModelImpl.java | 115 ++++++++++++++ .../php/module/MagentoModule.java | 25 +++ .../php/module/ModuleManager.java | 142 ++++++++++++++++++ .../magento2plugin/php/module/ModuleUtil.java | 8 + .../MagentoApiInspection.html | 5 + 9 files changed, 493 insertions(+), 2 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java create mode 100644 src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/MagentoModule.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/ModuleManager.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java create mode 100644 src/inspectionDescriptions/MagentoApiInspection.html diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index cb9bc4390..79314802a 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -67,8 +67,6 @@ - - @@ -77,9 +75,16 @@ + + + diff --git a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java new file mode 100644 index 000000000..0ad4c0fe4 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java @@ -0,0 +1,87 @@ +package com.magento.idea.magento2plugin.php.index; + +import com.intellij.json.JsonFileType; +import com.intellij.json.psi.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.indexing.*; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; +import com.magento.idea.magento2plugin.php.module.ComposerPackageModelImpl; +import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by dkvashnin on 12/3/15. + */ +public class ModulePackageFileBasedIndex extends ScalarIndexExtension { + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.php.index.module"); + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new DataIndexer() { + @NotNull + @Override + public Map map(@NotNull FileContent fileContent) { + Map map = new HashMap<>(); + JsonFile jsonFile = (JsonFile)fileContent.getPsiFile(); + + JsonObject jsonObject = PsiTreeUtil.getChildOfType(jsonFile, JsonObject.class); + ComposerPackageModel composerObject = new ComposerPackageModelImpl(jsonObject); + + if (!"magento2-module".equals(composerObject.getType())) { + return map; + } + + String name = composerObject.getName(); + + if (name != null) { + map.put(name, null); + } + + + return map; + } + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return new EnumeratorStringDescriptor(); + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return new FileBasedIndex.InputFilter() { + @Override + public boolean acceptInput(@NotNull VirtualFile virtualFile) { + return virtualFile.getFileType().equals(JsonFileType.INSTANCE) && virtualFile.getName().equals("composer.json"); + } + }; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 0; + } +} diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java new file mode 100644 index 000000000..a8d13f5d9 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -0,0 +1,79 @@ +package com.magento.idea.magento2plugin.php.inspections; + +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment; +import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag; +import com.jetbrains.php.lang.inspections.PhpInspection; +import com.jetbrains.php.lang.psi.elements.*; +import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; +import com.magento.idea.magento2plugin.php.module.MagentoModule; +import com.magento.idea.magento2plugin.php.module.ModuleManager; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 12/4/15. + */ +public class MagentoApiInspection extends PhpInspection { + public static final String API_TAG = "@api"; + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean isOnTheFly) { + return new PhpElementVisitor() { + @Override + public void visitPhpMethodReference(MethodReference reference) { + MagentoApiInspection.check(reference, "Method #ref is not in module API", problemsHolder); + } + + @Override + public void visitPhpClassReference(ClassReference classReference) { + MagentoApiInspection.check(classReference, "Class #ref is not in module API", problemsHolder); + } + }; + } + + private static void check(PhpReference reference, String desc, ProblemsHolder holder) { + PsiElement element = reference.resolve(); + + if(element instanceof PhpNamedElement) { + MagentoModule referenceSourceModule = getMagentoModule((PhpPsiElement) element); + MagentoModule currentModule = getMagentoModule((PhpPsiElement) (reference.getElement())); + + + if (!areDifferentModules(referenceSourceModule, currentModule)) { + return; + } + + PhpDocComment docComment = ((PhpNamedElement)element).getDocComment(); + if(docComment == null) { + holder.registerProblem(reference, desc, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + return; + } + + PhpDocTag[] elements = docComment.getTagElementsByName(API_TAG); + if(elements.length == 0) { + holder.registerProblem(reference, desc, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + } + } + + private static MagentoModule getMagentoModule(PhpPsiElement element) { + ModuleManager moduleManager = ModuleManager.getInstance(element.getProject()); + return moduleManager.getModuleForFile(element.getContainingFile()); + } + + private static boolean areDifferentModules(MagentoModule magentoModule1, MagentoModule magentoModule2) { + if (magentoModule1 == null) { + return false; + } + + if (magentoModule2 == null) { + return false; + } + + return magentoModule1 != magentoModule2; + } +} diff --git a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java new file mode 100644 index 000000000..de05df6ee --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java @@ -0,0 +1,25 @@ +package com.magento.idea.magento2plugin.php.module; + +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +/** + * Created by dkvashnin on 12/5/15. + */ +public interface ComposerPackageModel { + @Nullable + String getName(); + + @Nullable + String getType(); + + @Nullable + String getVersion(); + + @Nullable + String[] getAutoloadFiles(); + + @Nullable + Map getAutoloadPsr4(); +} diff --git a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java new file mode 100644 index 000000000..47c6179b0 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java @@ -0,0 +1,115 @@ +package com.magento.idea.magento2plugin.php.module; + +import com.intellij.json.psi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Created by dkvashnin on 12/5/15. + */ +public class ComposerPackageModelImpl implements ComposerPackageModel { + private JsonObject sourceComposerJson; + + public static final String NAME = "name"; + public static final String TYPE = "type"; + public static final String VERSION = "version"; + public static final String AUTOLOAD = "autoload"; + public static final String PSR4 = "psr4"; + public static final String FILES = "file"; + + + public ComposerPackageModelImpl(JsonObject sourceComposerJson) { + this.sourceComposerJson = sourceComposerJson; + } + + @Nullable + @Override + public String getName() { + return getStringPropertyValue(NAME); + } + + @Nullable + @Override + public String getType() { + return getStringPropertyValue(TYPE); + } + + @Nullable + @Override + public String getVersion() { + return getStringPropertyValue(VERSION); + } + + @Nullable + @Override + public String[] getAutoloadFiles() { + JsonObject autoloadObject = getPropertyValueOfType(AUTOLOAD, JsonObject.class); + if (autoloadObject != null) { + JsonArray jsonArray = getPropertyValueOfType(FILES, JsonArray.class); + if (jsonArray != null) { + List files = jsonArray.getValueList() + .stream() + .filter(value -> value instanceof JsonStringLiteral) + .map(v -> ((JsonStringLiteral) v).getValue()) + .collect(Collectors.toList()); + + return files.size() > 0 ? files.toArray(new String[files.size()]) : null; + } + } + + return null; + } + + @Nullable + @Override + public Map getAutoloadPsr4() { + JsonObject autoloadObject = getPropertyValueOfType(AUTOLOAD, JsonObject.class); + if (autoloadObject != null) { + JsonObject jsonObject = getPropertyValueOfType(PSR4, JsonObject.class); + if (jsonObject != null) { + Map map = new HashMap(); + for (JsonProperty property: jsonObject.getPropertyList()) { + JsonValue value = property.getValue(); + + if (value != null && value instanceof JsonStringLiteral) { + map.put(property.getName(), ((JsonStringLiteral) value).getValue()); + } + } + + return map.size() > 0 ? map : null; + } + } + + return null; + } + + @Nullable + public T getPropertyValueOfType(String propertyName, @NotNull Class aClass) { + JsonProperty property = sourceComposerJson.findProperty(propertyName); + if (property == null) { + return null; + } + JsonValue value = property.getValue(); + if (value != null && aClass.isInstance(value)) { + return aClass.cast(value); + } + + return null; + } + + @Nullable + private String getStringPropertyValue(String propertyName) { + JsonStringLiteral stringLiteral = getPropertyValueOfType(propertyName, JsonStringLiteral.class); + + if (stringLiteral != null) { + return stringLiteral.getValue(); + } + + return null; + } +} diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java new file mode 100644 index 000000000..0cd955001 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java @@ -0,0 +1,25 @@ +package com.magento.idea.magento2plugin.php.module; + +import com.intellij.psi.PsiFile; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * Created by dkvashnin on 12/5/15. + */ +public interface MagentoModule { + @Nullable + String getMagentoName(); + + @Nullable + List getMagentoDependencies(); + + @Nullable + ComposerPackageModel getComposerModel(); + + boolean isFileInContext(PsiFile psiFile); + + boolean isClassInContext(PhpClass phpClass); +} diff --git a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java b/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java new file mode 100644 index 000000000..10fd296a8 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java @@ -0,0 +1,142 @@ +package com.magento.idea.magento2plugin.php.module; + +import com.intellij.json.psi.JsonFile; +import com.intellij.json.psi.JsonObject; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.php.index.ModulePackageFileBasedIndex; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Created by dkvashnin on 12/5/15. + */ +public class ModuleManager { + private Map modules = new HashMap<>(); + private long cacheStartTime; + private static final int CACHE_LIFE_TIME = 20000; + private static ModuleManager moduleManager; + private Project project; + + private ModuleManager(Project project){ + this.project = project; + } + + public static ModuleManager getInstance(Project project) { + if (moduleManager == null) { + moduleManager = new ModuleManager(project); + } + return moduleManager; + } + + synchronized public Collection getModules() { + if (cacheStartTime + CACHE_LIFE_TIME < System.currentTimeMillis()) { + flushModules(); + loadModules(); + cacheStartTime = System.currentTimeMillis(); + } + + return modules.values(); + } + + @Nullable + public MagentoModule getModuleForFile(PsiFile psiFile) { + for (MagentoModule magentoModule: this.getModules()) { + if (magentoModule.isFileInContext(psiFile)) { + return magentoModule; + } + } + + return null; + } + + public void flushModules() { + modules = new HashMap<>(); + } + + private void loadModules() { + Collection packages = FileBasedIndex.getInstance().getAllKeys(ModulePackageFileBasedIndex.NAME, this.project); + PsiManager psiManager = PsiManager.getInstance(this.project); + for (String packageName: packages) { + if (modules.containsKey(packageName)) { + continue; + } + + + Collection containingFiles = FileBasedIndex.getInstance() + .getContainingFiles(ModulePackageFileBasedIndex.NAME, packageName, GlobalSearchScope.allScope(this.project)); + + if (containingFiles.size() > 0) { + VirtualFile configurationFile = containingFiles.iterator().next(); + + PsiFile psiFile = psiManager.findFile(configurationFile); + if (psiFile != null && psiFile instanceof JsonFile) { + JsonObject jsonObject = PsiTreeUtil.getChildOfType((JsonFile) psiFile, JsonObject.class); + modules.put( + packageName, + new MagentoModuleImpl(new ComposerPackageModelImpl(jsonObject), psiFile.getContainingDirectory()) + ); + } + } + } + } +} + +/** + * Created by dkvashnin on 12/5/15. + */ +class MagentoModuleImpl implements MagentoModule { + private ComposerPackageModel composerPackageModel; + private PsiDirectory directory; + + public MagentoModuleImpl(ComposerPackageModel composerPackageModel, PsiDirectory directory) { + + this.composerPackageModel = composerPackageModel; + this.directory = directory; + } + + @Nullable + @Override + public String getMagentoName() { + return null; + } + + @Nullable + @Override + public List getMagentoDependencies() { + return null; + } + + @Nullable + @Override + public ComposerPackageModel getComposerModel() { + return composerPackageModel; + } + + @Override + public boolean isFileInContext(PsiFile psiFile) { + PsiDirectory containingDirectory = psiFile.getContainingDirectory(); + while (containingDirectory != null) { + if (containingDirectory.getManager().areElementsEquivalent(containingDirectory, directory)) { + return true; + } + + containingDirectory = containingDirectory.getParentDirectory(); + } + + return false; + } + + @Override + public boolean isClassInContext(PhpClass phpClass) { + return false; + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java b/src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java new file mode 100644 index 000000000..b1dddc9fa --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java @@ -0,0 +1,8 @@ +package com.magento.idea.magento2plugin.php.module; + +/** + * Created by dkvashnin on 12/5/15. + */ +public class ModuleUtil { + +} diff --git a/src/inspectionDescriptions/MagentoApiInspection.html b/src/inspectionDescriptions/MagentoApiInspection.html new file mode 100644 index 000000000..02a3c1db6 --- /dev/null +++ b/src/inspectionDescriptions/MagentoApiInspection.html @@ -0,0 +1,5 @@ + + +Non Module public API usage. + + \ No newline at end of file From 5723407083e517c55f3e329bcb2c1488bf23bfc5 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Wed, 9 Dec 2015 15:02:26 +0200 Subject: [PATCH 14/51] Modules tool view --- META-INF/plugin.xml | 7 ++ .../idea/magento2plugin/Magento2Icons.java | 1 + .../php/inspections/MagentoApiInspection.java | 68 +++++++++-------- .../php/module/ComposerPackageModel.java | 3 + .../php/module/ComposerPackageModelImpl.java | 15 +++- .../php/module/MagentoModule.java | 3 + .../php/module/ModuleManager.java | 26 ++++++- .../magento2plugin/php/tool/ModuleTool.form | 26 +++++++ .../php/tool/ModuleToolWindowFactory.java | 69 ++++++++++++++++++ src/resources/magento2-module.png | Bin 0 -> 1140 bytes 10 files changed, 186 insertions(+), 32 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form create mode 100644 src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java create mode 100644 src/resources/magento2-module.png diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 79314802a..869f84ea3 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -58,6 +58,13 @@ com.intellij.modules.platform + + + diff --git a/src/com/magento/idea/magento2plugin/Magento2Icons.java b/src/com/magento/idea/magento2plugin/Magento2Icons.java index f9375f957..fb09a2e34 100644 --- a/src/com/magento/idea/magento2plugin/Magento2Icons.java +++ b/src/com/magento/idea/magento2plugin/Magento2Icons.java @@ -10,4 +10,5 @@ public class Magento2Icons { public static final Icon PLUGIN = IconLoader.getIcon("icons/interception_reference.png"); public static final Icon CONFIGURATION = IconLoader.getIcon("icons/xml_reference.png"); + } diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index a8d13f5d9..697db0b22 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -25,55 +25,63 @@ public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, bo return new PhpElementVisitor() { @Override public void visitPhpMethodReference(MethodReference reference) { - MagentoApiInspection.check(reference, "Method #ref is not in module API", problemsHolder); + PsiElement referencedElement = reference.resolve(); + + if(referencedElement instanceof Method) { + PhpClass phpClass = ((Method) referencedElement).getContainingClass(); + + if (phpClass == null) { + return; + } + + if (!MagentoApiInspection.isValidReference(phpClass, reference.getElement()) + || !MagentoApiInspection.isValidReference((Method) referencedElement, reference.getElement())) { + problemsHolder.registerProblem(reference, "Method #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + } } @Override - public void visitPhpClassReference(ClassReference classReference) { - MagentoApiInspection.check(classReference, "Class #ref is not in module API", problemsHolder); + public void visitPhpClassReference(ClassReference reference) { + PsiElement referencedElement = reference.resolve(); + + if(referencedElement instanceof PhpClass) { + if (!MagentoApiInspection.isValidReference((PhpClass) referencedElement, reference.getElement())) { + problemsHolder.registerProblem(reference, "Class #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + } } }; } - private static void check(PhpReference reference, String desc, ProblemsHolder holder) { - PsiElement element = reference.resolve(); + private static boolean isValidReference(PhpNamedElement referencedElement, PsiElement contextElement) { + MagentoModule referenceSourceModule = getMagentoModule(referencedElement); + MagentoModule currentModule = getMagentoModule(contextElement); - if(element instanceof PhpNamedElement) { - MagentoModule referenceSourceModule = getMagentoModule((PhpPsiElement) element); - MagentoModule currentModule = getMagentoModule((PhpPsiElement) (reference.getElement())); + if (!areDifferentModules(referenceSourceModule, currentModule)) { + return true; + } - if (!areDifferentModules(referenceSourceModule, currentModule)) { - return; - } - - PhpDocComment docComment = ((PhpNamedElement)element).getDocComment(); - if(docComment == null) { - holder.registerProblem(reference, desc, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - return; - } - - PhpDocTag[] elements = docComment.getTagElementsByName(API_TAG); - if(elements.length == 0) { - holder.registerProblem(reference, desc, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } + PhpDocComment docComment = referencedElement.getDocComment(); + if(docComment == null) { + return false; } + + PhpDocTag[] elements = docComment.getTagElementsByName(API_TAG); + return elements.length > 0; } - private static MagentoModule getMagentoModule(PhpPsiElement element) { + private static MagentoModule getMagentoModule(PsiElement element) { ModuleManager moduleManager = ModuleManager.getInstance(element.getProject()); return moduleManager.getModuleForFile(element.getContainingFile()); } - private static boolean areDifferentModules(MagentoModule magentoModule1, MagentoModule magentoModule2) { - if (magentoModule1 == null) { - return false; - } - - if (magentoModule2 == null) { + private static boolean areDifferentModules(MagentoModule magentoModule, MagentoModule currentPackage) { + if (magentoModule == null) { return false; } - return magentoModule1 != magentoModule2; + return magentoModule != currentPackage; } } diff --git a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java index de05df6ee..187d8bc94 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java +++ b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModel.java @@ -14,6 +14,9 @@ public interface ComposerPackageModel { @Nullable String getType(); + @Nullable + String getVendor(); + @Nullable String getVersion(); diff --git a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java index 47c6179b0..a011f45c7 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java +++ b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java @@ -22,7 +22,6 @@ public class ComposerPackageModelImpl implements ComposerPackageModel { public static final String PSR4 = "psr4"; public static final String FILES = "file"; - public ComposerPackageModelImpl(JsonObject sourceComposerJson) { this.sourceComposerJson = sourceComposerJson; } @@ -39,6 +38,20 @@ public String getType() { return getStringPropertyValue(TYPE); } + @Nullable + @Override + public String getVendor() { + String nameProperty = getStringPropertyValue(NAME); + if (nameProperty != null) { + String[] vendorAndPackage = nameProperty.split("/"); + if (vendorAndPackage.length == 2) { + return vendorAndPackage[0]; + } + } + + return null; + } + @Nullable @Override public String getVersion() { diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java index 0cd955001..8c130d592 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java @@ -1,5 +1,6 @@ package com.magento.idea.magento2plugin.php.module; +import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import com.jetbrains.php.lang.psi.elements.PhpClass; import org.jetbrains.annotations.Nullable; @@ -22,4 +23,6 @@ public interface MagentoModule { boolean isFileInContext(PsiFile psiFile); boolean isClassInContext(PhpClass phpClass); + + PsiDirectory getSourceDirectory(); } diff --git a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java b/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java index 10fd296a8..9ed719f4d 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java @@ -9,6 +9,8 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.FileBasedIndex; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.php.index.ModulePackageFileBasedIndex; @@ -96,6 +98,8 @@ private void loadModules() { class MagentoModuleImpl implements MagentoModule { private ComposerPackageModel composerPackageModel; private PsiDirectory directory; + private static final String DEFAULT_MODULE_NAME = "Undefined module"; + private static final String CONFIGURATION_PATH = "etc"; public MagentoModuleImpl(ComposerPackageModel composerPackageModel, PsiDirectory directory) { @@ -106,7 +110,22 @@ public MagentoModuleImpl(ComposerPackageModel composerPackageModel, PsiDirectory @Nullable @Override public String getMagentoName() { - return null; + PsiDirectory configurationDir = directory.findSubdirectory(CONFIGURATION_PATH); + if (configurationDir != null) { + PsiFile configurationFile = configurationDir.findFile("module.xml"); + + if (configurationFile != null && configurationFile instanceof XmlFile) { + XmlTag rootTag = ((XmlFile) configurationFile).getRootTag(); + if (rootTag != null) { + XmlTag module = rootTag.findFirstSubTag("module"); + if (module != null && module.getAttributeValue("name") != null) { + return module.getAttributeValue("name"); + } + } + } + } + + return DEFAULT_MODULE_NAME; } @Nullable @@ -139,4 +158,9 @@ public boolean isFileInContext(PsiFile psiFile) { public boolean isClassInContext(PhpClass phpClass) { return false; } + + @Override + public PsiDirectory getSourceDirectory() { + return directory; + } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form b/src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form new file mode 100644 index 000000000..4b6cc17a1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form @@ -0,0 +1,26 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java new file mode 100644 index 000000000..aae56d016 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java @@ -0,0 +1,69 @@ +package com.magento.idea.magento2plugin.php.tool; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; +import com.magento.idea.magento2plugin.php.module.MagentoModule; +import com.magento.idea.magento2plugin.php.module.ModuleManager; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by dkvashnin on 12/7/15. + */ +public class ModuleToolWindowFactory implements ToolWindowFactory { + private JPanel windowContent; + private JTree modulesTree; + private ToolWindow myToolWindow; + + private static final String UNDEFINED_VENDOR = "Undefined"; + + @Override + public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { + myToolWindow = toolWindow; + initializeModulesTree(project); + ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); + Content content = contentFactory.createContent(windowContent, "", false); + toolWindow.getContentManager().addContent(content); + } + + private void initializeModulesTree(Project project) { + ModuleManager moduleManager = ModuleManager.getInstance(project); + + Map vendorNodes = new HashMap<>(); + + DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Project modules"); + + modulesTree.setModel(new DefaultTreeModel(rootNode)); + + for (MagentoModule magentoModule: moduleManager.getModules()) { + ComposerPackageModel packageModel = magentoModule.getComposerModel(); + if (packageModel == null) { + continue; + } + + String vendorName = packageModel.getVendor(); + if (vendorName == null) { + vendorName = UNDEFINED_VENDOR; + } + + if (!vendorNodes.containsKey(vendorName)) { + vendorNodes.put(vendorName, new DefaultMutableTreeNode(vendorName)); + rootNode.add(vendorNodes.get(vendorName)); + } + + vendorNodes.get(vendorName).add(new DefaultMutableTreeNode(magentoModule.getMagentoName())); + } + } +} \ No newline at end of file diff --git a/src/resources/magento2-module.png b/src/resources/magento2-module.png new file mode 100644 index 0000000000000000000000000000000000000000..7cd4cfdc9d69dd32d07e404f36e3167810b8c20d GIT binary patch literal 1140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pn}NEkcg59UmvUF{9L`nl>DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtH5O0c3d|4@L;p!@;Rg)$-uz0#nZ(x#6qw% z*w;rmP+;En+jp7%-t97fbpGg!AI$%fdpa*>J@VyOnPV^`Bh=x_iiMq=UlTZ_OuJkT zHnZ!q@yP`m&Zr0o^zIQC*6$GaVJX|*8nkP7e$D4yss$f%5^qllhofaiRbWPuWL1{-}v!bS(q%jmAv;l!<~5%r4FCo zG;z<-%zXUuNbWI-|5gQIw^LOtO-u{97EG8pVYB!*+2pv7je?iWqsuheeX^$uUZ@r6 z&kVGF{)fTzhU9yBdDY!dCI!8)hzl?IcgJwml(YvNX`S}EE2J-%{?$)EIp2GJ%;B>q z=gn9*hq1LW_KALg>8_rC8#QM>o@D&@3`e$S^}U}>tIAA2raZDeV1A%_`f5#v-9_`6 z=AJEmQ~OTTyZmwD+MB1&uM^#tveSd*?y0E)y}s_kdk=3bt@9VUxHIwZJR3*GGa-ky zm$Bu${yuj9!Pm>~I@Z}t!6lzGzc4T2ROxx8%UwK|eS3RId5B2GfzE8bT(%wdtE|?q z-F9qlz~($hhlwAyoMQAye)Rg?H>P#si!zj!oa7R8la`D)@*swHqfeXEx(lIPoKJ;3 zK8tI;Sm@BLTVtH6-Q?BICQ_okqic$!!l~#fX6@Y%S5z!r^Yy=B!Jpuh3ah52{!sPk zd#?Ond)o03pP3$k^OTu6c8OmNo%rlkDEF6>st5bt_r3VUmU8PUk5gyxPa*j~rJGGP z*j!B-C!CqRQ0~f;m1^N;ZEF7$-3#`$Gz<7`5zuWM3E3yCh zk9Z9uS;a*!wKDj)H+0u}r{+{n(PUo2-tyk)lUq;j+WBW)=ZP&3d-?NyWbUu@X(iPc zUw7r?{#5zk5b#cGeuLw)Wqb(UUJ{8j#W5U+fgZF*zm$)D_Vl)Ue7&iJ+; PR1|o+`njxgN@xNAM+VB? literal 0 HcmV?d00001 From 1cb76a978fca74db77215e24eaf6446486ba9ca3 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 18 Dec 2015 23:26:41 +0200 Subject: [PATCH 15/51] Fixed @api inspection, added context completions for Block classes in layouts, added context completions for Observer classes --- .../php/inspections/MagentoApiInspection.java | 2 +- .../php/util/ImplementationMatcher.java | 33 ++++++++++++++++ .../magento2plugin/php/util/MagentoTypes.java | 9 +++++ .../php/util/PsiContextMatcherManager.java | 39 +++++++++++++++++++ .../util/PsiContextMatcherI.java | 10 +++++ .../completion/ClassCompletionProvider.java | 14 +++++-- .../xml/completion/CompletionProviderI.java | 4 ++ .../VirtualTypeCompletionProvider.java | 9 ++++- .../completion/DiCompletionContributor.java | 2 +- .../LayoutCompletionContributor.java | 14 +++---- .../ReferenceComponentCompletionProvider.java | 9 ++++- .../reference/LayoutReferenceContributor.java | 10 ++--- .../EventCompletionContributor.java | 8 +++- .../ObserverReferenceContributor.java | 5 ++- .../reference/util/ClassesResultsFiller.java | 6 ++- .../util/ImplementationContextDecorator.java | 38 ++++++++++++++++++ 16 files changed, 188 insertions(+), 24 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java create mode 100644 src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java create mode 100644 src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java create mode 100644 src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java create mode 100644 src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index 697db0b22..5d7c92936 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -35,7 +35,7 @@ public void visitPhpMethodReference(MethodReference reference) { } if (!MagentoApiInspection.isValidReference(phpClass, reference.getElement()) - || !MagentoApiInspection.isValidReference((Method) referencedElement, reference.getElement())) { + && !MagentoApiInspection.isValidReference((Method) referencedElement, reference.getElement())) { problemsHolder.registerProblem(reference, "Method #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } diff --git a/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java b/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java new file mode 100644 index 000000000..1f9852b77 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java @@ -0,0 +1,33 @@ +package com.magento.idea.magento2plugin.php.util; + +import com.intellij.psi.PsiElement; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; + +/** +* Created by dkvashnin on 12/18/15. +*/ +public class ImplementationMatcher implements PsiContextMatcherI { + private String type; + + public ImplementationMatcher(String type) { + this.type = type; + } + + @Override + public boolean match(PsiElement psiElement) { + if (psiElement instanceof PhpClass) { + for (PhpClass parent : ((PhpClass)psiElement).getImplementedInterfaces()) { + if (parent.getPresentableFQN().equals(type)) { + return true; + } + } + + PhpClass parent = ((PhpClass) psiElement).getSuperClass(); + if (parent != null) { + return match(parent); + } + } + return false; + } +} diff --git a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java new file mode 100644 index 000000000..49d7ec18a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java @@ -0,0 +1,9 @@ +package com.magento.idea.magento2plugin.php.util; + +/** + * Created by dkvashnin on 12/18/15. + */ +public class MagentoTypes { + public static final String BLOCK_TYPE = "Magento\\Framework\\View\\Element\\BlockInterface"; + public static final String OBSERVER_TYPE = "Magento\\Framework\\Event\\ObserverInterface"; +} diff --git a/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java b/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java new file mode 100644 index 000000000..926bd6f02 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java @@ -0,0 +1,39 @@ +package com.magento.idea.magento2plugin.php.util; + +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by dkvashnin on 12/18/15. + */ +public class PsiContextMatcherManager { + private static PsiContextMatcherManager INSTANCE; + + private Map map = new HashMap<>(); + + private PsiContextMatcherManager() {} + + public ImplementationMatcher getImplementationMatcherForType(String type) { + if (map.containsKey(type)) { + + PsiContextMatcherI psiContextMatcherI = map.get(type); + if (psiContextMatcherI instanceof ImplementationMatcher) { + return (ImplementationMatcher)psiContextMatcherI; + } + } + ImplementationMatcher implementationMatcher = new ImplementationMatcher(type); + map.put(type, implementationMatcher); + + return implementationMatcher; + } + + public static PsiContextMatcherManager getInstance() { + if (INSTANCE == null) { + INSTANCE = new PsiContextMatcherManager(); + } + + return INSTANCE; + } +} diff --git a/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java b/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java new file mode 100644 index 000000000..683959f59 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java @@ -0,0 +1,10 @@ +package com.magento.idea.magento2plugin.util; + +import com.intellij.psi.PsiElement; + +/** + * Created by dkvashnin on 12/18/15. + */ +public interface PsiContextMatcherI { + boolean match(PsiElement psiElement); +} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java index f8a699640..e066d3085 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java @@ -8,6 +8,8 @@ import com.jetbrains.php.PhpIcons; import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; @@ -20,7 +22,7 @@ public class ClassCompletionProvider implements CompletionProviderI { public final static CompletionProviderI INSTANCE = new ClassCompletionProvider(); @Override - public List collectCompletionResult(PsiElement psiElement) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { List result = new ArrayList<>(); PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); String prefix = StringUtil.unquoteString(psiElement.getText()); @@ -30,11 +32,12 @@ public List collectCompletionResult(PsiElement psiElement) { for (String className: classNames) { Collection classesByName = phpIndex.getClassesByName(className); for (PhpClass phpClass: classesByName) { - String classFqn = phpClass.getPresentableFQN(); - if (classFqn == null) { + if (context != null && !context.match(phpClass)) { continue; } + String classFqn = phpClass.getPresentableFQN(); + result.add( LookupElementBuilder .create(classFqn) @@ -45,4 +48,9 @@ public List collectCompletionResult(PsiElement psiElement) { return result; } + + @Override + public List collectCompletionResult(PsiElement psiElement) { + return collectCompletionResult(psiElement, null); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java index 3d347a041..b3f943860 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java @@ -2,6 +2,8 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.psi.PsiElement; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -9,5 +11,7 @@ * Created by dkvashnin on 11/17/15. */ public interface CompletionProviderI { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context); + public List collectCompletionResult(PsiElement psiElement); } diff --git a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java index 1a3b13ab4..32269e902 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java @@ -3,7 +3,9 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiElement; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -15,7 +17,7 @@ public class VirtualTypeCompletionProvider implements CompletionProviderI { public final static CompletionProviderI INSTANCE = new VirtualTypeCompletionProvider(); @Override - public List collectCompletionResult(PsiElement psiElement) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { List result = new ArrayList<>(); String[] allVirtualTypesNames = VirtualTypesNamesFileBasedIndex.getAllVirtualTypesNames( psiElement.getProject() @@ -27,4 +29,9 @@ public List collectCompletionResult(PsiElement psiElement) { return result; } + + @Override + public List collectCompletionResult(PsiElement psiElement) { + return collectCompletionResult(psiElement, null); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java index 42bcfba29..1f0e8add0 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java @@ -41,4 +41,4 @@ public void addCompletions(@NotNull CompletionParameters parameters, } ); } -} \ No newline at end of file +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java index 1056e83d0..73742fd4b 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java @@ -5,22 +5,19 @@ import com.intellij.openapi.project.Project; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; -import com.intellij.util.PlatformIcons; import com.intellij.util.ProcessingContext; -import com.intellij.util.indexing.FileBasedIndex; -import com.intellij.xml.util.XmlIconProvider; -import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.php.util.MagentoTypes; +import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; -import com.magento.idea.magento2plugin.xml.layout.index.AbstractComponentNameFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import org.jetbrains.annotations.NotNull; -import java.util.Collection; import java.util.stream.Collectors; /** @@ -44,8 +41,10 @@ public LayoutCompletionContributor() { @Override protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { PsiElement psiElement = completionParameters.getOriginalPosition(); + PsiContextMatcherI completionContext = PsiContextMatcherManager.getInstance() + .getImplementationMatcherForType(MagentoTypes.BLOCK_TYPE); for (CompletionProviderI completionProvider: typeCompletionProviders) { - completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); + completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement, completionContext)); } } } @@ -103,4 +102,5 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters } ); } + } diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java index 1cbf9fda9..8e0078101 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java @@ -5,8 +5,10 @@ import com.intellij.psi.PsiElement; import com.intellij.util.indexing.ID; import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; @@ -23,7 +25,7 @@ public ReferenceComponentCompletionProvider(ID indexId) { } @Override - public List collectCompletionResult(PsiElement psiElement) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { Collection keys = LayoutIndexUtility.getAllKeys(indexId, psiElement.getProject()); List results = new ArrayList<>(); @@ -35,4 +37,9 @@ public List collectCompletionResult(PsiElement psiElement) { return results; } + + @Override + public List collectCompletionResult(PsiElement psiElement) { + return collectCompletionResult(psiElement, null); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index dfcd9b164..836baa650 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -1,24 +1,20 @@ package com.magento.idea.magento2plugin.xml.layout.reference; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.*; -import com.intellij.psi.search.FilenameIndex; -import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; -import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.reference.fill.BlockResultsFiller; import com.magento.idea.magento2plugin.xml.layout.reference.fill.ContainerResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ImplementationContextDecorator; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; import java.util.Arrays; -import java.util.Collection; import java.util.List; /** @@ -32,7 +28,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelperUtility.getTagAttributeValuePattern("block", "class"), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, + new ImplementationContextDecorator(ClassesResultsFiller.INSTANCE, MagentoTypes.BLOCK_TYPE), VirtualTypesResultsFiller.INSTANCE } ) diff --git a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java index 61d077794..1be94a494 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java @@ -5,10 +5,13 @@ import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.php.util.MagentoTypes; +import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; +import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; import com.magento.idea.magento2plugin.xml.observer.XmlHelper; import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; import org.jetbrains.annotations.NotNull; @@ -31,9 +34,11 @@ public EventCompletionContributor() { new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { + ImplementationMatcher completionContext = PsiContextMatcherManager.getInstance() + .getImplementationMatcherForType(MagentoTypes.OBSERVER_TYPE); PsiElement psiElement = completionParameters.getOriginalPosition(); for (CompletionProviderI completionProvider: typeCompletionProviders) { - completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); + completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement, completionContext)); } } } @@ -56,5 +61,6 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters } ); } + } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java index c43ef5f20..a5e7a814e 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java @@ -1,14 +1,17 @@ package com.magento.idea.magento2plugin.xml.observer.reference; import com.intellij.psi.*; +import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.observer.XmlHelper; import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsDeclarationsFilesResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ImplementationContextDecorator; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; + /** * Created by dkvashnin on 11/2/15. */ @@ -20,7 +23,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelper.getTagAttributeValuePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, + new ImplementationContextDecorator(ClassesResultsFiller.INSTANCE, MagentoTypes.OBSERVER_TYPE), VirtualTypesResultsFiller.INSTANCE } ) diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java index 944c973d8..cce7c8310 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java @@ -22,7 +22,11 @@ public void fillResolveResults(PsiElement psiElement, List result PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); for (PhpClass phpClass : phpIndex.getClassesByFQN(PhpLangUtil.toFQN(typeName))) { - results.add(new PsiElementResolveResult(phpClass)); + addResult(results, phpClass); } } + + protected void addResult(List results, PhpClass phpClass) { + results.add(new PsiElementResolveResult(phpClass)); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java new file mode 100644 index 000000000..bd944f282 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java @@ -0,0 +1,38 @@ +package com.magento.idea.magento2plugin.xml.reference.util; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.ResolveResult; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; +import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; + +import java.util.List; + +/** + * Created by dkvashnin on 12/18/15. + */ +public class ImplementationContextDecorator implements ReferenceResultsFiller { + private ReferenceResultsFiller subject; + private String type; + + public ImplementationContextDecorator(ReferenceResultsFiller subject, String type) { + this.subject = subject; + this.type = type; + } + + @Override + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { + subject.fillResolveResults(psiElement, results, typeName); + + ImplementationMatcher implementationMatcher = PsiContextMatcherManager.getInstance() + .getImplementationMatcherForType(type); + for (ResolveResult resolveResult : results) { + PsiElement element = resolveResult.getElement(); + + if (element instanceof PhpClass && !implementationMatcher.match(element)) { + results.remove(resolveResult); + } + } + + } +} From c38bb88520e6ec1ed721d77ceba5703d6f87f45d Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sat, 19 Dec 2015 00:05:38 +0200 Subject: [PATCH 16/51] Added ObjectManager usage inspection in module scope --- META-INF/plugin.xml | 10 ++++++++-- .../php/inspections/ObjectManagerInspection.java | 7 +++++++ .../idea/magento2plugin/php/util/MagentoTypes.java | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 869f84ea3..67c80ce04 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -58,12 +58,13 @@ com.intellij.modules.platform + @@ -89,9 +90,14 @@ + diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java new file mode 100644 index 000000000..ca68802c6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java @@ -0,0 +1,7 @@ +package com.magento.idea.magento2plugin.php.inspections; + +/** + * Created by dkvashnin on 12/18/15. + */ +public class ObjectManagerInspection { +} diff --git a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java index 49d7ec18a..f155ea27b 100644 --- a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java +++ b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java @@ -6,4 +6,5 @@ public class MagentoTypes { public static final String BLOCK_TYPE = "Magento\\Framework\\View\\Element\\BlockInterface"; public static final String OBSERVER_TYPE = "Magento\\Framework\\Event\\ObserverInterface"; + public static final String OBJECT_MANAGER_TYPE = "Magento\\Framework\\ObjectManagerInterface"; } From 13fb080f9bba3e4d28dd9b763cbf6d55bc02e372 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sat, 19 Dec 2015 12:21:02 +0200 Subject: [PATCH 17/51] Improved event references for Observeres resolution --- .../inspections/ObjectManagerInspection.java | 74 ++++++++++++++++++- .../magento2plugin/php/util/MagentoTypes.java | 1 + .../reference/EventReferenceProvider.java | 18 ++++- .../ObjectManagerInspection.html | 5 ++ 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/inspectionDescriptions/ObjectManagerInspection.html diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java index ca68802c6..c81df3ad9 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java @@ -1,7 +1,79 @@ package com.magento.idea.magento2plugin.php.inspections; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiReference; +import com.jetbrains.php.lang.inspections.PhpInspection; +import com.jetbrains.php.lang.psi.elements.ClassReference; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.MethodReference; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; +import com.magento.idea.magento2plugin.php.module.ModuleManager; +import com.magento.idea.magento2plugin.php.util.MagentoTypes; +import org.jetbrains.annotations.NotNull; + /** * Created by dkvashnin on 12/18/15. */ -public class ObjectManagerInspection { +public class ObjectManagerInspection extends PhpInspection { + @NotNull + @Override + public PsiElementVisitor buildVisitor(ProblemsHolder problemsHolder, boolean b) { + return new PhpElementVisitor() { + @Override + public void visitPhpMethodReference(MethodReference reference) { + PsiElement referencedElement = reference.resolve(); + + if(referencedElement instanceof Method) { + ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); + if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { + return; + } + + PhpClass phpClass = ((Method) referencedElement).getContainingClass(); + + verifyPhpClass(phpClass, reference); + } + } + + @Override + public void visitPhpClassReference(ClassReference reference) { + PsiElement referencedElement = reference.resolve(); + + if(referencedElement instanceof PhpClass) { + ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); + if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { + return; + } + + verifyPhpClass((PhpClass)referencedElement, reference); + } + } + + private void verifyPhpClass(PhpClass phpClass, PsiReference reference) { + if (phpClass == null) { + return; + } + + if (phpClass.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { + registerProblem(reference); + return; + } + + for (PhpClass implementedInterface : phpClass.getImplementedInterfaces()) { + if (implementedInterface.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { + registerProblem(reference); + return; + } + } + } + + private void registerProblem(PsiReference reference) { + problemsHolder.registerProblem(reference, "ObjectManager is not recommended to use in module", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + }; + } } diff --git a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java index f155ea27b..2221bda0a 100644 --- a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java +++ b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java @@ -7,4 +7,5 @@ public class MagentoTypes { public static final String BLOCK_TYPE = "Magento\\Framework\\View\\Element\\BlockInterface"; public static final String OBSERVER_TYPE = "Magento\\Framework\\Event\\ObserverInterface"; public static final String OBJECT_MANAGER_TYPE = "Magento\\Framework\\ObjectManagerInterface"; + public static final String EVENT_MANAGER_TYPE = "Magento\\Framework\\Event\\ManagerInterface"; } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java index f88e4fa31..e1be2efdc 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java @@ -5,8 +5,12 @@ import com.intellij.psi.PsiReferenceProvider; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; +import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.ParameterList; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.php.util.MagentoTypes; +import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; import com.magento.idea.magento2plugin.xml.reference.TypeReference; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import org.jetbrains.annotations.NotNull; @@ -16,6 +20,7 @@ */ class EventReferenceProvider extends PsiReferenceProvider { private final ReferenceResultsFiller[] resultsFillers; + private static final String DISPATCH_METHOD = "dispatch"; public EventReferenceProvider(ReferenceResultsFiller[] resultsFillers) { this.resultsFillers = resultsFillers; @@ -35,11 +40,20 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @No } MethodReference methodReference = (MethodReference)parameterList.getContext(); - if (!methodReference.getName().equals("dispatch")) { + if (!DISPATCH_METHOD.equals(methodReference.getName())) { return new PsiReference[0]; } + PsiElement resolvedElement = methodReference.resolve(); + if (resolvedElement != null && resolvedElement instanceof Method) { + PhpClass containingClass = ((Method) resolvedElement).getContainingClass(); - return new PsiReference[]{new TypeReference(psiElement, this.resultsFillers, true)}; + if (containingClass != null && MagentoTypes.EVENT_MANAGER_TYPE.equals(containingClass.getPresentableFQN())) { + return new PsiReference[]{new TypeReference(psiElement, this.resultsFillers, true)}; + } + } + + + return new PsiReference[0]; } } diff --git a/src/inspectionDescriptions/ObjectManagerInspection.html b/src/inspectionDescriptions/ObjectManagerInspection.html new file mode 100644 index 000000000..5c82c6735 --- /dev/null +++ b/src/inspectionDescriptions/ObjectManagerInspection.html @@ -0,0 +1,5 @@ + + +ObjectManager usage in Module scope + + \ No newline at end of file From d927d17338213bb080dc8720f03028ea870dea4c Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov Date: Sun, 20 Dec 2015 16:52:59 +0200 Subject: [PATCH 18/51] Added reference resolver for services webapi xml configurations --- META-INF/plugin.xml | 1 + magento2plugin.iml | 2 +- .../magento2plugin/xml/webapi/XmlHelper.java | 21 +++++ .../ServiceReferenceContributor.java | 39 ++++++++ .../fill/ServiceMethodResultsFiller.java | 90 +++++++++++++++++++ 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java create mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java create mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 67c80ce04..f9ba414f8 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -70,6 +70,7 @@ + diff --git a/magento2plugin.iml b/magento2plugin.iml index 26aa60e1f..1be1d0108 100644 --- a/magento2plugin.iml +++ b/magento2plugin.iml @@ -6,7 +6,7 @@ - + diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java new file mode 100644 index 000000000..5df177b7a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java @@ -0,0 +1,21 @@ +package com.magento.idea.magento2plugin.xml.webapi; + +import com.intellij.patterns.XmlAttributeValuePattern; +import com.magento.idea.magento2plugin.xml.XmlHelperUtility; + +/** + * Created by isentiabov on 20.12.2015. + */ +public class XmlHelper extends XmlHelperUtility { + public static final String FILE_TYPE = "webapi"; + public static final String SERVICE_TAG = "service"; + public static final String METHOD_ATTRIBUTE = "method"; + public static final String CLASS_ATTRIBUTE = "class"; + + /** + * + */ + public static XmlAttributeValuePattern getMethodAttributePattern() { + return getTagAttributeValuePattern(SERVICE_TAG, METHOD_ATTRIBUTE, FILE_TYPE); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java new file mode 100644 index 000000000..1ee70712d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java @@ -0,0 +1,39 @@ +package com.magento.idea.magento2plugin.xml.webapi.reference; + +import com.intellij.patterns.XmlAttributeValuePattern; +import com.intellij.psi.PsiReferenceContributor; +import com.intellij.psi.PsiReferenceRegistrar; +import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; +import com.magento.idea.magento2plugin.xml.reference.util.InterfacesResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; +import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; +import com.magento.idea.magento2plugin.xml.webapi.reference.fill.ServiceMethodResultsFiller; +import org.jetbrains.annotations.NotNull; + +/** + * Created by isentiabov on 20.12.2015. + */ +public class ServiceReferenceContributor extends PsiReferenceContributor{ + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { + // + XmlAttributeValuePattern serviceTag = XmlHelper.getTagAttributeValuePattern( + XmlHelper.SERVICE_TAG, + XmlHelper.CLASS_ATTRIBUTE + ); + psiReferenceRegistrar.registerReferenceProvider( + serviceTag, + new XmlReferenceProvider(new ReferenceResultsFiller[]{ + InterfacesResultsFiller.INSTANCE + })); + + // + XmlAttributeValuePattern methodAttribute = XmlHelper.getMethodAttributePattern(); + psiReferenceRegistrar.registerReferenceProvider( + methodAttribute, + new XmlReferenceProvider(new ReferenceResultsFiller[]{ + new ServiceMethodResultsFiller() + }) + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java new file mode 100644 index 000000000..9b0ff2041 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java @@ -0,0 +1,90 @@ +package com.magento.idea.magento2plugin.xml.webapi.reference.fill; + +import com.intellij.patterns.XmlAttributeValuePattern; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlTag; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; +import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; +import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; + +import javax.annotation.Nullable; +import java.util.List; + +/** + * Created by isentiabov on 20.12.2015. + */ +public class ServiceMethodResultsFiller implements ReferenceResultsFiller { + @Override + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { + // get service xml tag `method` attribute + XmlAttribute methodAttribute = getMethodAttribute(psiElement); + if (methodAttribute == null) { + return; + } + + // get service xml tag + XmlTag serviceTag = getServiceTag(methodAttribute); + if (serviceTag == null) { + return; + } + + // get service xml tag `class` attribute + XmlAttribute classAttribute = getClassAttribute(serviceTag); + if (classAttribute == null) { + return; + } + + PhpClass serviceInterface = getServiceInterface(classAttribute); + if (serviceInterface == null) { + return; + } + + fillResults(serviceInterface, results, typeName); + } + + protected XmlAttribute getMethodAttribute(PsiElement xmlAttribute) { + return PsiTreeUtil.getParentOfType(xmlAttribute, XmlAttribute.class); + } + + protected XmlTag getServiceTag(XmlAttribute xmlAttribute) { + return PsiTreeUtil.getParentOfType(xmlAttribute, XmlTag.class); + } + + protected XmlAttribute getClassAttribute(XmlTag xmlTag) { + return xmlTag.getAttribute(XmlHelper.CLASS_ATTRIBUTE); + } + + @Nullable + protected PhpClass getServiceInterface(XmlAttribute xmlAttribute) { + XmlAttributeValue value = xmlAttribute.getValueElement(); + if (value == null) { + return null; + } + + PsiReference reference = value.getReference(); + if (reference == null) { + return null; + } + + return (PhpClass)reference.resolve(); + } + + protected void fillResults(PhpClass serviceInterface, List results, String typeName) { + for (Method method : serviceInterface.getMethods()) { + if (method.getName().equals(typeName)) { + results.add( + new PhpResolveResult(method) + ); + + break; + } + } + } +} From 97e43bd42c540381ce74f05ba9d5c34bc7565666 Mon Sep 17 00:00:00 2001 From: Michail Slabko Date: Sun, 20 Dec 2015 17:32:19 +0200 Subject: [PATCH 19/51] Add autocompletion for webapi services --- META-INF/plugin.xml | 1 + .../InterfaceCompletionProvider.java | 53 +++++++++ .../magento2plugin/xml/webapi/XmlHelper.java | 47 ++++++++ .../WebApiCompletionContributor.java | 103 ++++++++++++++++++ .../fill/ServiceMethodResultsFiller.java | 2 +- 5 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index f9ba414f8..dbbdf4d4c 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -73,6 +73,7 @@ + diff --git a/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java new file mode 100644 index 000000000..860a137f6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java @@ -0,0 +1,53 @@ +package com.magento.idea.magento2plugin.xml.completion; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.jetbrains.php.PhpIcons; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by mslabko on 18.12.2015. + */ +public class InterfaceCompletionProvider implements CompletionProviderI { + public final static CompletionProviderI INSTANCE = new InterfaceCompletionProvider(); + + @Override + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { + List result = new ArrayList<>(); + PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); + + Collection interfaceNames = phpIndex.getAllInterfaceNames(); + + for (String interfaceName: interfaceNames) { + Collection classesByName = phpIndex.getInterfacesByName(interfaceName); + for (PhpClass phpClass: classesByName) { + if (context != null && !context.match(phpClass)) { + continue; + } + + String classFqn = phpClass.getPresentableFQN(); + + result.add( + LookupElementBuilder + .create(classFqn) + .withIcon(PhpIcons.CLASS_ICON) + ); + } + } + + return result; + } + + @Override + public List collectCompletionResult(PsiElement psiElement) { + return collectCompletionResult(psiElement, null); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java index 5df177b7a..b5de94c2f 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java @@ -1,6 +1,10 @@ package com.magento.idea.magento2plugin.xml.webapi; +import com.intellij.patterns.PsiElementPattern; import com.intellij.patterns.XmlAttributeValuePattern; +import com.intellij.patterns.XmlPatterns; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTokenType; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; /** @@ -18,4 +22,47 @@ public class XmlHelper extends XmlHelperUtility { public static XmlAttributeValuePattern getMethodAttributePattern() { return getTagAttributeValuePattern(SERVICE_TAG, METHOD_ATTRIBUTE, FILE_TYPE); } + + /** + * \Namespace\Class + * @param typeName Type name + */ + public static PsiElementPattern.Capture getArgumentValuePatternForType(String typeName) { + return XmlPatterns + .psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withParent( + XmlPatterns + .xmlText() + .withParent(XmlPatterns + .xmlTag() + .withName("argument") + .withAttributeValue("xsi:type", typeName) + ) + ).inFile(XmlHelper.getXmlFilePattern(FILE_TYPE)); + } + + /** + * \Namespace\Class + * @param typeName Type name + */ + public static PsiElementPattern.Capture getItemValuePatternForType(String typeName) { + return XmlPatterns + .psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withParent( + XmlPatterns + .xmlText() + .withParent(XmlPatterns + .xmlTag() + .withName("item") + .withAttributeValue("xsi:type", typeName) + ) + ).inFile(XmlHelper.getXmlFilePattern(FILE_TYPE)); + } + + /** + * + */ + public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { + return getTagAttributePattern(tag, attributeName, FILE_TYPE); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java new file mode 100644 index 000000000..265018d5d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java @@ -0,0 +1,103 @@ +package com.magento.idea.magento2plugin.xml.webapi.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.patterns.XmlPatterns; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.PhpLangUtil; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; +import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; +import org.jetbrains.annotations.NotNull; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.Nullable; + +import java.util.Iterator; + +/** + * Created by mslabko on 10/15/15. + */ +public class WebApiCompletionContributor extends CompletionContributor { + private CompletionProviderI[] completionProviders = new CompletionProviderI[] { + InterfaceCompletionProvider.INSTANCE + }; + + public WebApiCompletionContributor() { + // add services to list + extend(CompletionType.BASIC, + XmlPatterns.or( + XmlHelper.getArgumentValuePatternForType("object"), + XmlHelper.getItemValuePatternForType("object"), + XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.CLASS_ATTRIBUTE) + ), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + PsiElement psiElement = parameters.getOriginalPosition(); + for (CompletionProviderI completionProvider: completionProviders) { + resultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); + } + } + } + ); + // Add service methods to list + extend( + CompletionType.BASIC, + XmlPatterns.or( + XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.METHOD_ATTRIBUTE) + ), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + + PsiElement psiElement = parameters.getOriginalPosition(); + + PhpClass serviceInterface = getServiceInterface(psiElement); + if (serviceInterface != null) { + for (Method serviceMethod : serviceInterface.getMethods()) { + resultSet.addElement(LookupElementBuilder + .create(serviceMethod.getName()) + .withIcon(PhpIcons.METHOD_ICON) + ); + } + } + } + } + ); + } + + @Nullable + private PhpClass getServiceInterface(PsiElement psiElement) { + XmlAttribute methodAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); + if (methodAttribute == null) { + return null; + } + XmlTag serviceTag = PsiTreeUtil.getParentOfType(methodAttribute, XmlTag.class); + if (serviceTag == null) { + return null; + } + XmlAttribute serviceAttribute = serviceTag.getAttribute(XmlHelper.CLASS_ATTRIBUTE); + if (serviceAttribute == null) { + return null; + } + String className = serviceAttribute.getValue(); + if (className == null) { + return null; + } + PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); + Iterator iterator = phpIndex.getInterfacesByFQN(PhpLangUtil.toFQN(className)).iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } + return null; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java index 9b0ff2041..a86a232d2 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java @@ -14,7 +14,7 @@ import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import java.util.List; /** From d32548dcc7d20fb98b056a58cb10a4a506982b7d Mon Sep 17 00:00:00 2001 From: Ievgen Sentiabov Date: Tue, 22 Dec 2015 22:15:38 +0200 Subject: [PATCH 20/51] Moved interface name resolver to separated class --- .../WebApiCompletionContributor.java | 20 +++------ .../fill/ServiceMethodResultsFiller.java | 33 ++------------ .../resolver/InterfaceNameResolver.java | 45 +++++++++++++++++++ 3 files changed, 55 insertions(+), 43 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java index 265018d5d..d3e918205 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java @@ -5,18 +5,17 @@ import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlTag; import com.intellij.util.ProcessingContext; import com.jetbrains.php.PhpIcons; import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; +import com.magento.idea.magento2plugin.xml.webapi.reference.resolver.InterfaceNameResolver; import org.jetbrains.annotations.NotNull; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.Nullable; import java.util.Iterator; @@ -77,19 +76,12 @@ public void addCompletions(@NotNull CompletionParameters parameters, @Nullable private PhpClass getServiceInterface(PsiElement psiElement) { - XmlAttribute methodAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); - if (methodAttribute == null) { - return null; - } - XmlTag serviceTag = PsiTreeUtil.getParentOfType(methodAttribute, XmlTag.class); - if (serviceTag == null) { - return null; - } - XmlAttribute serviceAttribute = serviceTag.getAttribute(XmlHelper.CLASS_ATTRIBUTE); - if (serviceAttribute == null) { + InterfaceNameResolver resolver = new InterfaceNameResolver(); + XmlAttribute classAttribute = resolver.getInterfaceAttributeByMethod(psiElement); + if (classAttribute == null) { return null; } - String className = serviceAttribute.getValue(); + String className = classAttribute.getValue(); if (className == null) { return null; } diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java index a86a232d2..d600c3216 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java @@ -1,20 +1,17 @@ package com.magento.idea.magento2plugin.xml.webapi.reference.fill; -import com.intellij.patterns.XmlAttributeValuePattern; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.ResolveResult; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; - +import com.magento.idea.magento2plugin.xml.webapi.reference.resolver.InterfaceNameResolver; import org.jetbrains.annotations.Nullable; + import java.util.List; /** @@ -23,20 +20,8 @@ public class ServiceMethodResultsFiller implements ReferenceResultsFiller { @Override public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - // get service xml tag `method` attribute - XmlAttribute methodAttribute = getMethodAttribute(psiElement); - if (methodAttribute == null) { - return; - } - - // get service xml tag - XmlTag serviceTag = getServiceTag(methodAttribute); - if (serviceTag == null) { - return; - } - - // get service xml tag `class` attribute - XmlAttribute classAttribute = getClassAttribute(serviceTag); + InterfaceNameResolver resolver = new InterfaceNameResolver(); + XmlAttribute classAttribute = resolver.getInterfaceAttributeByMethod(psiElement); if (classAttribute == null) { return; } @@ -49,17 +34,7 @@ public void fillResolveResults(PsiElement psiElement, List result fillResults(serviceInterface, results, typeName); } - protected XmlAttribute getMethodAttribute(PsiElement xmlAttribute) { - return PsiTreeUtil.getParentOfType(xmlAttribute, XmlAttribute.class); - } - - protected XmlTag getServiceTag(XmlAttribute xmlAttribute) { - return PsiTreeUtil.getParentOfType(xmlAttribute, XmlTag.class); - } - protected XmlAttribute getClassAttribute(XmlTag xmlTag) { - return xmlTag.getAttribute(XmlHelper.CLASS_ATTRIBUTE); - } @Nullable protected PhpClass getServiceInterface(XmlAttribute xmlAttribute) { diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java new file mode 100644 index 000000000..37f6b1c1c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java @@ -0,0 +1,45 @@ +package com.magento.idea.magento2plugin.xml.webapi.reference.resolver; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; +import org.jetbrains.annotations.Nullable; + +/** + * Created by isentiabov on 22.12.2015. + */ +public class InterfaceNameResolver { + + @Nullable + public XmlAttribute getInterfaceAttributeByMethod(PsiElement psiElement) + { + // get service xml tag `method` attribute + XmlAttribute methodAttribute = getMethodAttribute(psiElement); + if (methodAttribute == null) { + return null; + } + + // get service xml tag + XmlTag serviceTag = getServiceTag(methodAttribute); + if (serviceTag == null) { + return null; + } + + // get service xml tag `class` attribute + return getClassAttribute(serviceTag); + } + + protected XmlAttribute getMethodAttribute(PsiElement xmlAttribute) { + return PsiTreeUtil.getParentOfType(xmlAttribute, XmlAttribute.class); + } + + protected XmlTag getServiceTag(XmlAttribute xmlAttribute) { + return PsiTreeUtil.getParentOfType(xmlAttribute, XmlTag.class); + } + + protected XmlAttribute getClassAttribute(XmlTag xmlTag) { + return xmlTag.getAttribute(XmlHelper.CLASS_ATTRIBUTE); + } +} From 2de644722e3816ce2124d658f5fd0d0c6a95c045 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Thu, 24 Dec 2015 21:56:36 +0200 Subject: [PATCH 21/51] Added support for old people using PhpStorm 8 with jre 1.7 --- META-INF/plugin.xml | 2 +- magento2plugin.iml | 1 + .../php/inspections/MagentoApiInspection.java | 60 +++++++------ .../inspections/ObjectManagerInspection.java | 86 +++++++++++-------- .../php/module/ComposerPackageModelImpl.java | 19 ++-- .../idea/magento2plugin/xml/di/XmlHelper.java | 4 + .../di/reference/ArgumentNameReference.java | 13 ++- .../di/reference/DiReferenceContributor.java | 16 ++-- .../resolver/VirtualTypeTagResolver.java | 2 +- .../LayoutCompletionContributor.java | 15 ++-- .../reference/LayoutReferenceContributor.java | 19 ++-- .../EventsDeclarationsFileBasedIndex.java | 2 +- 12 files changed, 131 insertions(+), 108 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 67c80ce04..b809a6dd1 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -47,7 +47,7 @@ - + diff --git a/magento2plugin.iml b/magento2plugin.iml index 26aa60e1f..0f0805366 100644 --- a/magento2plugin.iml +++ b/magento2plugin.iml @@ -5,6 +5,7 @@ + diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index 5d7c92936..4c683e49c 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -22,36 +22,48 @@ public class MagentoApiInspection extends PhpInspection { @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean isOnTheFly) { - return new PhpElementVisitor() { - @Override - public void visitPhpMethodReference(MethodReference reference) { - PsiElement referencedElement = reference.resolve(); - - if(referencedElement instanceof Method) { - PhpClass phpClass = ((Method) referencedElement).getContainingClass(); - - if (phpClass == null) { - return; - } - - if (!MagentoApiInspection.isValidReference(phpClass, reference.getElement()) - && !MagentoApiInspection.isValidReference((Method) referencedElement, reference.getElement())) { - problemsHolder.registerProblem(reference, "Method #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } + + return new ApiInspectionVisitor(problemsHolder); + } + + private class ApiInspectionVisitor extends PhpElementVisitor { + + private ProblemsHolder problemsHolder; + + public ApiInspectionVisitor(@NotNull ProblemsHolder problemsHolder) { + super(); + + this.problemsHolder = problemsHolder; + } + + @Override + public void visitPhpMethodReference(MethodReference reference) { + PsiElement referencedElement = reference.resolve(); + + if(referencedElement instanceof Method) { + PhpClass phpClass = ((Method) referencedElement).getContainingClass(); + + if (phpClass == null) { + return; + } + + if (!MagentoApiInspection.isValidReference(phpClass, reference.getElement()) + && !MagentoApiInspection.isValidReference((Method) referencedElement, reference.getElement())) { + problemsHolder.registerProblem(reference, "Method #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } + } - @Override - public void visitPhpClassReference(ClassReference reference) { - PsiElement referencedElement = reference.resolve(); + @Override + public void visitPhpClassReference(ClassReference reference) { + PsiElement referencedElement = reference.resolve(); - if(referencedElement instanceof PhpClass) { - if (!MagentoApiInspection.isValidReference((PhpClass) referencedElement, reference.getElement())) { - problemsHolder.registerProblem(reference, "Class #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } + if(referencedElement instanceof PhpClass) { + if (!MagentoApiInspection.isValidReference((PhpClass) referencedElement, reference.getElement())) { + problemsHolder.registerProblem(reference, "Class #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } - }; + } } private static boolean isValidReference(PhpNamedElement referencedElement, PsiElement contextElement) { diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java index c81df3ad9..b1f90d7ce 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java @@ -21,59 +21,69 @@ public class ObjectManagerInspection extends PhpInspection { @NotNull @Override - public PsiElementVisitor buildVisitor(ProblemsHolder problemsHolder, boolean b) { - return new PhpElementVisitor() { - @Override - public void visitPhpMethodReference(MethodReference reference) { - PsiElement referencedElement = reference.resolve(); + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean b) { + return new OMInspectionVisitor(problemsHolder); + } - if(referencedElement instanceof Method) { - ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); - if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { - return; - } + private class OMInspectionVisitor extends PhpElementVisitor { - PhpClass phpClass = ((Method) referencedElement).getContainingClass(); + private ProblemsHolder problemsHolder; - verifyPhpClass(phpClass, reference); - } - } + public OMInspectionVisitor(@NotNull ProblemsHolder problemsHolder) { + super(); + this.problemsHolder = problemsHolder; + } - @Override - public void visitPhpClassReference(ClassReference reference) { - PsiElement referencedElement = reference.resolve(); + @Override + public void visitPhpMethodReference(MethodReference reference) { + PsiElement referencedElement = reference.resolve(); - if(referencedElement instanceof PhpClass) { - ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); - if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { - return; - } - - verifyPhpClass((PhpClass)referencedElement, reference); + if(referencedElement instanceof Method) { + ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); + if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { + return; } + + PhpClass phpClass = ((Method) referencedElement).getContainingClass(); + + verifyPhpClass(phpClass, reference); } + } - private void verifyPhpClass(PhpClass phpClass, PsiReference reference) { - if (phpClass == null) { + @Override + public void visitPhpClassReference(ClassReference reference) { + PsiElement referencedElement = reference.resolve(); + + if(referencedElement instanceof PhpClass) { + ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); + if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { return; } - if (phpClass.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { + verifyPhpClass((PhpClass)referencedElement, reference); + } + } + + private void verifyPhpClass(PhpClass phpClass, PsiReference reference) { + if (phpClass == null) { + return; + } + + if (phpClass.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { + registerProblem(reference); + return; + } + + for (PhpClass implementedInterface : phpClass.getImplementedInterfaces()) { + if (implementedInterface.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { registerProblem(reference); return; } - - for (PhpClass implementedInterface : phpClass.getImplementedInterfaces()) { - if (implementedInterface.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { - registerProblem(reference); - return; - } - } } + } - private void registerProblem(PsiReference reference) { - problemsHolder.registerProblem(reference, "ObjectManager is not recommended to use in module", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } - }; + private void registerProblem(PsiReference reference) { + problemsHolder.registerProblem(reference, "ObjectManager is not recommended to use in module", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } } } diff --git a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java index a011f45c7..f1f1948d4 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java +++ b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java @@ -1,13 +1,14 @@ package com.magento.idea.magento2plugin.php.module; import com.intellij.json.psi.*; +import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * Created by dkvashnin on 12/5/15. @@ -65,12 +66,12 @@ public String[] getAutoloadFiles() { if (autoloadObject != null) { JsonArray jsonArray = getPropertyValueOfType(FILES, JsonArray.class); if (jsonArray != null) { - List files = jsonArray.getValueList() - .stream() - .filter(value -> value instanceof JsonStringLiteral) - .map(v -> ((JsonStringLiteral) v).getValue()) - .collect(Collectors.toList()); - + List files = new ArrayList<>(); + for(JsonValue value: jsonArray.getValueList()) { + if (value instanceof JsonStringLiteral) { + files.add(StringUtils.strip(value.getText(), "\"")); + } + } return files.size() > 0 ? files.toArray(new String[files.size()]) : null; } } @@ -90,7 +91,7 @@ public Map getAutoloadPsr4() { JsonValue value = property.getValue(); if (value != null && value instanceof JsonStringLiteral) { - map.put(property.getName(), ((JsonStringLiteral) value).getValue()); + map.put(property.getName(), StringUtils.strip(value.getText(), "\"")); } } @@ -120,7 +121,7 @@ private String getStringPropertyValue(String propertyName) { JsonStringLiteral stringLiteral = getPropertyValueOfType(propertyName, JsonStringLiteral.class); if (stringLiteral != null) { - return stringLiteral.getValue(); + return StringUtils.strip(stringLiteral.getText(), "\""); } return null; diff --git a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java index fa34de197..948ee4380 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java +++ b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java @@ -21,6 +21,10 @@ public class XmlHelper extends XmlHelperUtility { public static final String TYPE_ATTRIBUTE = "type"; public static final String FOR_ATTRIBUTE = "for"; + public static final String OBJECT_TYPE = "object"; + public static final String CONST_TYPE = "const"; + public static final String INIT_TYPE = "init_parameter"; + /** * diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java b/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java index 193dd3ab1..11149e5da 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java @@ -18,7 +18,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; /** * Created by dkvashnin on 10/18/15. @@ -38,13 +37,11 @@ public ResolveResult[] multiResolve(boolean b) { List list = new ArrayList(); String argumentName = StringUtil.unquoteString(getElement().getText()); - list.addAll( - getParameters() - .stream() - .filter(parameter -> parameter.getName().equals(argumentName)) - .map(PsiElementResolveResult::new) - .collect(Collectors.toList()) - ); + for (Parameter parameter: getParameters()) { + if (argumentName.equals(parameter.getName())) { + list.add(new PsiElementResolveResult(parameter)); + } + } return list.toArray(new ResolveResult[list.size()]); } diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java index 2e51f3180..9599ad1ef 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java @@ -16,10 +16,6 @@ * Created by Warider on 17.08.2015. */ public class DiReferenceContributor extends PsiReferenceContributor { - private static final String OBJECT_TYPE_NAME = "object"; - private static final String CONST_TYPE_NAME = "const"; - private static final String INIT_TYPE_NAME = "init_parameter"; - @Override public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { // @@ -70,8 +66,8 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // SomeClassOrVirtualType psiReferenceRegistrar.registerReferenceProvider( XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType(OBJECT_TYPE_NAME), - XmlHelper.getItemValuePatternForType(OBJECT_TYPE_NAME) + XmlHelper.getArgumentValuePatternForType(XmlHelper.OBJECT_TYPE), + XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE) ), new XmlReferenceProvider( new ReferenceResultsFiller[]{ @@ -90,10 +86,10 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // SomeClass::SOME_CONSTANT psiReferenceRegistrar.registerReferenceProvider( XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType(CONST_TYPE_NAME), - XmlHelper.getArgumentValuePatternForType(INIT_TYPE_NAME), - XmlHelper.getItemValuePatternForType(CONST_TYPE_NAME), - XmlHelper.getItemValuePatternForType(INIT_TYPE_NAME) + XmlHelper.getArgumentValuePatternForType(XmlHelper.CONST_TYPE), + XmlHelper.getArgumentValuePatternForType(XmlHelper.INIT_TYPE), + XmlHelper.getItemValuePatternForType(XmlHelper.CONST_TYPE), + XmlHelper.getItemValuePatternForType(XmlHelper.INIT_TYPE) ), new PsiReferenceProvider() { @NotNull diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java index d40a5a246..1268d6bdc 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java @@ -20,7 +20,7 @@ public String resolveTypeName(XmlTag xmlTag) { String parentTypeName = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); if (parentTypeName == null) { - return parentTypeName; + return null; } String superParentName = VirtualTypesNamesFileBasedIndex.getSuperParentTypeName(xmlTag.getProject(), parentTypeName); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java index 73742fd4b..b915e3829 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java @@ -5,6 +5,7 @@ import com.intellij.openapi.project.Project; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlFile; import com.intellij.util.ProcessingContext; import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; @@ -18,8 +19,6 @@ import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import org.jetbrains.annotations.NotNull; -import java.util.stream.Collectors; - /** * Created by dkvashnin on 11/18/15. */ @@ -91,13 +90,11 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { PsiElement psiElement = completionParameters.getOriginalPosition(); Project project = psiElement.getProject(); - - completionResultSet.addAllElements( - LayoutUtility.getLayoutFiles(project) - .stream() - .map(e -> LookupElementBuilder.create(e.getVirtualFile().getNameWithoutExtension())) - .collect(Collectors.toList()) - ); + for (XmlFile xmlFile: LayoutUtility.getLayoutFiles(project)) { + completionResultSet.addElement( + LookupElementBuilder.create(xmlFile.getVirtualFile().getNameWithoutExtension()) + ); + } } } ); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index 836baa650..e25579131 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -65,13 +65,18 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelperUtility.getTagAttributeValuePattern("update", "handle"), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - (psiElement, results, typeName) -> results.addAll( - Arrays.asList( - PsiElementResolveResult.createResults( - LayoutUtility.getLayoutFiles(psiElement.getProject(), typeName) - ) - ) - ) + new ReferenceResultsFiller() { + @Override + public void fillResolveResults(PsiElement psiElement, List results, String typeName) { + results.addAll( + Arrays.asList( + PsiElementResolveResult.createResults( + LayoutUtility.getLayoutFiles(psiElement.getProject(), typeName) + ) + ) + ); + } + } } ) ); diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java index c270968cb..8a1c8ce14 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java @@ -50,7 +50,7 @@ public Map map(@NotNull FileContent fileContent) { List results = new ArrayList(); recursiveFill(results, phpFile); for (String result: results) { - map.putIfAbsent(result, null); + map.put(result, null); } return map; From 457f3476821807ca51489f44fc570cfa708c299d Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Thu, 24 Dec 2015 23:11:04 +0200 Subject: [PATCH 22/51] Di - Smart class/virtualType completion for type arguments depending on their type DI - Smart class/virtualType completion for preference depending on its type --- .../php/util/ImplementationMatcher.java | 2 +- .../util/PsiContextMatcherI.java | 6 +- .../completion/ClassCompletionProvider.java | 4 +- .../xml/completion/CompletionProviderI.java | 4 +- .../VirtualTypeCompletionProvider.java | 16 +- .../completion/DiCompletionContributor.java | 192 +++++++++++++++++- .../VirtualTypesNamesFileBasedIndex.java | 17 ++ .../xml/di/reference/ConstantReference.java | 7 +- .../ReferenceComponentCompletionProvider.java | 4 +- 9 files changed, 233 insertions(+), 19 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java b/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java index 1f9852b77..41fd5c3fd 100644 --- a/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java +++ b/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java @@ -7,7 +7,7 @@ /** * Created by dkvashnin on 12/18/15. */ -public class ImplementationMatcher implements PsiContextMatcherI { +public class ImplementationMatcher implements PsiContextMatcherI { private String type; public ImplementationMatcher(String type) { diff --git a/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java b/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java index 683959f59..7ab6d1ff4 100644 --- a/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java +++ b/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java @@ -1,10 +1,8 @@ package com.magento.idea.magento2plugin.util; -import com.intellij.psi.PsiElement; - /** * Created by dkvashnin on 12/18/15. */ -public interface PsiContextMatcherI { - boolean match(PsiElement psiElement); +public interface PsiContextMatcherI { + boolean match(T psiElement); } diff --git a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java index e066d3085..688e4d096 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java @@ -18,8 +18,8 @@ /** * Created by dkvashnin on 11/17/15. */ -public class ClassCompletionProvider implements CompletionProviderI { - public final static CompletionProviderI INSTANCE = new ClassCompletionProvider(); +public class ClassCompletionProvider implements CompletionProviderI { + public final static ClassCompletionProvider INSTANCE = new ClassCompletionProvider(); @Override public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { diff --git a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java index b3f943860..09348290d 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java @@ -10,8 +10,8 @@ /** * Created by dkvashnin on 11/17/15. */ -public interface CompletionProviderI { - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context); +public interface CompletionProviderI { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context); public List collectCompletionResult(PsiElement psiElement); } diff --git a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java index 32269e902..82d51b4b0 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java @@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement; import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; +import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -13,18 +14,25 @@ /** * Created by dkvashnin on 11/17/15. */ -public class VirtualTypeCompletionProvider implements CompletionProviderI { - public final static CompletionProviderI INSTANCE = new VirtualTypeCompletionProvider(); +public class VirtualTypeCompletionProvider implements CompletionProviderI { + public final static VirtualTypeCompletionProvider INSTANCE = new VirtualTypeCompletionProvider(); @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { List result = new ArrayList<>(); + String input = StringUtils.strip(psiElement.getText(), "\""); String[] allVirtualTypesNames = VirtualTypesNamesFileBasedIndex.getAllVirtualTypesNames( psiElement.getProject() ); for (String name: allVirtualTypesNames) { - result.add(LookupElementBuilder.create(name)); + if (name.toLowerCase().contains(input.toLowerCase())) { + if (context != null && !context.match(name)) { + continue; + } + + result.add(LookupElementBuilder.create(name)); + } } return result; diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java index 1f0e8add0..e046fc496 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java @@ -1,14 +1,29 @@ package com.magento.idea.magento2plugin.xml.di.completion; import com.intellij.codeInsight.completion.*; +import com.intellij.openapi.project.Project; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.Parameter; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.xml.di.XmlHelper; +import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; /** * Created by dkvashnin on 10/15/15. @@ -22,10 +37,8 @@ public class DiCompletionContributor extends CompletionContributor { public DiCompletionContributor() { extend(CompletionType.BASIC, XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType("object"), - XmlHelper.getItemValuePatternForType("object"), + XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE), XmlHelper.getTagAttributePattern(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE), - XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.TYPE_ATTRIBUTE), XmlHelper.getTagAttributePattern(XmlHelper.VIRTUAL_TYPE_TAG, XmlHelper.TYPE_ATTRIBUTE), XmlHelper.getTagAttributePattern(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE) ), @@ -40,5 +53,178 @@ public void addCompletions(@NotNull CompletionParameters parameters, } } ); + + extend(CompletionType.BASIC, + XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.TYPE_ATTRIBUTE), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + PsiElement psiElement = parameters.getOriginalPosition(); + PhpClass preferenceClass = getPreferenceClass(psiElement); + + if (preferenceClass == null) { + return; + } + + ParentTypeMatcher parentTypeMatcher = new ParentTypeMatcher(preferenceClass); + resultSet.addAllElements(ClassCompletionProvider.INSTANCE + .collectCompletionResult(psiElement, parentTypeMatcher) + ); + + resultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE + .collectCompletionResult( + psiElement, + new VirtualTypeParentMatcher(parentTypeMatcher, psiElement.getProject()) + ) + ); + } + } + ); + + extend(CompletionType.BASIC, + XmlHelper.getArgumentValuePatternForType(XmlHelper.OBJECT_TYPE), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + PsiElement psiElement = parameters.getOriginalPosition(); + + PhpClass argumentClass = getArgumentClass(psiElement); + + if (argumentClass == null) { + return; + } + + ParentTypeMatcher parentTypeMatcher = new ParentTypeMatcher(argumentClass); + + resultSet.addAllElements(ClassCompletionProvider.INSTANCE + .collectCompletionResult(psiElement, parentTypeMatcher) + ); + + resultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE + .collectCompletionResult( + psiElement, + new VirtualTypeParentMatcher(parentTypeMatcher, psiElement.getProject()) + ) + ); + } + } + ); + } + + private class ParentTypeMatcher implements PsiContextMatcherI { + + private PhpClass parentType; + + public ParentTypeMatcher(PhpClass parentType) { + this.parentType = parentType; + } + + @Override + public boolean match(PsiElement psiElement) { + if (!(psiElement instanceof PhpClass)) { + return false; + } + + return parentType.equals(psiElement) + || match(((PhpClass)psiElement).getImplementedInterfaces()) + || match(((PhpClass) psiElement).getSuperClass()); + } + + public boolean match(@Nullable PhpClass[] probableMistakes) { + if (probableMistakes == null) { + return false; + } + + boolean result = false; + + for (PhpClass probableMistake : probableMistakes) { + result = parentType.equals(probableMistake) || match(probableMistake.getImplementedInterfaces()); + } + + return result; + } + } + + private class VirtualTypeParentMatcher implements PsiContextMatcherI { + private ParentTypeMatcher parentTypeMatcher; + private Project project; + + public VirtualTypeParentMatcher(ParentTypeMatcher parentTypeMatcher, Project project) { + this.parentTypeMatcher = parentTypeMatcher; + this.project = project; + } + + @Override + public boolean match(String virtualType) { + List superParentTypes = VirtualTypesNamesFileBasedIndex.getSuperParentTypes(project, virtualType); + + return parentTypeMatcher.match( + superParentTypes.toArray(new PhpClass[superParentTypes.size()]) + ); + } + } + + @Nullable + private PhpClass getPreferenceClass(PsiElement psiElement) { + XmlAttribute parentAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); + if (parentAttribute == null) { + return null; + } + + XmlTag xmlTag = parentAttribute.getParent(); + XmlAttribute preferenceAttr = xmlTag.getAttribute(XmlHelper.FOR_ATTRIBUTE); + if (preferenceAttr == null) { + return null; + } + + XmlAttributeValue valueElement = preferenceAttr.getValueElement(); + PsiReference reference = valueElement.getReference(); + if (reference == null) { + return null; + } + + PsiElement element = reference.resolve(); + if (element instanceof PhpClass) { + return (PhpClass) element; + } + + return null; + } + + @Nullable + private PhpClass getArgumentClass(PsiElement psiElement) { + XmlTag xmlTag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class); + if (xmlTag == null) { + return null; + } + + XmlAttribute preferenceAttr = xmlTag.getAttribute(XmlHelper.NAME_ATTRIBUTE); + if (preferenceAttr == null) { + return null; + } + + XmlAttributeValue valueElement = preferenceAttr.getValueElement(); + PsiReference reference = valueElement.getReference(); + if (reference == null) { + return null; + } + + PsiElement element = reference.resolve(); + if (element instanceof Parameter) { + String stringResolved = ((Parameter) element).getDeclaredType().toStringResolved(); + PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); + + ArrayList result = new ArrayList<>(); + result.addAll(phpIndex.getClassesByFQN(stringResolved)); + result.addAll(phpIndex.getInterfacesByFQN(stringResolved)); + + if (result.size() > 0) { + return result.get(0); + } + } + + return null; } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java index d18be7d93..68bef93ef 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java @@ -17,6 +17,7 @@ import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.PhpClass; import org.jetbrains.annotations.NotNull; @@ -100,6 +101,22 @@ public static String getSuperParentTypeName(final Project project, String inputC : superName; } + public static List getSuperParentTypes(final Project project, String inputChildTypeName) { + List result = new ArrayList<>(); + + String superName = getSuperParentTypeName(project, inputChildTypeName); + if (superName == null) { + return result; + } + + PhpIndex phpIndex = PhpIndex.getInstance(project); + + result.addAll(phpIndex.getClassesByFQN(superName)); + result.addAll(phpIndex.getInterfacesByFQN(superName)); + + return result; + } + @NotNull @Override public ID getName() { diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java b/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java index 6907a7f66..f34cf7714 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -41,7 +42,11 @@ public ResolveResult[] multiResolve(boolean b) { String constantName = parts.get(1); List fields = new ArrayList(); - for (PhpClass phpClass: phpIndex.getClassesByFQN(className)) { + Collection classesAndInterfaces = new ArrayList<>(); + classesAndInterfaces.addAll(phpIndex.getClassesByFQN(className)); + classesAndInterfaces.addAll(phpIndex.getInterfacesByFQN(className)); + + for (PhpClass phpClass: classesAndInterfaces) { for(Field field: phpClass.getFields()) { if (field.isConstant() && field.getName().equals(constantName)) { fields.add(new PsiElementResolveResult(field)); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java index 8e0078101..ca6daaf67 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java @@ -17,7 +17,7 @@ /** * Created by dkvashnin on 11/18/15. */ -public class ReferenceComponentCompletionProvider implements CompletionProviderI { +public class ReferenceComponentCompletionProvider implements CompletionProviderI { private ID indexId; public ReferenceComponentCompletionProvider(ID indexId) { @@ -25,7 +25,7 @@ public ReferenceComponentCompletionProvider(ID indexId) { } @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { Collection keys = LayoutIndexUtility.getAllKeys(indexId, psiElement.getProject()); List results = new ArrayList<>(); From 3a6b304f2f8faa7a76a9453fb3311c93687e72ea Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Thu, 24 Dec 2015 23:52:35 +0200 Subject: [PATCH 23/51] Refactored webapi completion/references --- magento2plugin.iml | 2 +- .../completion/ClassCompletionProvider.java | 2 +- .../InterfaceCompletionProvider.java | 14 ++- .../magento2plugin/xml/webapi/XmlHelper.java | 59 +++++------ .../WebApiCompletionContributor.java | 98 +++++++++---------- .../fill/ServiceMethodResultsFiller.java | 18 ++-- .../resolver/InterfaceNameResolver.java | 45 --------- 7 files changed, 92 insertions(+), 146 deletions(-) delete mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java diff --git a/magento2plugin.iml b/magento2plugin.iml index 83921c24b..0f0805366 100644 --- a/magento2plugin.iml +++ b/magento2plugin.iml @@ -7,7 +7,7 @@ - + diff --git a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java index 688e4d096..327a4ee31 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java @@ -22,7 +22,7 @@ public class ClassCompletionProvider implements CompletionProviderI public final static ClassCompletionProvider INSTANCE = new ClassCompletionProvider(); @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { List result = new ArrayList<>(); PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); String prefix = StringUtil.unquoteString(psiElement.getText()); diff --git a/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java index 860a137f6..63dfe4f2d 100644 --- a/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java @@ -7,6 +7,7 @@ import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.util.PsiContextMatcherI; +import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -16,17 +17,22 @@ /** * Created by mslabko on 18.12.2015. */ -public class InterfaceCompletionProvider implements CompletionProviderI { - public final static CompletionProviderI INSTANCE = new InterfaceCompletionProvider(); +public class InterfaceCompletionProvider implements CompletionProviderI { + public final static InterfaceCompletionProvider INSTANCE = new InterfaceCompletionProvider(); @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { + public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { List result = new ArrayList<>(); PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); + String input = StringUtils.strip(psiElement.getText(), "\""); Collection interfaceNames = phpIndex.getAllInterfaceNames(); for (String interfaceName: interfaceNames) { + if (!interfaceName.toLowerCase().contains(input.toLowerCase())) { + continue; + } + Collection classesByName = phpIndex.getInterfacesByName(interfaceName); for (PhpClass phpClass: classesByName) { if (context != null && !context.match(phpClass)) { @@ -38,7 +44,7 @@ public List collectCompletionResult(PsiElement psiElement, @Nulla result.add( LookupElementBuilder .create(classFqn) - .withIcon(PhpIcons.CLASS_ICON) + .withIcon(PhpIcons.INTERFACE_ICON) ); } } diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java index b5de94c2f..cbd6e4b73 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java @@ -4,8 +4,12 @@ import com.intellij.patterns.XmlAttributeValuePattern; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; import com.intellij.psi.xml.XmlTokenType; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; +import org.jetbrains.annotations.Nullable; /** * Created by isentiabov on 20.12.2015. @@ -23,46 +27,29 @@ public static XmlAttributeValuePattern getMethodAttributePattern() { return getTagAttributeValuePattern(SERVICE_TAG, METHOD_ATTRIBUTE, FILE_TYPE); } - /** - * \Namespace\Class - * @param typeName Type name - */ - public static PsiElementPattern.Capture getArgumentValuePatternForType(String typeName) { - return XmlPatterns - .psiElement(XmlTokenType.XML_DATA_CHARACTERS) - .withParent( - XmlPatterns - .xmlText() - .withParent(XmlPatterns - .xmlTag() - .withName("argument") - .withAttributeValue("xsi:type", typeName) - ) - ).inFile(XmlHelper.getXmlFilePattern(FILE_TYPE)); - } - - /** - * \Namespace\Class - * @param typeName Type name - */ - public static PsiElementPattern.Capture getItemValuePatternForType(String typeName) { - return XmlPatterns - .psiElement(XmlTokenType.XML_DATA_CHARACTERS) - .withParent( - XmlPatterns - .xmlText() - .withParent(XmlPatterns - .xmlTag() - .withName("item") - .withAttributeValue("xsi:type", typeName) - ) - ).inFile(XmlHelper.getXmlFilePattern(FILE_TYPE)); - } - /** * */ public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { return getTagAttributePattern(tag, attributeName, FILE_TYPE); } + + @Nullable + public static XmlAttribute getInterfaceAttributeByMethod(PsiElement psiElement) + { + // get service xml tag `method` attribute + XmlAttribute methodAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); + if (methodAttribute == null) { + return null; + } + + // get service xml tag + XmlTag serviceTag = PsiTreeUtil.getParentOfType(methodAttribute, XmlTag.class); + if (serviceTag == null) { + return null; + } + + // get service xml tag `class` attribute + return serviceTag.getAttribute(CLASS_ATTRIBUTE); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java index d3e918205..61ef95a50 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java @@ -2,94 +2,90 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.util.ProcessingContext; import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; -import com.magento.idea.magento2plugin.xml.webapi.reference.resolver.InterfaceNameResolver; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Iterator; - /** * Created by mslabko on 10/15/15. */ public class WebApiCompletionContributor extends CompletionContributor { - private CompletionProviderI[] completionProviders = new CompletionProviderI[] { - InterfaceCompletionProvider.INSTANCE - }; - public WebApiCompletionContributor() { // add services to list - extend(CompletionType.BASIC, - XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType("object"), - XmlHelper.getItemValuePatternForType("object"), - XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.CLASS_ATTRIBUTE) - ), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - PsiElement psiElement = parameters.getOriginalPosition(); - for (CompletionProviderI completionProvider: completionProviders) { - resultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); - } - } + extend( + CompletionType.BASIC, + XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.CLASS_ATTRIBUTE), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + PsiElement psiElement = parameters.getOriginalPosition(); + + resultSet.addAllElements(InterfaceCompletionProvider.INSTANCE.collectCompletionResult(psiElement)); } + } ); + // Add service methods to list extend( - CompletionType.BASIC, - XmlPatterns.or( - XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.METHOD_ATTRIBUTE) - ), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { + CompletionType.BASIC, + XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.METHOD_ATTRIBUTE), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + + PsiElement psiElement = parameters.getOriginalPosition(); - PsiElement psiElement = parameters.getOriginalPosition(); + PhpClass serviceInterface = getServiceInterface(psiElement); + if (serviceInterface != null) { + for (Method serviceMethod : serviceInterface.getMethods()) { - PhpClass serviceInterface = getServiceInterface(psiElement); - if (serviceInterface != null) { - for (Method serviceMethod : serviceInterface.getMethods()) { - resultSet.addElement(LookupElementBuilder - .create(serviceMethod.getName()) - .withIcon(PhpIcons.METHOD_ICON) - ); - } + resultSet.addElement( + LookupElementBuilder + .create(serviceMethod.getName()) + .withIcon(PhpIcons.METHOD_ICON) + ); } } } + } ); } @Nullable private PhpClass getServiceInterface(PsiElement psiElement) { - InterfaceNameResolver resolver = new InterfaceNameResolver(); - XmlAttribute classAttribute = resolver.getInterfaceAttributeByMethod(psiElement); + XmlAttribute classAttribute = XmlHelper.getInterfaceAttributeByMethod(psiElement); if (classAttribute == null) { return null; } - String className = classAttribute.getValue(); - if (className == null) { + + XmlAttributeValue xmlAttributeValue = classAttribute.getValueElement(); + + if (xmlAttributeValue == null) { + return null; + } + + PsiReference reference = xmlAttributeValue.getReference(); + if (reference == null) { return null; } - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - Iterator iterator = phpIndex.getInterfacesByFQN(PhpLangUtil.toFQN(className)).iterator(); - if (iterator.hasNext()) { - return iterator.next(); + + PsiElement element = reference.resolve(); + + if (element instanceof PhpClass) { + return (PhpClass) element; } + return null; } } diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java index d600c3216..65d0d665c 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java @@ -1,17 +1,18 @@ package com.magento.idea.magento2plugin.xml.webapi.reference.fill; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; import com.intellij.psi.ResolveResult; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; +import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.webapi.reference.resolver.InterfaceNameResolver; +import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; import org.jetbrains.annotations.Nullable; +import java.util.Iterator; import java.util.List; /** @@ -20,8 +21,7 @@ public class ServiceMethodResultsFiller implements ReferenceResultsFiller { @Override public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - InterfaceNameResolver resolver = new InterfaceNameResolver(); - XmlAttribute classAttribute = resolver.getInterfaceAttributeByMethod(psiElement); + XmlAttribute classAttribute = XmlHelper.getInterfaceAttributeByMethod(psiElement); if (classAttribute == null) { return; } @@ -43,12 +43,14 @@ protected PhpClass getServiceInterface(XmlAttribute xmlAttribute) { return null; } - PsiReference reference = value.getReference(); - if (reference == null) { - return null; + PhpIndex phpIndex = PhpIndex.getInstance(xmlAttribute.getProject()); + + Iterator iterator = phpIndex.getInterfacesByFQN(value.getValue()).iterator(); + if (iterator.hasNext()) { + return iterator.next(); } - return (PhpClass)reference.resolve(); + return null; } protected void fillResults(PhpClass serviceInterface, List results, String typeName) { diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java deleted file mode 100644 index 37f6b1c1c..000000000 --- a/src/com/magento/idea/magento2plugin/xml/webapi/reference/resolver/InterfaceNameResolver.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.magento.idea.magento2plugin.xml.webapi.reference.resolver; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlTag; -import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; -import org.jetbrains.annotations.Nullable; - -/** - * Created by isentiabov on 22.12.2015. - */ -public class InterfaceNameResolver { - - @Nullable - public XmlAttribute getInterfaceAttributeByMethod(PsiElement psiElement) - { - // get service xml tag `method` attribute - XmlAttribute methodAttribute = getMethodAttribute(psiElement); - if (methodAttribute == null) { - return null; - } - - // get service xml tag - XmlTag serviceTag = getServiceTag(methodAttribute); - if (serviceTag == null) { - return null; - } - - // get service xml tag `class` attribute - return getClassAttribute(serviceTag); - } - - protected XmlAttribute getMethodAttribute(PsiElement xmlAttribute) { - return PsiTreeUtil.getParentOfType(xmlAttribute, XmlAttribute.class); - } - - protected XmlTag getServiceTag(XmlAttribute xmlAttribute) { - return PsiTreeUtil.getParentOfType(xmlAttribute, XmlTag.class); - } - - protected XmlAttribute getClassAttribute(XmlTag xmlTag) { - return xmlTag.getAttribute(XmlHelper.CLASS_ATTRIBUTE); - } -} From 15e891620cbc41adfc91252dd330d5e356d60168 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Thu, 24 Dec 2015 23:57:12 +0200 Subject: [PATCH 24/51] Added completion for preference interfaces --- .../di/completion/DiCompletionContributor.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java index e046fc496..a5b4009ed 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java @@ -16,6 +16,7 @@ import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; +import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.xml.di.XmlHelper; import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; @@ -54,6 +55,21 @@ public void addCompletions(@NotNull CompletionParameters parameters, } ); + extend( + CompletionType.BASIC, + XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.FOR_ATTRIBUTE), + new CompletionProvider() { + public void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + PsiElement psiElement = parameters.getOriginalPosition(); + resultSet.addAllElements(InterfaceCompletionProvider.INSTANCE + .collectCompletionResult(psiElement) + ); + } + } + ); + extend(CompletionType.BASIC, XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.TYPE_ATTRIBUTE), new CompletionProvider() { From b424dd459a1d2cd5a9bd8fa59de8c48e4cb7a516 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 25 Dec 2015 00:22:30 +0200 Subject: [PATCH 25/51] Changed version, added notes --- META-INF/plugin.xml | 40 ++++++++++++++++++++++++++++++++++++++-- magento2plugin.iml | 1 - 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index e3609cfca..bade7bc47 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,14 +1,50 @@ com.magento.idea.magento2plugin Magento2 - 0.0.9 - Dmytro Kvashnin + 0.1 + Dmytro Kvashnin Features + +

Configuration smart completion and references

+
    +
  • di.xml
  • +
  • layouts
  • +
  • events.xml
  • +
  • webapi.xml
  • +
+ +

Inspections

+
    +
  • @api usage
  • +
  • ObjectManager usage
  • +
+ +

Code helpers

+
    +
  • "Navigate to configuration" reference in scope of class/interface
  • +
  • "Go to plugin" reference in scope of class/interface
  • +
]]>
0.1 +
    +
  • Context type completion for:
    + - Observers completion only for ObserverInterface impl in events.xml
    + - Blocks completion only for BlockInterface name in layouts.xml
    + - Preference configuration in di.xml
    + - Type hinting for object arguments in di.xml
    +
  • +
  • @api usage inspection in Module context
  • +
  • ObjectManager usage inspection in Module context
  • +
  • virtualType arguments resolution
  • +
  • webapi.xml interface/method completion/references
  • +
  • Support for old people using PhpStorm 8 or JDK1.7
  • +
+

0.0.9

  • Added Reference and completion support for layouts
    diff --git a/magento2plugin.iml b/magento2plugin.iml index 0f0805366..26aa60e1f 100644 --- a/magento2plugin.iml +++ b/magento2plugin.iml @@ -5,7 +5,6 @@ - From b59780a8be98f0bc9f1e8d0144e04670cf36a115 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 25 Dec 2015 00:22:24 +0200 Subject: [PATCH 26/51] Update README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index c77893b89..b0d7f4518 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,32 @@ This is a plugin for Magento 2 development in the PhpStorm IDE. It is available 4. Install the plugin and restart PhpStorm +## Works with +* PhpStorm >= 8.0.3 +* JRE >= 1.7 + +

    Features

    + +

    Configuration smart completion and references

    +
      +
    • di.xml
    • +
    • layouts
    • +
    • events.xml
    • +
    • webapi.xml
    • +
    + +

    Inspections

    +
      +
    • @api usage
    • +
    • ObjectManager usage
    • +
    + +

    Code helpers

    +
      +
    • "Navigate to configuration" reference in scope of class/interface
    • +
    • "Go to plugin" reference in scope of class/interface
    • +
    + ## License Copyright (c) 2015 Dmytro Kvashnin. See LICENSE.md for details. From c49cef293f66613f3e8e00f2b2cce5d53b64977f Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 25 Dec 2015 15:11:16 +0200 Subject: [PATCH 27/51] Fixed performance issues and concurrency bugs --- .../php/util/PsiContextMatcherManager.java | 14 +------------- .../LayoutCompletionContributor.java | 18 +++++++++--------- .../reference/LayoutReferenceContributor.java | 6 +++++- .../completion/EventCompletionContributor.java | 12 +++--------- .../ObserverReferenceContributor.java | 6 +++++- .../util/ImplementationContextDecorator.java | 8 +++----- 6 files changed, 26 insertions(+), 38 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java b/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java index 926bd6f02..398dc8d69 100644 --- a/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java +++ b/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java @@ -11,22 +11,10 @@ public class PsiContextMatcherManager { private static PsiContextMatcherManager INSTANCE; - private Map map = new HashMap<>(); - private PsiContextMatcherManager() {} public ImplementationMatcher getImplementationMatcherForType(String type) { - if (map.containsKey(type)) { - - PsiContextMatcherI psiContextMatcherI = map.get(type); - if (psiContextMatcherI instanceof ImplementationMatcher) { - return (ImplementationMatcher)psiContextMatcherI; - } - } - ImplementationMatcher implementationMatcher = new ImplementationMatcher(type); - map.put(type, implementationMatcher); - - return implementationMatcher; + return new ImplementationMatcher(type); } public static PsiContextMatcherManager getInstance() { diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java index b915e3829..7955b752c 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java @@ -7,6 +7,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.xml.XmlFile; import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; import com.magento.idea.magento2plugin.util.PsiContextMatcherI; @@ -23,11 +24,6 @@ * Created by dkvashnin on 11/18/15. */ public class LayoutCompletionContributor extends CompletionContributor { - private CompletionProviderI[] typeCompletionProviders = new CompletionProviderI[] { - ClassCompletionProvider.INSTANCE, - VirtualTypeCompletionProvider.INSTANCE - }; - private ReferenceComponentCompletionProvider containerCompletionProvider = new ReferenceComponentCompletionProvider(ContainerFileBasedIndex.NAME); private ReferenceComponentCompletionProvider blockCompletionProvider = new ReferenceComponentCompletionProvider(BlockFileBasedIndex.NAME); @@ -40,11 +36,15 @@ public LayoutCompletionContributor() { @Override protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { PsiElement psiElement = completionParameters.getOriginalPosition(); - PsiContextMatcherI completionContext = PsiContextMatcherManager.getInstance() + ImplementationMatcher completionContext = PsiContextMatcherManager.getInstance() .getImplementationMatcherForType(MagentoTypes.BLOCK_TYPE); - for (CompletionProviderI completionProvider: typeCompletionProviders) { - completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement, completionContext)); - } + completionResultSet.addAllElements( + ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext) + ); + + completionResultSet.addAllElements( + VirtualTypeCompletionProvider.INSTANCE.collectCompletionResult(psiElement) + ); } } ); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index e25579131..70a13e45a 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -2,6 +2,7 @@ import com.intellij.patterns.XmlPatterns; import com.intellij.psi.*; +import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; @@ -28,7 +29,10 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelperUtility.getTagAttributeValuePattern("block", "class"), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - new ImplementationContextDecorator(ClassesResultsFiller.INSTANCE, MagentoTypes.BLOCK_TYPE), + new ImplementationContextDecorator( + ClassesResultsFiller.INSTANCE, + new ImplementationMatcher(MagentoTypes.BLOCK_TYPE) + ), VirtualTypesResultsFiller.INSTANCE } ) diff --git a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java index 1be94a494..aa715477e 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java @@ -22,11 +22,6 @@ * Created by dkvashnin on 11/17/15. */ public class EventCompletionContributor extends CompletionContributor { - private CompletionProviderI[] typeCompletionProviders = new CompletionProviderI[] { - ClassCompletionProvider.INSTANCE, - VirtualTypeCompletionProvider.INSTANCE - }; - public EventCompletionContributor() { extend( CompletionType.BASIC, @@ -37,9 +32,9 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters ImplementationMatcher completionContext = PsiContextMatcherManager.getInstance() .getImplementationMatcherForType(MagentoTypes.OBSERVER_TYPE); PsiElement psiElement = completionParameters.getOriginalPosition(); - for (CompletionProviderI completionProvider: typeCompletionProviders) { - completionResultSet.addAllElements(completionProvider.collectCompletionResult(psiElement, completionContext)); - } + + completionResultSet.addAllElements(ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext)); + completionResultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE.collectCompletionResult(psiElement)); } } ); @@ -56,7 +51,6 @@ protected void addCompletions(@NotNull CompletionParameters completionParameters for (String eventName: eventNames) { completionResultSet.addElement(LookupElementBuilder.create(eventName)); } - } } ); diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java index a5e7a814e..79c5ca23d 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java @@ -1,6 +1,7 @@ package com.magento.idea.magento2plugin.xml.observer.reference; import com.intellij.psi.*; +import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.observer.XmlHelper; @@ -23,7 +24,10 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelper.getTagAttributeValuePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - new ImplementationContextDecorator(ClassesResultsFiller.INSTANCE, MagentoTypes.OBSERVER_TYPE), + new ImplementationContextDecorator( + ClassesResultsFiller.INSTANCE, + new ImplementationMatcher(MagentoTypes.OBSERVER_TYPE) + ), VirtualTypesResultsFiller.INSTANCE } ) diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java index bd944f282..de255f76a 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java @@ -13,19 +13,17 @@ */ public class ImplementationContextDecorator implements ReferenceResultsFiller { private ReferenceResultsFiller subject; - private String type; + private ImplementationMatcher implementationMatcher; - public ImplementationContextDecorator(ReferenceResultsFiller subject, String type) { + public ImplementationContextDecorator(ReferenceResultsFiller subject, ImplementationMatcher implementationMatcher) { this.subject = subject; - this.type = type; + this.implementationMatcher = implementationMatcher; } @Override public void fillResolveResults(PsiElement psiElement, List results, String typeName) { subject.fillResolveResults(psiElement, results, typeName); - ImplementationMatcher implementationMatcher = PsiContextMatcherManager.getInstance() - .getImplementationMatcherForType(type); for (ResolveResult resolveResult : results) { PsiElement element = resolveResult.getElement(); From 4b13d2b10ab34a1d6c0557227bcb3976dfeafe5d Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Fri, 25 Dec 2015 17:26:23 +0200 Subject: [PATCH 28/51] Fixed bugs - layout container references --- .../php/util/PsiContextMatcherManager.java | 27 --------- .../completion/DiCompletionContributor.java | 59 +------------------ .../xml/layout/LayoutUtility.java | 5 ++ .../LayoutCompletionContributor.java | 6 +- .../layout/index/ContainerFileBasedIndex.java | 7 ++- .../layout/index/util/LayoutIndexUtility.java | 3 +- .../reference/LayoutReferenceContributor.java | 39 ++++++++---- .../EventCompletionContributor.java | 9 ++- .../ObserverReferenceContributor.java | 8 +-- .../xml/util/ParentTypeMatcher.java | 42 +++++++++++++ .../xml/util/VirtualTypeParentMatcher.java | 31 ++++++++++ 11 files changed, 122 insertions(+), 114 deletions(-) delete mode 100644 src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java create mode 100644 src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java create mode 100644 src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java diff --git a/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java b/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java deleted file mode 100644 index 398dc8d69..000000000 --- a/src/com/magento/idea/magento2plugin/php/util/PsiContextMatcherManager.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.magento.idea.magento2plugin.php.util; - -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by dkvashnin on 12/18/15. - */ -public class PsiContextMatcherManager { - private static PsiContextMatcherManager INSTANCE; - - private PsiContextMatcherManager() {} - - public ImplementationMatcher getImplementationMatcherForType(String type) { - return new ImplementationMatcher(type); - } - - public static PsiContextMatcherManager getInstance() { - if (INSTANCE == null) { - INSTANCE = new PsiContextMatcherManager(); - } - - return INSTANCE; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java index a5b4009ed..c0db61d02 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java @@ -1,7 +1,6 @@ package com.magento.idea.magento2plugin.xml.di.completion; import com.intellij.codeInsight.completion.*; -import com.intellij.openapi.project.Project; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; @@ -13,18 +12,17 @@ import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.Parameter; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; +import com.magento.idea.magento2plugin.xml.util.ParentTypeMatcher; +import com.magento.idea.magento2plugin.xml.util.VirtualTypeParentMatcher; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.List; /** * Created by dkvashnin on 10/15/15. @@ -129,59 +127,6 @@ public void addCompletions(@NotNull CompletionParameters parameters, ); } - private class ParentTypeMatcher implements PsiContextMatcherI { - - private PhpClass parentType; - - public ParentTypeMatcher(PhpClass parentType) { - this.parentType = parentType; - } - - @Override - public boolean match(PsiElement psiElement) { - if (!(psiElement instanceof PhpClass)) { - return false; - } - - return parentType.equals(psiElement) - || match(((PhpClass)psiElement).getImplementedInterfaces()) - || match(((PhpClass) psiElement).getSuperClass()); - } - - public boolean match(@Nullable PhpClass[] probableMistakes) { - if (probableMistakes == null) { - return false; - } - - boolean result = false; - - for (PhpClass probableMistake : probableMistakes) { - result = parentType.equals(probableMistake) || match(probableMistake.getImplementedInterfaces()); - } - - return result; - } - } - - private class VirtualTypeParentMatcher implements PsiContextMatcherI { - private ParentTypeMatcher parentTypeMatcher; - private Project project; - - public VirtualTypeParentMatcher(ParentTypeMatcher parentTypeMatcher, Project project) { - this.parentTypeMatcher = parentTypeMatcher; - this.project = project; - } - - @Override - public boolean match(String virtualType) { - List superParentTypes = VirtualTypesNamesFileBasedIndex.getSuperParentTypes(project, virtualType); - - return parentTypeMatcher.match( - superParentTypes.toArray(new PhpClass[superParentTypes.size()]) - ); - } - } - @Nullable private PhpClass getPreferenceClass(PsiElement psiElement) { XmlAttribute parentAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java index 79015a2f6..823854b7f 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java @@ -23,6 +23,11 @@ public static boolean isLayoutFile(VirtualFile virtualFile) { return virtualFile.getFileType() == XmlFileType.INSTANCE && parent.isDirectory() && parent.getName().endsWith("layout"); } + public static boolean isLayoutFile(PsiFile psiFile) { + VirtualFile virtualFile = psiFile.getVirtualFile(); + return isLayoutFile(virtualFile); + } + public static List getLayoutFiles(Project project, @Nullable String fileName) { List results = new ArrayList(); Collection xmlFiles = FilenameIndex.getAllFilesByExt(project, "xml"); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java index 7955b752c..4272d091f 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java @@ -9,11 +9,8 @@ import com.intellij.util.ProcessingContext; import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; import com.magento.idea.magento2plugin.php.util.MagentoTypes; -import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; -import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; @@ -36,8 +33,7 @@ public LayoutCompletionContributor() { @Override protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { PsiElement psiElement = completionParameters.getOriginalPosition(); - ImplementationMatcher completionContext = PsiContextMatcherManager.getInstance() - .getImplementationMatcherForType(MagentoTypes.BLOCK_TYPE); + ImplementationMatcher completionContext = new ImplementationMatcher(MagentoTypes.BLOCK_TYPE); completionResultSet.addAllElements( ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext) ); diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java index 816b4420b..f6d4935a0 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java @@ -18,6 +18,11 @@ public ID getName() { @NotNull @Override public DataIndexer getIndexer() { - return new LayoutDataIndexer("block", "name"); + return new LayoutDataIndexer("container", "name"); + } + + @Override + public int getVersion() { + return 1; } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java index 5d20de1e0..184b7de99 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java @@ -11,6 +11,7 @@ import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.xml.layout.index.BlockClassFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; import java.util.ArrayList; import java.util.Collection; @@ -65,7 +66,7 @@ public static List getBlockDeclarations(String componentName, Project pr } public static List getContainerDeclarations(String componentName, Project project) { - return getComponentDeclarations(componentName, "container", BlockFileBasedIndex.NAME, project, new NameComponentMatcher()); + return getComponentDeclarations(componentName, "container", ContainerFileBasedIndex.NAME, project, new NameComponentMatcher()); } public static List getBlockClassDeclarations(PhpClass phpClass, Project project) { diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java index 70a13e45a..ccd1f1743 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java @@ -2,15 +2,14 @@ import com.intellij.patterns.XmlPatterns; import com.intellij.psi.*; -import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; -import com.magento.idea.magento2plugin.php.util.MagentoTypes; +import com.intellij.util.ProcessingContext; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; import com.magento.idea.magento2plugin.xml.layout.reference.fill.BlockResultsFiller; import com.magento.idea.magento2plugin.xml.layout.reference.fill.ContainerResultsFiller; +import com.magento.idea.magento2plugin.xml.reference.TypeReference; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ImplementationContextDecorator; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; @@ -27,12 +26,9 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen // psiReferenceRegistrar.registerReferenceProvider( XmlHelperUtility.getTagAttributeValuePattern("block", "class"), - new XmlReferenceProvider( + new LayoutReferenceProvider( new ReferenceResultsFiller[]{ - new ImplementationContextDecorator( - ClassesResultsFiller.INSTANCE, - new ImplementationMatcher(MagentoTypes.BLOCK_TYPE) - ), + ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } ) @@ -49,7 +45,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelperUtility.getTagAttributeValuePattern("move", "before"), XmlHelperUtility.getTagAttributeValuePattern("move", "after") ), - new XmlReferenceProvider( + new LayoutReferenceProvider( new ReferenceResultsFiller[]{ new BlockResultsFiller() } @@ -58,7 +54,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen psiReferenceRegistrar.registerReferenceProvider( XmlHelperUtility.getTagAttributeValuePattern("referenceContainer", "name"), - new XmlReferenceProvider( + new LayoutReferenceProvider( new ReferenceResultsFiller[]{ new ContainerResultsFiller() } @@ -67,7 +63,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen psiReferenceRegistrar.registerReferenceProvider( XmlHelperUtility.getTagAttributeValuePattern("update", "handle"), - new XmlReferenceProvider( + new LayoutReferenceProvider( new ReferenceResultsFiller[]{ new ReferenceResultsFiller() { @Override @@ -85,4 +81,25 @@ public void fillResolveResults(PsiElement psiElement, List result ) ); } + + private class LayoutReferenceProvider extends PsiReferenceProvider { + private final ReferenceResultsFiller[] resultsFillers; + + public LayoutReferenceProvider(ReferenceResultsFiller[] resultsFillers) { + super(); + this.resultsFillers = resultsFillers; + } + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { + PsiFile containingFile = psiElement.getContainingFile(); + if (!LayoutUtility.isLayoutFile(containingFile)) { + return new PsiReference[0]; + } + + return new PsiReference[]{new TypeReference(psiElement, resultsFillers)}; + } + } + } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java index aa715477e..b0cd063d3 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java @@ -6,10 +6,8 @@ import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; import com.magento.idea.magento2plugin.php.util.MagentoTypes; -import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; import com.magento.idea.magento2plugin.xml.XmlHelperUtility; import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; -import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; import com.magento.idea.magento2plugin.xml.observer.XmlHelper; @@ -29,11 +27,12 @@ public EventCompletionContributor() { new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - ImplementationMatcher completionContext = PsiContextMatcherManager.getInstance() - .getImplementationMatcherForType(MagentoTypes.OBSERVER_TYPE); + ImplementationMatcher completionContext = new ImplementationMatcher(MagentoTypes.OBSERVER_TYPE); PsiElement psiElement = completionParameters.getOriginalPosition(); - completionResultSet.addAllElements(ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext)); + completionResultSet.addAllElements( + ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext) + ); completionResultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE.collectCompletionResult(psiElement)); } } diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java index 79c5ca23d..c90e2d50c 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java @@ -1,13 +1,10 @@ package com.magento.idea.magento2plugin.xml.observer.reference; import com.intellij.psi.*; -import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; -import com.magento.idea.magento2plugin.php.util.MagentoTypes; import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; import com.magento.idea.magento2plugin.xml.observer.XmlHelper; import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsDeclarationsFilesResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ImplementationContextDecorator; import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; import org.jetbrains.annotations.NotNull; @@ -24,10 +21,7 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen XmlHelper.getTagAttributeValuePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE), new XmlReferenceProvider( new ReferenceResultsFiller[]{ - new ImplementationContextDecorator( - ClassesResultsFiller.INSTANCE, - new ImplementationMatcher(MagentoTypes.OBSERVER_TYPE) - ), + ClassesResultsFiller.INSTANCE, VirtualTypesResultsFiller.INSTANCE } ) diff --git a/src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java b/src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java new file mode 100644 index 000000000..69500cf85 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java @@ -0,0 +1,42 @@ +package com.magento.idea.magento2plugin.xml.util; + +import com.intellij.psi.PsiElement; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; +import org.jetbrains.annotations.Nullable; + +/** +* Created by dkvashnin on 12/25/15. +*/ +public class ParentTypeMatcher implements PsiContextMatcherI { + private PhpClass parentType; + + public ParentTypeMatcher(PhpClass parentType) { + this.parentType = parentType; + } + + @Override + public boolean match(PsiElement psiElement) { + if (!(psiElement instanceof PhpClass)) { + return false; + } + + return parentType.equals(psiElement) + || match(((PhpClass)psiElement).getImplementedInterfaces()) + || match(((PhpClass) psiElement).getSuperClass()); + } + + public boolean match(@Nullable PhpClass[] probableMistakes) { + if (probableMistakes == null) { + return false; + } + + boolean result = false; + + for (PhpClass probableMistake : probableMistakes) { + result = parentType.equals(probableMistake) || match(probableMistake.getImplementedInterfaces()); + } + + return result; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java b/src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java new file mode 100644 index 000000000..b83b95ee9 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java @@ -0,0 +1,31 @@ +package com.magento.idea.magento2plugin.xml.util; + +import com.intellij.openapi.project.Project; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.util.PsiContextMatcherI; +import com.magento.idea.magento2plugin.xml.di.completion.DiCompletionContributor; +import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; + +import java.util.List; + +/** +* Created by dkvashnin on 12/25/15. +*/ +public class VirtualTypeParentMatcher implements PsiContextMatcherI { + private ParentTypeMatcher parentTypeMatcher; + private Project project; + + public VirtualTypeParentMatcher(ParentTypeMatcher parentTypeMatcher, Project project) { + this.parentTypeMatcher = parentTypeMatcher; + this.project = project; + } + + @Override + public boolean match(String virtualType) { + List superParentTypes = VirtualTypesNamesFileBasedIndex.getSuperParentTypes(project, virtualType); + + return parentTypeMatcher.match( + superParentTypes.toArray(new PhpClass[superParentTypes.size()]) + ); + } +} From 03d0d24f8eca19fe61fd883c532b68b83ca257f0 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sat, 26 Dec 2015 00:01:40 +0200 Subject: [PATCH 29/51] Fixed null pointer for PsiLightFile usage --- .../magento/idea/magento2plugin/php/module/ModuleManager.java | 2 +- .../magento/idea/magento2plugin/xml/layout/LayoutUtility.java | 3 +-- .../xml/reference/util/ImplementationContextDecorator.java | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java b/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java index 9ed719f4d..001f52afe 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java @@ -142,7 +142,7 @@ public ComposerPackageModel getComposerModel() { @Override public boolean isFileInContext(PsiFile psiFile) { - PsiDirectory containingDirectory = psiFile.getContainingDirectory(); + PsiDirectory containingDirectory = psiFile.getOriginalFile().getContainingDirectory(); while (containingDirectory != null) { if (containingDirectory.getManager().areElementsEquivalent(containingDirectory, directory)) { return true; diff --git a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java index 823854b7f..0c2867b7d 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java @@ -3,7 +3,6 @@ import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElementResolveResult; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.FilenameIndex; @@ -24,7 +23,7 @@ public static boolean isLayoutFile(VirtualFile virtualFile) { } public static boolean isLayoutFile(PsiFile psiFile) { - VirtualFile virtualFile = psiFile.getVirtualFile(); + VirtualFile virtualFile = psiFile.getOriginalFile().getVirtualFile(); return isLayoutFile(virtualFile); } diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java index de255f76a..66fe5a4b8 100644 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java +++ b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java @@ -4,7 +4,6 @@ import com.intellij.psi.ResolveResult; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; -import com.magento.idea.magento2plugin.php.util.PsiContextMatcherManager; import java.util.List; From 03b42ccf0353805a8c624cb4dbf7fd84347d941b Mon Sep 17 00:00:00 2001 From: Alexander Paliarush Date: Sat, 2 Jan 2016 21:50:18 +0200 Subject: [PATCH 30/51] Added "Navigate to Web API configuration" line marker --- META-INF/plugin.xml | 2 + README.md | 3 +- .../idea/magento2plugin/Magento2Icons.java | 1 + .../magento2plugin/icons/webapi_reference.png | Bin 0 -> 627 bytes .../icons/webapi_reference@2x.png | Bin 0 -> 1328 bytes .../linemarker/PluginLineMarkerProvider.java | 1 - .../linemarker/WebApiLineMarkerProvider.java | 131 +++ .../index/WebApiTypesFileBasedIndex.java | 778 ++++++++++++++++++ 8 files changed, 914 insertions(+), 2 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/icons/webapi_reference.png create mode 100644 src/com/magento/idea/magento2plugin/icons/webapi_reference@2x.png create mode 100644 src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java create mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index bade7bc47..df2c56fce 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -121,10 +121,12 @@ + + Code helpers
    • "Navigate to configuration" reference in scope of class/interface
    • -
    • "Go to plugin" reference in scope of class/interface
    • +
    • "Go to plugin" reference in scope of class/interface and method
    • +
    • "Navigate to Web API configuration" reference in scope of class/interface and method
    ## License diff --git a/src/com/magento/idea/magento2plugin/Magento2Icons.java b/src/com/magento/idea/magento2plugin/Magento2Icons.java index fb09a2e34..39d1d5f2f 100644 --- a/src/com/magento/idea/magento2plugin/Magento2Icons.java +++ b/src/com/magento/idea/magento2plugin/Magento2Icons.java @@ -10,5 +10,6 @@ public class Magento2Icons { public static final Icon PLUGIN = IconLoader.getIcon("icons/interception_reference.png"); public static final Icon CONFIGURATION = IconLoader.getIcon("icons/xml_reference.png"); + public static final Icon WEB_API = IconLoader.getIcon("icons/webapi_reference.png"); } diff --git a/src/com/magento/idea/magento2plugin/icons/webapi_reference.png b/src/com/magento/idea/magento2plugin/icons/webapi_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..db41f5df3967c08d9eeb8c50383cd0a003dc2808 GIT binary patch literal 627 zcmV-(0*w8MP);6)7{KXyE5*EFxR73)XlBgImf#HdSl8}Ksd=ni% z0g{Rs46Tkp7ARIn@Q|1g0U5>#8j7<(nnG;%h(YnlXkqe9k3+{rw!*D^^lV{bw%CY_ zVoOZU7f+opxQ1*fI8C%>e;+Q~5ev5pQQL&IbXP3h6VnUO*5=ejap`_x{)UJK+M0sG zC}8c40T}B;42*i+9booaA!?YpEC9YdGtr8yRS^LsLU`k|b>y@>y-=Jja(39njHqjC ze6nlskuKbrVJpcX?&mY8#Oan!DQB z|M1vk8e7;DG9W@^i|Q@Bxwi9ndi%&Y@!;nU#_DsEDV$)CA1o#+Lk0H43>rTsY*>8( z823-015=;6$|FVD7XLs1ieW_ zK~z}7#h1;FUBwlJzg6dS+Ym&nZMSC#Y|B5GH(-RAAcYZQ9s%BgQN}^y8F+#yPmp0I zHf;lvNiqnu-8Ob)gR$YB+KWL|oxj^4MRJrQmF~Ug?6dc(wSQ_|`STBd;?%3Vbi2?c zAb|un7(f7!63BqdGr8EJ$tGg5!NM2>4)6v`#$n}bHqXt^Pk-szIlV*InNCp=;u8qQP5ib2IAw$U7b0S^^G zy&uI6yKDxDaAQY;wh7a9>amLBSzw@2IorKgOPS`CTmw>>d{>E)H3M9bVY9{ExvK0MQdU zm43x7nBV(Tr$3yX{Qm9Fp+|Sz062B<{->R~otm)>fB7iO&l*7a>=o(VPtxe)=>zoF zkB3E}StJPXAbUu7lki47yt8bHGZ%%k>@1wc{u`+U2TCcPCc3qDEfz3(`w_Q~sa-01v;Z6DjJu8i6G8l#i01EFz@H+DgNfKPH`er4E+w z(T~UI*+cx~ZgIQ&61?@ns`_txJk-Yg*H354;3+|;;>gwD?%@)^g?Hxp_c;IOKrg+! z%KuHze79J2S&2<_yR_r+2obp0}~xz^6z8z>|+Pf8(bQw?Q6%X|+LRt7;rg8q#$THDnRXb3F`4H%@lEnBBG4w^+Kd z5-G9zE#%MM4x}o(Ya2E_H(#w)VJ6#W;$!?ilV8$GQ_j^*@zIYGEJp37aTbiazdDEt zK{cO_Sza0&n(0A)8$eA)KS`!oDx2}en4FIHG)*~Y25{09lRDoLe=p`r{;z!bg$BovB>t~gB55w~|L1T#|HIYEiR{1A mm(i#f%J0e77^9QO{>QHq>B+|WvhxW50000 getPluginsForClass(@NotNull PhpClass phpClass, @NotNull St return classPluginsMap.get(classFQN); } - List> plugins = FileBasedIndex.getInstance() .getValues( PluginToTypeFileBasedIndex.NAME, diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java new file mode 100644 index 000000000..54fb7112b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java @@ -0,0 +1,131 @@ +package com.magento.idea.magento2plugin.php.linemarker; + +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTag; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.Magento2Icons; +import com.magento.idea.magento2plugin.xml.webapi.index.WebApiTypesFileBasedIndex; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Line marker for methods and classes which are exposed as web APIs. + *

    + * Allows to open related web API config. + * Tooltip displays a list of related REST routes. + */ +public class WebApiLineMarkerProvider implements LineMarkerProvider { + + @Nullable + @Override + public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { + return null; + } + + @Override + public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { + for (PsiElement psiElement : list) { + WebApiRoutesCollector collector = new WebApiRoutesCollector(); + List results = new ArrayList<>(); + if (psiElement instanceof Method) { + results = collector.getRoutes((Method) psiElement); + } else if (psiElement instanceof PhpClass) { + results = collector.getRoutes((PhpClass) psiElement); + } + + if (results.size() == 0) { + continue; + } + String tooltipText = "Navigate to Web API configuration:

    ";
    +            for (XmlTag routeTag : results) {
    +                tooltipText += routeTag.getName() + "\n";
    +            }
    +            tooltipText += "
    "; + NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. + create(Magento2Icons.WEB_API). + setTargets(results). + setTooltipText(tooltipText); + collection.add(builder.createLineMarkerInfo(psiElement)); + } + } +} + +/** + * Web API config nodes collector for service methods and classes. Has built in caching. + */ +class WebApiRoutesCollector { + + private HashMap> routesCache = new HashMap<>(); + + private static final Map HTTP_METHODS_SORT_ORDER = new HashMap() {{ + put("GET", 1); + put("PUT", 2); + put("POS", 3); + put("DEL", 4); + }}; + + /** + * Get sorted list of Web API routes related to the specified class. + */ + public List getRoutes(@NotNull PhpClass phpClass) { + List routesForClass = new ArrayList<>(); + for (Method method : phpClass.getMethods()) { + routesForClass.addAll(getRoutes(method)); + } + /** Make sure that routes are sorted as follows: GET, PUT, POST, DELETE */ + Collections.sort( + routesForClass, + new Comparator() { + @Override + public int compare(XmlTag firstTag, XmlTag secondTag) { + String substring = firstTag.getName().substring(2, 5); + Integer firstSortOrder = HTTP_METHODS_SORT_ORDER.get(substring); + Integer secondSortOrder = HTTP_METHODS_SORT_ORDER.get(secondTag.getName().substring(2, 5)); + return firstSortOrder.compareTo(secondSortOrder); + } + } + ); + return routesForClass; + } + + /** + * Get list of Web API routes related to the specified method. + *

    + * Results are cached. + */ + public List getRoutes(@NotNull Method method) { + String methodFqn = method.getFQN(); + if (!routesCache.containsKey(methodFqn)) { + routesCache.put(methodFqn, extractRoutesForMethod(method)); + } + return routesCache.get(methodFqn); + } + + /** + * Get list of Web API routes related to the specified method. + *

    + * Web API declarations for parent classes are taken into account. + * Results are not cached. + */ + public List extractRoutesForMethod(@NotNull Method method) { + List routesForMethod = WebApiTypesFileBasedIndex.getWebApiRoutes(method); + PhpClass phpClass = method.getContainingClass(); + if (phpClass == null) { + return routesForMethod; + } + for (PhpClass parent : method.getContainingClass().getSupers()) { + for (Method parentMethod : parent.getMethods()) { + if (parentMethod.getName().equals(method.getName())) { + routesForMethod.addAll(extractRoutesForMethod(parentMethod)); + } + } + } + return routesForMethod; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java new file mode 100644 index 000000000..9353c7697 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java @@ -0,0 +1,778 @@ +package com.magento.idea.magento2plugin.xml.webapi.index; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.lang.ASTNode; +import com.intellij.lang.Language; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.xml.XmlDocumentImpl; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.*; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import com.jetbrains.php.lang.PhpLangUtil; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.*; + +/** + * Indexer for classes/interfaces which have methods exposed via Web API. + */ +public class WebApiTypesFileBasedIndex extends ScalarIndexExtension { + + public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.webapi.index.webapi_types"); + + private final KeyDescriptor keyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public ID getName() { + return NAME; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new DataIndexer() { + + @NotNull + @Override + public Map map(@NotNull FileContent fileContent) { + Map map = new HashMap<>(); + + PsiFile psiFile = fileContent.getPsiFile(); + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); + if (document == null) { + return map; + } + + XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if (xmlTags == null) { + return map; + } + + for (XmlTag xmlTag : xmlTags) { + if (xmlTag.getName().equals("routes")) { + for (XmlTag routeNode : xmlTag.findSubTags("route")) { + for (XmlTag serviceNode : routeNode.findSubTags("service")) { + String typeName = serviceNode.getAttributeValue("class"); + if (typeName != null) { + map.put(PhpLangUtil.toPresentableFQN(typeName), null); + } + } + } + } + } + return map; + } + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return keyDescriptor; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return new FileBasedIndex.InputFilter() { + @Override + public boolean acceptInput(@NotNull VirtualFile file) { + return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("webapi"); + } + }; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } + + /** + * Get list of Web API routes associated with the provided method. + * + * Parent classes are not taken into account. + */ + public static List getWebApiRoutes(Method method) { + List tags = new ArrayList<>(); + if (!method.getAccess().isPublic()) { + return tags; + } + PhpClass phpClass = method.getContainingClass(); + String methodFqn = method.getName(); + if (phpClass == null) { + return tags; + } + String classFqn = phpClass.getPresentableFQN(); + if (classFqn == null) { + return tags; + } + Collection containingFiles = FileBasedIndex + .getInstance() + .getContainingFiles( + NAME, + classFqn, + GlobalSearchScope.allScope(phpClass.getProject()) + ); + + PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); + for (VirtualFile virtualFile : containingFiles) { + XmlFile file = (XmlFile) psiManager.findFile(virtualFile); + if (file == null) { + continue; + } + XmlTag rootTag = file.getRootTag(); + fillRelatedTags(classFqn, methodFqn, rootTag, tags); + } + return tags; + } + + /** + * Find routes related to the specified method within single webapi.xml + */ + private static void fillRelatedTags(String classFqn, String methodFqn, XmlTag parentTag, List tagsReferences) { + for (XmlTag routeNode : parentTag.findSubTags("route")) { + for (XmlTag serviceNode : routeNode.findSubTags("service")) { + String typeName = serviceNode.getAttributeValue("class"); + String methodName = serviceNode.getAttributeValue("method"); + if (typeName != null && typeName.equals(classFqn) + && methodName != null && methodName.equals(methodFqn) + ) { + tagsReferences.add(new WebApiLineMarkerXmlTagDecorator(routeNode)); + } + } + } + } +} + +/** + * Decorator for XmlTag, which allows to render REST routes in web API line marker. + */ +class WebApiLineMarkerXmlTagDecorator implements XmlTag { + + private XmlTag xmlTag; + + public WebApiLineMarkerXmlTagDecorator(XmlTag xmlTag) { + this.xmlTag = xmlTag; + } + + @Override + @NotNull + @NonNls + public String getName() { + String httpMethod = this.xmlTag.getAttributeValue("method"); + String route = this.xmlTag.getAttributeValue("url"); + if (httpMethod != null && route != null) { + return String.format(" %-7s %s", httpMethod, route); + } + return xmlTag.getName(); + } + + @Override + @NotNull + @NonNls + public String getNamespace() { + return xmlTag.getNamespace(); + } + + @Override + @NotNull + @NonNls + public String getLocalName() { + return xmlTag.getLocalName(); + } + + @Override + @Nullable + public XmlElementDescriptor getDescriptor() { + return xmlTag.getDescriptor(); + } + + @Override + @NotNull + public XmlAttribute[] getAttributes() { + return xmlTag.getAttributes(); + } + + @Override + @Nullable + public XmlAttribute getAttribute(@NonNls String s, @NonNls String s1) { + return xmlTag.getAttribute(s, s1); + } + + @Override + @Nullable + public XmlAttribute getAttribute(@NonNls String s) { + return xmlTag.getAttribute(s); + } + + @Override + @Nullable + public String getAttributeValue(@NonNls String s, @NonNls String s1) { + return xmlTag.getAttributeValue(s, s1); + } + + @Override + @Nullable + public String getAttributeValue(@NonNls String s) { + return xmlTag.getAttributeValue(s); + } + + @Override + public XmlAttribute setAttribute(@NonNls String s, @NonNls String s1, @NonNls String s2) throws IncorrectOperationException { + return xmlTag.setAttribute(s, s1, s2); + } + + @Override + public XmlAttribute setAttribute(@NonNls String s, @NonNls String s1) throws IncorrectOperationException { + return xmlTag.setAttribute(s, s1); + } + + @Override + public XmlTag createChildTag(@NonNls String s, @NonNls String s1, @Nullable @NonNls String s2, boolean b) { + return xmlTag.createChildTag(s, s1, s2, b); + } + + @Override + public XmlTag addSubTag(XmlTag xmlTag, boolean b) { + return this.xmlTag.addSubTag(xmlTag, b); + } + + @Override + @NotNull + public XmlTag[] getSubTags() { + return xmlTag.getSubTags(); + } + + @Override + @NotNull + public XmlTag[] findSubTags(@NonNls String s) { + return xmlTag.findSubTags(s); + } + + @Override + @NotNull + public XmlTag[] findSubTags(@NonNls String s, @Nullable String s1) { + return xmlTag.findSubTags(s, s1); + } + + @Override + @Nullable + public XmlTag findFirstSubTag(@NonNls String s) { + return xmlTag.findFirstSubTag(s); + } + + @Override + @NotNull + @NonNls + public String getNamespacePrefix() { + return xmlTag.getNamespacePrefix(); + } + + @Override + @NotNull + @NonNls + public String getNamespaceByPrefix(@NonNls String s) { + return xmlTag.getNamespaceByPrefix(s); + } + + @Override + @Nullable + public String getPrefixByNamespace(@NonNls String s) { + return xmlTag.getPrefixByNamespace(s); + } + + @Override + public String[] knownNamespaces() { + return xmlTag.knownNamespaces(); + } + + @Override + public boolean hasNamespaceDeclarations() { + return xmlTag.hasNamespaceDeclarations(); + } + + @Override + @NotNull + public Map getLocalNamespaceDeclarations() { + return xmlTag.getLocalNamespaceDeclarations(); + } + + @Override + @NotNull + public XmlTagValue getValue() { + return xmlTag.getValue(); + } + + @Override + @Nullable + public XmlNSDescriptor getNSDescriptor(@NonNls String s, boolean b) { + return xmlTag.getNSDescriptor(s, b); + } + + @Override + public boolean isEmpty() { + return xmlTag.isEmpty(); + } + + @Override + public void collapseIfEmpty() { + xmlTag.collapseIfEmpty(); + } + + @Override + @Nullable + @NonNls + public String getSubTagText(@NonNls String s) { + return xmlTag.getSubTagText(s); + } + + @Override + public boolean processElements(PsiElementProcessor psiElementProcessor, PsiElement psiElement) { + return xmlTag.processElements(psiElementProcessor, psiElement); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public Project getProject() throws PsiInvalidElementAccessException { + return xmlTag.getProject(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public Language getLanguage() { + return xmlTag.getLanguage(); + } + + @Override + @Contract( + pure = true + ) + public PsiManager getManager() { + return xmlTag.getManager(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public PsiElement[] getChildren() { + return xmlTag.getChildren(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getParent() { + return xmlTag.getParent(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getFirstChild() { + return xmlTag.getFirstChild(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getLastChild() { + return xmlTag.getLastChild(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getNextSibling() { + return xmlTag.getNextSibling(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getPrevSibling() { + return xmlTag.getPrevSibling(); + } + + @Override + @Contract( + pure = true + ) + public PsiFile getContainingFile() throws PsiInvalidElementAccessException { + return xmlTag.getContainingFile(); + } + + @Override + @Contract( + pure = true + ) + public TextRange getTextRange() { + return xmlTag.getTextRange(); + } + + @Override + @Contract( + pure = true + ) + public int getStartOffsetInParent() { + return xmlTag.getStartOffsetInParent(); + } + + @Override + @Contract( + pure = true + ) + public int getTextLength() { + return xmlTag.getTextLength(); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiElement findElementAt(int i) { + return xmlTag.findElementAt(i); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiReference findReferenceAt(int i) { + return xmlTag.findReferenceAt(i); + } + + @Override + @Contract( + pure = true + ) + public int getTextOffset() { + return xmlTag.getTextOffset(); + } + + @Override + @NonNls + @Contract( + pure = true + ) + public String getText() { + return xmlTag.getText(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public char[] textToCharArray() { + return xmlTag.textToCharArray(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getNavigationElement() { + return xmlTag.getNavigationElement(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getOriginalElement() { + return xmlTag.getOriginalElement(); + } + + @Override + @Contract( + pure = true + ) + public boolean textMatches(@NotNull @NonNls CharSequence charSequence) { + return xmlTag.textMatches(charSequence); + } + + @Override + @Contract( + pure = true + ) + public boolean textMatches(@NotNull PsiElement psiElement) { + return xmlTag.textMatches(psiElement); + } + + @Override + @Contract( + pure = true + ) + public boolean textContains(char c) { + return xmlTag.textContains(c); + } + + @Override + public void accept(@NotNull PsiElementVisitor psiElementVisitor) { + xmlTag.accept(psiElementVisitor); + } + + @Override + public void acceptChildren(@NotNull PsiElementVisitor psiElementVisitor) { + xmlTag.acceptChildren(psiElementVisitor); + } + + @Override + public PsiElement copy() { + return xmlTag.copy(); + } + + @Override + public PsiElement add(@NotNull PsiElement psiElement) throws IncorrectOperationException { + return xmlTag.add(psiElement); + } + + @Override + public PsiElement addBefore(@NotNull PsiElement psiElement, @Nullable PsiElement psiElement1) throws IncorrectOperationException { + return xmlTag.addBefore(psiElement, psiElement1); + } + + @Override + public PsiElement addAfter(@NotNull PsiElement psiElement, @Nullable PsiElement psiElement1) throws IncorrectOperationException { + return xmlTag.addAfter(psiElement, psiElement1); + } + + @Override + public void checkAdd(@NotNull PsiElement psiElement) throws IncorrectOperationException { + xmlTag.checkAdd(psiElement); + } + + @Override + public PsiElement addRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException { + return xmlTag.addRange(psiElement, psiElement1); + } + + @Override + public PsiElement addRangeBefore(@NotNull PsiElement psiElement, @NotNull PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException { + return xmlTag.addRangeBefore(psiElement, psiElement1, psiElement2); + } + + @Override + public PsiElement addRangeAfter(PsiElement psiElement, PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException { + return xmlTag.addRangeAfter(psiElement, psiElement1, psiElement2); + } + + @Override + public void delete() throws IncorrectOperationException { + xmlTag.delete(); + } + + @Override + public void checkDelete() throws IncorrectOperationException { + xmlTag.checkDelete(); + } + + @Override + public void deleteChildRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException { + xmlTag.deleteChildRange(psiElement, psiElement1); + } + + @Override + public PsiElement replace(@NotNull PsiElement psiElement) throws IncorrectOperationException { + return xmlTag.replace(psiElement); + } + + @Override + @Contract( + pure = true + ) + public boolean isValid() { + return xmlTag.isValid(); + } + + @Override + @Contract( + pure = true + ) + public boolean isWritable() { + return xmlTag.isWritable(); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiReference getReference() { + return xmlTag.getReference(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public PsiReference[] getReferences() { + return xmlTag.getReferences(); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public T getCopyableUserData(Key key) { + return xmlTag.getCopyableUserData(key); + } + + @Override + public void putCopyableUserData(Key key, @Nullable T t) { + xmlTag.putCopyableUserData(key, t); + } + + @Override + public boolean processDeclarations(@NotNull PsiScopeProcessor psiScopeProcessor, @NotNull ResolveState resolveState, @Nullable PsiElement psiElement, @NotNull PsiElement psiElement1) { + return xmlTag.processDeclarations(psiScopeProcessor, resolveState, psiElement, psiElement1); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiElement getContext() { + return xmlTag.getContext(); + } + + @Override + @Contract( + pure = true + ) + public boolean isPhysical() { + return xmlTag.isPhysical(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public GlobalSearchScope getResolveScope() { + return xmlTag.getResolveScope(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public SearchScope getUseScope() { + return xmlTag.getUseScope(); + } + + @Override + @Contract( + pure = true + ) + public ASTNode getNode() { + return xmlTag.getNode(); + } + + @Override + @NonNls + @Contract( + pure = true + ) + public String toString() { + return xmlTag.toString(); + } + + @Override + @Contract( + pure = true + ) + public boolean isEquivalentTo(PsiElement psiElement) { + return xmlTag.isEquivalentTo(psiElement); + } + + @Override + @Nullable + public T getUserData(@NotNull Key key) { + return xmlTag.getUserData(key); + } + + @Override + public void putUserData(@NotNull Key key, @Nullable T t) { + xmlTag.putUserData(key, t); + } + + @Override + public Icon getIcon(@IconFlags int i) { + return xmlTag.getIcon(i); + } + + @Override + public PsiElement setName(@NonNls @NotNull String s) throws IncorrectOperationException { + return xmlTag.setName(s); + } + + @Override + @Nullable + public PsiMetaData getMetaData() { + return xmlTag.getMetaData(); + } + + @Override + @Nullable + public XmlTag getParentTag() { + return xmlTag.getParentTag(); + } + + @Override + @Nullable + public XmlTagChild getNextSiblingInTag() { + return xmlTag.getNextSiblingInTag(); + } + + @Override + @Nullable + public XmlTagChild getPrevSiblingInTag() { + return xmlTag.getPrevSiblingInTag(); + } +} From 95506558f9b89d4f120371561d4c0a52d3bb3992 Mon Sep 17 00:00:00 2001 From: Alexander Paliarush Date: Thu, 7 Jan 2016 12:27:42 +0200 Subject: [PATCH 31/51] Web API line marker improvements - Enhanced routes sorting - Configuration files declared in tests are excluded from indexing --- META-INF/plugin.xml | 3 +- .../linemarker/WebApiLineMarkerProvider.java | 40 ++++++++++++------- .../index/WebApiTypesFileBasedIndex.java | 3 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index df2c56fce..cce1c97c6 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -25,7 +25,8 @@

    Code helpers

    • "Navigate to configuration" reference in scope of class/interface
    • -
    • "Go to plugin" reference in scope of class/interface
    • +
    • "Go to plugin" reference in scope of class/interface and method
    • +
    • "Navigate to Web API configuration" reference in scope of class/interface and method
    ]]> diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java index 54fb7112b..c3697abb4 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java @@ -78,19 +78,7 @@ public List getRoutes(@NotNull PhpClass phpClass) { for (Method method : phpClass.getMethods()) { routesForClass.addAll(getRoutes(method)); } - /** Make sure that routes are sorted as follows: GET, PUT, POST, DELETE */ - Collections.sort( - routesForClass, - new Comparator() { - @Override - public int compare(XmlTag firstTag, XmlTag secondTag) { - String substring = firstTag.getName().substring(2, 5); - Integer firstSortOrder = HTTP_METHODS_SORT_ORDER.get(substring); - Integer secondSortOrder = HTTP_METHODS_SORT_ORDER.get(secondTag.getName().substring(2, 5)); - return firstSortOrder.compareTo(secondSortOrder); - } - } - ); + sortRoutes(routesForClass); return routesForClass; } @@ -102,7 +90,9 @@ public int compare(XmlTag firstTag, XmlTag secondTag) { public List getRoutes(@NotNull Method method) { String methodFqn = method.getFQN(); if (!routesCache.containsKey(methodFqn)) { - routesCache.put(methodFqn, extractRoutesForMethod(method)); + List routesForMethod = extractRoutesForMethod(method); + sortRoutes(routesForMethod); + routesCache.put(methodFqn, routesForMethod); } return routesCache.get(methodFqn); } @@ -128,4 +118,26 @@ public List extractRoutesForMethod(@NotNull Method method) { } return routesForMethod; } + + /** + * Make sure that routes are sorted as follows: GET, PUT, POST, DELETE. Then by path. + */ + private void sortRoutes(List routes) { + Collections.sort( + routes, + new Comparator() { + @Override + public int compare(XmlTag firstTag, XmlTag secondTag) { + String substring = firstTag.getName().substring(2, 5); + Integer firstSortOrder = HTTP_METHODS_SORT_ORDER.get(substring); + Integer secondSortOrder = HTTP_METHODS_SORT_ORDER.get(secondTag.getName().substring(2, 5)); + if (firstSortOrder.compareTo(secondSortOrder) == 0) { + /** Sort by route if HTTP methods are equal */ + return firstTag.getName().compareTo(secondTag.getName()); + } + return firstSortOrder.compareTo(secondSortOrder); + } + } + ); + } } diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java index 9353c7697..487ee1868 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java @@ -98,7 +98,8 @@ public FileBasedIndex.InputFilter getInputFilter() { return new FileBasedIndex.InputFilter() { @Override public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("webapi"); + return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("webapi") + && !file.getPath().contains("testsuite") && !file.getPath().contains("_files"); } }; } From 200fed80a24c234d4e920d33a1d1b0200143fcde Mon Sep 17 00:00:00 2001 From: Alexander Paliarush Date: Sat, 9 Jan 2016 00:50:21 +0200 Subject: [PATCH 32/51] XML configuration line marker improvements - Each type of XmlNodes now has custom user-friendly representation, when rendered in line marker - Corresponding Magento area is specified for each item in line marker --- .../ClassConfigurationLineMarkerProvider.java | 20 +- .../TypeConfigurationFileBasedIndex.java | 107 ++- .../xml/index/LineMarkerXmlTagDecorator.java | 636 ++++++++++++++++++ .../layout/index/util/LayoutIndexUtility.java | 37 +- .../index/WebApiTypesFileBasedIndex.java | 611 +---------------- 5 files changed, 800 insertions(+), 611 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java index 216e0b4fc..36cd3943c 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java @@ -12,9 +12,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; /** * Created by dkvashnin on 11/15/15. @@ -43,11 +41,23 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll if (results.size() == 0) { continue; } - + Collections.sort( + results, + new Comparator() { + @Override + public int compare(XmlTag firstTag, XmlTag secondTag) { + return firstTag.getName().compareTo(secondTag.getName()); + } + } + ); + String tooltipText = "Navigate to configuration:"; + for (XmlTag resultItem: results) { + tooltipText += "\n " + resultItem.getName(); + } NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. create(Magento2Icons.CONFIGURATION). setTargets(results). - setTooltipText("Navigate to configuration"); + setTooltipText(tooltipText); collection.add(builder.createLineMarkerInfo(psiElement)); } diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java index f31457bff..61261d5f7 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java @@ -16,7 +16,9 @@ import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.xml.di.XmlHelper; +import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -79,7 +81,7 @@ private static void fillRelatedTags(String classFqn, XmlTag parentTag, List getName() { @@ -174,3 +195,87 @@ public int getVersion() { return 0; } } + +/** + * Decorator for XmlTag, which improves readability of "preference" node in configuration line marker. + */ +class DiPreferenceLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + public DiPreferenceLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @Override + @NotNull + @NonNls + public String getName() { + String preference = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); + if (preference != null) { + return String.format("[%s] preference %s", getAreaName(), preference); + } + return xmlTag.getName(); + } +} + +/** + * Decorator for XmlTag, which improves readability of "type" node in configuration line marker. + */ +class DiTypeLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + public DiTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @Override + @NotNull + @NonNls + public String getName() { + return String.format("[%s] type declaration", getAreaName()); + } +} + +/** + * Decorator for XmlTag, which improves readability of "plugin" node in configuration line marker. + */ +class DiPluginLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + public DiPluginLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @Override + @NotNull + @NonNls + public String getName() { + XmlTag typeTag = xmlTag.getParentTag(); + if (typeTag == null) { + return xmlTag.getName(); + } + String type = typeTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); + if (type == null) { + return xmlTag.getName(); + } + return String.format("[%s] plugin for %s", getAreaName(), type); + } +} + +/** + * Decorator for XmlTag, which improves readability of "virtualType" node in configuration line marker. + */ +class DiVirtualTypeLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + public DiVirtualTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @Override + @NotNull + @NonNls + public String getName() { + String type = xmlTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); + if (type != null) { + return String.format("[%s] virtual type %s", getAreaName(), type); + } + return xmlTag.getName(); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java b/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java new file mode 100644 index 000000000..d33b5081d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java @@ -0,0 +1,636 @@ +package com.magento.idea.magento2plugin.xml.index; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.Language; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.meta.PsiMetaData; +import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlTagChild; +import com.intellij.psi.xml.XmlTagValue; +import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.XmlElementDescriptor; +import com.intellij.xml.XmlNSDescriptor; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Map; + +/** + * Decorator for XmlTag, which allows to render user-friendly line markers. + */ +abstract public class LineMarkerXmlTagDecorator implements XmlTag { + + protected XmlTag xmlTag; + + public LineMarkerXmlTagDecorator(XmlTag xmlTag) { + this.xmlTag = xmlTag; + } + + @NotNull + protected String getAreaName() { + String configDirectory = xmlTag.getContainingFile().getVirtualFile().getParent().getName(); + return configDirectory.equals("etc") ? "global" : configDirectory; + } + + /** + * Get line marker text. This method should be overridden to generate user-friendly XmlTag presentation. + */ + @Override + @NotNull + @NonNls + abstract public String getName(); + + @Override + @NotNull + @NonNls + public String getNamespace() { + return xmlTag.getNamespace(); + } + + @Override + @NotNull + @NonNls + public String getLocalName() { + return xmlTag.getLocalName(); + } + + @Override + @Nullable + public XmlElementDescriptor getDescriptor() { + return xmlTag.getDescriptor(); + } + + @Override + @NotNull + public XmlAttribute[] getAttributes() { + return xmlTag.getAttributes(); + } + + @Override + @Nullable + public XmlAttribute getAttribute(@NonNls String s, @NonNls String s1) { + return xmlTag.getAttribute(s, s1); + } + + @Override + @Nullable + public XmlAttribute getAttribute(@NonNls String s) { + return xmlTag.getAttribute(s); + } + + @Override + @Nullable + public String getAttributeValue(@NonNls String s, @NonNls String s1) { + return xmlTag.getAttributeValue(s, s1); + } + + @Override + @Nullable + public String getAttributeValue(@NonNls String s) { + return xmlTag.getAttributeValue(s); + } + + @Override + public XmlAttribute setAttribute(@NonNls String s, @NonNls String s1, @NonNls String s2) throws IncorrectOperationException { + return xmlTag.setAttribute(s, s1, s2); + } + + @Override + public XmlAttribute setAttribute(@NonNls String s, @NonNls String s1) throws IncorrectOperationException { + return xmlTag.setAttribute(s, s1); + } + + @Override + public XmlTag createChildTag(@NonNls String s, @NonNls String s1, @Nullable @NonNls String s2, boolean b) { + return xmlTag.createChildTag(s, s1, s2, b); + } + + @Override + public XmlTag addSubTag(XmlTag xmlTag, boolean b) { + return this.xmlTag.addSubTag(xmlTag, b); + } + + @Override + @NotNull + public XmlTag[] getSubTags() { + return xmlTag.getSubTags(); + } + + @Override + @NotNull + public XmlTag[] findSubTags(@NonNls String s) { + return xmlTag.findSubTags(s); + } + + @Override + @NotNull + public XmlTag[] findSubTags(@NonNls String s, @Nullable String s1) { + return xmlTag.findSubTags(s, s1); + } + + @Override + @Nullable + public XmlTag findFirstSubTag(@NonNls String s) { + return xmlTag.findFirstSubTag(s); + } + + @Override + @NotNull + @NonNls + public String getNamespacePrefix() { + return xmlTag.getNamespacePrefix(); + } + + @Override + @NotNull + @NonNls + public String getNamespaceByPrefix(@NonNls String s) { + return xmlTag.getNamespaceByPrefix(s); + } + + @Override + @Nullable + public String getPrefixByNamespace(@NonNls String s) { + return xmlTag.getPrefixByNamespace(s); + } + + @Override + public String[] knownNamespaces() { + return xmlTag.knownNamespaces(); + } + + @Override + public boolean hasNamespaceDeclarations() { + return xmlTag.hasNamespaceDeclarations(); + } + + @Override + @NotNull + public Map getLocalNamespaceDeclarations() { + return xmlTag.getLocalNamespaceDeclarations(); + } + + @Override + @NotNull + public XmlTagValue getValue() { + return xmlTag.getValue(); + } + + @Override + @Nullable + public XmlNSDescriptor getNSDescriptor(@NonNls String s, boolean b) { + return xmlTag.getNSDescriptor(s, b); + } + + @Override + public boolean isEmpty() { + return xmlTag.isEmpty(); + } + + @Override + public void collapseIfEmpty() { + xmlTag.collapseIfEmpty(); + } + + @Override + @Nullable + @NonNls + public String getSubTagText(@NonNls String s) { + return xmlTag.getSubTagText(s); + } + + @Override + public boolean processElements(PsiElementProcessor psiElementProcessor, PsiElement psiElement) { + return xmlTag.processElements(psiElementProcessor, psiElement); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public Project getProject() throws PsiInvalidElementAccessException { + return xmlTag.getProject(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public Language getLanguage() { + return xmlTag.getLanguage(); + } + + @Override + @Contract( + pure = true + ) + public PsiManager getManager() { + return xmlTag.getManager(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public PsiElement[] getChildren() { + return xmlTag.getChildren(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getParent() { + return xmlTag.getParent(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getFirstChild() { + return xmlTag.getFirstChild(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getLastChild() { + return xmlTag.getLastChild(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getNextSibling() { + return xmlTag.getNextSibling(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getPrevSibling() { + return xmlTag.getPrevSibling(); + } + + @Override + @Contract( + pure = true + ) + public PsiFile getContainingFile() throws PsiInvalidElementAccessException { + return xmlTag.getContainingFile(); + } + + @Override + @Contract( + pure = true + ) + public TextRange getTextRange() { + return xmlTag.getTextRange(); + } + + @Override + @Contract( + pure = true + ) + public int getStartOffsetInParent() { + return xmlTag.getStartOffsetInParent(); + } + + @Override + @Contract( + pure = true + ) + public int getTextLength() { + return xmlTag.getTextLength(); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiElement findElementAt(int i) { + return xmlTag.findElementAt(i); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiReference findReferenceAt(int i) { + return xmlTag.findReferenceAt(i); + } + + @Override + @Contract( + pure = true + ) + public int getTextOffset() { + return xmlTag.getTextOffset(); + } + + @Override + @NonNls + @Contract( + pure = true + ) + public String getText() { + return xmlTag.getText(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public char[] textToCharArray() { + return xmlTag.textToCharArray(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getNavigationElement() { + return xmlTag.getNavigationElement(); + } + + @Override + @Contract( + pure = true + ) + public PsiElement getOriginalElement() { + return xmlTag.getOriginalElement(); + } + + @Override + @Contract( + pure = true + ) + public boolean textMatches(@NotNull @NonNls CharSequence charSequence) { + return xmlTag.textMatches(charSequence); + } + + @Override + @Contract( + pure = true + ) + public boolean textMatches(@NotNull PsiElement psiElement) { + return xmlTag.textMatches(psiElement); + } + + @Override + @Contract( + pure = true + ) + public boolean textContains(char c) { + return xmlTag.textContains(c); + } + + @Override + public void accept(@NotNull PsiElementVisitor psiElementVisitor) { + xmlTag.accept(psiElementVisitor); + } + + @Override + public void acceptChildren(@NotNull PsiElementVisitor psiElementVisitor) { + xmlTag.acceptChildren(psiElementVisitor); + } + + @Override + public PsiElement copy() { + return xmlTag.copy(); + } + + @Override + public PsiElement add(@NotNull PsiElement psiElement) throws IncorrectOperationException { + return xmlTag.add(psiElement); + } + + @Override + public PsiElement addBefore(@NotNull PsiElement psiElement, @Nullable PsiElement psiElement1) throws IncorrectOperationException { + return xmlTag.addBefore(psiElement, psiElement1); + } + + @Override + public PsiElement addAfter(@NotNull PsiElement psiElement, @Nullable PsiElement psiElement1) throws IncorrectOperationException { + return xmlTag.addAfter(psiElement, psiElement1); + } + + @Override + public void checkAdd(@NotNull PsiElement psiElement) throws IncorrectOperationException { + xmlTag.checkAdd(psiElement); + } + + @Override + public PsiElement addRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException { + return xmlTag.addRange(psiElement, psiElement1); + } + + @Override + public PsiElement addRangeBefore(@NotNull PsiElement psiElement, @NotNull PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException { + return xmlTag.addRangeBefore(psiElement, psiElement1, psiElement2); + } + + @Override + public PsiElement addRangeAfter(PsiElement psiElement, PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException { + return xmlTag.addRangeAfter(psiElement, psiElement1, psiElement2); + } + + @Override + public void delete() throws IncorrectOperationException { + xmlTag.delete(); + } + + @Override + public void checkDelete() throws IncorrectOperationException { + xmlTag.checkDelete(); + } + + @Override + public void deleteChildRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException { + xmlTag.deleteChildRange(psiElement, psiElement1); + } + + @Override + public PsiElement replace(@NotNull PsiElement psiElement) throws IncorrectOperationException { + return xmlTag.replace(psiElement); + } + + @Override + @Contract( + pure = true + ) + public boolean isValid() { + return xmlTag.isValid(); + } + + @Override + @Contract( + pure = true + ) + public boolean isWritable() { + return xmlTag.isWritable(); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiReference getReference() { + return xmlTag.getReference(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public PsiReference[] getReferences() { + return xmlTag.getReferences(); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public T getCopyableUserData(Key key) { + return xmlTag.getCopyableUserData(key); + } + + @Override + public void putCopyableUserData(Key key, @Nullable T t) { + xmlTag.putCopyableUserData(key, t); + } + + @Override + public boolean processDeclarations(@NotNull PsiScopeProcessor psiScopeProcessor, @NotNull ResolveState resolveState, @Nullable PsiElement psiElement, @NotNull PsiElement psiElement1) { + return xmlTag.processDeclarations(psiScopeProcessor, resolveState, psiElement, psiElement1); + } + + @Override + @Nullable + @Contract( + pure = true + ) + public PsiElement getContext() { + return xmlTag.getContext(); + } + + @Override + @Contract( + pure = true + ) + public boolean isPhysical() { + return xmlTag.isPhysical(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public GlobalSearchScope getResolveScope() { + return xmlTag.getResolveScope(); + } + + @Override + @NotNull + @Contract( + pure = true + ) + public SearchScope getUseScope() { + return xmlTag.getUseScope(); + } + + @Override + @Contract( + pure = true + ) + public ASTNode getNode() { + return xmlTag.getNode(); + } + + @Override + @NonNls + @Contract( + pure = true + ) + public String toString() { + return xmlTag.toString(); + } + + @Override + @Contract( + pure = true + ) + public boolean isEquivalentTo(PsiElement psiElement) { + return xmlTag.isEquivalentTo(psiElement); + } + + @Override + @Nullable + public T getUserData(@NotNull Key key) { + return xmlTag.getUserData(key); + } + + @Override + public void putUserData(@NotNull Key key, @Nullable T t) { + xmlTag.putUserData(key, t); + } + + @Override + public Icon getIcon(@IconFlags int i) { + return xmlTag.getIcon(i); + } + + @Override + public PsiElement setName(@NonNls @NotNull String s) throws IncorrectOperationException { + return xmlTag.setName(s); + } + + @Override + @Nullable + public PsiMetaData getMetaData() { + return xmlTag.getMetaData(); + } + + @Override + @Nullable + public XmlTag getParentTag() { + return xmlTag.getParentTag(); + } + + @Override + @Nullable + public XmlTagChild getNextSiblingInTag() { + return xmlTag.getNextSiblingInTag(); + } + + @Override + @Nullable + public XmlTagChild getPrevSiblingInTag() { + return xmlTag.getPrevSiblingInTag(); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java index 184b7de99..e286e972e 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java @@ -9,9 +9,12 @@ import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.ID; import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; import com.magento.idea.magento2plugin.xml.layout.index.BlockClassFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; @@ -72,7 +75,12 @@ public static List getContainerDeclarations(String componentName, Projec public static List getBlockClassDeclarations(PhpClass phpClass, Project project) { String className = phpClass.getPresentableFQN(); - return getComponentDeclarations(className, "block", BlockClassFileBasedIndex.NAME, project, new ClassComponentMatcher()); + List blockTags = getComponentDeclarations(className, "block", BlockClassFileBasedIndex.NAME, project, new ClassComponentMatcher()); + List decoratedBlockTags = new ArrayList<>(); + for (XmlTag blockTag: blockTags) { + decoratedBlockTags.add(new LayoutBlockLineMarkerXmlTagDecorator(blockTag)); + } + return decoratedBlockTags; } } @@ -92,4 +100,31 @@ class ClassComponentMatcher implements ComponentMatcher { public boolean matches(String value, XmlTag tag) { return value.equals(tag.getAttributeValue("class")); } +} + +/** + * Decorator for XmlTag, which improves readability of "block" node in configuration line marker. + */ +class LayoutBlockLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + public LayoutBlockLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @Override + @NotNull + @NonNls + public String getName() { + String name = xmlTag.getAttributeValue("name"); + if (name != null) { + return String.format("[%s] block %s", getAreaName(), name); + } + return xmlTag.getName(); + } + + @NotNull + @Override + protected String getAreaName() { + return xmlTag.getContainingFile().getVirtualFile().getParent().getParent().getName(); + } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java index 487ee1868..3c994f643 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java @@ -1,36 +1,24 @@ package com.magento.idea.magento2plugin.xml.webapi.index; import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.lang.ASTNode; -import com.intellij.lang.Language; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; import com.intellij.psi.impl.source.xml.XmlDocumentImpl; -import com.intellij.psi.meta.PsiMetaData; -import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.PsiElementProcessor; -import com.intellij.psi.search.SearchScope; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.*; -import com.intellij.util.IncorrectOperationException; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.*; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; -import com.intellij.xml.XmlElementDescriptor; -import com.intellij.xml.XmlNSDescriptor; import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import org.jetbrains.annotations.Contract; +import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.util.*; /** @@ -174,12 +162,10 @@ private static void fillRelatedTags(String classFqn, String methodFqn, XmlTag pa /** * Decorator for XmlTag, which allows to render REST routes in web API line marker. */ -class WebApiLineMarkerXmlTagDecorator implements XmlTag { - - private XmlTag xmlTag; +class WebApiLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { public WebApiLineMarkerXmlTagDecorator(XmlTag xmlTag) { - this.xmlTag = xmlTag; + super(xmlTag); } @Override @@ -193,587 +179,4 @@ public String getName() { } return xmlTag.getName(); } - - @Override - @NotNull - @NonNls - public String getNamespace() { - return xmlTag.getNamespace(); - } - - @Override - @NotNull - @NonNls - public String getLocalName() { - return xmlTag.getLocalName(); - } - - @Override - @Nullable - public XmlElementDescriptor getDescriptor() { - return xmlTag.getDescriptor(); - } - - @Override - @NotNull - public XmlAttribute[] getAttributes() { - return xmlTag.getAttributes(); - } - - @Override - @Nullable - public XmlAttribute getAttribute(@NonNls String s, @NonNls String s1) { - return xmlTag.getAttribute(s, s1); - } - - @Override - @Nullable - public XmlAttribute getAttribute(@NonNls String s) { - return xmlTag.getAttribute(s); - } - - @Override - @Nullable - public String getAttributeValue(@NonNls String s, @NonNls String s1) { - return xmlTag.getAttributeValue(s, s1); - } - - @Override - @Nullable - public String getAttributeValue(@NonNls String s) { - return xmlTag.getAttributeValue(s); - } - - @Override - public XmlAttribute setAttribute(@NonNls String s, @NonNls String s1, @NonNls String s2) throws IncorrectOperationException { - return xmlTag.setAttribute(s, s1, s2); - } - - @Override - public XmlAttribute setAttribute(@NonNls String s, @NonNls String s1) throws IncorrectOperationException { - return xmlTag.setAttribute(s, s1); - } - - @Override - public XmlTag createChildTag(@NonNls String s, @NonNls String s1, @Nullable @NonNls String s2, boolean b) { - return xmlTag.createChildTag(s, s1, s2, b); - } - - @Override - public XmlTag addSubTag(XmlTag xmlTag, boolean b) { - return this.xmlTag.addSubTag(xmlTag, b); - } - - @Override - @NotNull - public XmlTag[] getSubTags() { - return xmlTag.getSubTags(); - } - - @Override - @NotNull - public XmlTag[] findSubTags(@NonNls String s) { - return xmlTag.findSubTags(s); - } - - @Override - @NotNull - public XmlTag[] findSubTags(@NonNls String s, @Nullable String s1) { - return xmlTag.findSubTags(s, s1); - } - - @Override - @Nullable - public XmlTag findFirstSubTag(@NonNls String s) { - return xmlTag.findFirstSubTag(s); - } - - @Override - @NotNull - @NonNls - public String getNamespacePrefix() { - return xmlTag.getNamespacePrefix(); - } - - @Override - @NotNull - @NonNls - public String getNamespaceByPrefix(@NonNls String s) { - return xmlTag.getNamespaceByPrefix(s); - } - - @Override - @Nullable - public String getPrefixByNamespace(@NonNls String s) { - return xmlTag.getPrefixByNamespace(s); - } - - @Override - public String[] knownNamespaces() { - return xmlTag.knownNamespaces(); - } - - @Override - public boolean hasNamespaceDeclarations() { - return xmlTag.hasNamespaceDeclarations(); - } - - @Override - @NotNull - public Map getLocalNamespaceDeclarations() { - return xmlTag.getLocalNamespaceDeclarations(); - } - - @Override - @NotNull - public XmlTagValue getValue() { - return xmlTag.getValue(); - } - - @Override - @Nullable - public XmlNSDescriptor getNSDescriptor(@NonNls String s, boolean b) { - return xmlTag.getNSDescriptor(s, b); - } - - @Override - public boolean isEmpty() { - return xmlTag.isEmpty(); - } - - @Override - public void collapseIfEmpty() { - xmlTag.collapseIfEmpty(); - } - - @Override - @Nullable - @NonNls - public String getSubTagText(@NonNls String s) { - return xmlTag.getSubTagText(s); - } - - @Override - public boolean processElements(PsiElementProcessor psiElementProcessor, PsiElement psiElement) { - return xmlTag.processElements(psiElementProcessor, psiElement); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public Project getProject() throws PsiInvalidElementAccessException { - return xmlTag.getProject(); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public Language getLanguage() { - return xmlTag.getLanguage(); - } - - @Override - @Contract( - pure = true - ) - public PsiManager getManager() { - return xmlTag.getManager(); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public PsiElement[] getChildren() { - return xmlTag.getChildren(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getParent() { - return xmlTag.getParent(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getFirstChild() { - return xmlTag.getFirstChild(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getLastChild() { - return xmlTag.getLastChild(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getNextSibling() { - return xmlTag.getNextSibling(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getPrevSibling() { - return xmlTag.getPrevSibling(); - } - - @Override - @Contract( - pure = true - ) - public PsiFile getContainingFile() throws PsiInvalidElementAccessException { - return xmlTag.getContainingFile(); - } - - @Override - @Contract( - pure = true - ) - public TextRange getTextRange() { - return xmlTag.getTextRange(); - } - - @Override - @Contract( - pure = true - ) - public int getStartOffsetInParent() { - return xmlTag.getStartOffsetInParent(); - } - - @Override - @Contract( - pure = true - ) - public int getTextLength() { - return xmlTag.getTextLength(); - } - - @Override - @Nullable - @Contract( - pure = true - ) - public PsiElement findElementAt(int i) { - return xmlTag.findElementAt(i); - } - - @Override - @Nullable - @Contract( - pure = true - ) - public PsiReference findReferenceAt(int i) { - return xmlTag.findReferenceAt(i); - } - - @Override - @Contract( - pure = true - ) - public int getTextOffset() { - return xmlTag.getTextOffset(); - } - - @Override - @NonNls - @Contract( - pure = true - ) - public String getText() { - return xmlTag.getText(); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public char[] textToCharArray() { - return xmlTag.textToCharArray(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getNavigationElement() { - return xmlTag.getNavigationElement(); - } - - @Override - @Contract( - pure = true - ) - public PsiElement getOriginalElement() { - return xmlTag.getOriginalElement(); - } - - @Override - @Contract( - pure = true - ) - public boolean textMatches(@NotNull @NonNls CharSequence charSequence) { - return xmlTag.textMatches(charSequence); - } - - @Override - @Contract( - pure = true - ) - public boolean textMatches(@NotNull PsiElement psiElement) { - return xmlTag.textMatches(psiElement); - } - - @Override - @Contract( - pure = true - ) - public boolean textContains(char c) { - return xmlTag.textContains(c); - } - - @Override - public void accept(@NotNull PsiElementVisitor psiElementVisitor) { - xmlTag.accept(psiElementVisitor); - } - - @Override - public void acceptChildren(@NotNull PsiElementVisitor psiElementVisitor) { - xmlTag.acceptChildren(psiElementVisitor); - } - - @Override - public PsiElement copy() { - return xmlTag.copy(); - } - - @Override - public PsiElement add(@NotNull PsiElement psiElement) throws IncorrectOperationException { - return xmlTag.add(psiElement); - } - - @Override - public PsiElement addBefore(@NotNull PsiElement psiElement, @Nullable PsiElement psiElement1) throws IncorrectOperationException { - return xmlTag.addBefore(psiElement, psiElement1); - } - - @Override - public PsiElement addAfter(@NotNull PsiElement psiElement, @Nullable PsiElement psiElement1) throws IncorrectOperationException { - return xmlTag.addAfter(psiElement, psiElement1); - } - - @Override - public void checkAdd(@NotNull PsiElement psiElement) throws IncorrectOperationException { - xmlTag.checkAdd(psiElement); - } - - @Override - public PsiElement addRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException { - return xmlTag.addRange(psiElement, psiElement1); - } - - @Override - public PsiElement addRangeBefore(@NotNull PsiElement psiElement, @NotNull PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException { - return xmlTag.addRangeBefore(psiElement, psiElement1, psiElement2); - } - - @Override - public PsiElement addRangeAfter(PsiElement psiElement, PsiElement psiElement1, PsiElement psiElement2) throws IncorrectOperationException { - return xmlTag.addRangeAfter(psiElement, psiElement1, psiElement2); - } - - @Override - public void delete() throws IncorrectOperationException { - xmlTag.delete(); - } - - @Override - public void checkDelete() throws IncorrectOperationException { - xmlTag.checkDelete(); - } - - @Override - public void deleteChildRange(PsiElement psiElement, PsiElement psiElement1) throws IncorrectOperationException { - xmlTag.deleteChildRange(psiElement, psiElement1); - } - - @Override - public PsiElement replace(@NotNull PsiElement psiElement) throws IncorrectOperationException { - return xmlTag.replace(psiElement); - } - - @Override - @Contract( - pure = true - ) - public boolean isValid() { - return xmlTag.isValid(); - } - - @Override - @Contract( - pure = true - ) - public boolean isWritable() { - return xmlTag.isWritable(); - } - - @Override - @Nullable - @Contract( - pure = true - ) - public PsiReference getReference() { - return xmlTag.getReference(); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public PsiReference[] getReferences() { - return xmlTag.getReferences(); - } - - @Override - @Nullable - @Contract( - pure = true - ) - public T getCopyableUserData(Key key) { - return xmlTag.getCopyableUserData(key); - } - - @Override - public void putCopyableUserData(Key key, @Nullable T t) { - xmlTag.putCopyableUserData(key, t); - } - - @Override - public boolean processDeclarations(@NotNull PsiScopeProcessor psiScopeProcessor, @NotNull ResolveState resolveState, @Nullable PsiElement psiElement, @NotNull PsiElement psiElement1) { - return xmlTag.processDeclarations(psiScopeProcessor, resolveState, psiElement, psiElement1); - } - - @Override - @Nullable - @Contract( - pure = true - ) - public PsiElement getContext() { - return xmlTag.getContext(); - } - - @Override - @Contract( - pure = true - ) - public boolean isPhysical() { - return xmlTag.isPhysical(); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public GlobalSearchScope getResolveScope() { - return xmlTag.getResolveScope(); - } - - @Override - @NotNull - @Contract( - pure = true - ) - public SearchScope getUseScope() { - return xmlTag.getUseScope(); - } - - @Override - @Contract( - pure = true - ) - public ASTNode getNode() { - return xmlTag.getNode(); - } - - @Override - @NonNls - @Contract( - pure = true - ) - public String toString() { - return xmlTag.toString(); - } - - @Override - @Contract( - pure = true - ) - public boolean isEquivalentTo(PsiElement psiElement) { - return xmlTag.isEquivalentTo(psiElement); - } - - @Override - @Nullable - public T getUserData(@NotNull Key key) { - return xmlTag.getUserData(key); - } - - @Override - public void putUserData(@NotNull Key key, @Nullable T t) { - xmlTag.putUserData(key, t); - } - - @Override - public Icon getIcon(@IconFlags int i) { - return xmlTag.getIcon(i); - } - - @Override - public PsiElement setName(@NonNls @NotNull String s) throws IncorrectOperationException { - return xmlTag.setName(s); - } - - @Override - @Nullable - public PsiMetaData getMetaData() { - return xmlTag.getMetaData(); - } - - @Override - @Nullable - public XmlTag getParentTag() { - return xmlTag.getParentTag(); - } - - @Override - @Nullable - public XmlTagChild getNextSiblingInTag() { - return xmlTag.getNextSiblingInTag(); - } - - @Override - @Nullable - public XmlTagChild getPrevSiblingInTag() { - return xmlTag.getPrevSiblingInTag(); - } } From 7e93ece55afb8acd26904db47a698cb052965327 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Wed, 6 Jan 2016 12:38:38 +0200 Subject: [PATCH 33/51] Fixed plugins description --- META-INF/plugin.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index cce1c97c6..cf38bfe5c 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -6,8 +6,9 @@ Features - +
    +

    Features

    +

    Configuration smart completion and references

    • di.xml
    • From c9c30274db749cdb7cd9e0bdf2c7fa45fa5dd544 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sat, 9 Jan 2016 22:44:03 +0200 Subject: [PATCH 34/51] Added Plugin Settings Refactored module manager to be more abstract --- META-INF/plugin.xml | 2 + .../magento/idea/magento2plugin/Settings.java | 38 ++++++ .../idea/magento2plugin/SettingsForm.form | 68 ++++++++++ .../idea/magento2plugin/SettingsForm.java | 79 +++++++++++ .../index/ModulePackageFileBasedIndex.java | 10 +- .../php/inspections/MagentoApiInspection.java | 6 +- .../inspections/ObjectManagerInspection.java | 11 +- .../php/module/ComposerPackageModelImpl.java | 2 +- .../php/module/MagentoComponent.java | 15 +++ .../php/module/MagentoComponentImp.java | 40 ++++++ ...ager.java => MagentoComponentManager.java} | 126 +++++++++--------- .../php/module/MagentoModule.java | 19 +-- .../php/tool/ModuleToolWindowFactory.java | 9 +- .../idea/magento2plugin/util/IndexUtil.java | 46 +++++++ 14 files changed, 371 insertions(+), 100 deletions(-) create mode 100644 src/com/magento/idea/magento2plugin/Settings.java create mode 100644 src/com/magento/idea/magento2plugin/SettingsForm.form create mode 100644 src/com/magento/idea/magento2plugin/SettingsForm.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java create mode 100644 src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java rename src/com/magento/idea/magento2plugin/php/module/{ModuleManager.java => MagentoComponentManager.java} (55%) create mode 100644 src/com/magento/idea/magento2plugin/util/IndexUtil.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index cf38bfe5c..4abb0d625 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -103,6 +103,8 @@ secondary="false" factoryClass="com.magento.idea.magento2plugin.php.tool.ModuleToolWindowFactory" /> --> + + diff --git a/src/com/magento/idea/magento2plugin/Settings.java b/src/com/magento/idea/magento2plugin/Settings.java new file mode 100644 index 000000000..e5a20d5e6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/Settings.java @@ -0,0 +1,38 @@ +package com.magento.idea.magento2plugin; + +import com.intellij.openapi.components.*; +import com.intellij.openapi.project.Project; +import com.intellij.util.xmlb.XmlSerializerUtil; +import org.jetbrains.annotations.Nullable; + +@State( + name = "Magento2PluginSettings", + storages = { + @Storage(id = "default", file = StoragePathMacros.PROJECT_FILE), + @Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/magento2plugin.xml", scheme = StorageScheme.DIRECTORY_BASED) + } +) +public class Settings implements PersistentStateComponent { + public boolean pluginEnabled = false; + + @Nullable + @Override + public Settings getState() { + return this; + } + + @Override + public void loadState(Settings settings) { + XmlSerializerUtil.copyBean(settings, this); + } + + protected Project project; + + public static Settings getInstance(Project project) { + Settings settings = ServiceManager.getService(project, Settings.class); + + settings.project = project; + + return settings; + } +} diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.form b/src/com/magento/idea/magento2plugin/SettingsForm.form new file mode 100644 index 000000000..82ba8f4fe --- /dev/null +++ b/src/com/magento/idea/magento2plugin/SettingsForm.form @@ -0,0 +1,68 @@ + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.java b/src/com/magento/idea/magento2plugin/SettingsForm.java new file mode 100644 index 000000000..da4f33637 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/SettingsForm.java @@ -0,0 +1,79 @@ +package com.magento.idea.magento2plugin; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.magento.idea.magento2plugin.util.IndexUtil; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * Created by dkvashnin on 1/9/16. + */ +public class SettingsForm implements Configurable { + private Project project; + private JCheckBox pluginEnabled; + private JButton buttonReindex; + private JPanel panel1; + private JButton regenerateUrnMapButton; + + public SettingsForm(@NotNull final Project project) { + this.project = project; + } + + @Nls + @Override + public String getDisplayName() { + return "Magento2 plugin"; + } + + @Nullable + @Override + public String getHelpTopic() { + return null; + } + + @Nullable + @Override + public JComponent createComponent() { + buttonReindex.addMouseListener( + new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + IndexUtil.manualReindex(); + super.mouseClicked(e); + } + } + ); + return (JComponent) panel1; + } + + @Override + public boolean isModified() { + return !pluginEnabled.isSelected() == getSettings().pluginEnabled; + } + + @Override + public void apply() throws ConfigurationException { + getSettings().pluginEnabled = pluginEnabled.isSelected(); + } + + @Override + public void reset() { + pluginEnabled.setSelected(getSettings().pluginEnabled); + } + + @Override + public void disposeUIResources() { + + } + + private Settings getSettings() { + return Settings.getInstance(project); + } +} diff --git a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java index 0ad4c0fe4..72677065c 100644 --- a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java @@ -5,17 +5,14 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.indexing.*; -import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; import com.magento.idea.magento2plugin.php.module.ComposerPackageModelImpl; -import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; -import java.util.Set; /** * Created by dkvashnin on 12/3/15. @@ -40,9 +37,12 @@ public Map map(@NotNull FileContent fileContent) { JsonFile jsonFile = (JsonFile)fileContent.getPsiFile(); JsonObject jsonObject = PsiTreeUtil.getChildOfType(jsonFile, JsonObject.class); + if (jsonObject == null) { + return map; + } ComposerPackageModel composerObject = new ComposerPackageModelImpl(jsonObject); - if (!"magento2-module".equals(composerObject.getType())) { + if (!"magento".equals(composerObject.getVendor())) { return map; } @@ -82,6 +82,6 @@ public boolean dependsOnFileContent() { @Override public int getVersion() { - return 0; + return 1; } } diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index 4c683e49c..670d191c7 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -10,7 +10,7 @@ import com.jetbrains.php.lang.psi.elements.*; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; import com.magento.idea.magento2plugin.php.module.MagentoModule; -import com.magento.idea.magento2plugin.php.module.ModuleManager; +import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import org.jetbrains.annotations.NotNull; /** @@ -85,8 +85,8 @@ private static boolean isValidReference(PhpNamedElement referencedElement, PsiEl } private static MagentoModule getMagentoModule(PsiElement element) { - ModuleManager moduleManager = ModuleManager.getInstance(element.getProject()); - return moduleManager.getModuleForFile(element.getContainingFile()); + MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(element.getProject()); + return magentoComponentManager.getComponentOfTypeForFile(element.getContainingFile(), MagentoModule.class); } private static boolean areDifferentModules(MagentoModule magentoModule, MagentoModule currentPackage) { diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java index b1f90d7ce..e364bc7d8 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java @@ -11,7 +11,8 @@ import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; -import com.magento.idea.magento2plugin.php.module.ModuleManager; +import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; +import com.magento.idea.magento2plugin.php.module.MagentoModule; import com.magento.idea.magento2plugin.php.util.MagentoTypes; import org.jetbrains.annotations.NotNull; @@ -39,8 +40,8 @@ public void visitPhpMethodReference(MethodReference reference) { PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof Method) { - ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); - if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { + MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(referencedElement.getProject()); + if (magentoComponentManager.getComponentOfTypeForFile(reference.getContainingFile(), MagentoModule.class) == null) { return; } @@ -55,8 +56,8 @@ public void visitPhpClassReference(ClassReference reference) { PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof PhpClass) { - ModuleManager moduleManager = ModuleManager.getInstance(referencedElement.getProject()); - if (moduleManager.getModuleForFile(reference.getContainingFile()) == null) { + MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(referencedElement.getProject()); + if (magentoComponentManager.getComponentOfTypeForFile(reference.getContainingFile(), MagentoModule.class) == null) { return; } diff --git a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java index f1f1948d4..ec10d8eb4 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java +++ b/src/com/magento/idea/magento2plugin/php/module/ComposerPackageModelImpl.java @@ -23,7 +23,7 @@ public class ComposerPackageModelImpl implements ComposerPackageModel { public static final String PSR4 = "psr4"; public static final String FILES = "file"; - public ComposerPackageModelImpl(JsonObject sourceComposerJson) { + public ComposerPackageModelImpl(@NotNull JsonObject sourceComposerJson) { this.sourceComposerJson = sourceComposerJson; } diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java new file mode 100644 index 000000000..290a201ef --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java @@ -0,0 +1,15 @@ +package com.magento.idea.magento2plugin.php.module; + +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Created by dkvashnin on 1/9/16. + */ +public interface MagentoComponent { + @Nullable + ComposerPackageModel getComposerModel(); + + boolean isFileInContext(@NotNull PsiFile psiFile); +} diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java new file mode 100644 index 000000000..7f380bc3f --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java @@ -0,0 +1,40 @@ +package com.magento.idea.magento2plugin.php.module; + +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Created by dkvashnin on 1/9/16. + */ +public class MagentoComponentImp implements MagentoComponent { + protected final ComposerPackageModel composerPackageModel; + protected final PsiDirectory directory; + + public MagentoComponentImp(ComposerPackageModel composerPackageModel, PsiDirectory directory) { + this.composerPackageModel = composerPackageModel; + this.directory = directory; + } + + @Nullable + @Override + public ComposerPackageModel getComposerModel() { + return composerPackageModel; + } + + @Override + public boolean isFileInContext(@NotNull PsiFile psiFile) { + PsiDirectory containingDirectory = psiFile.getOriginalFile().getContainingDirectory(); + while (containingDirectory != null) { + if (containingDirectory.getManager().areElementsEquivalent(containingDirectory, directory)) { + return true; + } + + containingDirectory = containingDirectory.getParentDirectory(); + } + + return false; + } + +} diff --git a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java similarity index 55% rename from src/com/magento/idea/magento2plugin/php/module/ModuleManager.java rename to src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java index 001f52afe..6df96faad 100644 --- a/src/com/magento/idea/magento2plugin/php/module/ModuleManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java @@ -12,8 +12,8 @@ import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.FileBasedIndex; -import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.php.index.ModulePackageFileBasedIndex; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -21,39 +21,68 @@ /** * Created by dkvashnin on 12/5/15. */ -public class ModuleManager { - private Map modules = new HashMap<>(); +public class MagentoComponentManager { + private Map components = new HashMap<>(); private long cacheStartTime; private static final int CACHE_LIFE_TIME = 20000; - private static ModuleManager moduleManager; + private static MagentoComponentManager magentoComponentManager; private Project project; - private ModuleManager(Project project){ + private MagentoComponentManager(Project project){ this.project = project; } - public static ModuleManager getInstance(Project project) { - if (moduleManager == null) { - moduleManager = new ModuleManager(project); + public static MagentoComponentManager getInstance(@NotNull Project project) { + if (magentoComponentManager == null) { + magentoComponentManager = new MagentoComponentManager(project); } - return moduleManager; + return magentoComponentManager; } - synchronized public Collection getModules() { + public Collection getAllModules() { + return getComponents().values(); + } + + @SuppressWarnings("unchecked") + public Collection getAllModulesOfType(@NotNull Class type) { + Collection result = new ArrayList<>(); + Map components = getComponents(); + for (String key: components.keySet()) { + if (type.isInstance(components.get(key))) { + result.add((T)components.get(key)); + } + } + + return result; + } + + synchronized private Map getComponents() { if (cacheStartTime + CACHE_LIFE_TIME < System.currentTimeMillis()) { flushModules(); loadModules(); cacheStartTime = System.currentTimeMillis(); } - return modules.values(); + return components; + } + + @Nullable + public MagentoComponent getComponentForFile(@NotNull PsiFile psiFile) { + for (MagentoComponent magentoComponent: this.getAllModules()) { + if (magentoComponent.isFileInContext(psiFile)) { + return magentoComponent; + } + } + + return null; } @Nullable - public MagentoModule getModuleForFile(PsiFile psiFile) { - for (MagentoModule magentoModule: this.getModules()) { - if (magentoModule.isFileInContext(psiFile)) { - return magentoModule; + @SuppressWarnings("unchecked") + public T getComponentOfTypeForFile(@NotNull PsiFile psiFile, @NotNull Class type) { + for (MagentoComponent magentoComponent: this.getAllModules()) { + if (type.isInstance(magentoComponent) && magentoComponent.isFileInContext(psiFile)) { + return (T)magentoComponent; } } @@ -61,18 +90,17 @@ public MagentoModule getModuleForFile(PsiFile psiFile) { } public void flushModules() { - modules = new HashMap<>(); + components = new HashMap<>(); } private void loadModules() { Collection packages = FileBasedIndex.getInstance().getAllKeys(ModulePackageFileBasedIndex.NAME, this.project); PsiManager psiManager = PsiManager.getInstance(this.project); for (String packageName: packages) { - if (modules.containsKey(packageName)) { + if (components.containsKey(packageName)) { continue; } - Collection containingFiles = FileBasedIndex.getInstance() .getContainingFiles(ModulePackageFileBasedIndex.NAME, packageName, GlobalSearchScope.allScope(this.project)); @@ -82,29 +110,39 @@ private void loadModules() { PsiFile psiFile = psiManager.findFile(configurationFile); if (psiFile != null && psiFile instanceof JsonFile) { JsonObject jsonObject = PsiTreeUtil.getChildOfType((JsonFile) psiFile, JsonObject.class); - modules.put( + if (jsonObject == null) { + continue; + } + + MagentoComponent magentoComponent; + ComposerPackageModel composerPackageModel = new ComposerPackageModelImpl(jsonObject); + if ("magento2-module".equals(composerPackageModel.getType())) { + magentoComponent = new MagentoModuleImpl(new ComposerPackageModelImpl(jsonObject), psiFile.getContainingDirectory()); + } else { + magentoComponent = new MagentoComponentImp(new ComposerPackageModelImpl(jsonObject), psiFile.getContainingDirectory()); + } + + components.put( packageName, - new MagentoModuleImpl(new ComposerPackageModelImpl(jsonObject), psiFile.getContainingDirectory()) + magentoComponent ); } } } } + + } /** * Created by dkvashnin on 12/5/15. */ -class MagentoModuleImpl implements MagentoModule { - private ComposerPackageModel composerPackageModel; - private PsiDirectory directory; +class MagentoModuleImpl extends MagentoComponentImp implements MagentoModule { private static final String DEFAULT_MODULE_NAME = "Undefined module"; private static final String CONFIGURATION_PATH = "etc"; public MagentoModuleImpl(ComposerPackageModel composerPackageModel, PsiDirectory directory) { - - this.composerPackageModel = composerPackageModel; - this.directory = directory; + super(composerPackageModel, directory); } @Nullable @@ -127,40 +165,4 @@ public String getMagentoName() { return DEFAULT_MODULE_NAME; } - - @Nullable - @Override - public List getMagentoDependencies() { - return null; - } - - @Nullable - @Override - public ComposerPackageModel getComposerModel() { - return composerPackageModel; - } - - @Override - public boolean isFileInContext(PsiFile psiFile) { - PsiDirectory containingDirectory = psiFile.getOriginalFile().getContainingDirectory(); - while (containingDirectory != null) { - if (containingDirectory.getManager().areElementsEquivalent(containingDirectory, directory)) { - return true; - } - - containingDirectory = containingDirectory.getParentDirectory(); - } - - return false; - } - - @Override - public boolean isClassInContext(PhpClass phpClass) { - return false; - } - - @Override - public PsiDirectory getSourceDirectory() { - return directory; - } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java index 8c130d592..210070a67 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java @@ -1,28 +1,11 @@ package com.magento.idea.magento2plugin.php.module; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiFile; -import com.jetbrains.php.lang.psi.elements.PhpClass; import org.jetbrains.annotations.Nullable; -import java.util.List; - /** * Created by dkvashnin on 12/5/15. */ -public interface MagentoModule { +public interface MagentoModule extends MagentoComponent { @Nullable String getMagentoName(); - - @Nullable - List getMagentoDependencies(); - - @Nullable - ComposerPackageModel getComposerModel(); - - boolean isFileInContext(PsiFile psiFile); - - boolean isClassInContext(PhpClass phpClass); - - PsiDirectory getSourceDirectory(); } diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java index aae56d016..b40cb8253 100644 --- a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java +++ b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java @@ -7,15 +7,12 @@ import com.intellij.ui.content.ContentFactory; import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; import com.magento.idea.magento2plugin.php.module.MagentoModule; -import com.magento.idea.magento2plugin.php.module.ModuleManager; +import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreePath; import java.util.HashMap; import java.util.Map; @@ -39,7 +36,7 @@ public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindo } private void initializeModulesTree(Project project) { - ModuleManager moduleManager = ModuleManager.getInstance(project); + MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(project); Map vendorNodes = new HashMap<>(); @@ -47,7 +44,7 @@ private void initializeModulesTree(Project project) { modulesTree.setModel(new DefaultTreeModel(rootNode)); - for (MagentoModule magentoModule: moduleManager.getModules()) { + for (MagentoModule magentoModule: magentoComponentManager.getAllModulesOfType(MagentoModule.class)) { ComposerPackageModel packageModel = magentoModule.getComposerModel(); if (packageModel == null) { continue; diff --git a/src/com/magento/idea/magento2plugin/util/IndexUtil.java b/src/com/magento/idea/magento2plugin/util/IndexUtil.java new file mode 100644 index 000000000..1de05d6d2 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/util/IndexUtil.java @@ -0,0 +1,46 @@ +package com.magento.idea.magento2plugin.util; + +import com.intellij.util.indexing.FileBasedIndexImpl; +import com.intellij.util.indexing.ID; +import com.magento.idea.magento2plugin.php.index.ModulePackageFileBasedIndex; +import com.magento.idea.magento2plugin.xml.di.index.PluginToTypeFileBasedIndex; +import com.magento.idea.magento2plugin.xml.di.index.TypeConfigurationFileBasedIndex; +import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.BlockClassFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; +import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; +import com.magento.idea.magento2plugin.xml.observer.index.EventObserverFileBasedIndex; +import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; +import com.magento.idea.magento2plugin.xml.webapi.index.WebApiTypesFileBasedIndex; + +/** + * Created by dkvashnin on 1/9/16. + */ +public class IndexUtil { + public static void manualReindex() { + ID[] indexIds = new ID[] { + // php + ModulePackageFileBasedIndex.NAME, + EventsDeclarationsFileBasedIndex.NAME, + + // xml configuration + // di + PluginToTypeFileBasedIndex.NAME, + TypeConfigurationFileBasedIndex.NAME, + VirtualTypesNamesFileBasedIndex.NAME, + // layouts + BlockClassFileBasedIndex.NAME, + BlockFileBasedIndex.NAME, + ContainerFileBasedIndex.NAME, + // events + EventObserverFileBasedIndex.NAME, + // webapi + WebApiTypesFileBasedIndex.NAME + }; + + for(ID id: indexIds) { + FileBasedIndexImpl.getInstance().requestRebuild(id); + FileBasedIndexImpl.getInstance().scheduleRebuild(id, new Throwable()); + } + } +} From 00a23b83b9ebdb0a8f56d61360dcd5717ace118a Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 10 Jan 2016 01:39:57 +0200 Subject: [PATCH 35/51] Added URN generation actionn --- .../magento/idea/magento2plugin/Settings.java | 5 + .../idea/magento2plugin/SettingsForm.form | 5 +- .../idea/magento2plugin/SettingsForm.java | 128 ++++++++++++++++++ .../index/ModulePackageFileBasedIndex.java | 11 +- .../php/inspections/MagentoApiInspection.java | 7 + .../inspections/ObjectManagerInspection.java | 7 + .../ClassConfigurationLineMarkerProvider.java | 6 + .../linemarker/PluginLineMarkerProvider.java | 6 + .../linemarker/WebApiLineMarkerProvider.java | 6 + .../php/module/MagentoComponent.java | 5 +- .../php/module/MagentoComponentImp.java | 9 +- .../php/module/MagentoComponentManager.java | 14 +- .../php/tool/ModuleToolWindowFactory.java | 2 +- 13 files changed, 195 insertions(+), 16 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/Settings.java b/src/com/magento/idea/magento2plugin/Settings.java index e5a20d5e6..86eac7def 100644 --- a/src/com/magento/idea/magento2plugin/Settings.java +++ b/src/com/magento/idea/magento2plugin/Settings.java @@ -3,6 +3,7 @@ import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; import com.intellij.util.xmlb.XmlSerializerUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @State( @@ -35,4 +36,8 @@ public static Settings getInstance(Project project) { return settings; } + + public static boolean isEnabled(@NotNull Project project) { + return getInstance(project).pluginEnabled; + } } diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.form b/src/com/magento/idea/magento2plugin/SettingsForm.form index 82ba8f4fe..65eda471c 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.form +++ b/src/com/magento/idea/magento2plugin/SettingsForm.form @@ -3,7 +3,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -55,6 +55,7 @@ + diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.java b/src/com/magento/idea/magento2plugin/SettingsForm.java index da4f33637..91d1b9dd7 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.java +++ b/src/com/magento/idea/magento2plugin/SettingsForm.java @@ -1,16 +1,30 @@ package com.magento.idea.magento2plugin; +import com.intellij.javaee.ExternalResourceManager; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FilenameIndex; +import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; +import com.magento.idea.magento2plugin.php.module.MagentoComponent; +import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; +import com.magento.idea.magento2plugin.php.module.MagentoModule; import com.magento.idea.magento2plugin.util.IndexUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.*; /** * Created by dkvashnin on 1/9/16. @@ -41,18 +55,36 @@ public String getHelpTopic() { @Nullable @Override public JComponent createComponent() { + onOff(); buttonReindex.addMouseListener( new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { IndexUtil.manualReindex(); + MagentoComponentManager.getInstance(project).flushModules(); super.mouseClicked(e); } } ); + + pluginEnabled.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + onOff(); + } + }); + + regenerateUrnMapButton.addMouseListener( + new RegenerateUrnMapListener(project) + ); return (JComponent) panel1; } + private void onOff() { + buttonReindex.setEnabled(pluginEnabled.isSelected()); + regenerateUrnMapButton.setEnabled(pluginEnabled.isSelected()); + } + @Override public boolean isModified() { return !pluginEnabled.isSelected() == getSettings().pluginEnabled; @@ -77,3 +109,99 @@ private Settings getSettings() { return Settings.getInstance(project); } } + +class RegenerateUrnMapListener extends MouseAdapter { + private final static String MODULE = "urn:magento:module:"; + private final static String FRAMEWORK = "urn:magento:framework:"; + + private Project project; + + public RegenerateUrnMapListener(@NotNull Project project) { + this.project = project; + } + + @Override + public void mouseClicked(MouseEvent e) { + ApplicationManager.getApplication().runWriteAction( + new Runnable() { + @Override + public void run() { + ExternalResourceManager externalResourceManager = ExternalResourceManager.getInstance(); + PsiManager psiManager = PsiManager.getInstance(project); + MagentoComponentManager componentManager = MagentoComponentManager.getInstance(project); + + Collection xsdFiles = FilenameIndex.getAllFilesByExt(project, "xsd"); + Collection components = componentManager.getAllComponents(); + + for (VirtualFile virtualFile: xsdFiles) { + PsiFile psiFile = psiManager.findFile(virtualFile); + if (psiFile == null) { + continue; + } + + MagentoComponent xsdOwner = findComponentForXsd(psiFile, components); + if (xsdOwner == null) { + continue; + } + + String urnKey = buildUrnKeyForFile(psiFile, xsdOwner); + if (urnKey == null) { + continue; + } + + externalResourceManager.addResource(urnKey, virtualFile.getCanonicalPath()); + } + } + } + ); + + super.mouseClicked(e); + } + + @Nullable + private MagentoComponent findComponentForXsd(@NotNull PsiFile psiFile, Collection components) { + for (MagentoComponent component: components) { + if (component.isFileInContext(psiFile)) { + return component; + } + } + + return null; + } + + @Nullable + private String buildUrnKeyForFile(@NotNull PsiFile psiFile, @NotNull MagentoComponent magentoComponent) { + String prefix = null; + + if (magentoComponent instanceof MagentoModule) { + prefix = MODULE + ((MagentoModule)magentoComponent).getMagentoName() + ":"; + } else { + ComposerPackageModel composerPackageModel = magentoComponent.getComposerModel(); + if ("magento2-library".equals(composerPackageModel.getType())) { + prefix = FRAMEWORK; + } + } + + if (prefix == null) { + return null; + } + + Stack relativePath = new Stack<>(); + relativePath.push(psiFile.getName()); + + PsiManager psiManager = magentoComponent.getDirectory().getManager(); + PsiDirectory parentDir = psiFile.getParent(); + while (parentDir != null && !psiManager.areElementsEquivalent(parentDir, magentoComponent.getDirectory())) { + relativePath.push("/"); + relativePath.push(parentDir.getName()); + parentDir = parentDir.getParentDirectory(); + } + + StringBuilder stringBuilder = new StringBuilder(prefix); + while (!relativePath.empty()) { + stringBuilder.append(relativePath.pop()); + } + + return stringBuilder.toString(); + } +} diff --git a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java index 72677065c..b06e7b972 100644 --- a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java @@ -7,6 +7,7 @@ import com.intellij.util.indexing.*; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; import com.magento.idea.magento2plugin.php.module.ComposerPackageModelImpl; import org.jetbrains.annotations.NotNull; @@ -35,6 +36,9 @@ public DataIndexer getIndexer() { public Map map(@NotNull FileContent fileContent) { Map map = new HashMap<>(); JsonFile jsonFile = (JsonFile)fileContent.getPsiFile(); + if (!Settings.isEnabled(jsonFile.getProject())) { + return map; + } JsonObject jsonObject = PsiTreeUtil.getChildOfType(jsonFile, JsonObject.class); if (jsonObject == null) { @@ -42,7 +46,12 @@ public Map map(@NotNull FileContent fileContent) { } ComposerPackageModel composerObject = new ComposerPackageModelImpl(jsonObject); - if (!"magento".equals(composerObject.getVendor())) { + String type = composerObject.getType(); + if (type == null) { + return map; + } + + if (!type.startsWith("magento2-")) { return map; } diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index 670d191c7..0f8492100 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -9,6 +9,7 @@ import com.jetbrains.php.lang.inspections.PhpInspection; import com.jetbrains.php.lang.psi.elements.*; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.php.module.MagentoModule; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import org.jetbrains.annotations.NotNull; @@ -38,6 +39,9 @@ public ApiInspectionVisitor(@NotNull ProblemsHolder problemsHolder) { @Override public void visitPhpMethodReference(MethodReference reference) { + if (!Settings.isEnabled(reference.getProject())) { + return; + } PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof Method) { @@ -56,6 +60,9 @@ public void visitPhpMethodReference(MethodReference reference) { @Override public void visitPhpClassReference(ClassReference reference) { + if (!Settings.isEnabled(reference.getProject())) { + return; + } PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof PhpClass) { diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java index e364bc7d8..d7b3fa84b 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java @@ -11,6 +11,7 @@ import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import com.magento.idea.magento2plugin.php.module.MagentoModule; import com.magento.idea.magento2plugin.php.util.MagentoTypes; @@ -37,6 +38,9 @@ public OMInspectionVisitor(@NotNull ProblemsHolder problemsHolder) { @Override public void visitPhpMethodReference(MethodReference reference) { + if (!Settings.isEnabled(reference.getProject())) { + return; + } PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof Method) { @@ -53,6 +57,9 @@ public void visitPhpMethodReference(MethodReference reference) { @Override public void visitPhpClassReference(ClassReference reference) { + if (!Settings.isEnabled(reference.getProject())) { + return; + } PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof PhpClass) { diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java index 36cd3943c..968b5d590 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java @@ -7,6 +7,7 @@ import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.Magento2Icons; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.di.index.TypeConfigurationFileBasedIndex; import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; import org.jetbrains.annotations.NotNull; @@ -31,6 +32,11 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { @Override public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { + if (list.size() > 0) { + if (!Settings.isEnabled(list.get(0).getProject())) { + return; + } + } for (PsiElement psiElement: list) { if (psiElement instanceof PhpClass) { List results = new ArrayList(); diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java index 13eddbb98..71cbec199 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java @@ -10,6 +10,7 @@ import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.Magento2Icons; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.di.index.PluginToTypeFileBasedIndex; import org.apache.commons.lang.WordUtils; import org.jetbrains.annotations.NotNull; @@ -29,6 +30,11 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { @Override public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { + if (list.size() > 0) { + if (!Settings.isEnabled(list.get(0).getProject())) { + return; + } + } PluginClassCache pluginClassCache = new PluginClassCache(); ClassPluginCollector classPluginCollector = new ClassPluginCollector(pluginClassCache); MethodPluginCollector methodPluginCollector = new MethodPluginCollector(pluginClassCache); diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java index c3697abb4..ce367d0be 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java @@ -8,6 +8,7 @@ import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.magento.idea.magento2plugin.Magento2Icons; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.webapi.index.WebApiTypesFileBasedIndex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +31,11 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { @Override public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { + if (list.size() > 0) { + if (!Settings.isEnabled(list.get(0).getProject())) { + return; + } + } for (PsiElement psiElement : list) { WebApiRoutesCollector collector = new WebApiRoutesCollector(); List results = new ArrayList<>(); diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java index 290a201ef..ea597b20f 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java @@ -1,5 +1,6 @@ package com.magento.idea.magento2plugin.php.module; +import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -8,8 +9,10 @@ * Created by dkvashnin on 1/9/16. */ public interface MagentoComponent { - @Nullable + ComposerPackageModel getComposerModel(); + PsiDirectory getDirectory(); + boolean isFileInContext(@NotNull PsiFile psiFile); } diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java index 7f380bc3f..524bfa8ae 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentImp.java @@ -3,7 +3,6 @@ import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Created by dkvashnin on 1/9/16. @@ -12,17 +11,21 @@ public class MagentoComponentImp implements MagentoComponent { protected final ComposerPackageModel composerPackageModel; protected final PsiDirectory directory; - public MagentoComponentImp(ComposerPackageModel composerPackageModel, PsiDirectory directory) { + public MagentoComponentImp(@NotNull ComposerPackageModel composerPackageModel, @NotNull PsiDirectory directory) { this.composerPackageModel = composerPackageModel; this.directory = directory; } - @Nullable @Override public ComposerPackageModel getComposerModel() { return composerPackageModel; } + @Override + public PsiDirectory getDirectory() { + return directory; + } + @Override public boolean isFileInContext(@NotNull PsiFile psiFile) { PsiDirectory containingDirectory = psiFile.getOriginalFile().getContainingDirectory(); diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java index 6df96faad..22643c1c6 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java @@ -39,12 +39,12 @@ public static MagentoComponentManager getInstance(@NotNull Project project) { return magentoComponentManager; } - public Collection getAllModules() { + public Collection getAllComponents() { return getComponents().values(); } @SuppressWarnings("unchecked") - public Collection getAllModulesOfType(@NotNull Class type) { + public Collection getAllComponentsOfType(@NotNull Class type) { Collection result = new ArrayList<>(); Map components = getComponents(); for (String key: components.keySet()) { @@ -68,7 +68,7 @@ synchronized private Map getComponents() { @Nullable public MagentoComponent getComponentForFile(@NotNull PsiFile psiFile) { - for (MagentoComponent magentoComponent: this.getAllModules()) { + for (MagentoComponent magentoComponent: this.getAllComponents()) { if (magentoComponent.isFileInContext(psiFile)) { return magentoComponent; } @@ -80,7 +80,7 @@ public MagentoComponent getComponentForFile(@NotNull PsiFile psiFile) { @Nullable @SuppressWarnings("unchecked") public T getComponentOfTypeForFile(@NotNull PsiFile psiFile, @NotNull Class type) { - for (MagentoComponent magentoComponent: this.getAllModules()) { + for (MagentoComponent magentoComponent: this.getAllComponents()) { if (type.isInstance(magentoComponent) && magentoComponent.isFileInContext(psiFile)) { return (T)magentoComponent; } @@ -89,7 +89,7 @@ public T getComponentOfTypeForFile(@NotNull PsiFile return null; } - public void flushModules() { + synchronized public void flushModules() { components = new HashMap<>(); } @@ -130,8 +130,6 @@ private void loadModules() { } } } - - } /** @@ -141,7 +139,7 @@ class MagentoModuleImpl extends MagentoComponentImp implements MagentoModule { private static final String DEFAULT_MODULE_NAME = "Undefined module"; private static final String CONFIGURATION_PATH = "etc"; - public MagentoModuleImpl(ComposerPackageModel composerPackageModel, PsiDirectory directory) { + public MagentoModuleImpl(@NotNull ComposerPackageModel composerPackageModel, @NotNull PsiDirectory directory) { super(composerPackageModel, directory); } diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java index b40cb8253..d5e5d2041 100644 --- a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java +++ b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java @@ -44,7 +44,7 @@ private void initializeModulesTree(Project project) { modulesTree.setModel(new DefaultTreeModel(rootNode)); - for (MagentoModule magentoModule: magentoComponentManager.getAllModulesOfType(MagentoModule.class)) { + for (MagentoModule magentoModule: magentoComponentManager.getAllComponentsOfType(MagentoModule.class)) { ComposerPackageModel packageModel = magentoModule.getComposerModel(); if (packageModel == null) { continue; From fc9ba499351c3c918658f49741e3d731d1825049 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 10 Jan 2016 02:39:14 +0200 Subject: [PATCH 36/51] Integrated indexes with plugin enabler --- .../magento/idea/magento2plugin/SettingsForm.java | 14 ++------------ .../xml/di/index/PluginToTypeFileBasedIndex.java | 5 +++++ .../di/index/TypeConfigurationFileBasedIndex.java | 8 +++++--- .../di/index/VirtualTypesNamesFileBasedIndex.java | 5 +++++ .../xml/layout/index/LayoutDataIndexer.java | 5 +++++ .../index/EventObserverFileBasedIndex.java | 5 +++++ .../index/EventsDeclarationsFileBasedIndex.java | 5 +++++ .../webapi/index/WebApiTypesFileBasedIndex.java | 5 +++++ 8 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.java b/src/com/magento/idea/magento2plugin/SettingsForm.java index 91d1b9dd7..6aa05c900 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.java +++ b/src/com/magento/idea/magento2plugin/SettingsForm.java @@ -55,7 +55,6 @@ public String getHelpTopic() { @Nullable @Override public JComponent createComponent() { - onOff(); buttonReindex.addMouseListener( new MouseAdapter() { @Override @@ -67,12 +66,8 @@ public void mouseClicked(MouseEvent e) { } ); - pluginEnabled.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - onOff(); - } - }); + buttonReindex.setEnabled(getSettings().pluginEnabled); + regenerateUrnMapButton.setEnabled(getSettings().pluginEnabled); regenerateUrnMapButton.addMouseListener( new RegenerateUrnMapListener(project) @@ -80,11 +75,6 @@ public void itemStateChanged(ItemEvent e) { return (JComponent) panel1; } - private void onOff() { - buttonReindex.setEnabled(pluginEnabled.isSelected()); - regenerateUrnMapButton.setEnabled(pluginEnabled.isSelected()); - } - @Override public boolean isModified() { return !pluginEnabled.isSelected() == getSettings().pluginEnabled; diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java index 9bdb912d7..c0048a4dc 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java @@ -11,6 +11,7 @@ import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; import org.jetbrains.annotations.NotNull; @@ -39,6 +40,10 @@ public Map> map(@NotNull FileContent fileContent) { Map> map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); if(document == null) { return map; diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java index 61261d5f7..a66e7f8ab 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java @@ -15,6 +15,7 @@ import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.di.XmlHelper; import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; @@ -41,9 +42,6 @@ public class TypeConfigurationFileBasedIndex extends ScalarIndexExtension getClassConfigurations(PhpClass phpClass) { String classFqn = phpClass.getPresentableFQN(); - if (classFqn == null) { - return null; - } Collection containingFiles = FileBasedIndex .getInstance() @@ -126,6 +124,10 @@ public Map map(@NotNull FileContent fileContent) { Map map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); if(document == null) { return map; diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java index 68bef93ef..cf493aa3c 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java @@ -20,6 +20,7 @@ import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.Settings; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -170,6 +171,10 @@ public Map map(@NotNull FileContent fileContent) { Map map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); if(document == null) { return map; diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java b/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java index 85cf566df..c7869fc7d 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java @@ -7,6 +7,7 @@ import com.intellij.util.indexing.DataIndexer; import com.intellij.util.indexing.FileContent; import com.jetbrains.php.lang.PhpLangUtil; +import com.magento.idea.magento2plugin.Settings; import org.jetbrains.annotations.NotNull; import java.util.HashMap; @@ -30,6 +31,10 @@ public Map map(@NotNull FileContent fileContent) { Map map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); if(document == null) { return map; diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java index 13122c269..46a4e3ece 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java @@ -11,6 +11,7 @@ import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; import org.jetbrains.annotations.NotNull; @@ -39,6 +40,10 @@ public Map> map(@NotNull FileContent fileContent) { Map> map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); if(document == null) { return map; diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java index 8a1c8ce14..76a81002f 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java @@ -16,6 +16,7 @@ import com.jetbrains.php.lang.psi.PhpFile; import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.ParameterList; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; import org.jetbrains.annotations.NotNull; @@ -47,6 +48,10 @@ public Map map(@NotNull FileContent fileContent) { Map map = new HashMap<>(); PhpFile phpFile = (PhpFile)fileContent.getPsiFile(); + if (!Settings.isEnabled(phpFile.getProject())) { + return map; + } + List results = new ArrayList(); recursiveFill(results, phpFile); for (String result: results) { diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java index 3c994f643..7a99043e4 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java @@ -15,6 +15,7 @@ import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.Settings; import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -47,6 +48,10 @@ public Map map(@NotNull FileContent fileContent) { Map map = new HashMap<>(); PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); if (document == null) { return map; From e7b21a6be4b6c3cdfb4c58120b0e54dea50e14b1 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 10 Jan 2016 02:59:52 +0200 Subject: [PATCH 37/51] Fixed User experience - if you've enabled plugin you smash reindex. --- src/com/magento/idea/magento2plugin/SettingsForm.form | 6 +++--- src/com/magento/idea/magento2plugin/SettingsForm.java | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.form b/src/com/magento/idea/magento2plugin/SettingsForm.form index 65eda471c..efc711f3f 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.form +++ b/src/com/magento/idea/magento2plugin/SettingsForm.form @@ -3,7 +3,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.java b/src/com/magento/idea/magento2plugin/SettingsForm.java index 6aa05c900..3501c8abb 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.java +++ b/src/com/magento/idea/magento2plugin/SettingsForm.java @@ -83,6 +83,8 @@ public boolean isModified() { @Override public void apply() throws ConfigurationException { getSettings().pluginEnabled = pluginEnabled.isSelected(); + buttonReindex.setEnabled(getSettings().pluginEnabled); + regenerateUrnMapButton.setEnabled(getSettings().pluginEnabled); } @Override From 419a45bba7fbb5051c9e5c8f7d8ed3eb62a47dd6 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 10 Jan 2016 11:38:15 +0200 Subject: [PATCH 38/51] Added new version description --- META-INF/plugin.xml | 9 ++++++- .../idea/magento2plugin/SettingsForm.form | 3 ++- .../idea/magento2plugin/SettingsForm.java | 24 ++++++++++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 4abb0d625..1d4b3f733 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,7 +1,7 @@ com.magento.idea.magento2plugin Magento2 - 0.1 + 0.2.0 Dmytro Kvashnin 0.2.0 +
        +
      • WebApi routes
      • +
      • nicer "Goto configuration" labels
      • +
      • plugin settings (manual reindex, URN generation, plugin on/off)
      • +
      +

      0.1

      • Context type completion for:
        diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.form b/src/com/magento/idea/magento2plugin/SettingsForm.form index efc711f3f..3317a0f20 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.form +++ b/src/com/magento/idea/magento2plugin/SettingsForm.form @@ -47,7 +47,8 @@ - + + diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.java b/src/com/magento/idea/magento2plugin/SettingsForm.java index 3501c8abb..d55631887 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.java +++ b/src/com/magento/idea/magento2plugin/SettingsForm.java @@ -1,6 +1,7 @@ package com.magento.idea.magento2plugin; import com.intellij.javaee.ExternalResourceManager; +import com.intellij.javaee.ExternalResourceManagerEx; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; @@ -59,8 +60,7 @@ public JComponent createComponent() { new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - IndexUtil.manualReindex(); - MagentoComponentManager.getInstance(project).flushModules(); + reindex(); super.mouseClicked(e); } } @@ -75,6 +75,11 @@ public void mouseClicked(MouseEvent e) { return (JComponent) panel1; } + private void reindex() { + IndexUtil.manualReindex(); + MagentoComponentManager.getInstance(project).flushModules(); + } + @Override public boolean isModified() { return !pluginEnabled.isSelected() == getSettings().pluginEnabled; @@ -85,6 +90,11 @@ public void apply() throws ConfigurationException { getSettings().pluginEnabled = pluginEnabled.isSelected(); buttonReindex.setEnabled(getSettings().pluginEnabled); regenerateUrnMapButton.setEnabled(getSettings().pluginEnabled); + + if (buttonReindex.isEnabled()) { + reindex(); + } + } @Override @@ -141,7 +151,15 @@ public void run() { continue; } - externalResourceManager.addResource(urnKey, virtualFile.getCanonicalPath()); + // we need to attach resource to a project scope + // but with ExternalResourceManager itself it's not possible unfortunately + if (externalResourceManager instanceof ExternalResourceManagerEx) { + ((ExternalResourceManagerEx)externalResourceManager).addResource( + urnKey, virtualFile.getCanonicalPath(), project + ); + } else { + externalResourceManager.addResource(urnKey, virtualFile.getCanonicalPath()); + } } } } From dc8f63e4fa58b4abe07247eeeb0d88ad96940d02 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Sun, 10 Jan 2016 12:02:55 +0200 Subject: [PATCH 39/51] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f155c7829..cf0f9849b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,10 @@ This is a plugin for Magento 2 development in the PhpStorm IDE. It is available 4. Install the plugin and restart PhpStorm +5. Go to Settings / Preferences / Other Settings / Magento2 plugin in the PhpStorm IDE + +6. Check "Enable" and "OK" button. + ## Works with * PhpStorm >= 8.0.3 * JRE >= 1.7 From af724633eb264a55e8b43acac67fccec7667ea0e Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Mon, 18 Jan 2016 14:30:07 +0200 Subject: [PATCH 40/51] Added information about primary config --- .../xml/index/LineMarkerXmlTagDecorator.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java b/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java index d33b5081d..97e30f1af 100644 --- a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java +++ b/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java @@ -5,6 +5,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.meta.PsiMetaData; import com.intellij.psi.scope.PsiScopeProcessor; @@ -33,14 +34,26 @@ abstract public class LineMarkerXmlTagDecorator implements XmlTag { protected XmlTag xmlTag; + protected Project project; + public LineMarkerXmlTagDecorator(XmlTag xmlTag) { this.xmlTag = xmlTag; + this.project = xmlTag.getProject(); } @NotNull protected String getAreaName() { - String configDirectory = xmlTag.getContainingFile().getVirtualFile().getParent().getName(); - return configDirectory.equals("etc") ? "global" : configDirectory; + VirtualFile containingDirectory = xmlTag.getContainingFile().getVirtualFile().getParent(); + String configDirectory = containingDirectory.getName(); + + if (configDirectory.equals("etc")) { + VirtualFile moduleDirectory = containingDirectory.getParent(); + if (moduleDirectory.getName().equals("app")) { + return "primary"; + } + return "global"; + } + return configDirectory; } /** From a0f7d63a9d27ef5253b27a7bb3104259469d84ec Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Mon, 18 Jan 2016 15:49:00 +0200 Subject: [PATCH 41/51] Added more representative descriptions for "goto configuration" --- META-INF/plugin.xml | 6 +++- .../php/module/MagentoComponentManager.java | 9 ++++-- .../php/module/MagentoModule.java | 1 - .../TypeConfigurationFileBasedIndex.java | 32 ++++++++++++------- .../xml/index/LineMarkerXmlTagDecorator.java | 23 ++++++++++++- .../layout/index/util/LayoutIndexUtility.java | 17 +++++----- .../index/WebApiTypesFileBasedIndex.java | 6 ++++ 7 files changed, 68 insertions(+), 26 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 1d4b3f733..9dd64434c 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,7 +1,7 @@ com.magento.idea.magento2plugin Magento2 - 0.2.0 + 0.2.1 Dmytro Kvashnin 0.2.1 +
          +
        • added module name for "Goto configuration" labels
        • +

        0.2.0

        • WebApi routes
        • diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java index 22643c1c6..b1a83541f 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java @@ -138,14 +138,18 @@ private void loadModules() { class MagentoModuleImpl extends MagentoComponentImp implements MagentoModule { private static final String DEFAULT_MODULE_NAME = "Undefined module"; private static final String CONFIGURATION_PATH = "etc"; + private String moduleName; public MagentoModuleImpl(@NotNull ComposerPackageModel composerPackageModel, @NotNull PsiDirectory directory) { super(composerPackageModel, directory); } - @Nullable @Override public String getMagentoName() { + if (moduleName != null) { + return moduleName; + } + PsiDirectory configurationDir = directory.findSubdirectory(CONFIGURATION_PATH); if (configurationDir != null) { PsiFile configurationFile = configurationDir.findFile("module.xml"); @@ -155,7 +159,8 @@ public String getMagentoName() { if (rootTag != null) { XmlTag module = rootTag.findFirstSubTag("module"); if (module != null && module.getAttributeValue("name") != null) { - return module.getAttributeValue("name"); + moduleName = module.getAttributeValue("name"); + return moduleName; } } } diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java index 210070a67..9dbb79885 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java @@ -6,6 +6,5 @@ * Created by dkvashnin on 12/5/15. */ public interface MagentoModule extends MagentoComponent { - @Nullable String getMagentoName(); } diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java index a66e7f8ab..b4c72bc42 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java @@ -207,6 +207,16 @@ public DiPreferenceLineMarkerXmlTagDecorator(XmlTag xmlTag) { super(xmlTag); } + @NotNull + @Override + public String getDescription() { + String preference = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); + if (preference != null) { + return String.format("preference %s", preference); + } + return xmlTag.getName(); + } + @Override @NotNull @NonNls @@ -228,11 +238,10 @@ public DiTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { super(xmlTag); } - @Override @NotNull - @NonNls - public String getName() { - return String.format("[%s] type declaration", getAreaName()); + @Override + public String getDescription() { + return "type declaration"; } } @@ -245,10 +254,9 @@ public DiPluginLineMarkerXmlTagDecorator(XmlTag xmlTag) { super(xmlTag); } - @Override @NotNull - @NonNls - public String getName() { + @Override + public String getDescription() { XmlTag typeTag = xmlTag.getParentTag(); if (typeTag == null) { return xmlTag.getName(); @@ -257,7 +265,8 @@ public String getName() { if (type == null) { return xmlTag.getName(); } - return String.format("[%s] plugin for %s", getAreaName(), type); + + return String.format("plugin for %s", type); } } @@ -270,13 +279,12 @@ public DiVirtualTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { super(xmlTag); } - @Override @NotNull - @NonNls - public String getName() { + @Override + public String getDescription() { String type = xmlTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); if (type != null) { - return String.format("[%s] virtual type %s", getAreaName(), type); + return String.format("virtual type %s", type); } return xmlTag.getName(); } diff --git a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java b/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java index 97e30f1af..7d6778f07 100644 --- a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java +++ b/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java @@ -2,6 +2,7 @@ import com.intellij.lang.ASTNode; import com.intellij.lang.Language; +import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -19,6 +20,9 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.XmlNSDescriptor; +import com.magento.idea.magento2plugin.php.module.MagentoComponent; +import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; +import com.magento.idea.magento2plugin.php.module.MagentoModule; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -56,13 +60,30 @@ protected String getAreaName() { return configDirectory; } + @NotNull + protected String getComponentName() { + MagentoComponentManager moduleManager = MagentoComponentManager.getInstance(project); + MagentoModule module = moduleManager.getComponentOfTypeForFile(xmlTag.getContainingFile(), MagentoModule.class); + + if (module == null) { + return ""; + } + + return module.getMagentoName(); + } + + @NotNull + abstract public String getDescription(); + /** * Get line marker text. This method should be overridden to generate user-friendly XmlTag presentation. */ @Override @NotNull @NonNls - abstract public String getName(); + public String getName() { + return String.format("%s [%s] - %s", getComponentName(), getAreaName(), getDescription()); + } @Override @NotNull diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java index e286e972e..a8f9798bb 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java +++ b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java @@ -111,20 +111,19 @@ public LayoutBlockLineMarkerXmlTagDecorator(XmlTag xmlTag) { super(xmlTag); } + @NotNull @Override + protected String getAreaName() { + return xmlTag.getContainingFile().getVirtualFile().getParent().getParent().getName(); + } + @NotNull - @NonNls - public String getName() { + @Override + public String getDescription() { String name = xmlTag.getAttributeValue("name"); if (name != null) { - return String.format("[%s] block %s", getAreaName(), name); + return String.format("block %s", name); } return xmlTag.getName(); } - - @NotNull - @Override - protected String getAreaName() { - return xmlTag.getContainingFile().getVirtualFile().getParent().getParent().getName(); - } } \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java index 7a99043e4..b4809ad30 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java @@ -173,6 +173,12 @@ public WebApiLineMarkerXmlTagDecorator(XmlTag xmlTag) { super(xmlTag); } + @NotNull + @Override + public String getDescription() { + return ""; + } + @Override @NotNull @NonNls From 853d2170d2c89601534266b05e2ea9fd7518157f Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Mon, 18 Jan 2016 16:03:51 +0200 Subject: [PATCH 42/51] Fixed IndexNotReadyException --- .../magento2plugin/php/inspections/MagentoApiInspection.java | 2 ++ .../magento2plugin/php/module/MagentoComponentManager.java | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index 0f8492100..216f09672 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -2,6 +2,7 @@ import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.project.DumbService; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment; @@ -42,6 +43,7 @@ public void visitPhpMethodReference(MethodReference reference) { if (!Settings.isEnabled(reference.getProject())) { return; } + PsiElement referencedElement = reference.resolve(); if(referencedElement instanceof Method) { diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java index b1a83541f..b0f1b5027 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java @@ -2,6 +2,7 @@ import com.intellij.json.psi.JsonFile; import com.intellij.json.psi.JsonObject; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; @@ -57,6 +58,10 @@ public Collection getAllComponentsOfType(@NotNul } synchronized private Map getComponents() { + if (DumbService.getInstance(project).isDumb()) { + return new HashMap<>(); + } + if (cacheStartTime + CACHE_LIFE_TIME < System.currentTimeMillis()) { flushModules(); loadModules(); From 8858bab5bee4efd3690c06cd50435b11292b4bb4 Mon Sep 17 00:00:00 2001 From: Dmytro Kvashnin Date: Thu, 18 Feb 2016 12:42:10 +0200 Subject: [PATCH 43/51] Improved argument name completion in di configuration Added reference/completion supprot for arguments with string type as a possible object type Fixed Already disposed issue with dumb project --- META-INF/plugin.xml | 2 +- magento2plugin.iml | 1 + .../php/module/MagentoComponentManager.java | 2 +- .../idea/magento2plugin/xml/di/XmlHelper.java | 2 ++ .../completion/DiCompletionContributor.java | 1 + .../di/reference/ArgumentNameReference.java | 33 +++++++++++++++++-- .../di/reference/DiReferenceContributor.java | 4 ++- .../ArgumentNameReferenceProvider.java | 2 +- 8 files changed, 41 insertions(+), 6 deletions(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 9dd64434c..e7eb7dfbe 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,7 +1,7 @@ com.magento.idea.magento2plugin Magento2 - 0.2.1 + 0.2.2 Dmytro Kvashnin + diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java index b0f1b5027..b8e0f0bb3 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java @@ -58,7 +58,7 @@ public Collection getAllComponentsOfType(@NotNul } synchronized private Map getComponents() { - if (DumbService.getInstance(project).isDumb()) { + if (DumbService.getInstance(project).isDumb() || project.isDisposed()) { return new HashMap<>(); } diff --git a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java index 948ee4380..8149c0c29 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java +++ b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java @@ -16,12 +16,14 @@ public class XmlHelper extends XmlHelperUtility { public static final String VIRTUAL_TYPE_TAG = "virtualType"; public static final String PREFERENCE_TAG = "preference"; public static final String ARGUMENT_TAG = "argument"; + public static final String ARGUMENTS_TAG = "arguments"; public static final String NAME_ATTRIBUTE = "name"; public static final String TYPE_ATTRIBUTE = "type"; public static final String FOR_ATTRIBUTE = "for"; public static final String OBJECT_TYPE = "object"; + public static final String STRING_TYPE = "string"; public static final String CONST_TYPE = "const"; public static final String INIT_TYPE = "init_parameter"; diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java index c0db61d02..0d8357437 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java @@ -37,6 +37,7 @@ public DiCompletionContributor() { extend(CompletionType.BASIC, XmlPatterns.or( XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE), + XmlHelper.getItemValuePatternForType(XmlHelper.STRING_TYPE), XmlHelper.getTagAttributePattern(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE), XmlHelper.getTagAttributePattern(XmlHelper.VIRTUAL_TYPE_TAG, XmlHelper.TYPE_ATTRIBUTE), XmlHelper.getTagAttributePattern(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE) diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java b/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java index 11149e5da..ab8bb4715 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java @@ -7,11 +7,13 @@ import com.intellij.psi.PsiElementResolveResult; import com.intellij.psi.PsiPolyVariantReferenceBase; import com.intellij.psi.ResolveResult; +import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.PhpIcons; import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.Parameter; import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.xml.di.XmlHelper; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -23,11 +25,13 @@ * Created by dkvashnin on 10/18/15. */ public class ArgumentNameReference extends PsiPolyVariantReferenceBase { + private XmlTag typeTag; private String typeName; - public ArgumentNameReference(@NotNull PsiElement psiElement, @NotNull String typeName) { + public ArgumentNameReference(@NotNull PsiElement psiElement, @NotNull XmlTag typeTag, @NotNull String typeName) { super(psiElement); + this.typeTag = typeTag; this.typeName = typeName; } @@ -50,10 +54,17 @@ public ResolveResult[] multiResolve(boolean b) { @Override public Object[] getVariants() { List variants = new ArrayList(); + List definedArguments = getAlreadyConfiguredArguments(); + for (Parameter parameter: getParameters()) { + String argumentName = parameter.getName(); + if (definedArguments.contains(argumentName)) { + continue; + } + variants.add( LookupElementBuilder - .create(parameter.getName()) + .create(argumentName) .withIcon(PhpIcons.PARAMETER) .withTypeText(parameter.getDeclaredType().toStringResolved()) ); @@ -80,4 +91,22 @@ private List getParameters() { return parameterList; } + + private List getAlreadyConfiguredArguments() + { + List result = new ArrayList<>(); + + XmlTag argumentsTag = typeTag.findFirstSubTag(XmlHelper.ARGUMENTS_TAG); + if (argumentsTag == null) { + return result; + } + + for (XmlTag argumentTag: argumentsTag.findSubTags(XmlHelper.ARGUMENT_TAG)) { + result.add( + argumentTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE) + ); + } + + return result; + } } diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java index 9599ad1ef..08a30b50b 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java @@ -64,10 +64,12 @@ public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferen ); // SomeClassOrVirtualType + // SomeClassOrVirtualType - lazy initialization psiReferenceRegistrar.registerReferenceProvider( XmlPatterns.or( XmlHelper.getArgumentValuePatternForType(XmlHelper.OBJECT_TYPE), - XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE) + XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE), + XmlHelper.getItemValuePatternForType(XmlHelper.STRING_TYPE) ), new XmlReferenceProvider( new ReferenceResultsFiller[]{ diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java index 0a13cd24b..8c6b52884 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java @@ -40,7 +40,7 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @No continue; } - return new PsiReference[]{new ArgumentNameReference(psiElement, typeName)}; + return new PsiReference[]{new ArgumentNameReference(psiElement, typeTag, typeName)}; } return new PsiReference[0]; From 1dac5e0f6a55a6a86c22cd024e2d865110893adf Mon Sep 17 00:00:00 2001 From: Daniel Espendiller Date: Wed, 2 Mar 2016 20:06:34 +0100 Subject: [PATCH 44/51] Add plugin repository badges --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index cf0f9849b..2809cfa26 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # PhpStorm Magento 2 Plugin +[![Version](http://phpstorm.espend.de/badge/8024/version)](https://plugins.jetbrains.com/plugin/8024) +[![Downloads](http://phpstorm.espend.de/badge/8024/downloads)](https://plugins.jetbrains.com/plugin/8024) +[![Downloads last month](http://phpstorm.espend.de/badge/8024/last-month)](https://plugins.jetbrains.com/plugin/8024) + This is a plugin for Magento 2 development in the PhpStorm IDE. It is available via the [JetBrains Plugin Repository](https://plugins.jetbrains.com/plugin/8024) ## Installation From 3849bbfa830beadfabdb6e97200ec75e5982496e Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Tue, 5 Dec 2017 17:28:17 +0200 Subject: [PATCH 45/51] Plugin Improvements - Added JavaScript reference contributor - General reference/completion improvements - Support all XML files (*.xml) - Added project detector - Move configuration seption to "Languages & Frameworks > Php > Magento" - Remove deprecated elements --- META-INF/plugin.xml | 81 ++--- magento2plugin.iml | 2 +- .../idea/magento2plugin/Magento2Icons.java | 15 - .../idea/magento2plugin/MagentoIcons.java | 12 + .../xml/XmlCompletionContributor.java | 104 ++++++ .../provider/CompositeCompletionProvider.java | 26 ++ .../EventNameCompletionContributor.java | 30 ++ .../LayoutBlockCompletionContributor.java | 34 ++ .../LayoutContainerCompletionContributor.java | 34 ++ .../LayoutUpdateCompletionContributor.java | 38 +++ .../provider/PhpClassCompletionProvider.java | 73 +++++ .../PhpClassMemberCompletionProvider.java | 61 ++++ ...ConstructorArgumentCompletionProvider.java | 43 +++ ...PhpServiceMethodCompletionContributor.java | 37 +++ .../VirtualTypeCompletionProvider.java | 40 +++ .../idea/magento2plugin/icons/webapi.png | Bin 0 -> 404 bytes .../idea/magento2plugin/indexes/DiIndex.java | 136 ++++++++ .../magento2plugin/indexes/EventIndex.java | 49 +++ .../magento2plugin/indexes/IndexManager.java | 36 +++ .../magento2plugin/indexes/LayoutIndex.java | 168 ++++++++++ .../index/ModulePackageFileBasedIndex.java | 96 ------ .../php/inspections/MagentoApiInspection.java | 5 +- .../inspections/ObjectManagerInspection.java | 2 +- .../ClassConfigurationLineMarkerProvider.java | 63 ++-- .../php/linemarker/Collector.java | 13 - .../linemarker/PluginLineMarkerProvider.java | 111 ++++--- .../linemarker/WebApiLineMarkerProvider.java | 157 +++++---- .../php/module/MagentoComponent.java | 1 - .../php/module/MagentoComponentManager.java | 11 +- .../php/module/MagentoModule.java | 2 - .../magento2plugin/php/module/ModuleUtil.java | 8 - .../php/tool/ModuleToolWindowFactory.java | 2 +- .../php/util/ImplementationMatcher.java | 33 -- .../util}/PhpPatternsHelper.java | 2 +- .../magento2plugin/php/util/PhpRegex.java | 12 + .../project/ProjectDetector.java | 50 +++ .../{ => project}/Settings.java | 10 +- .../{ => project}/SettingsForm.form | 2 +- .../{ => project}/SettingsForm.java | 18 +- .../reference/js/JsReferenceContributor.java | 24 ++ .../php/PhpReferenceContributor.java | 18 ++ .../provider/CompositeReferenceProvider.java | 31 ++ .../EventDispatchReferenceProvider.java | 36 +++ .../provider/EventNameReferenceProvider.java | 63 ++++ .../provider/FilePathReferenceProvider.java | 241 ++++++++++++++ .../LayoutBlockReferenceProvider.java | 27 ++ .../LayoutContainerReferenceProvider.java | 30 ++ .../LayoutUpdateReferenceProvider.java | 27 ++ .../provider/ModuleNameReferenceProvider.java | 74 +++++ .../PhpClassMemberReferenceProvider.java | 58 ++++ .../provider/PhpClassReferenceProvider.java | 70 ++++ ...pConstructorArgumentReferenceProvider.java | 47 +++ .../PhpServiceMethodReferenceProvider.java | 41 +++ .../VirtualTypeReferenceProvider.java | 33 ++ .../xml/PolyVariantReferenceBase.java | 46 +++ .../xml/XmlReferenceContributor.java | 156 +++++++++ .../stubs/indexes/BlockClassNameIndex.java | 27 ++ .../stubs/indexes/BlockNameIndex.java | 25 ++ .../stubs/indexes/ContainerNameIndex.java | 31 ++ .../stubs/indexes/EventNameIndex.java | 133 ++++++++ .../indexes/EventObserverIndex.java} | 50 +-- .../indexes}/LayoutDataIndexer.java | 36 ++- .../stubs/indexes/ModuleNameIndex.java | 88 +++++ .../stubs/indexes/ModulePackageIndex.java | 89 ++++++ .../stubs/indexes/NamedComponentIndex.java | 37 +++ .../indexes/PluginIndex.java} | 50 +-- .../stubs/indexes/TypeConfigurationIndex.java | 300 ++++++++++++++++++ .../stubs/indexes/VirtualTypeIndex.java | 87 +++++ .../indexes/WebApiTypeIndex.java} | 130 ++++---- .../idea/magento2plugin/util/IndexUtil.java | 46 --- .../util/PsiContextMatcherI.java | 8 - .../LineMarkerXmlTagDecorator.java | 6 +- .../magento2plugin/xml/XmlHelperUtility.java | 106 ------- .../magento2plugin/xml/XmlPsiTreeUtil.java | 51 +++ .../completion/ClassCompletionProvider.java | 56 ---- .../xml/completion/CompletionProviderI.java | 17 - .../InterfaceCompletionProvider.java | 59 ---- .../VirtualTypeCompletionProvider.java | 45 --- .../idea/magento2plugin/xml/di/XmlHelper.java | 116 ------- .../completion/DiCompletionContributor.java | 192 ----------- .../TypeConfigurationFileBasedIndex.java | 291 ----------------- .../VirtualTypesNamesFileBasedIndex.java | 204 ------------ .../di/reference/ArgumentNameReference.java | 112 ------- .../xml/di/reference/ConstantReference.java | 65 ---- .../di/reference/DiReferenceContributor.java | 116 ------- .../ArgumentNameReferenceProvider.java | 48 --- .../provider/XmlReferenceProvider.java | 27 -- .../provider/resolver/ClassNameResolver.java | 29 -- .../provider/resolver/TypeTagResolver.java | 25 -- .../resolver/VirtualTypeTagResolver.java | 36 --- .../xml/index/StringSetDataExternalizer.java | 40 --- .../xml/layout/LayoutUtility.java | 54 ---- .../LayoutCompletionContributor.java | 99 ------ .../ReferenceComponentCompletionProvider.java | 45 --- .../AbstractComponentNameFileBasedIndex.java | 52 --- .../index/BlockClassFileBasedIndex.java | 25 -- .../xml/layout/index/BlockFileBasedIndex.java | 23 -- .../layout/index/ContainerFileBasedIndex.java | 28 -- .../layout/index/util/LayoutIndexUtility.java | 129 -------- .../reference/LayoutReferenceContributor.java | 105 ------ .../reference/fill/BlockResultsFiller.java | 28 -- .../fill/ContainerResultsFiller.java | 28 -- .../xml/observer/XmlHelper.java | 24 -- .../EventCompletionContributor.java | 59 ---- .../EventsDeclarationsFileBasedIndex.java | 126 -------- .../reference/EventReferenceContributor.java | 27 -- .../reference/EventReferenceProvider.java | 59 ---- .../ObserverReferenceContributor.java | 39 --- .../util/ClassResultsFillerWrapper.java | 36 --- ...EventsConfigurationFilesResultsFiller.java | 41 --- .../EventsDeclarationsFilesResultsFiller.java | 56 ---- .../xml/reference/TypeReference.java | 54 ---- .../reference/util/ClassesResultsFiller.java | 32 -- .../util/ImplementationContextDecorator.java | 35 -- .../util/InterfacesResultsFiller.java | 28 -- .../util/ReferenceResultsFiller.java | 13 - .../util/VirtualTypesResultsFiller.java | 31 -- .../xml/util/ParentTypeMatcher.java | 42 --- .../xml/util/VirtualTypeParentMatcher.java | 31 -- .../magento2plugin/xml/webapi/XmlHelper.java | 55 ---- .../WebApiCompletionContributor.java | 91 ------ .../ServiceReferenceContributor.java | 39 --- .../fill/ServiceMethodResultsFiller.java | 67 ---- 123 files changed, 3229 insertions(+), 3789 deletions(-) delete mode 100644 src/com/magento/idea/magento2plugin/Magento2Icons.java create mode 100644 src/com/magento/idea/magento2plugin/MagentoIcons.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java create mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/icons/webapi.png create mode 100644 src/com/magento/idea/magento2plugin/indexes/DiIndex.java create mode 100644 src/com/magento/idea/magento2plugin/indexes/EventIndex.java create mode 100644 src/com/magento/idea/magento2plugin/indexes/IndexManager.java create mode 100644 src/com/magento/idea/magento2plugin/indexes/LayoutIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/php/linemarker/Collector.java delete mode 100644 src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java delete mode 100644 src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java rename src/com/magento/idea/magento2plugin/{xml/observer => php/util}/PhpPatternsHelper.java (93%) create mode 100644 src/com/magento/idea/magento2plugin/php/util/PhpRegex.java create mode 100644 src/com/magento/idea/magento2plugin/project/ProjectDetector.java rename src/com/magento/idea/magento2plugin/{ => project}/Settings.java (82%) rename src/com/magento/idea/magento2plugin/{ => project}/SettingsForm.form (97%) rename src/com/magento/idea/magento2plugin/{ => project}/SettingsForm.java (95%) create mode 100644 src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java create mode 100644 src/com/magento/idea/magento2plugin/reference/php/PhpReferenceContributor.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/CompositeReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/EventDispatchReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/EventNameReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/LayoutBlockReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/LayoutContainerReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/LayoutUpdateReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/ModuleNameReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/PhpClassMemberReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/PhpConstructorArgumentReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/PhpServiceMethodReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/provider/VirtualTypeReferenceProvider.java create mode 100644 src/com/magento/idea/magento2plugin/reference/xml/PolyVariantReferenceBase.java create mode 100644 src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/BlockClassNameIndex.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/BlockNameIndex.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/ContainerNameIndex.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/EventNameIndex.java rename src/com/magento/idea/magento2plugin/{xml/observer/index/EventObserverFileBasedIndex.java => stubs/indexes/EventObserverIndex.java} (65%) rename src/com/magento/idea/magento2plugin/{xml/layout/index => stubs/indexes}/LayoutDataIndexer.java (59%) create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/ModulePackageIndex.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/NamedComponentIndex.java rename src/com/magento/idea/magento2plugin/{xml/di/index/PluginToTypeFileBasedIndex.java => stubs/indexes/PluginIndex.java} (66%) create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/TypeConfigurationIndex.java create mode 100644 src/com/magento/idea/magento2plugin/stubs/indexes/VirtualTypeIndex.java rename src/com/magento/idea/magento2plugin/{xml/webapi/index/WebApiTypesFileBasedIndex.java => stubs/indexes/WebApiTypeIndex.java} (52%) delete mode 100644 src/com/magento/idea/magento2plugin/util/IndexUtil.java delete mode 100644 src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java rename src/com/magento/idea/magento2plugin/xml/{index => }/LineMarkerXmlTagDecorator.java (98%) delete mode 100644 src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java create mode 100644 src/com/magento/idea/magento2plugin/xml/XmlPsiTreeUtil.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/ClassNameResolver.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java delete mode 100644 src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index e7eb7dfbe..2dc7afcfd 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,6 +1,6 @@ - + com.magento.idea.magento2plugin - Magento2 + Magento PhpStorm 0.2.2 Dmytro Kvashnin @@ -96,7 +96,7 @@ - + @@ -104,6 +104,7 @@ com.intellij.modules.lang --> com.jetbrains.php + JavaScript com.intellij.modules.platform @@ -114,46 +115,50 @@ secondary="false" factoryClass="com.magento.idea.magento2plugin.php.tool.ModuleToolWindowFactory" /> --> - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + @@ -168,4 +173,4 @@ - \ No newline at end of file + diff --git a/magento2plugin.iml b/magento2plugin.iml index 0f0805366..8ae22fb2d 100644 --- a/magento2plugin.iml +++ b/magento2plugin.iml @@ -9,7 +9,7 @@ - + \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/Magento2Icons.java b/src/com/magento/idea/magento2plugin/Magento2Icons.java deleted file mode 100644 index 39d1d5f2f..000000000 --- a/src/com/magento/idea/magento2plugin/Magento2Icons.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.magento.idea.magento2plugin; - -import com.intellij.openapi.util.IconLoader; - -import javax.swing.*; - -/** - * Created by dkvashnin on 11/14/15. - */ -public class Magento2Icons { - public static final Icon PLUGIN = IconLoader.getIcon("icons/interception_reference.png"); - public static final Icon CONFIGURATION = IconLoader.getIcon("icons/xml_reference.png"); - public static final Icon WEB_API = IconLoader.getIcon("icons/webapi_reference.png"); - -} diff --git a/src/com/magento/idea/magento2plugin/MagentoIcons.java b/src/com/magento/idea/magento2plugin/MagentoIcons.java new file mode 100644 index 000000000..25f73aba4 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/MagentoIcons.java @@ -0,0 +1,12 @@ +package com.magento.idea.magento2plugin; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * Created by dkvashnin on 11/14/15. + */ +public class MagentoIcons { + public static final Icon WEB_API = IconLoader.getIcon("icons/webapi.png"); +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java new file mode 100644 index 000000000..a561da568 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java @@ -0,0 +1,104 @@ +package com.magento.idea.magento2plugin.completion.xml; + +import com.intellij.codeInsight.completion.CompletionContributor; +import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.patterns.XmlPatterns; +import com.intellij.psi.xml.XmlTokenType; +import com.magento.idea.magento2plugin.completion.xml.provider.*; +import com.magento.idea.magento2plugin.php.util.PhpRegex; + +import static com.intellij.patterns.PlatformPatterns.psiElement; +import static com.intellij.patterns.StandardPatterns.string; +import static com.intellij.patterns.XmlPatterns.xmlFile; + +public class XmlCompletionContributor extends CompletionContributor { + + public XmlCompletionContributor() { + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .withText(string().matches(PhpRegex.Xml.CLASS_ELEMENT)), + new CompositeCompletionProvider( + new PhpClassCompletionProvider(), + new PhpClassMemberCompletionProvider() + ) + ); + + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withText(string().matches(PhpRegex.Xml.CLASS_ELEMENT)), + new CompositeCompletionProvider( + new PhpClassCompletionProvider(), + new PhpClassMemberCompletionProvider() + ) + ); + + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("type")), + new VirtualTypeCompletionProvider() + ); + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("virtualType"))), + new VirtualTypeCompletionProvider() + ); + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withParent(XmlPatterns.xmlText().withParent(XmlPatterns.xmlTag().withChild( + XmlPatterns.xmlAttribute().withName("xsi:type").withValue(string().oneOf("object")))) + ), + new VirtualTypeCompletionProvider() + ); + + // + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("argument") + .withParent(XmlPatterns.xmlTag().withName("arguments")) + ) + ).inFile(xmlFile().withName(string().endsWith("di.xml"))), + new PhpConstructorArgumentCompletionProvider() + ); + + // + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("method") + .withParent(XmlPatterns.xmlTag().withName("service")) + ).inFile(xmlFile().withName(string().endsWith("webapi.xml"))), + new PhpServiceMethodCompletionContributor() + ); + + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("referenceContainer")) + ), + new LayoutContainerCompletionContributor() + ); + + extend(CompletionType.BASIC, XmlPatterns.or( + psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN).inside(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("referenceBlock"))), + psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN).inside(XmlPatterns.xmlAttribute() + .withName(string().oneOf("before", "after")) + .withParent(XmlPatterns.xmlTag().withName("block"))), + psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN).inside(XmlPatterns.xmlAttribute() + .withName(string().oneOf("before", "after", "destination", "element")) + .withParent(XmlPatterns.xmlTag().withName("move"))), + psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN).inside(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("remove"))) + ), + new LayoutBlockCompletionContributor() + ); + + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("handle") + .withParent(XmlPatterns.xmlTag().withName("update")) + ), + new LayoutUpdateCompletionContributor() + ); + + // event name completion contributor + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) + .inside(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("event")) + ).inFile(xmlFile().withName(string().endsWith("events.xml"))), + new EventNameCompletionContributor() + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java new file mode 100644 index 000000000..cd05299c8 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java @@ -0,0 +1,26 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +public class CompositeCompletionProvider extends CompletionProvider { + + private CompletionProvider[] providers = null; + + @SafeVarargs + public CompositeCompletionProvider(CompletionProvider ...providers) { + this.providers = providers; + } + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + for (CompletionProvider provider : providers) { + provider.addCompletionVariants(parameters, context, result); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java new file mode 100644 index 000000000..fa5e1f2e5 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java @@ -0,0 +1,30 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.EventNameIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class EventNameCompletionContributor extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + + Collection eventNames = FileBasedIndex.getInstance() + .getAllKeys(EventNameIndex.KEY, position.getProject()); + + for (String eventName: eventNames) { + result.addElement(LookupElementBuilder.create(eventName)); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java new file mode 100644 index 000000000..f852e471e --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java @@ -0,0 +1,34 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import com.magento.idea.magento2plugin.stubs.indexes.BlockNameIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class LayoutBlockCompletionContributor extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + Collection keys = LayoutIndex.getAllKeys(BlockNameIndex.KEY, position.getProject()); + for (String key: keys) { + result.addElement( + LookupElementBuilder.create(key).withIcon(PhpIcons.XML_TAG_ICON) + ); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java new file mode 100644 index 000000000..38845a2f1 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java @@ -0,0 +1,34 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ContainerNameIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class LayoutContainerCompletionContributor extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + Collection keys = LayoutIndex.getAllKeys(ContainerNameIndex.KEY, position.getProject()); + for (String key: keys) { + result.addElement( + LookupElementBuilder.create(key).withIcon(PhpIcons.XML_TAG_ICON) + ); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java new file mode 100644 index 000000000..ae5d7d8f9 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java @@ -0,0 +1,38 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class LayoutUpdateCompletionContributor extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + List targets = LayoutIndex.getLayoutFiles(position.getProject()); + if (targets.size() > 0) { + for (XmlFile file : targets) { + result.addElement( + LookupElementBuilder + .create(file.getVirtualFile().getNameWithoutExtension()) + .withIcon(PhpIcons.XML_TAG_ICON) + ); + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java new file mode 100644 index 000000000..9a9885eb7 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java @@ -0,0 +1,73 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.elements.PhpNamespace; +import com.magento.idea.magento2plugin.php.util.PhpRegex; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PhpClassCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + String prefix = result.getPrefixMatcher().getPrefix(); + prefix = prefix.startsWith("\\") ? prefix : "\\" + prefix; + + Matcher matcher = Pattern.compile(PhpRegex.Xml.CLASS_NAME).matcher(prefix); + + if (!matcher.matches()) { + return; + } + + String prefixShortName = prefix.substring(prefix.lastIndexOf(92) + 1); + String namespace = prefix.substring(0, prefix.lastIndexOf(92)); + namespace = namespace.startsWith("\\") ? namespace : "\\" + namespace; + + PhpIndex phpIndex = PhpIndex.getInstance(parameters.getPosition().getProject()); + + final Collection phpClasses = new THashSet<>(); + for (PhpNamespace phpNamespace : phpIndex.getNamespacesByName(namespace.toLowerCase())) { + phpClasses.addAll(PsiTreeUtil.getChildrenOfTypeAsList(phpNamespace.getStatements(), PhpClass.class)); + } + phpClasses.removeIf(c -> !c.getName().contains(prefixShortName)); + + for (PhpClass phpClass : phpClasses) { + result.addElement( + LookupElementBuilder + .create(phpClass.getPresentableFQN()) + .withIcon(phpClass.getIcon()) + ); + } + + final Collection namespaces = phpIndex.getChildNamespacesByParentName(namespace + "\\"); + for (String namespaceName : namespaces) { + if (namespaceName.contains(prefixShortName)) { + result.addElement( + LookupElementBuilder + .create(namespace.substring(1) + "\\" + namespaceName) + .withIcon(PhpIcons.NAMESPACE) + ); + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java new file mode 100644 index 000000000..44fed2b4e --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java @@ -0,0 +1,61 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.Field; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.elements.PhpClassMember; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class PhpClassMemberCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + final Collection members = new THashSet<>(); + String prefix = result.getPrefixMatcher().getPrefix(); + + if (!(prefix.lastIndexOf("::") > 0 && prefix.lastIndexOf("\\") > 0 + && prefix.lastIndexOf("::") > prefix.lastIndexOf("\\"))) { + return; + } + + String className = prefix.substring(0, prefix.lastIndexOf("::")); + + PhpIndex phpIndex = PhpIndex.getInstance(parameters.getPosition().getProject()); + for (PhpClass phpClass : phpIndex.getAnyByFQN(className)) { + members.addAll(phpClass.getFields()); + members.addAll(phpClass.getMethods()); + } + + for (PhpClassMember member : members) { + if (Field.class.isInstance(member)) { + result.addElement( + LookupElementBuilder + .create(className + (((Field) member).isConstant() ? "::" : "::$") + member.getName()) + .withIcon(member.getIcon()) + ); + } else { + result.addElement( + LookupElementBuilder + .create(className + "::" + member.getName() + "()") + .withIcon(member.getIcon()) + ); + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java new file mode 100644 index 000000000..29a8cdaed --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java @@ -0,0 +1,43 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.Parameter; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.indexes.DiIndex; +import org.jetbrains.annotations.NotNull; + +public class PhpConstructorArgumentCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null || !(position instanceof XmlElement)) { + return; + } + + + DiIndex diIndex = DiIndex.getInstance(position.getProject()); + PhpClass phpClass = diIndex.getPhpClassOfArgument((XmlElement) position); + if (phpClass != null) { + Method constructor = phpClass.getConstructor(); + if (constructor != null) { + for (Parameter parameter : constructor.getParameters()) { + result.addElement( + LookupElementBuilder + .create(parameter.getName()) + .withIcon(parameter.getIcon()) + ); + } + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java new file mode 100644 index 000000000..45f6c62f0 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java @@ -0,0 +1,37 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.indexes.DiIndex; +import org.jetbrains.annotations.NotNull; + +public class PhpServiceMethodCompletionContributor extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + PhpClass phpClass = DiIndex.getPhpClassOfServiceMethod((XmlElement) position); + if (phpClass != null) { + for (Method method : phpClass.getMethods()) { + result.addElement( + LookupElementBuilder + .create(method.getName()) + .withIcon(method.getIcon()) + ); + } + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java new file mode 100644 index 000000000..40919919e --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java @@ -0,0 +1,40 @@ +package com.magento.idea.magento2plugin.completion.xml.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.completion.PlainPrefixMatcher; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.magento.idea.magento2plugin.indexes.DiIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class VirtualTypeCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + String prefix = result.getPrefixMatcher().getPrefix(); + + DiIndex index = DiIndex.getInstance(position.getProject()); + Collection elements = index.getAllVirtualTypeElementNames(new PlainPrefixMatcher(prefix), position.getResolveScope()); + + for (String elementName:elements) { + result.addElement( + LookupElementBuilder + .create(elementName) + .withIcon(PhpIcons.CLASS_ICON) + ); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/icons/webapi.png b/src/com/magento/idea/magento2plugin/icons/webapi.png new file mode 100644 index 0000000000000000000000000000000000000000..b473fb8b47ecab18097a53721aa062d77e51065b GIT binary patch literal 404 zcmV;F0c-w=P)4q2@`ez@e5q?43j2Jasw)8MAEPtB!*_d4txeE0~O3gV!wd72%V1= z^!4=#0Ts*x(LfC@AlCr#1*mum5dR0!4EO-Z1t8l%3Ze8JkT*a!1Hl($FX1wv7^E3U zhk|Sdxd4h^z+6L&0rOxAk(~Y?um91aG6hTY5w@Ky@Zmu5e`4|ao)8Q%6a$`Y&;9>k zbN2r?dkg=++gJ4e>Gr(;54Yri#X<5fcID$XV9SKC|DAbG|ChG-|8L2(|9^8`#{Won zt^W%eeEv72+5X=@Ga4+1(}0&i(+|vy0c$9ZG5>#Ub=v>FBA5T~_ZR&?y(sbjq*6Eh z2287P|G#5$#Q(b+v%nfb27p}j7U-Q*Km%r0d*U}>QKRqwexSyl0_XpkAx8f%tw{MF y<)Qt*J;wp;q6^EC@f(1S?*UyhvBZ^N%m4tJox%(Y>=8=<0000 phpClasses = phpIndex.getAnyByFQN(className); + + if (phpClasses.size() > 0) { + return phpClasses.iterator().next(); + } + + return null; + } + + @Nullable + public static PhpClass getPhpClassOfServiceMethod(XmlElement psiMethodValueElement) { + XmlTag serviceTag = PsiTreeUtil.getParentOfType(psiMethodValueElement, XmlTag.class); + if (serviceTag == null) { + return null; + } + + XmlAttribute attribute = serviceTag.getAttribute("class"); + if (attribute == null) { + return null; + } + + XmlAttributeValue valueElement = attribute.getValueElement(); + if (valueElement == null) { + return null; + } + + for (PsiReference reference : valueElement.getReferences()) { + if (reference != null) { + PsiElement element = reference.resolve(); + if (element instanceof PhpClass) { + return (PhpClass) element; + } + } + } + + return null; + } + + public Collection getVirtualTypeElements(final String name, final GlobalSearchScope scope) { + Collection result = new ArrayList<>(); + + Collection virtualFiles = + FileBasedIndex.getInstance().getContainingFiles(VirtualTypeIndex.KEY, name, scope); + + for (VirtualFile virtualFile : virtualFiles) { + XmlFile xmlFile = (XmlFile) PsiManager.getInstance(project).findFile(virtualFile); + if (xmlFile != null) { + Collection valueElements = XmlPsiTreeUtil + .findAttributeValueElements(xmlFile, "virtualType", "name", name); + result.addAll(valueElements); + } + } + return result; + } + + public Collection getAllVirtualTypeElementNames(PrefixMatcher prefixMatcher, final GlobalSearchScope scope) { + Collection keys = + FileBasedIndex.getInstance().getAllKeys(VirtualTypeIndex.KEY, project); + + keys.removeIf(k -> !prefixMatcher.prefixMatches(k)); + return keys; + } + + @NotNull + private String getTopTypeOfVirtualType(@NonNull String name) { + List values; + int parentNestingLevel = 0; + int maxNestingLevel = 5; + + do { + values = FileBasedIndex.getInstance() + .getValues(VirtualTypeIndex.KEY, name, GlobalSearchScope.allScope(project)); + if (values.size() > 0 && values.get(0) != null) { + name = values.get(0); + } + } while (values.size() > 0 || maxNestingLevel > parentNestingLevel++); + + return name; + } +} diff --git a/src/com/magento/idea/magento2plugin/indexes/EventIndex.java b/src/com/magento/idea/magento2plugin/indexes/EventIndex.java new file mode 100644 index 000000000..578b0f808 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/indexes/EventIndex.java @@ -0,0 +1,49 @@ +package com.magento.idea.magento2plugin.indexes; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.EventNameIndex; +import com.magento.idea.magento2plugin.xml.XmlPsiTreeUtil; + +import java.util.ArrayList; +import java.util.Collection; + +public class EventIndex { + + private static EventIndex INSTANCE; + + private Project project; + + private EventIndex() { + } + + public static EventIndex getInstance(final Project project) { + if (null == INSTANCE) { + INSTANCE = new EventIndex(); + } + INSTANCE.project = project; + + return INSTANCE; + } + + public Collection getEventElements(final String name, final GlobalSearchScope scope) { + Collection result = new ArrayList<>(); + + Collection virtualFiles = + FileBasedIndex.getInstance().getContainingFiles(EventNameIndex.KEY, name, scope); + + for (VirtualFile virtualFile : virtualFiles) { + XmlFile xmlFile = (XmlFile) PsiManager.getInstance(project).findFile(virtualFile); + Collection valueElements = XmlPsiTreeUtil + .findAttributeValueElements(xmlFile, "event", "name", name); + result.addAll(valueElements); + } + return result; + } +} diff --git a/src/com/magento/idea/magento2plugin/indexes/IndexManager.java b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java new file mode 100644 index 000000000..fd5b33665 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/indexes/IndexManager.java @@ -0,0 +1,36 @@ +package com.magento.idea.magento2plugin.indexes; + +import com.intellij.util.indexing.FileBasedIndexImpl; +import com.intellij.util.indexing.ID; +import com.magento.idea.magento2plugin.stubs.indexes.*; + +/** + * Created by dkvashnin on 1/9/16. + */ +public class IndexManager { + public static void manualReindex() { + ID[] indexIds = new ID[] { + // php + ModulePackageIndex.KEY, + // xml|di configuration + PluginIndex.KEY, + TypeConfigurationIndex.KEY, + VirtualTypeIndex.KEY, + // layouts + BlockClassNameIndex.KEY, + BlockNameIndex.KEY, + ContainerNameIndex.KEY, + // events + EventNameIndex.KEY, + EventObserverIndex.KEY, + // webapi + WebApiTypeIndex.KEY, + ModuleNameIndex.KEY + }; + + for (ID id: indexIds) { + FileBasedIndexImpl.getInstance().requestRebuild(id); + FileBasedIndexImpl.getInstance().scheduleRebuild(id, new Throwable()); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/indexes/LayoutIndex.java b/src/com/magento/idea/magento2plugin/indexes/LayoutIndex.java new file mode 100644 index 000000000..c6b794c4d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/indexes/LayoutIndex.java @@ -0,0 +1,168 @@ +package com.magento.idea.magento2plugin.indexes; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.ID; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.stubs.indexes.BlockClassNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.BlockNameIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ContainerNameIndex; +import com.magento.idea.magento2plugin.xml.LineMarkerXmlTagDecorator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by dkvashnin on 11/20/15. + */ +public class LayoutIndex { + private static List getComponentDeclarations(String componentValue, String componentType, ID id, Project project, ComponentMatcher componentMatcher) { + List results = new ArrayList(); + Collection containingFiles = FileBasedIndex.getInstance() + .getContainingFiles( + id, + componentValue, + GlobalSearchScope.allScope(project) + ); + PsiManager psiManager = PsiManager.getInstance(project); + + for (VirtualFile virtualFile: containingFiles) { + XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); + if (xmlFile == null) { + continue; + } + + XmlTag rootTag = xmlFile.getRootTag(); + if (rootTag == null) { + continue; + } + collectComponentDeclarations(rootTag, results, componentValue, componentType, componentMatcher); + } + + return results; + } + + public static boolean isLayoutFile(VirtualFile virtualFile) { + VirtualFile parent = virtualFile.getParent(); + return virtualFile.getFileType() == XmlFileType.INSTANCE && parent.isDirectory() + && parent.getName().endsWith("layout"); + } + + public static boolean isLayoutFile(PsiFile psiFile) { + VirtualFile virtualFile = psiFile.getOriginalFile().getVirtualFile(); + return isLayoutFile(virtualFile); + } + + public static List getLayoutFiles(Project project, @Nullable String fileName) { + List results = new ArrayList(); + Collection xmlFiles = FilenameIndex.getAllFilesByExt(project, "xml"); + + PsiManager psiManager = PsiManager.getInstance(project); + for (VirtualFile xmlFile: xmlFiles) { + if (isLayoutFile(xmlFile)) { + if (fileName != null && !xmlFile.getNameWithoutExtension().equals(fileName)) { + continue; + } + + PsiFile file = psiManager.findFile(xmlFile); + if (file != null) { + results.add((XmlFile)file); + } + } + } + + return results; + } + + public static List getLayoutFiles(Project project) { + return getLayoutFiles(project, null); + } + + public static Collection getAllKeys(ID id, Project project) { + return FileBasedIndex.getInstance().getAllKeys(id, project); + } + + private static void collectComponentDeclarations(XmlTag parentTag, List results, String componentName, String componentType, ComponentMatcher componentMatcher) { + for (XmlTag childTag: parentTag.getSubTags()) { + if (componentType.equals(childTag.getName()) && componentMatcher.matches(componentName, childTag)) { + results.add(childTag); + } else if(childTag.getSubTags().length > 0 ) { + collectComponentDeclarations(childTag, results, componentName, componentType, componentMatcher); + } + } + } + + public static List getBlockDeclarations(String componentName, Project project) { + return getComponentDeclarations(componentName, "block", BlockNameIndex.KEY, project, new NameComponentMatcher()); + } + + public static List getContainerDeclarations(String componentName, Project project) { + return getComponentDeclarations(componentName, "container", ContainerNameIndex.KEY, project, new NameComponentMatcher()); + } + + public static List getBlockClassDeclarations(PhpClass phpClass, Project project) { + String className = phpClass.getPresentableFQN(); + + List blockTags = getComponentDeclarations(className, "block", BlockClassNameIndex.KEY, project, new ClassComponentMatcher()); + List decoratedBlockTags = new ArrayList<>(); + for (XmlTag blockTag: blockTags) { + decoratedBlockTags.add(new LayoutBlockLineMarkerXmlTagDecorator(blockTag)); + } + return decoratedBlockTags; + } + + private interface ComponentMatcher { + boolean matches(String value, XmlTag tag); + } + + private static class NameComponentMatcher implements ComponentMatcher { + @Override + public boolean matches(String value, XmlTag tag) { + return value.equals(tag.getAttributeValue("name")); + } + } + + private static class ClassComponentMatcher implements ComponentMatcher { + @Override + public boolean matches(String value, XmlTag tag) { + return value.equals(tag.getAttributeValue("class")); + } + } + + /** + * Decorator for XmlTag, which improves readability of "block" node in configuration line marker. + */ + private static class LayoutBlockLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + LayoutBlockLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @NotNull + @Override + protected String getAreaName() { + return xmlTag.getContainingFile().getVirtualFile().getParent().getParent().getName(); + } + + @NotNull + @Override + public String getDescription() { + String name = xmlTag.getAttributeValue("name"); + if (name != null) { + return String.format("block %s", name); + } + return xmlTag.getName(); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java b/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java deleted file mode 100644 index b06e7b972..000000000 --- a/src/com/magento/idea/magento2plugin/php/index/ModulePackageFileBasedIndex.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.magento.idea.magento2plugin.php.index; - -import com.intellij.json.JsonFileType; -import com.intellij.json.psi.*; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.indexing.*; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; -import com.magento.idea.magento2plugin.php.module.ComposerPackageModelImpl; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by dkvashnin on 12/3/15. - */ -public class ModulePackageFileBasedIndex extends ScalarIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.php.index.module"); - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return new DataIndexer() { - @NotNull - @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); - JsonFile jsonFile = (JsonFile)fileContent.getPsiFile(); - if (!Settings.isEnabled(jsonFile.getProject())) { - return map; - } - - JsonObject jsonObject = PsiTreeUtil.getChildOfType(jsonFile, JsonObject.class); - if (jsonObject == null) { - return map; - } - ComposerPackageModel composerObject = new ComposerPackageModelImpl(jsonObject); - - String type = composerObject.getType(); - if (type == null) { - return map; - } - - if (!type.startsWith("magento2-")) { - return map; - } - - String name = composerObject.getName(); - - if (name != null) { - map.put(name, null); - } - - - return map; - } - }; - } - - @NotNull - @Override - public KeyDescriptor getKeyDescriptor() { - return new EnumeratorStringDescriptor(); - } - - @NotNull - @Override - public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile virtualFile) { - return virtualFile.getFileType().equals(JsonFileType.INSTANCE) && virtualFile.getName().equals("composer.json"); - } - }; - } - - @Override - public boolean dependsOnFileContent() { - return true; - } - - @Override - public int getVersion() { - return 1; - } -} diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java index 216f09672..945f36f3a 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java @@ -2,7 +2,6 @@ import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; -import com.intellij.openapi.project.DumbService; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment; @@ -10,9 +9,9 @@ import com.jetbrains.php.lang.inspections.PhpInspection; import com.jetbrains.php.lang.psi.elements.*; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.php.module.MagentoModule; +import com.magento.idea.magento2plugin.project.Settings; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; +import com.magento.idea.magento2plugin.php.module.MagentoModule; import org.jetbrains.annotations.NotNull; /** diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java index d7b3fa84b..9b1c0cbbc 100644 --- a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java +++ b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java @@ -11,7 +11,7 @@ import com.jetbrains.php.lang.psi.elements.MethodReference; import com.jetbrains.php.lang.psi.elements.PhpClass; import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; -import com.magento.idea.magento2plugin.Settings; +import com.magento.idea.magento2plugin.project.Settings; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import com.magento.idea.magento2plugin.php.module.MagentoModule; import com.magento.idea.magento2plugin.php.util.MagentoTypes; diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java index 968b5d590..9a518a87c 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/ClassConfigurationLineMarkerProvider.java @@ -3,27 +3,25 @@ import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.icons.AllIcons; import com.intellij.psi.PsiElement; import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.Magento2Icons; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.di.index.TypeConfigurationFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import com.magento.idea.magento2plugin.stubs.indexes.TypeConfigurationIndex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; /** * Created by dkvashnin on 11/15/15. */ public class ClassConfigurationLineMarkerProvider implements LineMarkerProvider { - public static List> COLLECTORS = new ArrayList>() {{ - add(new DiConfigurationCollector()); - add(new LayoutConfigurationCollector()); - }}; - @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { @@ -40,48 +38,25 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll for (PsiElement psiElement: list) { if (psiElement instanceof PhpClass) { List results = new ArrayList(); - for (Collector collector: COLLECTORS) { - results.addAll(collector.collect((PhpClass) psiElement)); - } + results.addAll(TypeConfigurationIndex.getClassConfigurations((PhpClass) psiElement)); + results.addAll(LayoutIndex.getBlockClassDeclarations((PhpClass) psiElement, psiElement.getProject())); - if (results.size() == 0) { + if (!(results.size() > 0)) { continue; } - Collections.sort( - results, - new Comparator() { - @Override - public int compare(XmlTag firstTag, XmlTag secondTag) { - return firstTag.getName().compareTo(secondTag.getName()); - } - } - ); - String tooltipText = "Navigate to configuration:"; + results.sort(Comparator.comparing(XmlTag::getName)); + + StringBuilder tooltipText = new StringBuilder("Navigate to configuration:"); for (XmlTag resultItem: results) { - tooltipText += "\n " + resultItem.getName(); + tooltipText.append("\n ").append(resultItem.getName()); } - NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. - create(Magento2Icons.CONFIGURATION). - setTargets(results). - setTooltipText(tooltipText); + NavigationGutterIconBuilder builder = NavigationGutterIconBuilder + .create(AllIcons.FileTypes.Xml) + .setTargets(results) + .setTooltipText(tooltipText.toString()); collection.add(builder.createLineMarkerInfo(psiElement)); } } } } - -class DiConfigurationCollector implements Collector { - @Override - public List collect(@NotNull PhpClass psiElement) { - return TypeConfigurationFileBasedIndex - .getClassConfigurations(psiElement); - } -} - -class LayoutConfigurationCollector implements Collector { - @Override - public List collect(@NotNull PhpClass psiElement) { - return LayoutIndexUtility.getBlockClassDeclarations(psiElement, psiElement.getProject()); - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/Collector.java b/src/com/magento/idea/magento2plugin/php/linemarker/Collector.java deleted file mode 100644 index e78d400cb..000000000 --- a/src/com/magento/idea/magento2plugin/php/linemarker/Collector.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.magento.idea.magento2plugin.php.linemarker; - -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Created by dkvashnin on 11/20/15. - */ -interface Collector { - List collect(@NotNull T psiElement); -} diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java index 71cbec199..eb8718d64 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/PluginLineMarkerProvider.java @@ -3,15 +3,15 @@ import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.icons.AllIcons; import com.intellij.psi.PsiElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.indexing.FileBasedIndex; import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.Magento2Icons; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.di.index.PluginToTypeFileBasedIndex; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.stubs.indexes.PluginIndex; import org.apache.commons.lang.WordUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,9 +29,9 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { } @Override - public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { - if (list.size() > 0) { - if (!Settings.isEnabled(list.get(0).getProject())) { + public void collectSlowLineMarkers(@NotNull List psiElements, @NotNull Collection collection) { + if (psiElements.size() > 0) { + if (!Settings.isEnabled(psiElements.get(0).getProject())) { return; } } @@ -39,7 +39,7 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll ClassPluginCollector classPluginCollector = new ClassPluginCollector(pluginClassCache); MethodPluginCollector methodPluginCollector = new MethodPluginCollector(pluginClassCache); - for (PsiElement psiElement : list) { + for (PsiElement psiElement : psiElements) { if (psiElement instanceof PhpClass || psiElement instanceof Method) { List results; @@ -50,21 +50,21 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll } if (results.size() > 0 ) { - NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. - create(Magento2Icons.PLUGIN). - setTargets(results). - setTooltipText("Navigate to plugins"); - - collection.add(builder.createLineMarkerInfo(psiElement)); + collection.add(NavigationGutterIconBuilder + .create(AllIcons.Nodes.Plugin) + .setTargets(results) + .setTooltipText("Navigate to plugins") + .createLineMarkerInfo(psiElement) + ); } } } } - class PluginClassCache { + private static class PluginClassCache { private HashMap> classPluginsMap = new HashMap>(); - public List getPluginsForClass(@NotNull PhpClass phpClass, @NotNull String classFQN) { + List getPluginsForClass(@NotNull PhpClass phpClass, @NotNull String classFQN) { List results = new ArrayList<>(); if (classPluginsMap.containsKey(classFQN)) { @@ -72,11 +72,7 @@ public List getPluginsForClass(@NotNull PhpClass phpClass, @NotNull St } List> plugins = FileBasedIndex.getInstance() - .getValues( - PluginToTypeFileBasedIndex.NAME, - classFQN, - GlobalSearchScope.allScope(phpClass.getProject()) - ); + .getValues(PluginIndex.KEY, classFQN, GlobalSearchScope.allScope(phpClass.getProject())); if (plugins.size() == 0) { classPluginsMap.put(classFQN, results); @@ -85,7 +81,6 @@ public List getPluginsForClass(@NotNull PhpClass phpClass, @NotNull St PhpIndex phpIndex = PhpIndex.getInstance(phpClass.getProject()); - for (Set pluginClassNames: plugins) { for (String pluginClassName: pluginClassNames) { results.addAll(phpIndex.getClassesByFQN(pluginClassName)); @@ -95,7 +90,7 @@ public List getPluginsForClass(@NotNull PhpClass phpClass, @NotNull St return results; } - public List getPluginsForClass(@NotNull PhpClass phpClass) + List getPluginsForClass(@NotNull PhpClass phpClass) { List pluginsForClass = getPluginsForClass(phpClass, phpClass.getPresentableFQN()); for (PhpClass parent: phpClass.getSupers()) { @@ -105,7 +100,7 @@ public List getPluginsForClass(@NotNull PhpClass phpClass) return pluginsForClass; } - public List getPluginMethods(@NotNull PhpClass plugin) { + List getPluginMethods(@NotNull PhpClass plugin) { List methodList = new ArrayList(); for (Method method : plugin.getMethods()) { if (method.getAccess().isPublic()) { @@ -118,7 +113,7 @@ public List getPluginMethods(@NotNull PhpClass plugin) { return methodList; } - public List getPluginMethods(List plugins) { + List getPluginMethods(List plugins) { List methodList = new ArrayList(); for (PhpClass plugin: plugins) { methodList.addAll(getPluginMethods(plugin)); @@ -126,50 +121,54 @@ public List getPluginMethods(List plugins) { return methodList; } } -} -class ClassPluginCollector implements Collector { - private PluginLineMarkerProvider.PluginClassCache pluginClassCache; + private static class ClassPluginCollector implements Collector { + private PluginLineMarkerProvider.PluginClassCache pluginClassCache; - public ClassPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { - this.pluginClassCache = pluginClassCache; - } + ClassPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { + this.pluginClassCache = pluginClassCache; + } - @Override - public List collect(@NotNull PhpClass psiElement) { - return pluginClassCache.getPluginsForClass(psiElement); + @Override + public List collect(@NotNull PhpClass psiElement) { + return pluginClassCache.getPluginsForClass(psiElement); + } } -} -class MethodPluginCollector implements Collector { - private PluginLineMarkerProvider.PluginClassCache pluginClassCache; + private static class MethodPluginCollector implements Collector { + private PluginLineMarkerProvider.PluginClassCache pluginClassCache; - public MethodPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { - this.pluginClassCache = pluginClassCache; - } + MethodPluginCollector(PluginLineMarkerProvider.PluginClassCache pluginClassCache) { + this.pluginClassCache = pluginClassCache; + } - @Override - public List collect(@NotNull Method psiElement) { - List results = new ArrayList<>(); + @Override + public List collect(@NotNull Method psiElement) { + List results = new ArrayList<>(); - PhpClass methodClass = psiElement.getContainingClass(); - if (methodClass == null) { - return results; - } + PhpClass methodClass = psiElement.getContainingClass(); + if (methodClass == null) { + return results; + } - List pluginsList = pluginClassCache.getPluginsForClass(methodClass); - List pluginMethods = pluginClassCache.getPluginMethods(pluginsList); + List pluginsList = pluginClassCache.getPluginsForClass(methodClass); + List pluginMethods = pluginClassCache.getPluginMethods(pluginsList); - String classMethodName = WordUtils.capitalize(psiElement.getName()); - for (Method pluginMethod: pluginMethods) { - if (isPluginMethodName(pluginMethod.getName(), classMethodName)) { - results.add(pluginMethod); + String classMethodName = WordUtils.capitalize(psiElement.getName()); + for (Method pluginMethod: pluginMethods) { + if (isPluginMethodName(pluginMethod.getName(), classMethodName)) { + results.add(pluginMethod); + } } + return results; + } + + private boolean isPluginMethodName(String pluginMethodName, String classMethodName) { + return pluginMethodName.substring(5).equals(classMethodName) || pluginMethodName.substring(6).equals(classMethodName); } - return results; } - private boolean isPluginMethodName(String pluginMethodName, String classMethodName) { - return pluginMethodName.substring(5).equals(classMethodName) || pluginMethodName.substring(6).equals(classMethodName); + private interface Collector { + List collect(@NotNull T psiElement); } -} \ No newline at end of file +} diff --git a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java index ce367d0be..fc6872f70 100644 --- a/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java +++ b/src/com/magento/idea/magento2plugin/php/linemarker/WebApiLineMarkerProvider.java @@ -7,9 +7,9 @@ import com.intellij.psi.xml.XmlTag; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.Magento2Icons; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.webapi.index.WebApiTypesFileBasedIndex; +import com.magento.idea.magento2plugin.MagentoIcons; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.stubs.indexes.WebApiTypeIndex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,13 +30,13 @@ public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) { } @Override - public void collectSlowLineMarkers(@NotNull List list, @NotNull Collection collection) { - if (list.size() > 0) { - if (!Settings.isEnabled(list.get(0).getProject())) { + public void collectSlowLineMarkers(@NotNull List psiElements, @NotNull Collection collection) { + if (psiElements.size() > 0) { + if (!Settings.isEnabled(psiElements.get(0).getProject())) { return; } } - for (PsiElement psiElement : list) { + for (PsiElement psiElement: psiElements) { WebApiRoutesCollector collector = new WebApiRoutesCollector(); List results = new ArrayList<>(); if (psiElement instanceof Method) { @@ -45,105 +45,102 @@ public void collectSlowLineMarkers(@NotNull List list, @NotNull Coll results = collector.getRoutes((PhpClass) psiElement); } - if (results.size() == 0) { + if (!(results.size() > 0)) { continue; } - String tooltipText = "Navigate to Web API configuration:
          ";
          +
          +            StringBuilder tooltipText = new StringBuilder("Navigate to Web API configuration:
          ");
                       for (XmlTag routeTag : results) {
          -                tooltipText += routeTag.getName() + "\n";
          +                tooltipText.append(routeTag.getName()).append("\n");
                       }
          -            tooltipText += "
          "; - NavigationGutterIconBuilder builder = NavigationGutterIconBuilder. - create(Magento2Icons.WEB_API). - setTargets(results). - setTooltipText(tooltipText); + tooltipText.append("
          "); + NavigationGutterIconBuilder builder = NavigationGutterIconBuilder + .create(MagentoIcons.WEB_API) + .setTargets(results) + .setTooltipText(tooltipText.toString()); collection.add(builder.createLineMarkerInfo(psiElement)); } } -} -/** - * Web API config nodes collector for service methods and classes. Has built in caching. - */ -class WebApiRoutesCollector { + /** + * Web API config nodes collector for service methods and classes. Has built in caching. + */ + private static class WebApiRoutesCollector { - private HashMap> routesCache = new HashMap<>(); + private HashMap> routesCache = new HashMap<>(); - private static final Map HTTP_METHODS_SORT_ORDER = new HashMap() {{ - put("GET", 1); - put("PUT", 2); - put("POS", 3); - put("DEL", 4); - }}; + private static final Map HTTP_METHODS_SORT_ORDER = new HashMap() {{ + put("GET", 1); + put("PUT", 2); + put("POS", 3); + put("DEL", 4); + }}; - /** - * Get sorted list of Web API routes related to the specified class. - */ - public List getRoutes(@NotNull PhpClass phpClass) { - List routesForClass = new ArrayList<>(); - for (Method method : phpClass.getMethods()) { - routesForClass.addAll(getRoutes(method)); + /** + * Get sorted list of Web API routes related to the specified class. + */ + List getRoutes(@NotNull PhpClass phpClass) { + List routesForClass = new ArrayList<>(); + for (Method method : phpClass.getMethods()) { + routesForClass.addAll(getRoutes(method)); + } + sortRoutes(routesForClass); + return routesForClass; } - sortRoutes(routesForClass); - return routesForClass; - } - /** - * Get list of Web API routes related to the specified method. - *

          - * Results are cached. - */ - public List getRoutes(@NotNull Method method) { - String methodFqn = method.getFQN(); - if (!routesCache.containsKey(methodFqn)) { - List routesForMethod = extractRoutesForMethod(method); - sortRoutes(routesForMethod); - routesCache.put(methodFqn, routesForMethod); + /** + * Get list of Web API routes related to the specified method. + *

          + * Results are cached. + */ + List getRoutes(@NotNull Method method) { + String methodFqn = method.getFQN(); + if (!routesCache.containsKey(methodFqn)) { + List routesForMethod = extractRoutesForMethod(method); + sortRoutes(routesForMethod); + routesCache.put(methodFqn, routesForMethod); + } + return routesCache.get(methodFqn); } - return routesCache.get(methodFqn); - } - /** - * Get list of Web API routes related to the specified method. - *

          - * Web API declarations for parent classes are taken into account. - * Results are not cached. - */ - public List extractRoutesForMethod(@NotNull Method method) { - List routesForMethod = WebApiTypesFileBasedIndex.getWebApiRoutes(method); - PhpClass phpClass = method.getContainingClass(); - if (phpClass == null) { - return routesForMethod; - } - for (PhpClass parent : method.getContainingClass().getSupers()) { - for (Method parentMethod : parent.getMethods()) { - if (parentMethod.getName().equals(method.getName())) { - routesForMethod.addAll(extractRoutesForMethod(parentMethod)); + /** + * Get list of Web API routes related to the specified method. + *

          + * Web API declarations for parent classes are taken into account. + * Results are not cached. + */ + List extractRoutesForMethod(@NotNull Method method) { + List routesForMethod = WebApiTypeIndex.getWebApiRoutes(method); + PhpClass phpClass = method.getContainingClass(); + if (phpClass == null) { + return routesForMethod; + } + for (PhpClass parent : method.getContainingClass().getSupers()) { + for (Method parentMethod : parent.getMethods()) { + if (parentMethod.getName().equals(method.getName())) { + routesForMethod.addAll(extractRoutesForMethod(parentMethod)); + } } } + return routesForMethod; } - return routesForMethod; - } - /** - * Make sure that routes are sorted as follows: GET, PUT, POST, DELETE. Then by path. - */ - private void sortRoutes(List routes) { - Collections.sort( - routes, - new Comparator() { - @Override - public int compare(XmlTag firstTag, XmlTag secondTag) { + /** + * Make sure that routes are sorted as follows: GET, PUT, POST, DELETE. Then by path. + */ + private void sortRoutes(List routes) { + routes.sort( + (firstTag, secondTag) -> { String substring = firstTag.getName().substring(2, 5); Integer firstSortOrder = HTTP_METHODS_SORT_ORDER.get(substring); Integer secondSortOrder = HTTP_METHODS_SORT_ORDER.get(secondTag.getName().substring(2, 5)); if (firstSortOrder.compareTo(secondSortOrder) == 0) { - /** Sort by route if HTTP methods are equal */ + // Sort by route if HTTP methods are equal return firstTag.getName().compareTo(secondTag.getName()); } return firstSortOrder.compareTo(secondSortOrder); } - } - ); + ); + } } } diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java index ea597b20f..303073d2c 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponent.java @@ -3,7 +3,6 @@ import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Created by dkvashnin on 1/9/16. diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java index b8e0f0bb3..6d7ad16b5 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoComponentManager.java @@ -13,11 +13,14 @@ import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.FileBasedIndex; -import com.magento.idea.magento2plugin.php.index.ModulePackageFileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ModulePackageIndex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; /** * Created by dkvashnin on 12/5/15. @@ -99,7 +102,7 @@ synchronized public void flushModules() { } private void loadModules() { - Collection packages = FileBasedIndex.getInstance().getAllKeys(ModulePackageFileBasedIndex.NAME, this.project); + Collection packages = FileBasedIndex.getInstance().getAllKeys(ModulePackageIndex.KEY, this.project); PsiManager psiManager = PsiManager.getInstance(this.project); for (String packageName: packages) { if (components.containsKey(packageName)) { @@ -107,7 +110,7 @@ private void loadModules() { } Collection containingFiles = FileBasedIndex.getInstance() - .getContainingFiles(ModulePackageFileBasedIndex.NAME, packageName, GlobalSearchScope.allScope(this.project)); + .getContainingFiles(ModulePackageIndex.KEY, packageName, GlobalSearchScope.allScope(this.project)); if (containingFiles.size() > 0) { VirtualFile configurationFile = containingFiles.iterator().next(); diff --git a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java index 9dbb79885..53c90e3cf 100644 --- a/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java +++ b/src/com/magento/idea/magento2plugin/php/module/MagentoModule.java @@ -1,7 +1,5 @@ package com.magento.idea.magento2plugin.php.module; -import org.jetbrains.annotations.Nullable; - /** * Created by dkvashnin on 12/5/15. */ diff --git a/src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java b/src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java deleted file mode 100644 index b1dddc9fa..000000000 --- a/src/com/magento/idea/magento2plugin/php/module/ModuleUtil.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.magento.idea.magento2plugin.php.module; - -/** - * Created by dkvashnin on 12/5/15. - */ -public class ModuleUtil { - -} diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java index d5e5d2041..9521fb957 100644 --- a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java +++ b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java @@ -6,8 +6,8 @@ import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; -import com.magento.idea.magento2plugin.php.module.MagentoModule; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; +import com.magento.idea.magento2plugin.php.module.MagentoModule; import org.jetbrains.annotations.NotNull; import javax.swing.*; diff --git a/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java b/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java deleted file mode 100644 index 41fd5c3fd..000000000 --- a/src/com/magento/idea/magento2plugin/php/util/ImplementationMatcher.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.magento.idea.magento2plugin.php.util; - -import com.intellij.psi.PsiElement; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; - -/** -* Created by dkvashnin on 12/18/15. -*/ -public class ImplementationMatcher implements PsiContextMatcherI { - private String type; - - public ImplementationMatcher(String type) { - this.type = type; - } - - @Override - public boolean match(PsiElement psiElement) { - if (psiElement instanceof PhpClass) { - for (PhpClass parent : ((PhpClass)psiElement).getImplementedInterfaces()) { - if (parent.getPresentableFQN().equals(type)) { - return true; - } - } - - PhpClass parent = ((PhpClass) psiElement).getSuperClass(); - if (parent != null) { - return match(parent); - } - } - return false; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/PhpPatternsHelper.java b/src/com/magento/idea/magento2plugin/php/util/PhpPatternsHelper.java similarity index 93% rename from src/com/magento/idea/magento2plugin/xml/observer/PhpPatternsHelper.java rename to src/com/magento/idea/magento2plugin/php/util/PhpPatternsHelper.java index 25a4df7af..bb7ef0e08 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/PhpPatternsHelper.java +++ b/src/com/magento/idea/magento2plugin/php/util/PhpPatternsHelper.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.xml.observer; +package com.magento.idea.magento2plugin.php.util; import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PlatformPatterns; diff --git a/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java b/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java new file mode 100644 index 000000000..54f1b6481 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java @@ -0,0 +1,12 @@ +package com.magento.idea.magento2plugin.php.util; + +public class PhpRegex { + public static class Xml { + public static final String CLASS_NAME + = "\\\\?([A-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(\\\\[A-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*)"; + + public static final String CLASS_MEMBER_NAME = "::\\$?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)(\\(\\))?"; + + public static final String CLASS_ELEMENT = CLASS_NAME + "(" + CLASS_MEMBER_NAME + ")?.*"; + } +} diff --git a/src/com/magento/idea/magento2plugin/project/ProjectDetector.java b/src/com/magento/idea/magento2plugin/project/ProjectDetector.java new file mode 100644 index 000000000..e91f161c7 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/project/ProjectDetector.java @@ -0,0 +1,50 @@ +package com.magento.idea.magento2plugin.project; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.*; +import com.intellij.platform.DirectoryProjectConfigurator; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.indexes.IndexManager; +import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; +import org.jetbrains.annotations.NotNull; + +import javax.swing.event.HyperlinkEvent; + + +public class ProjectDetector implements DirectoryProjectConfigurator { + @Override + public void configureProject(Project project, @NotNull VirtualFile virtualFile, Ref ref) { + StartupManager.getInstance(project).runWhenProjectIsInitialized(() -> { + DumbService.getInstance(project).smartInvokeLater(() -> { + if (null == VfsUtil.findRelativeFile(project.getBaseDir(), "app", "etc", "di.xml")) { + return; + } + Notification notification = new Notification("Magento", "Magento", + "Enable Magento support for this project?", + NotificationType.INFORMATION, new NotificationListener.Adapter() { + @Override + public void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent event) { + Settings.getInstance(project).pluginEnabled = true; + IndexManager.manualReindex(); + MagentoComponentManager.getInstance(project).flushModules(); + notification.expire(); + } + } + ); + Notifications.Bus.notify(notification, project); + }); + }); + } +} diff --git a/src/com/magento/idea/magento2plugin/Settings.java b/src/com/magento/idea/magento2plugin/project/Settings.java similarity index 82% rename from src/com/magento/idea/magento2plugin/Settings.java rename to src/com/magento/idea/magento2plugin/project/Settings.java index 86eac7def..7ebbd82dd 100644 --- a/src/com/magento/idea/magento2plugin/Settings.java +++ b/src/com/magento/idea/magento2plugin/project/Settings.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin; +package com.magento.idea.magento2plugin.project; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; @@ -27,14 +27,8 @@ public void loadState(Settings settings) { XmlSerializerUtil.copyBean(settings, this); } - protected Project project; - public static Settings getInstance(Project project) { - Settings settings = ServiceManager.getService(project, Settings.class); - - settings.project = project; - - return settings; + return ServiceManager.getService(project, Settings.class); } public static boolean isEnabled(@NotNull Project project) { diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.form b/src/com/magento/idea/magento2plugin/project/SettingsForm.form similarity index 97% rename from src/com/magento/idea/magento2plugin/SettingsForm.form rename to src/com/magento/idea/magento2plugin/project/SettingsForm.form index 3317a0f20..75600130c 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.form +++ b/src/com/magento/idea/magento2plugin/project/SettingsForm.form @@ -1,5 +1,5 @@ -

          + diff --git a/src/com/magento/idea/magento2plugin/SettingsForm.java b/src/com/magento/idea/magento2plugin/project/SettingsForm.java similarity index 95% rename from src/com/magento/idea/magento2plugin/SettingsForm.java rename to src/com/magento/idea/magento2plugin/project/SettingsForm.java index d55631887..254e1aa72 100644 --- a/src/com/magento/idea/magento2plugin/SettingsForm.java +++ b/src/com/magento/idea/magento2plugin/project/SettingsForm.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin; +package com.magento.idea.magento2plugin.project; import com.intellij.javaee.ExternalResourceManager; import com.intellij.javaee.ExternalResourceManagerEx; @@ -11,27 +11,29 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.FilenameIndex; +import com.magento.idea.magento2plugin.indexes.IndexManager; import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; import com.magento.idea.magento2plugin.php.module.MagentoComponent; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import com.magento.idea.magento2plugin.php.module.MagentoModule; -import com.magento.idea.magento2plugin.util.IndexUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.*; +import java.util.Collection; +import java.util.Stack; /** * Created by dkvashnin on 1/9/16. */ public class SettingsForm implements Configurable { - private Project project; + + private final static String DISPLAY_NAME = "Magento"; + + private final Project project; private JCheckBox pluginEnabled; private JButton buttonReindex; private JPanel panel1; @@ -44,7 +46,7 @@ public SettingsForm(@NotNull final Project project) { @Nls @Override public String getDisplayName() { - return "Magento2 plugin"; + return SettingsForm.DISPLAY_NAME; } @Nullable @@ -76,7 +78,7 @@ public void mouseClicked(MouseEvent e) { } private void reindex() { - IndexUtil.manualReindex(); + IndexManager.manualReindex(); MagentoComponentManager.getInstance(project).flushModules(); } diff --git a/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java b/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java new file mode 100644 index 000000000..df12ccd60 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java @@ -0,0 +1,24 @@ +package com.magento.idea.magento2plugin.reference.js; + +import com.intellij.lang.javascript.patterns.JSPatterns; +import com.intellij.psi.*; +import com.magento.idea.magento2plugin.reference.provider.FilePathReferenceProvider; +import com.magento.idea.magento2plugin.reference.provider.ModuleNameReferenceProvider; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.patterns.StandardPatterns.string; + +public class JsReferenceContributor extends PsiReferenceContributor { + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider( + JSPatterns.jsLiteralExpression().withText(string().matches(".*[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+.*")), + new ModuleNameReferenceProvider() + ); + + registrar.registerReferenceProvider( + JSPatterns.jsLiteralExpression().withText(string().matches(".*\\W([\\w-]+/)*[\\w\\.-]+.*")), + new FilePathReferenceProvider() + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/php/PhpReferenceContributor.java b/src/com/magento/idea/magento2plugin/reference/php/PhpReferenceContributor.java new file mode 100644 index 000000000..b77c7de57 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/php/PhpReferenceContributor.java @@ -0,0 +1,18 @@ +package com.magento.idea.magento2plugin.reference.php; + +import com.intellij.psi.PsiReferenceContributor; +import com.intellij.psi.PsiReferenceRegistrar; +import com.magento.idea.magento2plugin.php.util.PhpPatternsHelper; +import com.magento.idea.magento2plugin.reference.provider.EventDispatchReferenceProvider; +import org.jetbrains.annotations.NotNull; + +public class PhpReferenceContributor extends PsiReferenceContributor { + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { + // ->dispatch("event_name") + registrar.registerReferenceProvider( + PhpPatternsHelper.STRING_METHOD_ARGUMENT, + new EventDispatchReferenceProvider() + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/CompositeReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/CompositeReferenceProvider.java new file mode 100644 index 000000000..b091e0efd --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/CompositeReferenceProvider.java @@ -0,0 +1,31 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CompositeReferenceProvider extends PsiReferenceProvider { + + private PsiReferenceProvider[] providers = null; + + public CompositeReferenceProvider(PsiReferenceProvider ...providers) { + this.providers = providers; + } + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + List result = new ArrayList<>(); + for (PsiReferenceProvider provider : providers) { + result.addAll(Arrays.asList(provider.getReferencesByElement(element, context))); + } + + return result.toArray(new PsiReference[result.size()]); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/EventDispatchReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/EventDispatchReferenceProvider.java new file mode 100644 index 000000000..7db623277 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/EventDispatchReferenceProvider.java @@ -0,0 +1,36 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.indexes.EventIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class EventDispatchReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + String value = StringUtil.unquoteString(element.getText()); + Collection targets = EventIndex.getInstance(element.getProject()) + .getEventElements( + value, + GlobalSearchScope.getScopeRestrictedByFileTypes( + GlobalSearchScope.allScope(element.getProject()), + XmlFileType.INSTANCE + ) + ); + + if (targets.size() > 0) { + return new PsiReference[] {new PolyVariantReferenceBase(element, targets)}; + } + return PsiReference.EMPTY_ARRAY; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/EventNameReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/EventNameReferenceProvider.java new file mode 100644 index 000000000..ccfb3a201 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/EventNameReferenceProvider.java @@ -0,0 +1,63 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.lang.PhpFileType; +import com.jetbrains.php.lang.psi.PhpFile; +import com.magento.idea.magento2plugin.php.util.PhpPatternsHelper; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import com.magento.idea.magento2plugin.stubs.indexes.EventNameIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class EventNameReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + String value = StringUtil.unquoteString(element.getText()); + Collection containingFiles = FileBasedIndex.getInstance() + .getContainingFiles(EventNameIndex.KEY, value, + GlobalSearchScope.getScopeRestrictedByFileTypes( + GlobalSearchScope.allScope(element.getProject()), + PhpFileType.INSTANCE + ) + ); + + PsiManager psiManager = PsiManager.getInstance(element.getProject()); + for (VirtualFile virtualFile: containingFiles) { + PhpFile phpFile = (PhpFile) psiManager.findFile(virtualFile); + if (phpFile != null) { + List psiElements = new ArrayList<>(); + recursiveFill(psiElements, phpFile, value); + if (psiElements.size() > 0) { + return new PsiReference[] {new PolyVariantReferenceBase(element, psiElements)}; + } + } + } + return PsiReference.EMPTY_ARRAY; + } + + private void recursiveFill(List psiElements, PsiElement psiElement, String typeName) { + if (PhpPatternsHelper.STRING_METHOD_ARGUMENT.accepts(psiElement)) { + if (StringUtil.unquoteString(psiElement.getText()).equals(typeName)) { + psiElements.add(psiElement); + } + return; + } + + for (PsiElement child: psiElement.getChildren()) { + recursiveFill(psiElements, child, typeName); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java new file mode 100644 index 000000000..68109764f --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java @@ -0,0 +1,241 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.*; +import com.intellij.psi.*; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; +import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FilePathReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + + List psiReferences = new ArrayList<>(); + + String origValue = element.getText(); + + String filePath = getFilePath(element); + if (null == filePath) { + return PsiReference.EMPTY_ARRAY; + } + + Collection files = getFiles(element); + if (!(files.size() > 0)) { + return PsiReference.EMPTY_ARRAY; + } + + PsiManager psiManager = PsiManager.getInstance(element.getProject()); + + String currentPath = ""; + String[] pathParts = filePath.split("/"); + for (int i = 0; i < pathParts.length; i++) { + String pathPart = pathParts[i]; + Boolean currentPathIsBuilt = false; + + Map> psiPathElements = new THashMap<>(); + + for (VirtualFile file : files) { + String fileUrl = file.getUrl(); + if (!fileUrl.contains(filePath)) { + continue; + } + String rootPathUrl = fileUrl.substring(0, fileUrl.indexOf(filePath)); + String[] relativePathParts = fileUrl.substring(fileUrl.indexOf(filePath)).split("/"); + + if (!currentPathIsBuilt) { + currentPath = currentPath.isEmpty() + ? currentPath.concat(relativePathParts[i]) + : currentPath.concat("/").concat(relativePathParts[i]); + currentPathIsBuilt = true; + } + + VirtualFile currentVf = VirtualFileManager.getInstance() + .findFileByUrl(rootPathUrl.concat(currentPath)); + + if (null != currentVf) { + PsiElement psiElement = currentVf.isDirectory() + ? psiManager.findDirectory(currentVf) + : psiManager.findFile(currentVf); + if (null != psiElement) { + + TextRange pathRange = new TextRange( + origValue.indexOf(filePath) + + (currentPath.lastIndexOf("/") == -1 ? 0 : currentPath.lastIndexOf("/") + 1), + origValue.indexOf(filePath) + + (currentPath.lastIndexOf("/") == -1 ? 0 : currentPath.lastIndexOf("/") + 1) + + pathPart.length() + ); + + if (!psiPathElements.containsKey(pathRange)) { + List list = new ArrayList<>(); + list.add(psiElement); + psiPathElements.put(pathRange, list); + } else { + psiPathElements.get(pathRange).add(psiElement); + } + } + } + } + + if (psiPathElements.size() > 0) { + psiPathElements.forEach(new BiConsumer>() { + @Override + public void accept(TextRange textRange, List psiElements) { + psiReferences.add(new PolyVariantReferenceBase(element, textRange, psiElements)); + } + }); + } + } + + return psiReferences.toArray(new PsiReference[psiReferences.size()]); + } + + private Collection getFiles(@NotNull PsiElement element) + { + Collection files = new ArrayList<>(); + + String filePath = getFilePath(element); + if (null == filePath) { + return files; + } + + String fileName = filePath.substring(filePath.lastIndexOf("/") + 1); + + if (fileName.matches(".*\\.\\w+$")) { + // extension presents + files = FilenameIndex.getVirtualFilesByName( + element.getProject(), + fileName, + GlobalSearchScope.allScope(element.getProject()) + ); + files.removeIf(f -> !f.getPath().endsWith(filePath)); + + // filter by module + Collection vfs = getModuleSourceFiles(element); + if (null != vfs) { + files.removeIf(f -> { + for (VirtualFile vf : vfs) { + if (f.getPath().startsWith(vf.getPath().concat("/"))) { + return false; + } + } + return true; + }); + } + } else if (isModuleNamePresent(element)) { + // extension absent + Collection vfs = getModuleSourceFiles(element); + if (null != vfs) { + for (VirtualFile vf : vfs) { + Collection vfChildren = getAllSubFiles(vf.findChild("view")); + if (null != vfChildren) { + vfChildren.removeIf(f -> { + if (!f.isDirectory()) { + String ext = f.getExtension(); + if (null != ext) { + return !f.getPath().endsWith(filePath.concat(".").concat(ext)); + } + } + return true; + }); + files.addAll(vfChildren); + } + } + } + } + + return files; + } + + private Collection getModuleFile(@NotNull PsiElement element) + { + String moduleName = getModuleName(element); + if (null == moduleName || moduleName.isEmpty()) { + return null; + } + return FileBasedIndex.getInstance() + .getContainingFiles(ModuleNameIndex.KEY, moduleName, + GlobalSearchScope.getScopeRestrictedByFileTypes( + GlobalSearchScope.allScope(element.getProject()), + XmlFileType.INSTANCE + ) + ); + } + + private Collection getModuleSourceFiles(@NotNull PsiElement element) + { + Collection virtualFiles = getModuleFile(element); + if (null == virtualFiles) { + return null; + } + virtualFiles.removeIf(vf -> !(vf != null && vf.getParent() != null && vf.getParent().getParent() != null)); + Collection sourceVfs = new ArrayList<>(); + for (VirtualFile vf : virtualFiles) { + sourceVfs.add(vf.getParent().getParent()); + } + return sourceVfs; + } + + private String getFilePath(@NotNull PsiElement element) + { + String value = element.getText(); + String moduleName = getModuleName(element); + if (null != moduleName && value.contains(moduleName)) { + value = value.replace(moduleName, ""); + } + + Pattern pattern = Pattern.compile("\\W?(([\\w-]+/)*[\\w\\.-]+)"); + Matcher matcher = pattern.matcher(value); + if (!matcher.find()) { + return null; + } + + return matcher.group(1); + } + + private String getModuleName(@NotNull PsiElement element) + { + Pattern pattern = Pattern.compile("(([A-Z][a-zA-Z0-9]+)_([A-Z][a-zA-Z0-9]+))"); + Matcher matcher = pattern.matcher(element.getText()); + return matcher.find() ? matcher.group(1) : null; + } + + private boolean isModuleNamePresent(@NotNull PsiElement element) + { + return getModuleName(element) != null; + } + + private Collection getAllSubFiles(VirtualFile virtualFile) + { + Collection list = new ArrayList<>(); + + if (null == virtualFile) { + return list; + } + + VfsUtilCore.visitChildrenRecursively(virtualFile, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!file.isDirectory()) { + list.add(file); + } + return super.visitFile(file); + } + }); + return list; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/LayoutBlockReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/LayoutBlockReferenceProvider.java new file mode 100644 index 000000000..1e79a0592 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/LayoutBlockReferenceProvider.java @@ -0,0 +1,27 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class LayoutBlockReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + String value = StringUtil.unquoteString(element.getText()); + List targets = LayoutIndex.getBlockDeclarations(value, element.getProject()); + if (targets.size() > 0) { + return new PsiReference[] {new PolyVariantReferenceBase(element, targets)}; + } + return PsiReference.EMPTY_ARRAY; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/LayoutContainerReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/LayoutContainerReferenceProvider.java new file mode 100644 index 000000000..1b591c026 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/LayoutContainerReferenceProvider.java @@ -0,0 +1,30 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class LayoutContainerReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + String value = StringUtil.unquoteString(element.getText()); + List targets = LayoutIndex.getContainerDeclarations(value, element.getProject()); + if (targets.size() > 0) { + return new PsiReference[] {new PolyVariantReferenceBase(element, targets)}; + } + return PsiReference.EMPTY_ARRAY; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/LayoutUpdateReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/LayoutUpdateReferenceProvider.java new file mode 100644 index 000000000..11bd788a2 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/LayoutUpdateReferenceProvider.java @@ -0,0 +1,27 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.xml.XmlFile; +import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class LayoutUpdateReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + String value = StringUtil.unquoteString(element.getText()); + List targets = LayoutIndex.getLayoutFiles(element.getProject(), value); + if (targets.size() > 0) { + return new PsiReference[] {new PolyVariantReferenceBase(element, targets)}; + } + return PsiReference.EMPTY_ARRAY; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/ModuleNameReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/ModuleNameReferenceProvider.java new file mode 100644 index 000000000..b76e4cc27 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/ModuleNameReferenceProvider.java @@ -0,0 +1,74 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.lang.PhpFileType; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ModuleNameReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + + List psiReferences = new ArrayList<>(); + String origValue = element.getText(); + + Pattern pattern = Pattern.compile("(([A-Z][a-zA-Z0-9]+)_([A-Z][a-zA-Z0-9]+))"); + Matcher matcher = pattern.matcher(element.getText()); + if (!matcher.find()) { + return PsiReference.EMPTY_ARRAY; + } + + String moduleName = matcher.group(1); + + Collection moduleFiles = FileBasedIndex.getInstance() + .getContainingFiles(ModuleNameIndex.KEY, moduleName, + GlobalSearchScope.getScopeRestrictedByFileTypes( + GlobalSearchScope.allScope(element.getProject()), + PhpFileType.INSTANCE + ) + ); + + PsiManager psiManager = PsiManager.getInstance(element.getProject()); + List psiElements = new ArrayList<>(); + + for (VirtualFile moduleVf : moduleFiles) { + if (moduleVf.getParent() == null) { + continue; + } + VirtualFile moduleSourceVf = moduleVf.getParent(); + if (!moduleSourceVf.isDirectory()) { + continue; + } + + PsiDirectory moduleSourceDirectory = psiManager.findDirectory(moduleSourceVf); + if (null == moduleSourceDirectory) { + continue; + } + + psiElements.add(moduleSourceDirectory); + } + + if (psiElements.size() > 0) { + TextRange range = new TextRange( + origValue.indexOf(moduleName), origValue.indexOf(moduleName) + moduleName.length() + ); + psiReferences.add(new PolyVariantReferenceBase(element, range, psiElements)); + } + + return psiReferences.toArray(new PsiReference[psiReferences.size()]); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/PhpClassMemberReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/PhpClassMemberReferenceProvider.java new file mode 100644 index 000000000..2f56169ad --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/PhpClassMemberReferenceProvider.java @@ -0,0 +1,58 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.elements.PhpClassMember; +import com.magento.idea.magento2plugin.php.util.PhpRegex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PhpClassMemberReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + List psiReferences = new ArrayList<>(); + final Collection members = new THashSet<>(); + + String origValue = element.getText(); + String value = StringUtil.unquoteString(element.getText()); + + Matcher matcher = Pattern.compile(PhpRegex.Xml.CLASS_MEMBER_NAME).matcher(value); + if (!matcher.find()) { + return PsiReference.EMPTY_ARRAY; + } + + String elementName = matcher.group(1); + String classFQN = value.substring(0, value.lastIndexOf("::")); + + PhpIndex phpIndex = PhpIndex.getInstance(element.getProject()); + for (final PhpClass phpClass : phpIndex.getAnyByFQN(classFQN)) { + members.addAll(phpClass.getFields()); + members.addAll(phpClass.getMethods()); + members.removeIf(c -> !c.getName().equals(elementName)); + } + + if (members.size() > 0) { + TextRange range = new TextRange( + origValue.indexOf(elementName), + origValue.indexOf(elementName) + elementName.length() + ); + psiReferences.add(new PolyVariantReferenceBase(element, range, members)); + } + return psiReferences.toArray(new PsiReference[psiReferences.size()]); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java new file mode 100644 index 000000000..5eb0b258a --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java @@ -0,0 +1,70 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.elements.PhpNamespace; +import com.magento.idea.magento2plugin.php.util.PhpRegex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PhpClassReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + List psiReferences = new ArrayList<>(); + + String origValue = element.getText(); + + Pattern pattern = Pattern.compile(PhpRegex.Xml.CLASS_NAME); + Matcher matcher = pattern.matcher(origValue); + if (!matcher.find()) { + return PsiReference.EMPTY_ARRAY; + } + + String classFQN = matcher.group(); + String[] fqnParts = classFQN.split("\\\\"); + + PhpIndex phpIndex = PhpIndex.getInstance(element.getProject()); + + StringBuilder namespace = new StringBuilder(); + String namespacePart; + for (int i = 0; i < fqnParts.length - 1; i++) { + namespacePart = fqnParts[i]; + + namespace.append("\\"); + namespace.append(namespacePart); + Collection references = phpIndex.getNamespacesByName(namespace.toString().toLowerCase()); + if (references.size() > 0) { + TextRange range = new TextRange( + origValue.indexOf(classFQN) + namespace.toString().lastIndexOf(92), + origValue.indexOf(classFQN) + namespace.toString().lastIndexOf(92) + namespacePart.length() + ); + psiReferences.add(new PolyVariantReferenceBase(element, range, references)); + } + } + + String className = classFQN.substring(classFQN.lastIndexOf(92) + 1); + Collection classes = phpIndex.getAnyByFQN(classFQN); + if (classes.size() > 0) { + TextRange range = new TextRange( + origValue.lastIndexOf(92) + 1, + origValue.lastIndexOf(92) + 1 + className.length() + ); + psiReferences.add(new PolyVariantReferenceBase(element, range, classes)); + } + + return psiReferences.toArray(new PsiReference[psiReferences.size()]); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/PhpConstructorArgumentReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/PhpConstructorArgumentReferenceProvider.java new file mode 100644 index 000000000..f92d3e73c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/PhpConstructorArgumentReferenceProvider.java @@ -0,0 +1,47 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.xml.XmlElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.Parameter; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.indexes.DiIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.Collection; + +public class PhpConstructorArgumentReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + + String parameterName = StringUtil.unquoteString(element.getText()); + if (parameterName.isEmpty() || !(element instanceof XmlElement)) { + return PsiReference.EMPTY_ARRAY; + } + + + DiIndex diIndex = DiIndex.getInstance(element.getProject()); + PhpClass phpClass = diIndex.getPhpClassOfArgument((XmlElement) element); + if (phpClass != null) { + Method constructor = phpClass.getConstructor(); + if (constructor != null) { + Collection parameterList = new THashSet<>(Arrays.asList(constructor.getParameters())); + parameterList.removeIf(p -> !p.getName().contains(parameterName)); + if (parameterList.size() > 0) { + return new PsiReference[] {new PolyVariantReferenceBase(element, parameterList)}; + } + } + } + + return PsiReference.EMPTY_ARRAY; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/PhpServiceMethodReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/PhpServiceMethodReferenceProvider.java new file mode 100644 index 000000000..70eb645ec --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/PhpServiceMethodReferenceProvider.java @@ -0,0 +1,41 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.xml.XmlElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.lang.psi.elements.Method; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.indexes.DiIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class PhpServiceMethodReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + if (!(element instanceof XmlElement)) { + return PsiReference.EMPTY_ARRAY; + } + + List psiReferences = new ArrayList<>(); + + String methodName = StringUtil.unquoteString(element.getText()); + + PhpClass phpClass = DiIndex.getPhpClassOfServiceMethod((XmlElement) element); + if (phpClass != null) { + Collection methods = phpClass.getMethods(); + methods.removeIf(m -> !m.getName().equalsIgnoreCase(methodName)); + psiReferences.add(new PolyVariantReferenceBase(element, methods)); + } + + return psiReferences.toArray(new PsiReference[psiReferences.size()]); + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/provider/VirtualTypeReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/VirtualTypeReferenceProvider.java new file mode 100644 index 000000000..787bec437 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/provider/VirtualTypeReferenceProvider.java @@ -0,0 +1,33 @@ +package com.magento.idea.magento2plugin.reference.provider; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.indexes.DiIndex; +import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class VirtualTypeReferenceProvider extends PsiReferenceProvider { + + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + + String value = StringUtil.unquoteString(element.getText()); + + DiIndex index = DiIndex.getInstance(element.getProject()); + Collection targets = index.getVirtualTypeElements(value, element.getResolveScope()); + + if (!(targets.size() > 0)) { + return PsiReference.EMPTY_ARRAY; + } + + return new PsiReference[] { + new PolyVariantReferenceBase(element, targets) + }; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/xml/PolyVariantReferenceBase.java b/src/com/magento/idea/magento2plugin/reference/xml/PolyVariantReferenceBase.java new file mode 100644 index 000000000..ca98f5404 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/xml/PolyVariantReferenceBase.java @@ -0,0 +1,46 @@ +package com.magento.idea.magento2plugin.reference.xml; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.PsiPolyVariantReferenceBase; +import com.intellij.psi.ResolveResult; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class PolyVariantReferenceBase extends PsiPolyVariantReferenceBase { + + /** + * Target elements + */ + private Collection targets; + + public PolyVariantReferenceBase(PsiElement element, Collection targets) { + super(element); + this.targets = targets; + } + + public PolyVariantReferenceBase(PsiElement element, TextRange range, Collection targets) { + super(element, range); + this.targets = targets; + } + + @NotNull + @Override + public ResolveResult[] multiResolve(boolean incompleteCode) { + ResolveResult[] resolveResults = new ResolveResult[targets.size()]; + + int i = 0; + for (PsiElement target : targets) { + resolveResults[i++] = new PsiElementResolveResult(target); + } + return resolveResults; + } + + @NotNull + @Override + public Object[] getVariants() { + return new Object[0]; + } +} diff --git a/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java b/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java new file mode 100644 index 000000000..ffa4eca63 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/reference/xml/XmlReferenceContributor.java @@ -0,0 +1,156 @@ +package com.magento.idea.magento2plugin.reference.xml; + +import com.intellij.patterns.XmlPatterns; +import com.intellij.psi.PsiReferenceContributor; +import com.intellij.psi.PsiReferenceRegistrar; +import com.intellij.psi.xml.XmlTokenType; +import com.magento.idea.magento2plugin.php.util.PhpRegex; +import com.magento.idea.magento2plugin.reference.provider.*; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.patterns.XmlPatterns.string; +import static com.intellij.patterns.XmlPatterns.xmlFile; + +public class XmlReferenceContributor extends PsiReferenceContributor { + + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { + + // + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withValue(string().matches(PhpRegex.Xml.CLASS_ELEMENT)), + new CompositeReferenceProvider( + new PhpClassReferenceProvider(), + new PhpClassMemberReferenceProvider() + ) + ); + + // Some\Php\ClassName[::CONST|$property|method()] + registrar.registerReferenceProvider( + XmlPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withText(string().matches(PhpRegex.Xml.CLASS_ELEMENT)), + new CompositeReferenceProvider( + new PhpClassReferenceProvider(), + new PhpClassMemberReferenceProvider() + ) + ); + + // virtual type references + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName("type")).inFile(xmlFile().withName(string().endsWith("di.xml")) + ), + new VirtualTypeReferenceProvider() + ); + registrar.registerReferenceProvider( + XmlPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS).withParent( + XmlPatterns.xmlText().withParent( + XmlPatterns.xmlTag().withChild( + XmlPatterns.xmlAttribute().withName("xsi:type") + ) + ) + ).inFile(xmlFile().withName(string().endsWith("di.xml"))), + new VirtualTypeReferenceProvider() + ); + + // arguments + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName("name").withParent( + XmlPatterns.xmlTag().withName("argument").withParent( + XmlPatterns.xmlTag().withName("arguments") + ) + ) + ).inFile(xmlFile().withName(string().endsWith("di.xml"))), + new PhpConstructorArgumentReferenceProvider() + ); + + // + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName("method").withParent( + XmlPatterns.xmlTag().withName("service") + ) + ).inFile(xmlFile().withName(string().endsWith("webapi.xml"))), + new PhpServiceMethodReferenceProvider() + ); + + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName("name").withParent( + XmlPatterns.xmlTag().withName("referenceContainer") + ) + ), + new LayoutContainerReferenceProvider() + ); + + registrar.registerReferenceProvider( + XmlPatterns.or( + XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("referenceBlock"))), + XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute() + .withName(string().oneOf("before", "after")) + .withParent(XmlPatterns.xmlTag().withName("block"))), + XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute() + .withName(string().oneOf("before", "after", "destination", "element")) + .withParent(XmlPatterns.xmlTag().withName("move"))), + XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute().withName("name") + .withParent(XmlPatterns.xmlTag().withName("remove"))) + ), + new LayoutBlockReferenceProvider() + ); + + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName("handle").withParent( + XmlPatterns.xmlTag().withName("update") + ) + ), + new LayoutUpdateReferenceProvider() + ); + + // + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withParent( + XmlPatterns.xmlAttribute().withName("name").withParent( + XmlPatterns.xmlTag().withName("event") + ) + ), + new EventNameReferenceProvider() + ); + + // + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withValue(string().matches(".*[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+.*")), + new CompositeReferenceProvider( + new ModuleNameReferenceProvider() + ) + ); + + // Module_Name[.*] + registrar.registerReferenceProvider( + XmlPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withText(string().matches(".*[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+.*")), + new CompositeReferenceProvider( + new ModuleNameReferenceProvider() + ) + ); + + // + registrar.registerReferenceProvider( + XmlPatterns.xmlAttributeValue().withValue(string().matches(".*\\W([\\w-]+/)*[\\w\\.-]+.*")), + new CompositeReferenceProvider( + new FilePathReferenceProvider() + ) + ); + + // path/to/some-of-file.some-ext + registrar.registerReferenceProvider( + XmlPatterns.psiElement(XmlTokenType.XML_DATA_CHARACTERS) + .withText(string().matches(".*\\W([\\w-]+/)*[\\w\\.-]+.*")), + new CompositeReferenceProvider( + new FilePathReferenceProvider() + ) + ); + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/BlockClassNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/BlockClassNameIndex.java new file mode 100644 index 000000000..28b2c8a8d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/BlockClassNameIndex.java @@ -0,0 +1,27 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import com.jetbrains.php.lang.PhpLangUtil; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/20/15. + */ +public class BlockClassNameIndex extends NamedComponentIndex { + public static final ID KEY = + ID.create("com.magento.idea.magento2plugin.stubs.indexes.block_class_name"); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new LayoutDataIndexer("block", "class", PhpLangUtil::toPresentableFQN); + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/BlockNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/BlockNameIndex.java new file mode 100644 index 000000000..46ebc25bc --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/BlockNameIndex.java @@ -0,0 +1,25 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class BlockNameIndex extends NamedComponentIndex { + public static final ID KEY = ID.create("com.magento.idea.magento2plugin.stubs.indexes.block_name"); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new LayoutDataIndexer("block", "name"); + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/ContainerNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/ContainerNameIndex.java new file mode 100644 index 000000000..0c32f20c8 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/ContainerNameIndex.java @@ -0,0 +1,31 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/18/15. + */ +public class ContainerNameIndex extends NamedComponentIndex { + public static final ID KEY = + ID.create("com.magento.idea.magento2plugin.stubs.indexes.container_name"); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new LayoutDataIndexer("container", "name"); + } + + @Override + public int getVersion() { + return 1; + } +} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/EventNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/EventNameIndex.java new file mode 100644 index 000000000..58acf2b5d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/EventNameIndex.java @@ -0,0 +1,133 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpFileType; +import com.jetbrains.php.lang.psi.PhpFile; +import com.jetbrains.php.lang.psi.elements.MethodReference; +import com.jetbrains.php.lang.psi.elements.ParameterList; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.php.util.PhpPatternsHelper; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by dkvashnin on 11/5/15. + */ +public class EventNameIndex extends ScalarIndexExtension { + public static final ID KEY = ID.create("com.magento.idea.magento2plugin.stubs.indexes.event_name"); + private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return inputData -> { + Map map = new HashMap<>(); + PsiFile psiFile = inputData.getPsiFile(); + + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + + if (psiFile instanceof PhpFile) { + grabEventNamesFromPhpFile((PhpFile) psiFile, map); + } else if (psiFile instanceof XmlFile) { + grabEventNamesFromXmlFile((XmlFile) psiFile, map); + } + + return map; + }; + } + + private void grabEventNamesFromPhpFile(PhpFile file, Map map) { + List results = new ArrayList<>(); + recursiveFill(results, file); + for (String result: results) { + map.put(result, null); + } + } + + private void recursiveFill(List results, PsiElement psiElement) { + if (PhpPatternsHelper.STRING_METHOD_ARGUMENT.accepts(psiElement) && isInContextOfDispatchMethod(psiElement)) { + String eventName= StringUtil.unquoteString(psiElement.getText()); + if (eventName.length() > 0) { + results.add(eventName); + } + return; + } + for(PsiElement child: psiElement.getChildren()) { + recursiveFill(results, child); + } + } + + private boolean isInContextOfDispatchMethod(PsiElement psiElement) { + ParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, ParameterList.class); + if (parameterList == null) { + return false; + } + if (!(parameterList.getContext() instanceof MethodReference)) { + return false; + } + MethodReference methodReference = (MethodReference)parameterList.getContext(); + return methodReference.getName() != null && methodReference.getName().equals("dispatch"); + } + + private void grabEventNamesFromXmlFile(XmlFile file, Map map) { + XmlDocument xmlDocument = file.getDocument(); + if (xmlDocument != null) { + XmlTag xmlRootTag = xmlDocument.getRootTag(); + if (xmlRootTag != null) { + for (XmlTag eventTag : xmlRootTag.findSubTags("event")) { + String name = eventTag.getAttributeValue("name"); + if (name != null && !name.isEmpty()) { + map.put(name, null); + } + } + } + } + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return file -> ( + file.getFileType() == PhpFileType.INSTANCE + || (file.getFileType() == XmlFileType.INSTANCE && file.getName().equals("events.xml")) + ); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/EventObserverIndex.java similarity index 65% rename from src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java rename to src/com/magento/idea/magento2plugin/stubs/indexes/EventObserverIndex.java index 46a4e3ece..0c309120a 100644 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventObserverFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/EventObserverIndex.java @@ -1,33 +1,37 @@ -package com.magento.idea.magento2plugin.xml.observer.index; +package com.magento.idea.magento2plugin.stubs.indexes; import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.xml.XmlDocumentImpl; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; +import com.jetbrains.php.lang.psi.stubs.indexes.StringSetDataExternalizer; +import com.magento.idea.magento2plugin.project.Settings; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * Created by dkvashnin on 11/2/15. */ -public class EventObserverFileBasedIndex extends FileBasedIndexExtension> { - public static final ID> NAME = ID.create("com.magento.idea.magento2plugin.xml.observer.index.event_observer"); +public class EventObserverIndex extends FileBasedIndexExtension> { + public static final ID> KEY = + ID.create("com.magento.idea.magento2plugin.stubs.indexes.event_observer"); private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); @NotNull @Override public ID> getName() { - return NAME; + return KEY; } @NotNull @@ -44,24 +48,25 @@ public Map> map(@NotNull FileContent fileContent) { return map; } - XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); - if(document == null) { + if (!(psiFile instanceof XmlFile)) { + return map; + } + + XmlDocument document = ((XmlFile) psiFile).getDocument(); + if (document == null) { return map; } XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); - if(xmlTags == null) { + if (xmlTags == null) { return map; } - for(XmlTag xmlTag: xmlTags) { - if(xmlTag.getName().equals("config")) { - for(XmlTag eventNode: xmlTag.findSubTags("event")) { + for (XmlTag xmlTag: xmlTags) { + if (xmlTag.getName().equals("config")) { + for (XmlTag eventNode: xmlTag.findSubTags("event")) { if (eventNode.getAttributeValue("name") != null) { - map.put( - eventNode.getAttributeValue("name"), - getObserversForEvent(eventNode) - ); + map.put(eventNode.getAttributeValue("name"), getObserversForEvent(eventNode)); } } } @@ -100,12 +105,7 @@ public DataExternalizer> getValueExternalizer() { @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("events"); - } - }; + return file -> (file.getFileType() == XmlFileType.INSTANCE && file.getName().equals("events.xml")); } @Override diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java b/src/com/magento/idea/magento2plugin/stubs/indexes/LayoutDataIndexer.java similarity index 59% rename from src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java rename to src/com/magento/idea/magento2plugin/stubs/indexes/LayoutDataIndexer.java index c7869fc7d..35f76dd65 100644 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/LayoutDataIndexer.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/LayoutDataIndexer.java @@ -1,30 +1,39 @@ -package com.magento.idea.magento2plugin.xml.layout.index; +package com.magento.idea.magento2plugin.stubs.indexes; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.xml.XmlDocumentImpl; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.DataIndexer; import com.intellij.util.indexing.FileContent; -import com.jetbrains.php.lang.PhpLangUtil; -import com.magento.idea.magento2plugin.Settings; +import com.magento.idea.magento2plugin.project.Settings; import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; /** * Created by dkvashnin on 11/18/15. */ public class LayoutDataIndexer implements DataIndexer { private String indexTag; + private String indexAttribute; - public LayoutDataIndexer(String indexTag, String indexAttribute) { + private Function valueProcessor; + + LayoutDataIndexer(String indexTag, String indexAttribute) { this.indexTag = indexTag; this.indexAttribute = indexAttribute; } + LayoutDataIndexer(String indexTag, String indexAttribute, Function valueProcessor) { + this(indexTag, indexAttribute); + this.valueProcessor = valueProcessor; + } + @NotNull @Override public Map map(@NotNull FileContent fileContent) { @@ -35,13 +44,17 @@ public Map map(@NotNull FileContent fileContent) { return map; } - XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); - if(document == null) { + if (!(psiFile instanceof XmlFile)) { + return map; + } + + XmlDocument document = ((XmlFile) psiFile).getDocument(); + if (document == null) { return map; } XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); - if(xmlTags == null) { + if (xmlTags == null) { return map; } @@ -54,10 +67,11 @@ public Map map(@NotNull FileContent fileContent) { private void fillResultMap(XmlTag parentTag, Map resultMap) { for (XmlTag childTag: parentTag.getSubTags()) { - if (indexTag.equals(childTag.getName())) { - String attributeValue = childTag.getAttributeValue(this.indexAttribute); + if (childTag.getName().equals(indexTag)) { + String attributeValue = childTag.getAttributeValue(indexAttribute); if (attributeValue != null) { - resultMap.put(PhpLangUtil.toPresentableFQN(attributeValue), null); + attributeValue = valueProcessor != null ? valueProcessor.apply(attributeValue) : attributeValue; + resultMap.put(attributeValue, null); } } fillResultMap(childTag, resultMap); diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java new file mode 100644 index 000000000..6500440b3 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java @@ -0,0 +1,88 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpFileType; +import com.jetbrains.php.lang.psi.PhpFile; +import com.jetbrains.php.lang.psi.elements.*; +import com.magento.idea.magento2plugin.project.Settings; +import org.jetbrains.annotations.NotNull; + + +import java.util.HashMap; +import java.util.Map; + +public class ModuleNameIndex extends ScalarIndexExtension { + public static final ID KEY = + ID.create("com.magento.idea.magento2plugin.stubs.indexes.module_name"); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return inputData -> { + Map map = new HashMap<>(); + PsiFile psiFile = inputData.getPsiFile(); + + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + + if (psiFile instanceof PhpFile) { + MethodReference method = PsiTreeUtil.findChildOfAnyType(psiFile, MethodReference.class); + if (method != null) { + ParameterList parameterList = method.getParameterList(); + if (parameterList != null) { + PsiElement firstParameter = parameterList.getFirstPsiChild(); + if (firstParameter != null && firstParameter instanceof ClassConstantReference) { + String constantName = ((ClassConstantReference) firstParameter).getName(); + if (constantName != null && constantName.equalsIgnoreCase("module")) { + PsiElement moduleName = ((ClassConstantReference) firstParameter).getNextPsiSibling(); + if (moduleName != null && moduleName instanceof StringLiteralExpression) { + map.put(StringUtil.unquoteString(moduleName.getText()), null); + } + } + } + } + } + } + + return map; + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return new EnumeratorStringDescriptor(); + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return virtualFile -> ( + virtualFile.getFileType().equals(PhpFileType.INSTANCE) + && virtualFile.getName().equals("registration.php") + ); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/ModulePackageIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/ModulePackageIndex.java new file mode 100644 index 000000000..63b71f694 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/ModulePackageIndex.java @@ -0,0 +1,89 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.json.JsonFileType; +import com.intellij.json.psi.JsonFile; +import com.intellij.json.psi.JsonObject; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; +import com.magento.idea.magento2plugin.php.module.ComposerPackageModelImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by dkvashnin on 12/3/15. + */ +public class ModulePackageIndex extends ScalarIndexExtension { + public static final ID KEY = + ID.create("com.magento.idea.magento2plugin.stubs.indexes.module_package"); + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return inputData -> { + Map map = new HashMap<>(); + JsonFile jsonFile = (JsonFile)inputData.getPsiFile(); + if (!Settings.isEnabled(jsonFile.getProject())) { + return map; + } + + JsonObject jsonObject = PsiTreeUtil.getChildOfType(jsonFile, JsonObject.class); + if (jsonObject == null) { + return map; + } + ComposerPackageModel composerObject = new ComposerPackageModelImpl(jsonObject); + + String type = composerObject.getType(); + if (type == null) { + return map; + } + + if (!type.startsWith("magento2-")) { + return map; + } + + String name = composerObject.getName(); + + if (name != null) { + map.put(name, null); + } + + return map; + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return new EnumeratorStringDescriptor(); + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return virtualFile -> ( + virtualFile.getFileType().equals(JsonFileType.INSTANCE) && virtualFile.getName().equals("composer.json") + ); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/NamedComponentIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/NamedComponentIndex.java new file mode 100644 index 000000000..270568d6d --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/NamedComponentIndex.java @@ -0,0 +1,37 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.ScalarIndexExtension; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.magento.idea.magento2plugin.indexes.LayoutIndex; +import org.jetbrains.annotations.NotNull; + +/** + * Created by dkvashnin on 11/18/15. + */ +public abstract class NamedComponentIndex extends ScalarIndexExtension { + private EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return LayoutIndex::isLayoutFile; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 0; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/PluginIndex.java similarity index 66% rename from src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java rename to src/com/magento/idea/magento2plugin/stubs/indexes/PluginIndex.java index c0048a4dc..1af8ee201 100644 --- a/src/com/magento/idea/magento2plugin/xml/di/index/PluginToTypeFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/PluginIndex.java @@ -1,33 +1,37 @@ -package com.magento.idea.magento2plugin.xml.di.index; +package com.magento.idea.magento2plugin.stubs.indexes; import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.source.xml.XmlDocumentImpl; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; +import com.jetbrains.php.lang.psi.stubs.indexes.StringSetDataExternalizer; +import com.magento.idea.magento2plugin.project.Settings; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * Created by dkvashnin on 11/10/15. */ -public class PluginToTypeFileBasedIndex extends FileBasedIndexExtension> { - public static final ID> NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.plugin_to_type"); +public class PluginIndex extends FileBasedIndexExtension> { + public static final ID> KEY + = ID.create("com.magento.idea.magento2plugin.stubs.indexes.plugin_to_type"); private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); @NotNull @Override public ID> getName() { - return NAME; + return KEY; } @NotNull @@ -44,27 +48,27 @@ public Map> map(@NotNull FileContent fileContent) { return map; } - XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); + if (!(psiFile instanceof XmlFile)) { + return map; + } + XmlDocument document = ((XmlFile) psiFile).getDocument(); if(document == null) { return map; } XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); - if(xmlTags == null) { + if (xmlTags == null) { return map; } - for(XmlTag xmlTag: xmlTags) { - if(xmlTag.getName().equals("config")) { - for(XmlTag typeNode: xmlTag.findSubTags("type")) { + for (XmlTag xmlTag: xmlTags) { + if (xmlTag.getName().equals("config")) { + for (XmlTag typeNode: xmlTag.findSubTags("type")) { String typeName = typeNode.getAttributeValue("name"); if (typeName != null) { Set plugins = getPluginsForType(typeNode); - if (plugins.size() != 0) { - map.put( - PhpLangUtil.toPresentableFQN(typeName), - getPluginsForType(typeNode) - ); + if (plugins.size() > 0) { + map.put(PhpLangUtil.toPresentableFQN(typeName), plugins); } } } @@ -103,12 +107,8 @@ public DataExternalizer> getValueExternalizer() { @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("di"); - } - }; + return virtualFile -> (virtualFile.getFileType() == XmlFileType.INSTANCE + && virtualFile.getNameWithoutExtension().equals("di")); } @Override diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/TypeConfigurationIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/TypeConfigurationIndex.java new file mode 100644 index 000000000..6ffc8e2e6 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/TypeConfigurationIndex.java @@ -0,0 +1,300 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.*; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.jetbrains.php.lang.PhpLangUtil; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.xml.LineMarkerXmlTagDecorator; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * Created by dkvashnin on 11/15/15. + */ +public class TypeConfigurationIndex extends ScalarIndexExtension { + public static final ID KEY = + ID.create("com.magento.idea.magento2plugin.stubs.indexes.type_configuration"); + private final EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + private static final String TYPE_TAG = "type"; + private static final String PLUGIN_TAG = "plugin"; + private static final String VIRTUAL_TYPE_TAG = "virtualType"; + private static final String PREFERENCE_TAG = "preference"; + private static final String NAME_ATTRIBUTE = "name"; + private static final String TYPE_ATTRIBUTE = "type"; + private static final String FOR_ATTRIBUTE = "for"; + + private static final Map TAG_ATTRIBUTE_RELATION = new HashMap() {{ + put(TYPE_TAG, NAME_ATTRIBUTE); + put(PREFERENCE_TAG, FOR_ATTRIBUTE); + put(PLUGIN_TAG, TYPE_ATTRIBUTE); + put(VIRTUAL_TYPE_TAG, TYPE_ATTRIBUTE); + put("event", null); + put("observer", "instance"); + }}; + + public static List getClassConfigurations(PhpClass phpClass) { + String classFqn = phpClass.getPresentableFQN(); + + Collection containingFiles = FileBasedIndex.getInstance() + .getContainingFiles(KEY, classFqn, GlobalSearchScope.allScope(phpClass.getProject()) + ); + + PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); + + List tags = new ArrayList(); + + for (VirtualFile virtualFile: containingFiles) { + XmlFile file = (XmlFile)psiManager.findFile(virtualFile); + + if (file == null) { + continue; + } + + XmlTag rootTag = file.getRootTag(); + fillRelatedTags(classFqn, rootTag, tags); + } + + return tags; + } + + private static void fillRelatedTags(String classFqn, XmlTag parentTag, List tagsReferences) { + for (XmlTag childTag: parentTag.getSubTags()) { + String tagName = childTag.getName(); + String attribute = TAG_ATTRIBUTE_RELATION.get(tagName); + if (attribute != null) { + String className = childTag.getAttributeValue(attribute); + if (className != null && PhpLangUtil.toPresentableFQN(className).equals(classFqn)) { + tagsReferences.add(getLineMarkerDecorator(childTag)); + } + } + + // type tag has plugin tags + if (tagName.equals(TYPE_TAG)) { + fillRelatedTags(classFqn, childTag, tagsReferences); + } + + if (tagName.equals("event")) { + fillRelatedTags(classFqn, childTag, tagsReferences); + } + } + } + + /** + * Decorate tag with appropriate line marker decorator. + */ + @NotNull + private static XmlTag getLineMarkerDecorator(XmlTag tag) { + switch (tag.getName()) { + case PREFERENCE_TAG: + return new DiPreferenceLineMarkerXmlTagDecorator(tag); + case TYPE_TAG: + return new DiTypeLineMarkerXmlTagDecorator(tag); + case PLUGIN_TAG: + return new DiPluginLineMarkerXmlTagDecorator(tag); + case VIRTUAL_TYPE_TAG: + return new DiVirtualTypeLineMarkerXmlTagDecorator(tag); + default: + return tag; + } + } + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public DataIndexer getIndexer() { + return new DataIndexer() { + @NotNull + @Override + public Map map(@NotNull FileContent fileContent) { + Map map = new HashMap<>(); + + PsiFile psiFile = fileContent.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + + if (!(psiFile instanceof XmlFile)) { + return map; + } + XmlDocument document = ((XmlFile) psiFile).getDocument(); + if (document == null) { + return map; + } + + XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if (xmlTags == null) { + return map; + } + + for (XmlTag xmlTag: xmlTags) { + if (xmlTag.getName().equals("config")) { + processConfigurationTags(xmlTag, map); + } + } + + return map; + } + + private void processConfigurationTags(XmlTag parentTag, Map results) { + for (XmlTag childTag: parentTag.getSubTags()) { + String tagName = childTag.getName(); + + String attribute = TAG_ATTRIBUTE_RELATION.get(tagName); + if (attribute != null) { + String className = childTag.getAttributeValue(attribute); + if (className != null) { + results.put(PhpLangUtil.toPresentableFQN(className), null); + } + } + + // type tag has plugin tags + if (tagName.equals(TYPE_TAG)) { + processConfigurationTags(childTag, results); + } + + if (tagName.equals("event")) { + processConfigurationTags(childTag, results); + } + } + } + }; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return myKeyDescriptor; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return virtualFile -> (virtualFile.getFileType() + == XmlFileType.INSTANCE + && (virtualFile.getNameWithoutExtension().equalsIgnoreCase("di") + || virtualFile.getNameWithoutExtension().equalsIgnoreCase("events")) + ); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 0; + } + + /** + * Decorator for XmlTag, which improves readability of "preference" node in configuration line marker. + */ + private static class DiPreferenceLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + DiPreferenceLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @NotNull + @Override + public String getDescription() { + String preference = xmlTag.getAttributeValue(TYPE_ATTRIBUTE); + if (preference != null) { + return String.format("preference %s", preference); + } + return xmlTag.getName(); + } + + @Override + @NotNull + @NonNls + public String getName() { + String preference = xmlTag.getAttributeValue(TYPE_ATTRIBUTE); + if (preference != null) { + return String.format("[%s] preference %s", getAreaName(), preference); + } + return xmlTag.getName(); + } + } + + /** + * Decorator for XmlTag, which improves readability of "type" node in configuration line marker. + */ + private static class DiTypeLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + DiTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @NotNull + @Override + public String getDescription() { + return "type declaration"; + } + } + + /** + * Decorator for XmlTag, which improves readability of "plugin" node in configuration line marker. + */ + private static class DiPluginLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + DiPluginLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @NotNull + @Override + public String getDescription() { + XmlTag typeTag = xmlTag.getParentTag(); + if (typeTag == null) { + return xmlTag.getName(); + } + String type = typeTag.getAttributeValue(NAME_ATTRIBUTE); + if (type == null) { + return xmlTag.getName(); + } + + return String.format("plugin for %s", type); + } + } + + /** + * Decorator for XmlTag, which improves readability of "virtualType" node in configuration line marker. + */ + private static class DiVirtualTypeLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + + DiVirtualTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } + + @NotNull + @Override + public String getDescription() { + String type = xmlTag.getAttributeValue(NAME_ATTRIBUTE); + if (type != null) { + return String.format("virtual type %s", type); + } + return xmlTag.getName(); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/VirtualTypeIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/VirtualTypeIndex.java new file mode 100644 index 000000000..636f2b5fd --- /dev/null +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/VirtualTypeIndex.java @@ -0,0 +1,87 @@ +package com.magento.idea.magento2plugin.stubs.indexes; + +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.psi.PsiFile; +import com.intellij.psi.xml.XmlDocument; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.indexing.*; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.EnumeratorStringDescriptor; +import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.xml.impl.DomApplicationComponent; +import com.magento.idea.magento2plugin.project.Settings; +import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public class VirtualTypeIndex extends FileBasedIndexExtension { + public static final ID KEY = ID.create( + "com.magento.idea.magento2plugin.stubs.indexes.virtual_type"); + private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); + + @NotNull + @Override + public DataIndexer getIndexer() { + return inputData -> { + Map map = new THashMap<>(); + PsiFile psiFile = inputData.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } + + if (psiFile instanceof XmlFile) { + XmlDocument xmlDocument = ((XmlFile) psiFile).getDocument(); + if (xmlDocument != null) { + XmlTag xmlRootTag = xmlDocument.getRootTag(); + if (xmlRootTag != null) { + for (XmlTag virtualTypeTag : xmlRootTag.findSubTags("virtualType")) { + String name = virtualTypeTag.getAttributeValue("name"); + String type = virtualTypeTag.getAttributeValue("type"); + + if (name != null && type != null && !name.isEmpty() && !type.isEmpty()) { + map.put(name, type); + } + } + } + } + } + return map; + }; + } + + @NotNull + @Override + public ID getName() { + return KEY; + } + + @NotNull + @Override + public KeyDescriptor getKeyDescriptor() { + return this.myKeyDescriptor; + } + + @NotNull + public DataExternalizer getValueExternalizer() { + return EnumeratorStringDescriptor.INSTANCE; + } + + @NotNull + @Override + public FileBasedIndex.InputFilter getInputFilter() { + return file -> + file.getFileType() == XmlFileType.INSTANCE && file.getName().equalsIgnoreCase("di.xml"); + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return DomApplicationComponent.getInstance().getCumulativeVersion(false); + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java similarity index 52% rename from src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java rename to src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java index b4809ad30..b0192d266 100644 --- a/src/com/magento/idea/magento2plugin/xml/webapi/index/WebApiTypesFileBasedIndex.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java @@ -1,12 +1,12 @@ -package com.magento.idea.magento2plugin.xml.webapi.index; +package com.magento.idea.magento2plugin.stubs.indexes; import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.source.xml.XmlDocumentImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.XmlDocument; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.indexing.*; @@ -15,8 +15,8 @@ import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; +import com.magento.idea.magento2plugin.project.Settings; +import com.magento.idea.magento2plugin.xml.LineMarkerXmlTagDecorator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -25,57 +25,56 @@ /** * Indexer for classes/interfaces which have methods exposed via Web API. */ -public class WebApiTypesFileBasedIndex extends ScalarIndexExtension { +public class WebApiTypeIndex extends ScalarIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.webapi.index.webapi_types"); + public static final ID KEY = ID.create("com.magento.idea.magento2plugin.stubs.indexes.webapi_type"); private final KeyDescriptor keyDescriptor = new EnumeratorStringDescriptor(); @NotNull @Override public ID getName() { - return NAME; + return KEY; } @NotNull @Override public DataIndexer getIndexer() { - return new DataIndexer() { + return inputData -> { + Map map = new HashMap<>(); - @NotNull - @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); + PsiFile psiFile = inputData.getPsiFile(); + if (!Settings.isEnabled(psiFile.getProject())) { + return map; + } - PsiFile psiFile = fileContent.getPsiFile(); - if (!Settings.isEnabled(psiFile.getProject())) { - return map; - } + if (!(psiFile instanceof XmlFile)) { + return map; + } - XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); - if (document == null) { - return map; - } + XmlDocument document = ((XmlFile) psiFile).getDocument(); + if (document == null) { + return map; + } - XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); - if (xmlTags == null) { - return map; - } + XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); + if (xmlTags == null) { + return map; + } - for (XmlTag xmlTag : xmlTags) { - if (xmlTag.getName().equals("routes")) { - for (XmlTag routeNode : xmlTag.findSubTags("route")) { - for (XmlTag serviceNode : routeNode.findSubTags("service")) { - String typeName = serviceNode.getAttributeValue("class"); - if (typeName != null) { - map.put(PhpLangUtil.toPresentableFQN(typeName), null); - } + for (XmlTag xmlTag : xmlTags) { + if (xmlTag.getName().equals("routes")) { + for (XmlTag routeNode : xmlTag.findSubTags("route")) { + for (XmlTag serviceNode : routeNode.findSubTags("service")) { + String typeName = serviceNode.getAttributeValue("class"); + if (typeName != null) { + map.put(PhpLangUtil.toPresentableFQN(typeName), null); } } } } - return map; } + return map; }; } @@ -88,13 +87,10 @@ public KeyDescriptor getKeyDescriptor() { @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("webapi") - && !file.getPath().contains("testsuite") && !file.getPath().contains("_files"); - } - }; + return file -> ( + file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("webapi") + && !file.getPath().contains("testsuite") && !file.getPath().contains("_files") + ); } @Override @@ -123,16 +119,8 @@ public static List getWebApiRoutes(Method method) { return tags; } String classFqn = phpClass.getPresentableFQN(); - if (classFqn == null) { - return tags; - } Collection containingFiles = FileBasedIndex - .getInstance() - .getContainingFiles( - NAME, - classFqn, - GlobalSearchScope.allScope(phpClass.getProject()) - ); + .getInstance().getContainingFiles(KEY, classFqn, GlobalSearchScope.allScope(phpClass.getProject())); PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); for (VirtualFile virtualFile : containingFiles) { @@ -162,32 +150,32 @@ private static void fillRelatedTags(String classFqn, String methodFqn, XmlTag pa } } } -} -/** - * Decorator for XmlTag, which allows to render REST routes in web API line marker. - */ -class WebApiLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { + /** + * Decorator for XmlTag, which allows to render REST routes in web API line marker. + */ + private static class WebApiLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - public WebApiLineMarkerXmlTagDecorator(XmlTag xmlTag) { - super(xmlTag); - } + WebApiLineMarkerXmlTagDecorator(XmlTag xmlTag) { + super(xmlTag); + } - @NotNull - @Override - public String getDescription() { - return ""; - } + @NotNull + @Override + public String getDescription() { + return ""; + } - @Override - @NotNull - @NonNls - public String getName() { - String httpMethod = this.xmlTag.getAttributeValue("method"); - String route = this.xmlTag.getAttributeValue("url"); - if (httpMethod != null && route != null) { - return String.format(" %-7s %s", httpMethod, route); + @Override + @NotNull + @NonNls + public String getName() { + String httpMethod = this.xmlTag.getAttributeValue("method"); + String route = this.xmlTag.getAttributeValue("url"); + if (httpMethod != null && route != null) { + return String.format(" %-7s %s", httpMethod, route); + } + return xmlTag.getName(); } - return xmlTag.getName(); } } diff --git a/src/com/magento/idea/magento2plugin/util/IndexUtil.java b/src/com/magento/idea/magento2plugin/util/IndexUtil.java deleted file mode 100644 index 1de05d6d2..000000000 --- a/src/com/magento/idea/magento2plugin/util/IndexUtil.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.magento.idea.magento2plugin.util; - -import com.intellij.util.indexing.FileBasedIndexImpl; -import com.intellij.util.indexing.ID; -import com.magento.idea.magento2plugin.php.index.ModulePackageFileBasedIndex; -import com.magento.idea.magento2plugin.xml.di.index.PluginToTypeFileBasedIndex; -import com.magento.idea.magento2plugin.xml.di.index.TypeConfigurationFileBasedIndex; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.BlockClassFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; -import com.magento.idea.magento2plugin.xml.observer.index.EventObserverFileBasedIndex; -import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; -import com.magento.idea.magento2plugin.xml.webapi.index.WebApiTypesFileBasedIndex; - -/** - * Created by dkvashnin on 1/9/16. - */ -public class IndexUtil { - public static void manualReindex() { - ID[] indexIds = new ID[] { - // php - ModulePackageFileBasedIndex.NAME, - EventsDeclarationsFileBasedIndex.NAME, - - // xml configuration - // di - PluginToTypeFileBasedIndex.NAME, - TypeConfigurationFileBasedIndex.NAME, - VirtualTypesNamesFileBasedIndex.NAME, - // layouts - BlockClassFileBasedIndex.NAME, - BlockFileBasedIndex.NAME, - ContainerFileBasedIndex.NAME, - // events - EventObserverFileBasedIndex.NAME, - // webapi - WebApiTypesFileBasedIndex.NAME - }; - - for(ID id: indexIds) { - FileBasedIndexImpl.getInstance().requestRebuild(id); - FileBasedIndexImpl.getInstance().scheduleRebuild(id, new Throwable()); - } - } -} diff --git a/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java b/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java deleted file mode 100644 index 7ab6d1ff4..000000000 --- a/src/com/magento/idea/magento2plugin/util/PsiContextMatcherI.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.magento.idea.magento2plugin.util; - -/** - * Created by dkvashnin on 12/18/15. - */ -public interface PsiContextMatcherI { - boolean match(T psiElement); -} diff --git a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java b/src/com/magento/idea/magento2plugin/xml/LineMarkerXmlTagDecorator.java similarity index 98% rename from src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java rename to src/com/magento/idea/magento2plugin/xml/LineMarkerXmlTagDecorator.java index 7d6778f07..d16baa157 100644 --- a/src/com/magento/idea/magento2plugin/xml/index/LineMarkerXmlTagDecorator.java +++ b/src/com/magento/idea/magento2plugin/xml/LineMarkerXmlTagDecorator.java @@ -1,8 +1,7 @@ -package com.magento.idea.magento2plugin.xml.index; +package com.magento.idea.magento2plugin.xml; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; -import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; @@ -20,7 +19,6 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.XmlNSDescriptor; -import com.magento.idea.magento2plugin.php.module.MagentoComponent; import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; import com.magento.idea.magento2plugin.php.module.MagentoModule; import org.jetbrains.annotations.Contract; @@ -61,7 +59,7 @@ protected String getAreaName() { } @NotNull - protected String getComponentName() { + private String getComponentName() { MagentoComponentManager moduleManager = MagentoComponentManager.getInstance(project); MagentoModule module = moduleManager.getComponentOfTypeForFile(xmlTag.getContainingFile(), MagentoModule.class); diff --git a/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java b/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java deleted file mode 100644 index ecb5e635f..000000000 --- a/src/com/magento/idea/magento2plugin/xml/XmlHelperUtility.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.magento.idea.magento2plugin.xml; - -import com.intellij.patterns.*; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.xml.XmlTag; -import org.jetbrains.annotations.Nullable; - -/** - * Created by dkvashnin on 11/2/15. - */ -public class XmlHelperUtility { - public static PsiFilePattern.Capture getXmlFilePattern(@Nullable String fileName) { - if (fileName == null) { - return getXmlFilePattern(); - } - - return XmlPatterns.psiFile() - .withName(XmlPatterns.string().equalTo(fileName + ".xml")); - } - - public static PsiFilePattern.Capture getXmlFilePattern() { - return XmlPatterns.psiFile() - .withName(XmlPatterns.string().endsWith(".xml")); - } - - public static PsiElementPattern.Capture getInsideTagPattern(String insideTagName) { - return XmlPatterns.psiElement(XmlTag.class).withName(insideTagName); - } - - /** - * - */ - public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagName, String attributeName, String fileType) { - return XmlPatterns - .xmlAttributeValue() - .withParent( - XmlPatterns - .xmlAttribute(attributeName) - .withParent( - XmlPatterns - .xmlTag() - .withName(tagName) - ) - ).inside( - getInsideTagPattern(tagName) - ).inFile(getXmlFilePattern(fileType)); - } - - /** - * - */ - public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagName, String attributeName) { - return XmlPatterns - .xmlAttributeValue() - .withParent( - XmlPatterns - .xmlAttribute(attributeName) - .withParent( - XmlPatterns - .xmlTag() - .withName(tagName) - ) - ).inside( - getInsideTagPattern(tagName) - ).inFile(getXmlFilePattern()); - } - - /** - * - */ - public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName, String fileName) { - return XmlPatterns - .psiElement() - .inside(XmlPatterns - .xmlAttributeValue() - .inside(XmlPatterns - .xmlAttribute() - .withName(attributeName) - .withParent(XmlPatterns - .xmlTag() - .withName(tag) - ) - ) - ).inFile(getXmlFilePattern(fileName)); - } - - /** - * - */ - public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { - return XmlPatterns - .psiElement() - .inside(XmlPatterns - .xmlAttributeValue() - .inside(XmlPatterns - .xmlAttribute() - .withName(attributeName) - .withParent(XmlPatterns - .xmlTag() - .withName(tag) - ) - ) - ).inFile(getXmlFilePattern()); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/XmlPsiTreeUtil.java b/src/com/magento/idea/magento2plugin/xml/XmlPsiTreeUtil.java new file mode 100644 index 000000000..9229d0716 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/xml/XmlPsiTreeUtil.java @@ -0,0 +1,51 @@ +package com.magento.idea.magento2plugin.xml; + +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.xml.*; +import gnu.trove.THashSet; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public class XmlPsiTreeUtil { + + @Nullable + public static XmlTag getTypeTagOfArgument(XmlElement psiArgumentValueElement) { + + XmlTag argumentTag = PsiTreeUtil.getParentOfType(psiArgumentValueElement, XmlTag.class); + XmlTag argumentsTag = PsiTreeUtil.getParentOfType(argumentTag, XmlTag.class); + return PsiTreeUtil.getParentOfType(argumentsTag, XmlTag.class); + } + + public static Collection findAttributeValueElements(XmlFile xmlFile, + String tagName, + String attributeName) { + Collection psiElements = new THashSet<>(); + + + XmlTag rootTag = xmlFile.getRootTag(); + if (rootTag == null) { + return psiElements; + } + + for (XmlTag tag: rootTag.findSubTags(tagName)) { + if (tag != null) { + XmlAttribute attribute = tag.getAttribute(attributeName); + if (attribute != null && attribute.getValueElement() != null) { + psiElements.add(attribute.getValueElement()); + } + } + }; + + return psiElements; + } + + public static Collection findAttributeValueElements(XmlFile xmlFile, + String tagName, + String attributeName, + String value) { + Collection psiElements = findAttributeValueElements(xmlFile, tagName, attributeName); + psiElements.removeIf(e -> e.getValue() == null || !e.getValue().equals(value)); + return psiElements; + } +} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java deleted file mode 100644 index 327a4ee31..000000000 --- a/src/com/magento/idea/magento2plugin/xml/completion/ClassCompletionProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.magento.idea.magento2plugin.xml.completion; - -import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; -import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/17/15. - */ -public class ClassCompletionProvider implements CompletionProviderI { - public final static ClassCompletionProvider INSTANCE = new ClassCompletionProvider(); - - @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { - List result = new ArrayList<>(); - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - String prefix = StringUtil.unquoteString(psiElement.getText()); - - Collection classNames = phpIndex.getAllClassNames(new CamelHumpMatcher(prefix)); - - for (String className: classNames) { - Collection classesByName = phpIndex.getClassesByName(className); - for (PhpClass phpClass: classesByName) { - if (context != null && !context.match(phpClass)) { - continue; - } - - String classFqn = phpClass.getPresentableFQN(); - - result.add( - LookupElementBuilder - .create(classFqn) - .withIcon(PhpIcons.CLASS_ICON) - ); - } - } - - return result; - } - - @Override - public List collectCompletionResult(PsiElement psiElement) { - return collectCompletionResult(psiElement, null); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java b/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java deleted file mode 100644 index 09348290d..000000000 --- a/src/com/magento/idea/magento2plugin/xml/completion/CompletionProviderI.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.magento.idea.magento2plugin.xml.completion; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.psi.PsiElement; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * Created by dkvashnin on 11/17/15. - */ -public interface CompletionProviderI { - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context); - - public List collectCompletionResult(PsiElement psiElement); -} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java deleted file mode 100644 index 63dfe4f2d..000000000 --- a/src/com/magento/idea/magento2plugin/xml/completion/InterfaceCompletionProvider.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.magento.idea.magento2plugin.xml.completion; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.psi.PsiElement; -import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import org.apache.commons.lang.StringUtils; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by mslabko on 18.12.2015. - */ -public class InterfaceCompletionProvider implements CompletionProviderI { - public final static InterfaceCompletionProvider INSTANCE = new InterfaceCompletionProvider(); - - @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { - List result = new ArrayList<>(); - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - String input = StringUtils.strip(psiElement.getText(), "\""); - - Collection interfaceNames = phpIndex.getAllInterfaceNames(); - - for (String interfaceName: interfaceNames) { - if (!interfaceName.toLowerCase().contains(input.toLowerCase())) { - continue; - } - - Collection classesByName = phpIndex.getInterfacesByName(interfaceName); - for (PhpClass phpClass: classesByName) { - if (context != null && !context.match(phpClass)) { - continue; - } - - String classFqn = phpClass.getPresentableFQN(); - - result.add( - LookupElementBuilder - .create(classFqn) - .withIcon(PhpIcons.INTERFACE_ICON) - ); - } - } - - return result; - } - - @Override - public List collectCompletionResult(PsiElement psiElement) { - return collectCompletionResult(psiElement, null); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java deleted file mode 100644 index 82d51b4b0..000000000 --- a/src/com/magento/idea/magento2plugin/xml/completion/VirtualTypeCompletionProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.magento.idea.magento2plugin.xml.completion; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.psi.PsiElement; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; -import org.apache.commons.lang.StringUtils; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by dkvashnin on 11/17/15. - */ -public class VirtualTypeCompletionProvider implements CompletionProviderI { - public final static VirtualTypeCompletionProvider INSTANCE = new VirtualTypeCompletionProvider(); - - @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { - List result = new ArrayList<>(); - String input = StringUtils.strip(psiElement.getText(), "\""); - String[] allVirtualTypesNames = VirtualTypesNamesFileBasedIndex.getAllVirtualTypesNames( - psiElement.getProject() - ); - - for (String name: allVirtualTypesNames) { - if (name.toLowerCase().contains(input.toLowerCase())) { - if (context != null && !context.match(name)) { - continue; - } - - result.add(LookupElementBuilder.create(name)); - } - } - - return result; - } - - @Override - public List collectCompletionResult(PsiElement psiElement) { - return collectCompletionResult(psiElement, null); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java deleted file mode 100644 index 8149c0c29..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/XmlHelper.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di; - -import com.intellij.patterns.*; -import com.intellij.psi.PsiElement; -import com.intellij.psi.xml.XmlTokenType; -import com.magento.idea.magento2plugin.xml.XmlHelperUtility; - -/** - * Created by Warider on 17.08.2015. - */ -public class XmlHelper extends XmlHelperUtility { - public static final String FILE_TYPE = "di"; - - public static final String TYPE_TAG = "type"; - public static final String PLUGIN_TAG = "plugin"; - public static final String VIRTUAL_TYPE_TAG = "virtualType"; - public static final String PREFERENCE_TAG = "preference"; - public static final String ARGUMENT_TAG = "argument"; - public static final String ARGUMENTS_TAG = "arguments"; - - public static final String NAME_ATTRIBUTE = "name"; - public static final String TYPE_ATTRIBUTE = "type"; - public static final String FOR_ATTRIBUTE = "for"; - - public static final String OBJECT_TYPE = "object"; - public static final String STRING_TYPE = "string"; - public static final String CONST_TYPE = "const"; - public static final String INIT_TYPE = "init_parameter"; - - - /** - * - */ - public static XmlAttributeValuePattern getDiTypePattern() { - return getTagAttributeValuePattern(TYPE_TAG, NAME_ATTRIBUTE, FILE_TYPE); - } - - /** - * - */ - public static XmlAttributeValuePattern getPluginTypePattern() { - return getTagAttributeValuePattern(PLUGIN_TAG, TYPE_ATTRIBUTE, FILE_TYPE); - } - - /** - * - */ - public static XmlAttributeValuePattern getDiPreferenceTypePattern() { - return getTagAttributeValuePattern(PREFERENCE_TAG, TYPE_ATTRIBUTE, FILE_TYPE); - } - - /** - * - */ - public static XmlAttributeValuePattern getDiPreferenceForPattern() { - return getTagAttributeValuePattern(PREFERENCE_TAG, FOR_ATTRIBUTE, FILE_TYPE); - } - - /** - * - */ - public static XmlAttributeValuePattern getDiVirtualTypePattern() { - return getTagAttributeValuePattern(VIRTUAL_TYPE_TAG, TYPE_ATTRIBUTE, FILE_TYPE); - } - - - /** - * - */ - public static XmlAttributeValuePattern getArgumentNamePattern() { - return getTagAttributeValuePattern(ARGUMENT_TAG, NAME_ATTRIBUTE, FILE_TYPE); - } - - /** - * \Namespace\Class - * @param typeName Type name - */ - public static PsiElementPattern.Capture getArgumentValuePatternForType(String typeName) { - return XmlPatterns - .psiElement(XmlTokenType.XML_DATA_CHARACTERS) - .withParent( - XmlPatterns - .xmlText() - .withParent(XmlPatterns - .xmlTag() - .withName("argument") - .withAttributeValue("xsi:type", typeName) - ) - ).inFile(XmlHelper.getXmlFilePattern(FILE_TYPE)); - } - - /** - * \Namespace\Class - * @param typeName Type name - */ - public static PsiElementPattern.Capture getItemValuePatternForType(String typeName) { - return XmlPatterns - .psiElement(XmlTokenType.XML_DATA_CHARACTERS) - .withParent( - XmlPatterns - .xmlText() - .withParent(XmlPatterns - .xmlTag() - .withName("item") - .withAttributeValue("xsi:type", typeName) - ) - ).inFile(XmlHelper.getXmlFilePattern(FILE_TYPE)); - } - - /** - * - */ - public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { - return getTagAttributePattern(tag, attributeName, FILE_TYPE); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java deleted file mode 100644 index 0d8357437..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/completion/DiCompletionContributor.java +++ /dev/null @@ -1,192 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.patterns.XmlPatterns; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.ProcessingContext; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.Parameter; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; -import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; -import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; -import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import com.magento.idea.magento2plugin.xml.util.ParentTypeMatcher; -import com.magento.idea.magento2plugin.xml.util.VirtualTypeParentMatcher; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; - -/** - * Created by dkvashnin on 10/15/15. - */ -public class DiCompletionContributor extends CompletionContributor { - private CompletionProviderI[] completionProviders = new CompletionProviderI[] { - ClassCompletionProvider.INSTANCE, - VirtualTypeCompletionProvider.INSTANCE - }; - - public DiCompletionContributor() { - extend(CompletionType.BASIC, - XmlPatterns.or( - XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE), - XmlHelper.getItemValuePatternForType(XmlHelper.STRING_TYPE), - XmlHelper.getTagAttributePattern(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE), - XmlHelper.getTagAttributePattern(XmlHelper.VIRTUAL_TYPE_TAG, XmlHelper.TYPE_ATTRIBUTE), - XmlHelper.getTagAttributePattern(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE) - ), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - PsiElement psiElement = parameters.getOriginalPosition(); - for (CompletionProviderI completionProvider: completionProviders) { - resultSet.addAllElements(completionProvider.collectCompletionResult(psiElement)); - } - } - } - ); - - extend( - CompletionType.BASIC, - XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.FOR_ATTRIBUTE), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - PsiElement psiElement = parameters.getOriginalPosition(); - resultSet.addAllElements(InterfaceCompletionProvider.INSTANCE - .collectCompletionResult(psiElement) - ); - } - } - ); - - extend(CompletionType.BASIC, - XmlHelper.getTagAttributePattern(XmlHelper.PREFERENCE_TAG, XmlHelper.TYPE_ATTRIBUTE), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - PsiElement psiElement = parameters.getOriginalPosition(); - PhpClass preferenceClass = getPreferenceClass(psiElement); - - if (preferenceClass == null) { - return; - } - - ParentTypeMatcher parentTypeMatcher = new ParentTypeMatcher(preferenceClass); - resultSet.addAllElements(ClassCompletionProvider.INSTANCE - .collectCompletionResult(psiElement, parentTypeMatcher) - ); - - resultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE - .collectCompletionResult( - psiElement, - new VirtualTypeParentMatcher(parentTypeMatcher, psiElement.getProject()) - ) - ); - } - } - ); - - extend(CompletionType.BASIC, - XmlHelper.getArgumentValuePatternForType(XmlHelper.OBJECT_TYPE), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - PsiElement psiElement = parameters.getOriginalPosition(); - - PhpClass argumentClass = getArgumentClass(psiElement); - - if (argumentClass == null) { - return; - } - - ParentTypeMatcher parentTypeMatcher = new ParentTypeMatcher(argumentClass); - - resultSet.addAllElements(ClassCompletionProvider.INSTANCE - .collectCompletionResult(psiElement, parentTypeMatcher) - ); - - resultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE - .collectCompletionResult( - psiElement, - new VirtualTypeParentMatcher(parentTypeMatcher, psiElement.getProject()) - ) - ); - } - } - ); - } - - @Nullable - private PhpClass getPreferenceClass(PsiElement psiElement) { - XmlAttribute parentAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); - if (parentAttribute == null) { - return null; - } - - XmlTag xmlTag = parentAttribute.getParent(); - XmlAttribute preferenceAttr = xmlTag.getAttribute(XmlHelper.FOR_ATTRIBUTE); - if (preferenceAttr == null) { - return null; - } - - XmlAttributeValue valueElement = preferenceAttr.getValueElement(); - PsiReference reference = valueElement.getReference(); - if (reference == null) { - return null; - } - - PsiElement element = reference.resolve(); - if (element instanceof PhpClass) { - return (PhpClass) element; - } - - return null; - } - - @Nullable - private PhpClass getArgumentClass(PsiElement psiElement) { - XmlTag xmlTag = PsiTreeUtil.getParentOfType(psiElement, XmlTag.class); - if (xmlTag == null) { - return null; - } - - XmlAttribute preferenceAttr = xmlTag.getAttribute(XmlHelper.NAME_ATTRIBUTE); - if (preferenceAttr == null) { - return null; - } - - XmlAttributeValue valueElement = preferenceAttr.getValueElement(); - PsiReference reference = valueElement.getReference(); - if (reference == null) { - return null; - } - - PsiElement element = reference.resolve(); - if (element instanceof Parameter) { - String stringResolved = ((Parameter) element).getDeclaredType().toStringResolved(); - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - - ArrayList result = new ArrayList<>(); - result.addAll(phpIndex.getClassesByFQN(stringResolved)); - result.addAll(phpIndex.getInterfacesByFQN(stringResolved)); - - if (result.size() > 0) { - return result.get(0); - } - } - - return null; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java deleted file mode 100644 index b4c72bc42..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/index/TypeConfigurationFileBasedIndex.java +++ /dev/null @@ -1,291 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.index; - -import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.source.xml.XmlDocumentImpl; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.indexing.*; -import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; -import com.jetbrains.php.lang.PhpLangUtil; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; -import com.magento.idea.magento2plugin.xml.index.StringSetDataExternalizer; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -/** - * Created by dkvashnin on 11/15/15. - */ -public class TypeConfigurationFileBasedIndex extends ScalarIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.type_configuration"); - private final EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); - - public static final Map TAG_ATTRIBUTE_RELATION = new HashMap() {{ - put(XmlHelper.TYPE_TAG, XmlHelper.NAME_ATTRIBUTE); - put(XmlHelper.PREFERENCE_TAG, XmlHelper.FOR_ATTRIBUTE); - put(XmlHelper.PLUGIN_TAG, XmlHelper.TYPE_ATTRIBUTE); - put(XmlHelper.VIRTUAL_TYPE_TAG, XmlHelper.TYPE_ATTRIBUTE); - }}; - - @Nullable - public static List getClassConfigurations(PhpClass phpClass) { - String classFqn = phpClass.getPresentableFQN(); - - Collection containingFiles = FileBasedIndex - .getInstance() - .getContainingFiles( - NAME, - classFqn, - GlobalSearchScope.allScope(phpClass.getProject()) - ); - - PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); - - List tags = new ArrayList(); - - for (VirtualFile virtualFile: containingFiles) { - XmlFile file = (XmlFile)psiManager.findFile(virtualFile); - - if (file == null) { - continue; - } - - XmlTag rootTag = file.getRootTag(); - fillRelatedTags(classFqn, rootTag, tags); - } - - return tags; - } - - private static void fillRelatedTags(String classFqn, XmlTag parentTag, List tagsReferences) { - for (XmlTag childTag: parentTag.getSubTags()) { - String tagName = childTag.getName(); - String attribute = TAG_ATTRIBUTE_RELATION.get(tagName); - if (attribute == null) { - continue; - } - - String className = childTag.getAttributeValue(attribute); - if (className != null && PhpLangUtil.toPresentableFQN(className).equals(classFqn)) { - tagsReferences.add(getLineMarkerDecorator(childTag)); - } - - // type tag has plugin tags - if (tagName.equals(XmlHelper.TYPE_TAG)) { - fillRelatedTags(classFqn, childTag, tagsReferences); - } - } - } - - /** - * Decorate tag with appropriate line marker decorator. - */ - @NotNull - private static XmlTag getLineMarkerDecorator(XmlTag tag) { - switch (tag.getName()) { - case XmlHelper.PREFERENCE_TAG: - return new DiPreferenceLineMarkerXmlTagDecorator(tag); - case XmlHelper.TYPE_TAG: - return new DiTypeLineMarkerXmlTagDecorator(tag); - case XmlHelper.PLUGIN_TAG: - return new DiPluginLineMarkerXmlTagDecorator(tag); - case XmlHelper.VIRTUAL_TYPE_TAG: - return new DiVirtualTypeLineMarkerXmlTagDecorator(tag); - default: - return tag; - } - } - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return new DataIndexer() { - @NotNull - @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); - - PsiFile psiFile = fileContent.getPsiFile(); - if (!Settings.isEnabled(psiFile.getProject())) { - return map; - } - - XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); - if(document == null) { - return map; - } - - XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); - if(xmlTags == null) { - return map; - } - - for(XmlTag xmlTag: xmlTags) { - if(xmlTag.getName().equals("config")) { - processConfigurationTags(xmlTag, map); - } - } - - return map; - } - - private void processConfigurationTags(XmlTag parentTag, Map results) { - for (XmlTag childTag: parentTag.getSubTags()) { - String tagName = childTag.getName(); - - String attribute = TAG_ATTRIBUTE_RELATION.get(tagName); - if (attribute == null) { - continue; - } - - String className = childTag.getAttributeValue(attribute); - if (className != null) { - results.put(PhpLangUtil.toPresentableFQN(className), null); - } - - // type tag has plugin tags - if (tagName.equals(XmlHelper.TYPE_TAG)) { - processConfigurationTags(childTag, results); - } - } - } - }; - } - - @NotNull - @Override - public KeyDescriptor getKeyDescriptor() { - return myKeyDescriptor; - } - - @NotNull - @Override - public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("di"); - } - }; - } - - @Override - public boolean dependsOnFileContent() { - return true; - } - - @Override - public int getVersion() { - return 0; - } -} - -/** - * Decorator for XmlTag, which improves readability of "preference" node in configuration line marker. - */ -class DiPreferenceLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - - public DiPreferenceLineMarkerXmlTagDecorator(XmlTag xmlTag) { - super(xmlTag); - } - - @NotNull - @Override - public String getDescription() { - String preference = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); - if (preference != null) { - return String.format("preference %s", preference); - } - return xmlTag.getName(); - } - - @Override - @NotNull - @NonNls - public String getName() { - String preference = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); - if (preference != null) { - return String.format("[%s] preference %s", getAreaName(), preference); - } - return xmlTag.getName(); - } -} - -/** - * Decorator for XmlTag, which improves readability of "type" node in configuration line marker. - */ -class DiTypeLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - - public DiTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { - super(xmlTag); - } - - @NotNull - @Override - public String getDescription() { - return "type declaration"; - } -} - -/** - * Decorator for XmlTag, which improves readability of "plugin" node in configuration line marker. - */ -class DiPluginLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - - public DiPluginLineMarkerXmlTagDecorator(XmlTag xmlTag) { - super(xmlTag); - } - - @NotNull - @Override - public String getDescription() { - XmlTag typeTag = xmlTag.getParentTag(); - if (typeTag == null) { - return xmlTag.getName(); - } - String type = typeTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); - if (type == null) { - return xmlTag.getName(); - } - - return String.format("plugin for %s", type); - } -} - -/** - * Decorator for XmlTag, which improves readability of "virtualType" node in configuration line marker. - */ -class DiVirtualTypeLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - - public DiVirtualTypeLineMarkerXmlTagDecorator(XmlTag xmlTag) { - super(xmlTag); - } - - @NotNull - @Override - public String getDescription() { - String type = xmlTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); - if (type != null) { - return String.format("virtual type %s", type); - } - return xmlTag.getName(); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java deleted file mode 100644 index cf493aa3c..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/index/VirtualTypesNamesFileBasedIndex.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.index; - -import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.source.xml.XmlDocumentImpl; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.ArrayUtil; -import com.intellij.util.indexing.*; -import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.PhpLangUtil; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.Settings; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -/** - * Created by dkvashnin on 10/13/15. - */ -public class VirtualTypesNamesFileBasedIndex extends FileBasedIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.di.index.virtual_types_names"); - private final EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); - private final MyDataIndexer myDataIndexer = new MyDataIndexer(); - - private static final int SUPER_MAX_NESTING_LEVEL = 3; - - public static String[] getAllVirtualTypesNames(final Project project) { - final Collection allKeys = FileBasedIndex.getInstance().getAllKeys(NAME, project); - return ArrayUtil.toStringArray(allKeys); - } - - public static XmlAttributeValue[] getVirtualTypesByName(final Project project, final String virtualTypeName, final GlobalSearchScope scope) { - List xmlAttributeList = new ArrayList(); - - Collection virtualFileCollection = FileBasedIndex.getInstance().getContainingFiles(NAME, virtualTypeName, scope); - PsiManager psiManager = PsiManager.getInstance(project); - - for (VirtualFile virtualFile: virtualFileCollection) { - XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); - if (xmlFile == null) { - continue; - } - - XmlTag rootTag = xmlFile.getRootTag(); - if (rootTag == null) { - continue; - } - - for (XmlTag typeTag: rootTag.getSubTags()) { - if (typeTag.getName().equals("virtualType")) { - XmlAttribute nameAttribute = typeTag.getAttribute("name"); - if (nameAttribute != null) { - if (nameAttribute.getValue() != null && nameAttribute.getValue().equals(virtualTypeName)) - - xmlAttributeList.add(nameAttribute.getValueElement()); - } - } - } - } - - return xmlAttributeList.toArray(new XmlAttributeValue[xmlAttributeList.size()]); - } - - public static String getParentTypeName(final Project project, String virtualTypeName) { - List originNames = FileBasedIndex.getInstance().getValues(NAME, virtualTypeName, GlobalSearchScope.allScope(project)); - - if (originNames.size() > 0) { - return originNames.get(0); - } - - return null; - } - - public static String getSuperParentTypeName(final Project project, String inputChildTypeName) { - String superName = null; - String childTypeName = inputChildTypeName; - - for (int index = 0; index < SUPER_MAX_NESTING_LEVEL; index++) { - superName = getParentTypeName(project, childTypeName); - - if (superName == null) { - superName = childTypeName; - break; - } - - childTypeName = superName; - } - - return superName == null - ? (!inputChildTypeName.equals(childTypeName) ? childTypeName : null) - : superName; - } - - public static List getSuperParentTypes(final Project project, String inputChildTypeName) { - List result = new ArrayList<>(); - - String superName = getSuperParentTypeName(project, inputChildTypeName); - if (superName == null) { - return result; - } - - PhpIndex phpIndex = PhpIndex.getInstance(project); - - result.addAll(phpIndex.getClassesByFQN(superName)); - result.addAll(phpIndex.getInterfacesByFQN(superName)); - - return result; - } - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return myDataIndexer; - } - - @NotNull - @Override - public KeyDescriptor getKeyDescriptor() { - return myKeyDescriptor; - } - - @NotNull - @Override - public DataExternalizer getValueExternalizer() { - return EnumeratorStringDescriptor.INSTANCE; - } - - @NotNull - @Override - public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("di"); - } - }; - } - - @Override - public boolean dependsOnFileContent() { - return true; - } - - @Override - public int getVersion() { - return 2; - } - - private class MyDataIndexer implements DataIndexer { - - @NotNull - @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); - - PsiFile psiFile = fileContent.getPsiFile(); - if (!Settings.isEnabled(psiFile.getProject())) { - return map; - } - - XmlDocumentImpl document = PsiTreeUtil.getChildOfType(psiFile, XmlDocumentImpl.class); - if(document == null) { - return map; - } - - XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); - if(xmlTags == null) { - return map; - } - - for(XmlTag xmlTag: xmlTags) { - if(xmlTag.getName().equals("config")) { - for(XmlTag typeNode: xmlTag.findSubTags("virtualType")) { - if (typeNode.getAttributeValue("name") != null && typeNode.getAttributeValue("type") != null) { - map.put( - typeNode.getAttributeValue("name"), - PhpLangUtil.toPresentableFQN(typeNode.getAttributeValue("type")) - ); - } - } - } - } - - return map; - } - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java b/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java deleted file mode 100644 index ab8bb4715..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/ArgumentNameReference.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.PsiPolyVariantReferenceBase; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.xml.XmlTag; -import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.Method; -import com.jetbrains.php.lang.psi.elements.Parameter; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Created by dkvashnin on 10/18/15. - */ -public class ArgumentNameReference extends PsiPolyVariantReferenceBase { - private XmlTag typeTag; - private String typeName; - - public ArgumentNameReference(@NotNull PsiElement psiElement, @NotNull XmlTag typeTag, @NotNull String typeName) { - super(psiElement); - - this.typeTag = typeTag; - this.typeName = typeName; - } - - @NotNull - @Override - public ResolveResult[] multiResolve(boolean b) { - List list = new ArrayList(); - - String argumentName = StringUtil.unquoteString(getElement().getText()); - for (Parameter parameter: getParameters()) { - if (argumentName.equals(parameter.getName())) { - list.add(new PsiElementResolveResult(parameter)); - } - } - - return list.toArray(new ResolveResult[list.size()]); - } - - @NotNull - @Override - public Object[] getVariants() { - List variants = new ArrayList(); - List definedArguments = getAlreadyConfiguredArguments(); - - for (Parameter parameter: getParameters()) { - String argumentName = parameter.getName(); - if (definedArguments.contains(argumentName)) { - continue; - } - - variants.add( - LookupElementBuilder - .create(argumentName) - .withIcon(PhpIcons.PARAMETER) - .withTypeText(parameter.getDeclaredType().toStringResolved()) - ); - } - - return variants.toArray(); - } - - private List getParameters() { - List parameterList = new ArrayList(); - - PhpIndex phpIndex = PhpIndex.getInstance(getElement().getProject()); - Collection classesByFQN = phpIndex.getClassesByFQN(typeName); - - for (PhpClass phpClass: classesByFQN) { - Method constructor = phpClass.getConstructor(); - if (constructor == null) { - continue; - } - - Parameter[] parameters = constructor.getParameters(); - Collections.addAll(parameterList, parameters); - } - - return parameterList; - } - - private List getAlreadyConfiguredArguments() - { - List result = new ArrayList<>(); - - XmlTag argumentsTag = typeTag.findFirstSubTag(XmlHelper.ARGUMENTS_TAG); - if (argumentsTag == null) { - return result; - } - - for (XmlTag argumentTag: argumentsTag.findSubTags(XmlHelper.ARGUMENT_TAG)) { - result.add( - argumentTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE) - ); - } - - return result; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java b/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java deleted file mode 100644 index f34cf7714..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/ConstantReference.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference; - -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.PsiPolyVariantReferenceBase; -import com.intellij.psi.ResolveResult; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.PhpLangUtil; -import com.jetbrains.php.lang.psi.elements.Field; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 10/22/15. - */ -public class ConstantReference extends PsiPolyVariantReferenceBase { - public ConstantReference(PsiElement psiElement) { - super(psiElement); - } - - @NotNull - @Override - public ResolveResult[] multiResolve(boolean b) { - PhpIndex phpIndex = PhpIndex.getInstance(getElement().getProject()); - List parts = StringUtil.split( - PhpLangUtil.toFQN( - StringUtil.unquoteString(getElement().getText()) - ), - "::" - ); - - if (parts.size() != 2) { - return new ResolveResult[0]; - } - - String className = parts.get(0); - String constantName = parts.get(1); - - List fields = new ArrayList(); - Collection classesAndInterfaces = new ArrayList<>(); - classesAndInterfaces.addAll(phpIndex.getClassesByFQN(className)); - classesAndInterfaces.addAll(phpIndex.getInterfacesByFQN(className)); - - for (PhpClass phpClass: classesAndInterfaces) { - for(Field field: phpClass.getFields()) { - if (field.isConstant() && field.getName().equals(constantName)) { - fields.add(new PsiElementResolveResult(field)); - } - } - } - - return fields.toArray(new ResolveResult[fields.size()]); - } - - @NotNull - @Override - public Object[] getVariants() { - return new Object[0]; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java deleted file mode 100644 index 08a30b50b..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/DiReferenceContributor.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference; - -import com.intellij.patterns.XmlPatterns; -import com.intellij.psi.*; -import com.intellij.util.ProcessingContext; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import com.magento.idea.magento2plugin.xml.di.reference.provider.ArgumentNameReferenceProvider; -import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; -import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.InterfacesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; -import org.jetbrains.annotations.NotNull; - -/** - * Created by Warider on 17.08.2015. - */ -public class DiReferenceContributor extends PsiReferenceContributor { - @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getDiPreferenceForPattern(), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - InterfacesResultsFiller.INSTANCE - } - ) - ); - - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getDiPreferenceTypePattern(), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getDiTypePattern(), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - InterfacesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getDiVirtualTypePattern(), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - - // SomeClassOrVirtualType - // SomeClassOrVirtualType - lazy initialization - psiReferenceRegistrar.registerReferenceProvider( - XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType(XmlHelper.OBJECT_TYPE), - XmlHelper.getItemValuePatternForType(XmlHelper.OBJECT_TYPE), - XmlHelper.getItemValuePatternForType(XmlHelper.STRING_TYPE) - ), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getArgumentNamePattern(), - new ArgumentNameReferenceProvider() - ); - - // SomeClass::SOME_CONSTANT - psiReferenceRegistrar.registerReferenceProvider( - XmlPatterns.or( - XmlHelper.getArgumentValuePatternForType(XmlHelper.CONST_TYPE), - XmlHelper.getArgumentValuePatternForType(XmlHelper.INIT_TYPE), - XmlHelper.getItemValuePatternForType(XmlHelper.CONST_TYPE), - XmlHelper.getItemValuePatternForType(XmlHelper.INIT_TYPE) - ), - new PsiReferenceProvider() { - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { - return new PsiReference[] {new ConstantReference(psiElement)}; - } - } - ); - - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getPluginTypePattern(), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java deleted file mode 100644 index 8c6b52884..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/ArgumentNameReferenceProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference.provider; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiReferenceProvider; -import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.ProcessingContext; -import com.magento.idea.magento2plugin.xml.di.reference.ArgumentNameReference; -import com.magento.idea.magento2plugin.xml.di.reference.provider.resolver.ClassNameResolver; -import com.magento.idea.magento2plugin.xml.di.reference.provider.resolver.TypeTagResolver; -import com.magento.idea.magento2plugin.xml.di.reference.provider.resolver.VirtualTypeTagResolver; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 10/19/15. - */ -public class ArgumentNameReferenceProvider extends PsiReferenceProvider { - private static ClassNameResolver[] classNameResolvers = new ClassNameResolver[] { - TypeTagResolver.INSTANCE, - VirtualTypeTagResolver.INSTANCE - }; - - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { - if (!(psiElement instanceof XmlAttributeValue)) { - return new PsiReference[0]; - } - - for (ClassNameResolver classNameResolver: classNameResolvers) { - XmlTag typeTag = classNameResolver.findTypeTag(psiElement); - - if (typeTag == null) { - continue; - } - - String typeName = classNameResolver.resolveTypeName(typeTag); - if (typeName == null) { - continue; - } - - return new PsiReference[]{new ArgumentNameReference(psiElement, typeTag, typeName)}; - } - - return new PsiReference[0]; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java deleted file mode 100644 index 132dfab7b..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/XmlReferenceProvider.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference.provider; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiReferenceProvider; -import com.intellij.util.ProcessingContext; -import com.magento.idea.magento2plugin.xml.reference.TypeReference; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import org.jetbrains.annotations.NotNull; - -/** - * Created by Warider on 17.08.2015. - */ -public class XmlReferenceProvider extends PsiReferenceProvider { - private final ReferenceResultsFiller[] resultsFillers; - - public XmlReferenceProvider(ReferenceResultsFiller[] resultsFillers) { - super(); - this.resultsFillers = resultsFillers; - } - - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { - return new PsiReference[]{new TypeReference(psiElement, resultsFillers)}; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/ClassNameResolver.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/ClassNameResolver.java deleted file mode 100644 index 4dca347dc..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/ClassNameResolver.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference.provider.resolver; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.xml.XmlElement; -import com.intellij.psi.xml.XmlTag; -import org.jetbrains.annotations.Nullable; - -/** - * Created by dkvashnin on 10/19/15. - */ -public abstract class ClassNameResolver { - - public XmlTag findTypeTag(PsiElement psiElement) { - if (psiElement instanceof XmlTag && ((XmlTag) psiElement).getName().equals(getTagName())) { - return (XmlTag) psiElement; - } - - if (psiElement.getParent() == null || !(psiElement.getParent() instanceof XmlElement)) { - return null; - } - - return findTypeTag(psiElement.getParent()); - } - - @Nullable - abstract public String resolveTypeName(XmlTag xmlTag); - - abstract protected String getTagName(); -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java deleted file mode 100644 index 4528cf864..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/TypeTagResolver.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference.provider.resolver; - -import com.intellij.psi.xml.XmlTag; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import org.jetbrains.annotations.Nullable; - -/** - * Created by dkvashnin on 10/19/15. - */ -public class TypeTagResolver extends ClassNameResolver { - public static final TypeTagResolver INSTANCE = new TypeTagResolver(); - - private TypeTagResolver() {} - - @Nullable - @Override - public String resolveTypeName(XmlTag xmlTag) { - return xmlTag.getAttributeValue(XmlHelper.NAME_ATTRIBUTE); - } - - @Override - protected String getTagName() { - return XmlHelper.TYPE_TAG; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java b/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java deleted file mode 100644 index 1268d6bdc..000000000 --- a/src/com/magento/idea/magento2plugin/xml/di/reference/provider/resolver/VirtualTypeTagResolver.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.magento.idea.magento2plugin.xml.di.reference.provider.resolver; - -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.indexing.FileBasedIndex; -import com.magento.idea.magento2plugin.xml.di.XmlHelper; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; -import org.jetbrains.annotations.Nullable; - -/** - * Created by dkvashnin on 10/20/15. - */ -public class VirtualTypeTagResolver extends ClassNameResolver { - public static final VirtualTypeTagResolver INSTANCE = new VirtualTypeTagResolver(); - - private VirtualTypeTagResolver() {} - - @Nullable - @Override - public String resolveTypeName(XmlTag xmlTag) { - String parentTypeName = xmlTag.getAttributeValue(XmlHelper.TYPE_ATTRIBUTE); - - if (parentTypeName == null) { - return null; - } - - String superParentName = VirtualTypesNamesFileBasedIndex.getSuperParentTypeName(xmlTag.getProject(), parentTypeName); - - return superParentName == null ? parentTypeName : superParentName; - - } - - @Override - protected String getTagName() { - return XmlHelper.VIRTUAL_TYPE_TAG; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java b/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java deleted file mode 100644 index f4102d466..000000000 --- a/src/com/magento/idea/magento2plugin/xml/index/StringSetDataExternalizer.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.magento.idea.magento2plugin.xml.index; - -import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.EnumeratorStringDescriptor; -import org.jetbrains.annotations.NotNull; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.util.HashSet; -import java.util.Set; - -/** - * Created by dkvashnin on 11/10/15. - */ -public class StringSetDataExternalizer implements DataExternalizer> { - - private final EnumeratorStringDescriptor myStringEnumerator = new EnumeratorStringDescriptor(); - - public synchronized void save(@NotNull DataOutput out, Set values) throws IOException { - - out.writeInt(values.size()); - for(String value: values) { - this.myStringEnumerator.save(out, value != null ? value : ""); - } - - } - - public synchronized Set read(@NotNull DataInput in) throws IOException { - Set set = new HashSet(); - int r = in.readInt(); - - while (r > 0) { - set.add(this.myStringEnumerator.read(in)); - r--; - } - - return set; - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java deleted file mode 100644 index 0c2867b7d..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/LayoutUtility.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout; - -import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.search.FilenameIndex; -import com.intellij.psi.xml.XmlFile; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/22/15. - */ -public class LayoutUtility { - public static boolean isLayoutFile(VirtualFile virtualFile) { - VirtualFile parent = virtualFile.getParent(); - return virtualFile.getFileType() == XmlFileType.INSTANCE && parent.isDirectory() && parent.getName().endsWith("layout"); - } - - public static boolean isLayoutFile(PsiFile psiFile) { - VirtualFile virtualFile = psiFile.getOriginalFile().getVirtualFile(); - return isLayoutFile(virtualFile); - } - - public static List getLayoutFiles(Project project, @Nullable String fileName) { - List results = new ArrayList(); - Collection xmlFiles = FilenameIndex.getAllFilesByExt(project, "xml"); - - PsiManager psiManager = PsiManager.getInstance(project); - for (VirtualFile xmlFile: xmlFiles) { - if (LayoutUtility.isLayoutFile(xmlFile)) { - if (fileName != null && !xmlFile.getNameWithoutExtension().equals(fileName)) { - continue; - } - - PsiFile file = psiManager.findFile(xmlFile); - if (file != null) { - results.add((XmlFile)file); - } - } - } - - return results; - } - - public static List getLayoutFiles(Project project) { - return getLayoutFiles(project, null); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java deleted file mode 100644 index 4272d091f..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/LayoutCompletionContributor.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.openapi.project.Project; -import com.intellij.patterns.XmlPatterns; -import com.intellij.psi.PsiElement; -import com.intellij.psi.xml.XmlFile; -import com.intellij.util.ProcessingContext; -import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; -import com.magento.idea.magento2plugin.php.util.MagentoTypes; -import com.magento.idea.magento2plugin.xml.XmlHelperUtility; -import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; -import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; -import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; -import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class LayoutCompletionContributor extends CompletionContributor { - private ReferenceComponentCompletionProvider containerCompletionProvider = new ReferenceComponentCompletionProvider(ContainerFileBasedIndex.NAME); - private ReferenceComponentCompletionProvider blockCompletionProvider = new ReferenceComponentCompletionProvider(BlockFileBasedIndex.NAME); - - - public LayoutCompletionContributor() { - extend( - CompletionType.BASIC, - XmlHelperUtility.getTagAttributePattern("block", "class"), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - PsiElement psiElement = completionParameters.getOriginalPosition(); - ImplementationMatcher completionContext = new ImplementationMatcher(MagentoTypes.BLOCK_TYPE); - completionResultSet.addAllElements( - ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext) - ); - - completionResultSet.addAllElements( - VirtualTypeCompletionProvider.INSTANCE.collectCompletionResult(psiElement) - ); - } - } - ); - - extend( - CompletionType.BASIC, - XmlHelperUtility.getTagAttributePattern("referenceContainer", "name"), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - PsiElement psiElement = completionParameters.getOriginalPosition(); - completionResultSet.addAllElements(containerCompletionProvider.collectCompletionResult(psiElement)); - } - } - ); - - extend( - CompletionType.BASIC, - XmlPatterns.or( - XmlHelperUtility.getTagAttributePattern("referenceBlock", "name"), - XmlHelperUtility.getTagAttributePattern("block", "before"), - XmlHelperUtility.getTagAttributePattern("block", "after"), - XmlHelperUtility.getTagAttributePattern("remove", "name"), - XmlHelperUtility.getTagAttributePattern("move", "element"), - XmlHelperUtility.getTagAttributePattern("move", "destination"), - XmlHelperUtility.getTagAttributePattern("move", "before"), - XmlHelperUtility.getTagAttributePattern("move", "after") - ), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - PsiElement psiElement = completionParameters.getOriginalPosition(); - completionResultSet.addAllElements(blockCompletionProvider.collectCompletionResult(psiElement)); - } - } - ); - - extend( - CompletionType.BASIC, - XmlHelperUtility.getTagAttributePattern("update", "handle"), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - PsiElement psiElement = completionParameters.getOriginalPosition(); - Project project = psiElement.getProject(); - for (XmlFile xmlFile: LayoutUtility.getLayoutFiles(project)) { - completionResultSet.addElement( - LookupElementBuilder.create(xmlFile.getVirtualFile().getNameWithoutExtension()) - ); - } - } - } - ); - } - -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java b/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java deleted file mode 100644 index ca6daaf67..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/completion/ReferenceComponentCompletionProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.completion; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.psi.PsiElement; -import com.intellij.util.indexing.ID; -import com.jetbrains.php.PhpIcons; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import com.magento.idea.magento2plugin.xml.completion.CompletionProviderI; -import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class ReferenceComponentCompletionProvider implements CompletionProviderI { - private ID indexId; - - public ReferenceComponentCompletionProvider(ID indexId) { - this.indexId = indexId; - } - - @Override - public List collectCompletionResult(PsiElement psiElement, @Nullable PsiContextMatcherI context) { - Collection keys = LayoutIndexUtility.getAllKeys(indexId, psiElement.getProject()); - - List results = new ArrayList<>(); - for (String key: keys) { - results.add( - LookupElementBuilder.create(key).withIcon(PhpIcons.XML_TAG_ICON) - ); - } - - return results; - } - - @Override - public List collectCompletionResult(PsiElement psiElement) { - return collectCompletionResult(psiElement, null); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java deleted file mode 100644 index 6cb598d14..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/AbstractComponentNameFileBasedIndex.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.index; - -import com.intellij.ide.highlighter.XmlFileType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.indexing.*; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; -import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/18/15. - */ -public abstract class AbstractComponentNameFileBasedIndex extends ScalarIndexExtension { - private EnumeratorStringDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); - - @NotNull - @Override - public KeyDescriptor getKeyDescriptor() { - return myKeyDescriptor; - } - - @NotNull - @Override - public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile virtualFile) { - return LayoutUtility.isLayoutFile(virtualFile); - } - }; - } - - @Override - public boolean dependsOnFileContent() { - return true; - } - - @Override - public int getVersion() { - return 0; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java deleted file mode 100644 index cfc9766f2..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockClassFileBasedIndex.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.index; - -import com.intellij.util.indexing.DataIndexer; -import com.intellij.util.indexing.FileContent; -import com.intellij.util.indexing.ID; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 11/20/15. - */ -public class BlockClassFileBasedIndex extends AbstractComponentNameFileBasedIndex { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.layout.index.block_class"); - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return new LayoutDataIndexer("block", "class"); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java deleted file mode 100644 index 7c2063309..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/BlockFileBasedIndex.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.index; - -import com.intellij.util.indexing.*; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class BlockFileBasedIndex extends AbstractComponentNameFileBasedIndex { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.layout.index.block_name"); - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return new LayoutDataIndexer("block", "name"); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java deleted file mode 100644 index f6d4935a0..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/ContainerFileBasedIndex.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.index; - -import com.intellij.util.indexing.*; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class ContainerFileBasedIndex extends AbstractComponentNameFileBasedIndex { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.layout.index.container_name"); - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return new LayoutDataIndexer("container", "name"); - } - - @Override - public int getVersion() { - return 1; - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java b/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java deleted file mode 100644 index a8f9798bb..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/index/util/LayoutIndexUtility.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.index.util; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.indexing.FileBasedIndex; -import com.intellij.util.indexing.ID; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.xml.index.LineMarkerXmlTagDecorator; -import com.magento.idea.magento2plugin.xml.layout.index.BlockClassFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.BlockFileBasedIndex; -import com.magento.idea.magento2plugin.xml.layout.index.ContainerFileBasedIndex; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/20/15. - */ -public class LayoutIndexUtility { - public static List getComponentDeclarations(String componentValue, String componentType, ID id, Project project, ComponentMatcher componentMatcher) { - List results = new ArrayList(); - Collection containingFiles = FileBasedIndex.getInstance() - .getContainingFiles( - id, - componentValue, - GlobalSearchScope.allScope(project) - ); - PsiManager psiManager = PsiManager.getInstance(project); - - for (VirtualFile virtualFile: containingFiles) { - XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); - if (xmlFile == null) { - continue; - } - - XmlTag rootTag = xmlFile.getRootTag(); - if (rootTag == null) { - continue; - } - collectComponentDeclarations(rootTag, results, componentValue, componentType, componentMatcher); - } - - return results; - } - - public static Collection getAllKeys(ID id, Project project) { - return FileBasedIndex.getInstance().getAllKeys(id, project); - } - - public static void collectComponentDeclarations(XmlTag parentTag, List results, String componentName, String componentType, ComponentMatcher componentMatcher) { - for (XmlTag childTag: parentTag.getSubTags()) { - if (componentType.equals(childTag.getName()) && componentMatcher.matches(componentName, childTag)) { - results.add(childTag); - } else if(childTag.getSubTags().length > 0 ) { - collectComponentDeclarations(childTag, results, componentName, componentType, componentMatcher); - } - } - } - - public static List getBlockDeclarations(String componentName, Project project) { - return getComponentDeclarations(componentName, "block", BlockFileBasedIndex.NAME, project, new NameComponentMatcher()); - } - - public static List getContainerDeclarations(String componentName, Project project) { - return getComponentDeclarations(componentName, "container", ContainerFileBasedIndex.NAME, project, new NameComponentMatcher()); - } - - public static List getBlockClassDeclarations(PhpClass phpClass, Project project) { - String className = phpClass.getPresentableFQN(); - - List blockTags = getComponentDeclarations(className, "block", BlockClassFileBasedIndex.NAME, project, new ClassComponentMatcher()); - List decoratedBlockTags = new ArrayList<>(); - for (XmlTag blockTag: blockTags) { - decoratedBlockTags.add(new LayoutBlockLineMarkerXmlTagDecorator(blockTag)); - } - return decoratedBlockTags; - } -} - -interface ComponentMatcher { - boolean matches(String value, XmlTag tag); -} - -class NameComponentMatcher implements ComponentMatcher { - @Override - public boolean matches(String value, XmlTag tag) { - return value.equals(tag.getAttributeValue("name")); - } -} - -class ClassComponentMatcher implements ComponentMatcher { - @Override - public boolean matches(String value, XmlTag tag) { - return value.equals(tag.getAttributeValue("class")); - } -} - -/** - * Decorator for XmlTag, which improves readability of "block" node in configuration line marker. - */ -class LayoutBlockLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - - public LayoutBlockLineMarkerXmlTagDecorator(XmlTag xmlTag) { - super(xmlTag); - } - - @NotNull - @Override - protected String getAreaName() { - return xmlTag.getContainingFile().getVirtualFile().getParent().getParent().getName(); - } - - @NotNull - @Override - public String getDescription() { - String name = xmlTag.getAttributeValue("name"); - if (name != null) { - return String.format("block %s", name); - } - return xmlTag.getName(); - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java deleted file mode 100644 index ccd1f1743..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/LayoutReferenceContributor.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.reference; - -import com.intellij.patterns.XmlPatterns; -import com.intellij.psi.*; -import com.intellij.util.ProcessingContext; -import com.magento.idea.magento2plugin.xml.XmlHelperUtility; -import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; -import com.magento.idea.magento2plugin.xml.layout.LayoutUtility; -import com.magento.idea.magento2plugin.xml.layout.reference.fill.BlockResultsFiller; -import com.magento.idea.magento2plugin.xml.layout.reference.fill.ContainerResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.TypeReference; -import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.List; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class LayoutReferenceContributor extends PsiReferenceContributor { - @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelperUtility.getTagAttributeValuePattern("block", "class"), - new LayoutReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - - psiReferenceRegistrar.registerReferenceProvider( - XmlPatterns.or( - XmlHelperUtility.getTagAttributeValuePattern("referenceBlock", "name"), - XmlHelperUtility.getTagAttributeValuePattern("block", "before"), - XmlHelperUtility.getTagAttributeValuePattern("block", "after"), - XmlHelperUtility.getTagAttributeValuePattern("remove", "name"), - XmlHelperUtility.getTagAttributeValuePattern("move", "element"), - XmlHelperUtility.getTagAttributeValuePattern("move", "destination"), - XmlHelperUtility.getTagAttributeValuePattern("move", "before"), - XmlHelperUtility.getTagAttributeValuePattern("move", "after") - ), - new LayoutReferenceProvider( - new ReferenceResultsFiller[]{ - new BlockResultsFiller() - } - ) - ); - - psiReferenceRegistrar.registerReferenceProvider( - XmlHelperUtility.getTagAttributeValuePattern("referenceContainer", "name"), - new LayoutReferenceProvider( - new ReferenceResultsFiller[]{ - new ContainerResultsFiller() - } - ) - ); - - psiReferenceRegistrar.registerReferenceProvider( - XmlHelperUtility.getTagAttributeValuePattern("update", "handle"), - new LayoutReferenceProvider( - new ReferenceResultsFiller[]{ - new ReferenceResultsFiller() { - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - results.addAll( - Arrays.asList( - PsiElementResolveResult.createResults( - LayoutUtility.getLayoutFiles(psiElement.getProject(), typeName) - ) - ) - ); - } - } - } - ) - ); - } - - private class LayoutReferenceProvider extends PsiReferenceProvider { - private final ReferenceResultsFiller[] resultsFillers; - - public LayoutReferenceProvider(ReferenceResultsFiller[] resultsFillers) { - super(); - this.resultsFillers = resultsFillers; - } - - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { - PsiFile containingFile = psiElement.getContainingFile(); - if (!LayoutUtility.isLayoutFile(containingFile)) { - return new PsiReference[0]; - } - - return new PsiReference[]{new TypeReference(psiElement, resultsFillers)}; - } - } - -} diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java deleted file mode 100644 index 1071ef103..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/BlockResultsFiller.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.reference.fill; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.xml.XmlTag; -import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; - -import java.util.Arrays; -import java.util.List; - -/** - * Created by dkvashnin on 11/20/15. - */ -public class BlockResultsFiller implements ReferenceResultsFiller { - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - List componentDeclarations = LayoutIndexUtility - .getBlockDeclarations( - typeName, - psiElement.getProject() - ); - - ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); - results.addAll(Arrays.asList(resolveResults)); - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java deleted file mode 100644 index 3cf4d1324..000000000 --- a/src/com/magento/idea/magento2plugin/xml/layout/reference/fill/ContainerResultsFiller.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.magento.idea.magento2plugin.xml.layout.reference.fill; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.xml.XmlTag; -import com.magento.idea.magento2plugin.xml.layout.index.util.LayoutIndexUtility; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; - -import java.util.Arrays; -import java.util.List; - -/** - * Created by dkvashnin on 11/18/15. - */ -public class ContainerResultsFiller implements ReferenceResultsFiller { - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - List componentDeclarations = LayoutIndexUtility - .getContainerDeclarations( - typeName, - psiElement.getProject() - ); - - ResolveResult[] resolveResults = PsiElementResolveResult.createResults(componentDeclarations); - results.addAll(Arrays.asList(resolveResults)); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java deleted file mode 100644 index 1a60455e6..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/XmlHelper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer; - -import com.intellij.patterns.XmlAttributeValuePattern; -import com.magento.idea.magento2plugin.xml.XmlHelperUtility; - -/** - * Created by dkvashnin on 11/17/15. - */ -public class XmlHelper extends XmlHelperUtility { - public static final String FILE_TYPE = "events"; - - public static final String OBSERVER_TAG = "observer"; - public static final String EVENT_TAG = "event"; - - public static final String NAME_ATTRIBUTE = "name"; - public static final String INSTANCE_ATTRIBUTE = "instance"; - - /** - * - */ - public static XmlAttributeValuePattern getTagAttributeValuePattern(String tagName, String attributeName) { - return getTagAttributeValuePattern(tagName, attributeName, FILE_TYPE); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java deleted file mode 100644 index b0cd063d3..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/completion/EventCompletionContributor.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.psi.PsiElement; -import com.intellij.util.ProcessingContext; -import com.intellij.util.indexing.FileBasedIndex; -import com.magento.idea.magento2plugin.php.util.MagentoTypes; -import com.magento.idea.magento2plugin.xml.XmlHelperUtility; -import com.magento.idea.magento2plugin.xml.completion.ClassCompletionProvider; -import com.magento.idea.magento2plugin.xml.completion.VirtualTypeCompletionProvider; -import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; -import com.magento.idea.magento2plugin.xml.observer.XmlHelper; -import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; - -/** - * Created by dkvashnin on 11/17/15. - */ -public class EventCompletionContributor extends CompletionContributor { - public EventCompletionContributor() { - extend( - CompletionType.BASIC, - XmlHelperUtility.getTagAttributePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE, XmlHelper.FILE_TYPE), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - ImplementationMatcher completionContext = new ImplementationMatcher(MagentoTypes.OBSERVER_TYPE); - PsiElement psiElement = completionParameters.getOriginalPosition(); - - completionResultSet.addAllElements( - ClassCompletionProvider.INSTANCE.collectCompletionResult(psiElement, completionContext) - ); - completionResultSet.addAllElements(VirtualTypeCompletionProvider.INSTANCE.collectCompletionResult(psiElement)); - } - } - ); - - extend( - CompletionType.BASIC, - XmlHelperUtility.getTagAttributePattern(XmlHelper.EVENT_TAG, XmlHelper.NAME_ATTRIBUTE, XmlHelper.FILE_TYPE), - new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters completionParameters, ProcessingContext processingContext, @NotNull CompletionResultSet completionResultSet) { - PsiElement psiElement = completionParameters.getOriginalPosition(); - Collection eventNames = FileBasedIndex.getInstance().getAllKeys(EventsDeclarationsFileBasedIndex.NAME, psiElement.getProject()); - - for (String eventName: eventNames) { - completionResultSet.addElement(LookupElementBuilder.create(eventName)); - } - } - } - ); - } - -} - diff --git a/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java b/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java deleted file mode 100644 index 76a81002f..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/index/EventsDeclarationsFileBasedIndex.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.index; - -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; - -import com.intellij.patterns.ElementPattern; -import com.intellij.patterns.PlatformPatterns; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.indexing.*; -import com.intellij.util.io.EnumeratorStringDescriptor; -import com.intellij.util.io.KeyDescriptor; -import com.jetbrains.php.lang.PhpFileType; -import com.jetbrains.php.lang.PhpLanguage; -import com.jetbrains.php.lang.patterns.PhpPatterns; -import com.jetbrains.php.lang.psi.PhpFile; -import com.jetbrains.php.lang.psi.elements.MethodReference; -import com.jetbrains.php.lang.psi.elements.ParameterList; -import com.magento.idea.magento2plugin.Settings; -import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by dkvashnin on 11/5/15. - */ -public class EventsDeclarationsFileBasedIndex extends ScalarIndexExtension { - public static final ID NAME = ID.create("com.magento.idea.magento2plugin.xml.observer.index.events"); - private final KeyDescriptor myKeyDescriptor = new EnumeratorStringDescriptor(); - - @NotNull - @Override - public ID getName() { - return NAME; - } - - @NotNull - @Override - public DataIndexer getIndexer() { - return new DataIndexer() { - @NotNull - @Override - public Map map(@NotNull FileContent fileContent) { - Map map = new HashMap<>(); - PhpFile phpFile = (PhpFile)fileContent.getPsiFile(); - - if (!Settings.isEnabled(phpFile.getProject())) { - return map; - } - - List results = new ArrayList(); - recursiveFill(results, phpFile); - for (String result: results) { - map.put(result, null); - } - - return map; - } - - private void recursiveFill(List results, PsiElement psiElement) { - if (PhpPatternsHelper.STRING_METHOD_ARGUMENT.accepts(psiElement) && isInContextOfDispatchMethod(psiElement)) { - String eventName= StringUtil.unquoteString(psiElement.getText()); - if (eventName.length() > 0) { - results.add(eventName); - } - - return; - } - - for(PsiElement child: psiElement.getChildren()) { - recursiveFill(results, child); - } - } - - private boolean isInContextOfDispatchMethod(PsiElement psiElement) { - ParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, ParameterList.class); - - if (parameterList == null) { - return false; - } - - if(!(parameterList.getContext() instanceof MethodReference)) { - return false; - } - - MethodReference methodReference = (MethodReference)parameterList.getContext(); - if (!methodReference.getName().equals("dispatch")) { - return false; - } - - return true; - } - }; - } - - @NotNull - @Override - public KeyDescriptor getKeyDescriptor() { - return myKeyDescriptor; - } - - @NotNull - @Override - public FileBasedIndex.InputFilter getInputFilter() { - return new FileBasedIndex.InputFilter() { - @Override - public boolean acceptInput(@NotNull VirtualFile file) { - return file.getFileType() == PhpFileType.INSTANCE; - } - }; - } - - @Override - public boolean dependsOnFileContent() { - return true; - } - - @Override - public int getVersion() { - return 1; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java deleted file mode 100644 index ab84e86b7..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceContributor.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.reference; - -import com.intellij.psi.*; -import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; -import com.magento.idea.magento2plugin.xml.observer.reference.util.ClassResultsFillerWrapper; -import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsConfigurationFilesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 11/2/15. - */ -public class EventReferenceContributor extends PsiReferenceContributor { - @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { - psiReferenceRegistrar.registerReferenceProvider( - PhpPatternsHelper.STRING_METHOD_ARGUMENT, - new EventReferenceProvider( - new ReferenceResultsFiller[] { - EventsConfigurationFilesResultsFiller.INSTANCE, - ClassResultsFillerWrapper.INSTANCE - } - ) - ); - } - -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java deleted file mode 100644 index e1be2efdc..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/EventReferenceProvider.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.reference; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiReferenceProvider; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.ProcessingContext; -import com.jetbrains.php.lang.psi.elements.Method; -import com.jetbrains.php.lang.psi.elements.MethodReference; -import com.jetbrains.php.lang.psi.elements.ParameterList; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.php.util.MagentoTypes; -import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; -import com.magento.idea.magento2plugin.xml.reference.TypeReference; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import org.jetbrains.annotations.NotNull; - -/** -* Created by dkvashnin on 11/3/15. -*/ -class EventReferenceProvider extends PsiReferenceProvider { - private final ReferenceResultsFiller[] resultsFillers; - private static final String DISPATCH_METHOD = "dispatch"; - - public EventReferenceProvider(ReferenceResultsFiller[] resultsFillers) { - this.resultsFillers = resultsFillers; - } - - @NotNull - @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { - ParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, ParameterList.class); - - if (parameterList == null) { - return new PsiReference[0]; - } - - if(!(parameterList.getContext() instanceof MethodReference)) { - return new PsiReference[0]; - } - - MethodReference methodReference = (MethodReference)parameterList.getContext(); - if (!DISPATCH_METHOD.equals(methodReference.getName())) { - return new PsiReference[0]; - } - - PsiElement resolvedElement = methodReference.resolve(); - if (resolvedElement != null && resolvedElement instanceof Method) { - PhpClass containingClass = ((Method) resolvedElement).getContainingClass(); - - if (containingClass != null && MagentoTypes.EVENT_MANAGER_TYPE.equals(containingClass.getPresentableFQN())) { - return new PsiReference[]{new TypeReference(psiElement, this.resultsFillers, true)}; - } - } - - - return new PsiReference[0]; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java deleted file mode 100644 index c90e2d50c..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/ObserverReferenceContributor.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.reference; - -import com.intellij.psi.*; -import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; -import com.magento.idea.magento2plugin.xml.observer.XmlHelper; -import com.magento.idea.magento2plugin.xml.observer.reference.util.EventsDeclarationsFilesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; -import org.jetbrains.annotations.NotNull; - - -/** - * Created by dkvashnin on 11/2/15. - */ -public class ObserverReferenceContributor extends PsiReferenceContributor { - @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { - // - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getTagAttributeValuePattern(XmlHelper.OBSERVER_TAG, XmlHelper.INSTANCE_ATTRIBUTE), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - ClassesResultsFiller.INSTANCE, - VirtualTypesResultsFiller.INSTANCE - } - ) - ); - - psiReferenceRegistrar.registerReferenceProvider( - XmlHelper.getTagAttributeValuePattern(XmlHelper.EVENT_TAG, XmlHelper.NAME_ATTRIBUTE), - new XmlReferenceProvider( - new ReferenceResultsFiller[]{ - EventsDeclarationsFilesResultsFiller.INSTANCE - } - ) - ); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java deleted file mode 100644 index df1ab025b..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/ClassResultsFillerWrapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.reference.util; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.indexing.FileBasedIndex; -import com.magento.idea.magento2plugin.xml.observer.index.EventObserverFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ClassesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.VirtualTypesResultsFiller; - -import java.util.List; -import java.util.Set; - -/** - * Created by dkvashnin on 11/3/15. - */ -public class ClassResultsFillerWrapper implements ReferenceResultsFiller { - public static final ReferenceResultsFiller INSTANCE = new ClassResultsFillerWrapper(); - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - List> observersTypesList = FileBasedIndex.getInstance().getValues( - EventObserverFileBasedIndex.NAME, - typeName, - GlobalSearchScope.allScope(psiElement.getProject()) - ); - - for (Set observerTypes: observersTypesList) { - for (String type: observerTypes) { - ClassesResultsFiller.INSTANCE.fillResolveResults(psiElement, results, type); - VirtualTypesResultsFiller.INSTANCE.fillResolveResults(psiElement, results, type); - } - } - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java deleted file mode 100644 index 04aeae84d..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsConfigurationFilesResultsFiller.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.reference.util; - -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.xml.XmlFile; -import com.intellij.util.indexing.FileBasedIndex; -import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; -import com.magento.idea.magento2plugin.xml.observer.index.EventObserverFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; - -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/3/15. - */ -public class EventsConfigurationFilesResultsFiller implements ReferenceResultsFiller { - public static final ReferenceResultsFiller INSTANCE = new EventsConfigurationFilesResultsFiller(); - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - Collection containingFiles = FileBasedIndex - .getInstance() - .getContainingFiles( - EventObserverFileBasedIndex.NAME, - typeName, - GlobalSearchScope.allScope(psiElement.getProject()) - ); - - PsiManager psiManager = PsiManager.getInstance(psiElement.getProject()); - for (VirtualFile virtualFile: containingFiles) { - XmlFile xmlFile = (XmlFile)psiManager.findFile(virtualFile); - if (xmlFile != null) { - results.add(new PhpResolveResult(xmlFile)); - } - } - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java deleted file mode 100644 index bf707e386..000000000 --- a/src/com/magento/idea/magento2plugin/xml/observer/reference/util/EventsDeclarationsFilesResultsFiller.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.magento.idea.magento2plugin.xml.observer.reference.util; - -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.indexing.FileBasedIndex; -import com.jetbrains.php.lang.psi.PhpFile; -import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; -import com.magento.idea.magento2plugin.xml.observer.PhpPatternsHelper; -import com.magento.idea.magento2plugin.xml.observer.index.EventsDeclarationsFileBasedIndex; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; - -import java.util.Collection; -import java.util.List; - -/** - * Created by dkvashnin on 11/5/15. - */ -public class EventsDeclarationsFilesResultsFiller implements ReferenceResultsFiller { - public static final ReferenceResultsFiller INSTANCE = new EventsDeclarationsFilesResultsFiller(); - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - Collection containingFiles = FileBasedIndex - .getInstance() - .getContainingFiles( - EventsDeclarationsFileBasedIndex.NAME, - typeName, - GlobalSearchScope.allScope(psiElement.getProject()) - ); - - PsiManager psiManager = PsiManager.getInstance(psiElement.getProject()); - for (VirtualFile virtualFile: containingFiles) { - PhpFile phpFile = (PhpFile)psiManager.findFile(virtualFile); - if (phpFile != null) { - recursiveFill(results, phpFile, typeName); - } - } - } - - private void recursiveFill(List results, PsiElement psiElement, String typeName) { - if (PhpPatternsHelper.STRING_METHOD_ARGUMENT.accepts(psiElement)) { - if (StringUtil.unquoteString(psiElement.getText()).equals(typeName)) { - results.add(new PhpResolveResult(psiElement)); - } - return; - } - - for(PsiElement child: psiElement.getChildren()) { - recursiveFill(results, child, typeName); - } - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java b/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java deleted file mode 100644 index 31dbf5563..000000000 --- a/src/com/magento/idea/magento2plugin/xml/reference/TypeReference.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.magento.idea.magento2plugin.xml.reference; - -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiPolyVariantReferenceBase; -import com.intellij.psi.ResolveResult; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Warider on 17.08.2015. - */ -public class TypeReference extends PsiPolyVariantReferenceBase { - private final boolean greedy; - - private ReferenceResultsFiller[] resultsFillers; - - public TypeReference(@NotNull PsiElement element, ReferenceResultsFiller[] resultsFillers) { - this(element, resultsFillers, false); - } - - public TypeReference(@NotNull PsiElement element, ReferenceResultsFiller[] resultsFillers, boolean greedy) { - super(element); - - this.resultsFillers = resultsFillers; - this.greedy = greedy; - } - - @NotNull - @Override - public ResolveResult[] multiResolve(boolean incompleteCode) { - List resolveResults = new ArrayList<>(); - String typeName = StringUtil.unquoteString(getElement().getText()); - - for (ReferenceResultsFiller referenceResultsFiller : resultsFillers) { - referenceResultsFiller.fillResolveResults(getElement(), resolveResults, typeName); - if (!greedy && resolveResults.size() > 0) { - break; - } - } - - return resolveResults.toArray(new ResolveResult[resolveResults.size()]); - } - - @NotNull - @Override - public Object[] getVariants() { - return new Object[0]; - } -} - diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java deleted file mode 100644 index cce7c8310..000000000 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ClassesResultsFiller.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.magento.idea.magento2plugin.xml.reference.util; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.ResolveResult; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.PhpLangUtil; -import com.jetbrains.php.lang.psi.elements.PhpClass; - -import java.util.List; - -/** - * Created by dkvashnin on 11/3/15. - */ -public class ClassesResultsFiller implements ReferenceResultsFiller { - public static final ReferenceResultsFiller INSTANCE = new ClassesResultsFiller(); - - private ClassesResultsFiller() {} - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - - for (PhpClass phpClass : phpIndex.getClassesByFQN(PhpLangUtil.toFQN(typeName))) { - addResult(results, phpClass); - } - } - - protected void addResult(List results, PhpClass phpClass) { - results.add(new PsiElementResolveResult(phpClass)); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java deleted file mode 100644 index 66fe5a4b8..000000000 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ImplementationContextDecorator.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.magento.idea.magento2plugin.xml.reference.util; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.ResolveResult; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.php.util.ImplementationMatcher; - -import java.util.List; - -/** - * Created by dkvashnin on 12/18/15. - */ -public class ImplementationContextDecorator implements ReferenceResultsFiller { - private ReferenceResultsFiller subject; - private ImplementationMatcher implementationMatcher; - - public ImplementationContextDecorator(ReferenceResultsFiller subject, ImplementationMatcher implementationMatcher) { - this.subject = subject; - this.implementationMatcher = implementationMatcher; - } - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - subject.fillResolveResults(psiElement, results, typeName); - - for (ResolveResult resolveResult : results) { - PsiElement element = resolveResult.getElement(); - - if (element instanceof PhpClass && !implementationMatcher.match(element)) { - results.remove(resolveResult); - } - } - - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java deleted file mode 100644 index 4b53a716c..000000000 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/InterfacesResultsFiller.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.magento.idea.magento2plugin.xml.reference.util; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.ResolveResult; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.PhpLangUtil; -import com.jetbrains.php.lang.psi.elements.PhpClass; - -import java.util.List; - -/** - * Created by dkvashnin on 11/3/15. - */ -public class InterfacesResultsFiller implements ReferenceResultsFiller { - public static final ReferenceResultsFiller INSTANCE = new InterfacesResultsFiller(); - - private InterfacesResultsFiller() {} - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - PhpIndex phpIndex = PhpIndex.getInstance(psiElement.getProject()); - - for (PhpClass phpClass : phpIndex.getInterfacesByFQN(PhpLangUtil.toFQN(typeName))) { - results.add(new PsiElementResolveResult(phpClass)); - } - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java deleted file mode 100644 index 25bdbbf3c..000000000 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/ReferenceResultsFiller.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.magento.idea.magento2plugin.xml.reference.util; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.ResolveResult; - -import java.util.List; - -/** - * Created by dkvashnin on 11/3/15. - */ -public interface ReferenceResultsFiller { - public void fillResolveResults(PsiElement psiElement, List results, String typeName); -} diff --git a/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java deleted file mode 100644 index 77edfd3b5..000000000 --- a/src/com/magento/idea/magento2plugin/xml/reference/util/VirtualTypesResultsFiller.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.magento.idea.magento2plugin.xml.reference.util; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.xml.XmlAttributeValue; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; - -import java.util.List; - -/** - * Created by dkvashnin on 11/3/15. - */ -public class VirtualTypesResultsFiller implements ReferenceResultsFiller { - public static final ReferenceResultsFiller INSTANCE = new VirtualTypesResultsFiller(); - - private VirtualTypesResultsFiller() {} - - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - XmlAttributeValue[] virtualTypesByName = VirtualTypesNamesFileBasedIndex.getVirtualTypesByName( - psiElement.getProject(), - typeName, - psiElement.getResolveScope() - ); - - for (XmlAttributeValue virtualType: virtualTypesByName) { - results.add(new PsiElementResolveResult(virtualType)); - } - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java b/src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java deleted file mode 100644 index 69500cf85..000000000 --- a/src/com/magento/idea/magento2plugin/xml/util/ParentTypeMatcher.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.magento.idea.magento2plugin.xml.util; - -import com.intellij.psi.PsiElement; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import org.jetbrains.annotations.Nullable; - -/** -* Created by dkvashnin on 12/25/15. -*/ -public class ParentTypeMatcher implements PsiContextMatcherI { - private PhpClass parentType; - - public ParentTypeMatcher(PhpClass parentType) { - this.parentType = parentType; - } - - @Override - public boolean match(PsiElement psiElement) { - if (!(psiElement instanceof PhpClass)) { - return false; - } - - return parentType.equals(psiElement) - || match(((PhpClass)psiElement).getImplementedInterfaces()) - || match(((PhpClass) psiElement).getSuperClass()); - } - - public boolean match(@Nullable PhpClass[] probableMistakes) { - if (probableMistakes == null) { - return false; - } - - boolean result = false; - - for (PhpClass probableMistake : probableMistakes) { - result = parentType.equals(probableMistake) || match(probableMistake.getImplementedInterfaces()); - } - - return result; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java b/src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java deleted file mode 100644 index b83b95ee9..000000000 --- a/src/com/magento/idea/magento2plugin/xml/util/VirtualTypeParentMatcher.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.magento.idea.magento2plugin.xml.util; - -import com.intellij.openapi.project.Project; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.util.PsiContextMatcherI; -import com.magento.idea.magento2plugin.xml.di.completion.DiCompletionContributor; -import com.magento.idea.magento2plugin.xml.di.index.VirtualTypesNamesFileBasedIndex; - -import java.util.List; - -/** -* Created by dkvashnin on 12/25/15. -*/ -public class VirtualTypeParentMatcher implements PsiContextMatcherI { - private ParentTypeMatcher parentTypeMatcher; - private Project project; - - public VirtualTypeParentMatcher(ParentTypeMatcher parentTypeMatcher, Project project) { - this.parentTypeMatcher = parentTypeMatcher; - this.project = project; - } - - @Override - public boolean match(String virtualType) { - List superParentTypes = VirtualTypesNamesFileBasedIndex.getSuperParentTypes(project, virtualType); - - return parentTypeMatcher.match( - superParentTypes.toArray(new PhpClass[superParentTypes.size()]) - ); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java b/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java deleted file mode 100644 index cbd6e4b73..000000000 --- a/src/com/magento/idea/magento2plugin/xml/webapi/XmlHelper.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.magento.idea.magento2plugin.xml.webapi; - -import com.intellij.patterns.PsiElementPattern; -import com.intellij.patterns.XmlAttributeValuePattern; -import com.intellij.patterns.XmlPatterns; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlTag; -import com.intellij.psi.xml.XmlTokenType; -import com.magento.idea.magento2plugin.xml.XmlHelperUtility; -import org.jetbrains.annotations.Nullable; - -/** - * Created by isentiabov on 20.12.2015. - */ -public class XmlHelper extends XmlHelperUtility { - public static final String FILE_TYPE = "webapi"; - public static final String SERVICE_TAG = "service"; - public static final String METHOD_ATTRIBUTE = "method"; - public static final String CLASS_ATTRIBUTE = "class"; - - /** - * - */ - public static XmlAttributeValuePattern getMethodAttributePattern() { - return getTagAttributeValuePattern(SERVICE_TAG, METHOD_ATTRIBUTE, FILE_TYPE); - } - - /** - * - */ - public static PsiElementPattern.Capture getTagAttributePattern(String tag, String attributeName) { - return getTagAttributePattern(tag, attributeName, FILE_TYPE); - } - - @Nullable - public static XmlAttribute getInterfaceAttributeByMethod(PsiElement psiElement) - { - // get service xml tag `method` attribute - XmlAttribute methodAttribute = PsiTreeUtil.getParentOfType(psiElement, XmlAttribute.class); - if (methodAttribute == null) { - return null; - } - - // get service xml tag - XmlTag serviceTag = PsiTreeUtil.getParentOfType(methodAttribute, XmlTag.class); - if (serviceTag == null) { - return null; - } - - // get service xml tag `class` attribute - return serviceTag.getAttribute(CLASS_ATTRIBUTE); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java b/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java deleted file mode 100644 index 61ef95a50..000000000 --- a/src/com/magento/idea/magento2plugin/xml/webapi/completion/WebApiCompletionContributor.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.magento.idea.magento2plugin.xml.webapi.completion; - -import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReference; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.util.ProcessingContext; -import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.lang.psi.elements.Method; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.xml.completion.InterfaceCompletionProvider; -import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * Created by mslabko on 10/15/15. - */ -public class WebApiCompletionContributor extends CompletionContributor { - public WebApiCompletionContributor() { - // add services to list - extend( - CompletionType.BASIC, - XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.CLASS_ATTRIBUTE), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - PsiElement psiElement = parameters.getOriginalPosition(); - - resultSet.addAllElements(InterfaceCompletionProvider.INSTANCE.collectCompletionResult(psiElement)); - } - } - ); - - // Add service methods to list - extend( - CompletionType.BASIC, - XmlHelper.getTagAttributePattern(XmlHelper.SERVICE_TAG, XmlHelper.METHOD_ATTRIBUTE), - new CompletionProvider() { - public void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - - PsiElement psiElement = parameters.getOriginalPosition(); - - PhpClass serviceInterface = getServiceInterface(psiElement); - if (serviceInterface != null) { - for (Method serviceMethod : serviceInterface.getMethods()) { - - resultSet.addElement( - LookupElementBuilder - .create(serviceMethod.getName()) - .withIcon(PhpIcons.METHOD_ICON) - ); - } - } - } - } - ); - } - - @Nullable - private PhpClass getServiceInterface(PsiElement psiElement) { - XmlAttribute classAttribute = XmlHelper.getInterfaceAttributeByMethod(psiElement); - if (classAttribute == null) { - return null; - } - - XmlAttributeValue xmlAttributeValue = classAttribute.getValueElement(); - - if (xmlAttributeValue == null) { - return null; - } - - PsiReference reference = xmlAttributeValue.getReference(); - if (reference == null) { - return null; - } - - PsiElement element = reference.resolve(); - - if (element instanceof PhpClass) { - return (PhpClass) element; - } - - return null; - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java deleted file mode 100644 index 1ee70712d..000000000 --- a/src/com/magento/idea/magento2plugin/xml/webapi/reference/ServiceReferenceContributor.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.magento.idea.magento2plugin.xml.webapi.reference; - -import com.intellij.patterns.XmlAttributeValuePattern; -import com.intellij.psi.PsiReferenceContributor; -import com.intellij.psi.PsiReferenceRegistrar; -import com.magento.idea.magento2plugin.xml.di.reference.provider.XmlReferenceProvider; -import com.magento.idea.magento2plugin.xml.reference.util.InterfacesResultsFiller; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; -import com.magento.idea.magento2plugin.xml.webapi.reference.fill.ServiceMethodResultsFiller; -import org.jetbrains.annotations.NotNull; - -/** - * Created by isentiabov on 20.12.2015. - */ -public class ServiceReferenceContributor extends PsiReferenceContributor{ - @Override - public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) { - // - XmlAttributeValuePattern serviceTag = XmlHelper.getTagAttributeValuePattern( - XmlHelper.SERVICE_TAG, - XmlHelper.CLASS_ATTRIBUTE - ); - psiReferenceRegistrar.registerReferenceProvider( - serviceTag, - new XmlReferenceProvider(new ReferenceResultsFiller[]{ - InterfacesResultsFiller.INSTANCE - })); - - // - XmlAttributeValuePattern methodAttribute = XmlHelper.getMethodAttributePattern(); - psiReferenceRegistrar.registerReferenceProvider( - methodAttribute, - new XmlReferenceProvider(new ReferenceResultsFiller[]{ - new ServiceMethodResultsFiller() - }) - ); - } -} diff --git a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java b/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java deleted file mode 100644 index 65d0d665c..000000000 --- a/src/com/magento/idea/magento2plugin/xml/webapi/reference/fill/ServiceMethodResultsFiller.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.magento.idea.magento2plugin.xml.webapi.reference.fill; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.xml.XmlAttribute; -import com.intellij.psi.xml.XmlAttributeValue; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.Method; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.jetbrains.php.lang.psi.resolve.PhpResolveResult; -import com.magento.idea.magento2plugin.xml.reference.util.ReferenceResultsFiller; -import com.magento.idea.magento2plugin.xml.webapi.XmlHelper; -import org.jetbrains.annotations.Nullable; - -import java.util.Iterator; -import java.util.List; - -/** - * Created by isentiabov on 20.12.2015. - */ -public class ServiceMethodResultsFiller implements ReferenceResultsFiller { - @Override - public void fillResolveResults(PsiElement psiElement, List results, String typeName) { - XmlAttribute classAttribute = XmlHelper.getInterfaceAttributeByMethod(psiElement); - if (classAttribute == null) { - return; - } - - PhpClass serviceInterface = getServiceInterface(classAttribute); - if (serviceInterface == null) { - return; - } - - fillResults(serviceInterface, results, typeName); - } - - - - @Nullable - protected PhpClass getServiceInterface(XmlAttribute xmlAttribute) { - XmlAttributeValue value = xmlAttribute.getValueElement(); - if (value == null) { - return null; - } - - PhpIndex phpIndex = PhpIndex.getInstance(xmlAttribute.getProject()); - - Iterator iterator = phpIndex.getInterfacesByFQN(value.getValue()).iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } - - return null; - } - - protected void fillResults(PhpClass serviceInterface, List results, String typeName) { - for (Method method : serviceInterface.getMethods()) { - if (method.getName().equals(typeName)) { - results.add( - new PhpResolveResult(method) - ); - - break; - } - } - } -} From 502c1635b842dad13eea4714e094a80e6ad717b9 Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Fri, 8 Dec 2017 16:20:39 +0200 Subject: [PATCH 46/51] Remove unused code --- META-INF/plugin.xml | 19 ---- .../icons/interception_reference.png | Bin 1335 -> 0 bytes .../icons/interception_reference@2x.png | Bin 2824 -> 0 bytes .../magento2plugin/icons/webapi_reference.png | Bin 627 -> 0 bytes .../icons/webapi_reference@2x.png | Bin 1328 -> 0 bytes .../magento2plugin/icons/xml_reference.png | Bin 1190 -> 0 bytes .../magento2plugin/icons/xml_reference@2x.png | Bin 2192 -> 0 bytes .../php/inspections/MagentoApiInspection.java | 107 ------------------ .../inspections/ObjectManagerInspection.java | 97 ---------------- .../magento2plugin/php/tool/ModuleTool.form | 26 ----- .../php/tool/ModuleToolWindowFactory.java | 66 ----------- .../magento2plugin/php/util/MagentoTypes.java | 11 -- .../MagentoApiInspection.html | 5 - .../ObjectManagerInspection.html | 5 - 14 files changed, 336 deletions(-) delete mode 100644 src/com/magento/idea/magento2plugin/icons/interception_reference.png delete mode 100644 src/com/magento/idea/magento2plugin/icons/interception_reference@2x.png delete mode 100644 src/com/magento/idea/magento2plugin/icons/webapi_reference.png delete mode 100644 src/com/magento/idea/magento2plugin/icons/webapi_reference@2x.png delete mode 100644 src/com/magento/idea/magento2plugin/icons/xml_reference.png delete mode 100644 src/com/magento/idea/magento2plugin/icons/xml_reference@2x.png delete mode 100644 src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java delete mode 100644 src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java delete mode 100644 src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form delete mode 100644 src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java delete mode 100644 src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java delete mode 100644 src/inspectionDescriptions/MagentoApiInspection.html delete mode 100644 src/inspectionDescriptions/ObjectManagerInspection.html diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 2dc7afcfd..0d44e98f7 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -108,13 +108,6 @@ com.intellij.modules.platform - - @@ -147,17 +139,6 @@ - - - - - - - - - - - diff --git a/src/com/magento/idea/magento2plugin/icons/interception_reference.png b/src/com/magento/idea/magento2plugin/icons/interception_reference.png deleted file mode 100644 index f6271f132ac0a27bdc4b3a39edd52aef9a2a36a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1335 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P{HZUkcg59UmvUF{9L`nl>DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtHP6qmLm5Rd1sY@-CA1Az=#^1qQAi7tkhHMA>m^>YcS^U|?qTba4!^5cHkw zpCKD6a;!f6-I+c6zAUZOzwpe|#A|EBl!WfJS69uDT3a?zFKWeFZNbeUj*c2!p9J3C z5-Zo^I@%f`ur(>VG%#9Gb%zGqNB*UXUjJK6DtRaG^Gkbn_Tw3r)#C5&SeKvsKKFgi z^S%UUd;14Zj!wQ?^#9|DykGC{dtdm>a!Bk=<13NV-ojg!@1J_>i#f983a^k-kHi&}09MQ@T_cF=aQ`i}h55{ZW! z3Z3>OoZQ>6A#Zg`N3fIq66u3eS8hHtzcTV(>b3=K&y?jilqK}|t=Y0%=u=+nvBM9T zo<4KsE?~^+R__$Fe07ieh_zkI$-;|^Z_jhox_?=sB;=K5?QAA9n^idyZA;B!?9zW+ zxUf{b>9g>&I{uk7QM_l z6z}eI=R{ohnfXfFRd;EgIor`b(^Go@#jy&I}cVFGo7&lIxc2lHX&}LrdJgb-YmwmaHEzdJW zJvEFsONrlZ{g+71`adl7b&S{dIjvr{^j8VrO7&kCuW3FxWw1E@xs{F5qOv%NuoL=g zwzJ)lUFrGfxB0{8=Z&82`*QJFYQN3=1MdwtMX1JxSxqcBUNtwOz|eb9)1ebellK-} z^@=#L^2&*e+{+$pyjwA6;jJ$PUqiM^CwzC`B-iU zm5*KsbiaMP@4GK9PdVNGWNqi_|9^d0Jy(a`=$E^@ z^Z2ZifQy2cH*7TFPxHB0d3*j8bG><5k9nL|Fa6J8nC-Y~P?mKG+C z>>aeT_HeV`#HgsR>}@yJ(8dq|YSZ|?p}BUFz7~!)01%}F0C5Qbu*nX^%>zI<3;-6q z0RWK=0Q*DpS{(G)3Eof(cOn2l6m}Lz#I0jw0O07wIk}PCY>p#*@xc(ZAKnK8i3kp5 zR|9}v1cH4G#*omUh~S_QA|gT`{G$TFKJSE~V9<{eQlLKA&Bh*Nj3;0~+7K-W4201wzq;;0ai$Ivfs%!Ze^78fxqcHDY842_2yp zLR9!k@)wT@hUiPcg_3ai5YP@U+6Ny_(g%Zg8vXtJ)Jekm|I;ai_{$dCAao}KRfoW! z{}0AC`?tP-p(4&g^V$gn(deHx^_yyL3?%4e=`#)#!Of+bqX<`0boyw zrHP@F8*gS-AkEoT{4r}QFZ%tncFhNX#)IW6=7TC=M*6Nhdqf0BpdPYPHZ&V4twAHv z6giq@`-sq{rD{Vhx3&^}dq7>s231rg*dQkfs!F39a(O&8P+rPG7p#RnW8P&p@25WV zCSjlD5!X&eSFtv09wQ%rkmx!#EZUmiZb=-=3UBqV9H-A@2&(jXR5Z=$G@ogGd#e~h zZ-_F=48#Xivb0m~ogK(rUHce4T~YzZQ;uvT=|?~JssZ0cbu_UowAT)|dKy2S(4$HNk|t=^bwbO!#8sXg(WO z#WyI$Uk;@zKa1^UAkU=RXn5M}<1m1I=cE~@vBn-%5$=@0rfxMpJQ-G99TopkGGuSj z;Fw+4NM6Hr?n*e2@rUS0AUuVsn|}-r8eJ)jZd!70OfbmS=l6LfMq8Q~m!&=bu;6&3 zp4#a&^0{ruV>d@cX0|Cm$Bohst*psh*L3w}gl>hyD}Jm>UrkvNvGEM!$oJ3Djncgf z4Bo~QniJbl^5*NIa${4+_o@#$-@IY;)%M`GEuxK#HkU4g)ev0`wuQ!CufL| zMzpawh@_p8J&bzy^_MHtukQ?Xh7V<=amGu8&fgvSEN9Kgy>woD=4iN|)|)%SJ@z&u z97a;-UQNGe%EU|w)Q&M6)m3nZ6?;}+rOaaDA0NlPQ^9rQ56y(H$hp1qvQ{2G9eMk7 z`wJ%Of%qV$z0N{-Wy}cM_1344b}}<{^-+1g^$1e8Pop2 zH+s7s9wQ7;W7CoNQN5*mmq&X$7AtL=EZ)SVN zRkeLAEJr3Ll6(tG3yPC3ew4JBM#jS?gQob(e38*BaU6w$D9JMoGTU-yn$SJx@ABO& z_OfbQxpI|AnVYx#I3F_K?frVesdZ-c9i>>*bR%^u?`lw{=S#-OhT+CgrCCtFInxVn zEl%?X7!(De!#o1xt9rL(n$DO(Zh>b+mf<1+^4LXE%n}`aG!QEhm3!dNT16KVrt4HX zp<$Lww|LI8bQj?!G1BZ~uboxwmeO2Lo~lLS!`En~DuDZGeG!+eaRP8cSRg5NfBY_= zMc{UlS#cA*G!+(-yy9fYpQW64)YuJzB2X+;kv!=_)~quQE#!=YC)C<0_EM3*-Tq4L zlv>nMp1_{HsS|H&J5VZ)I+A7yRFaOOL=zsfI^IzW6QzvAW^Xt+b%=U!=3&;N3(|FB zOr?%O^YyxUBg9%*34_CN>yrE7eounhyQ`mYj=B&29yQTR?PJS0Y`K(Fa(U()Q(o$}1@%HgfA~CIp%8(!W_=g6pbuyTd;7lgvV=yqrv1%|8a!8GFiU5GRlIcO=Z{H5-|(>seEg`5yrTZ|$~+ z_8Z*t{=PF%;6Zzb5U~4rQ{o@+2d{d5TVp-<&UL_@%j_j|6%&JKO@0CRj*-k_443U z?yiCP)2ZuiH$9@9)nfKi+snI7?za=&HG`S#ZNmu^>>B!1vJEz`v>NwEOKwWnLCT^| zAQVGERn_WbFrY)C1TfI)YmX6&LVPIU{^0cY*X_Kn0|kM zxlei%Io5NW6srUyT_O}8wv(0TP=3OZF<=&^UvpX39<}S+zTX;%Wpp(y3)M{)|T)zBn$+{KU&fCH-pKck& zoV=>WOid3r8OGk4K_gy9Yzu|hP4Dj~S8rIE$+3h5--*UGo$xhwroHb9EU)itd3d`{ z8lIGNzI!dCP4P>Y=f3{Kh3c$bIdp|{n{AIo_i~+`*5aOcDfS}5buA4)Wkg0MdGlyF zU#d0PGh!HH!zEHz;27TE-W!Vd)L1!QlY`BEA1*#4;he!|JGpcK`85xkrI6W+yjJ;2 zpEU2h`@n diff --git a/src/com/magento/idea/magento2plugin/icons/webapi_reference.png b/src/com/magento/idea/magento2plugin/icons/webapi_reference.png deleted file mode 100644 index db41f5df3967c08d9eeb8c50383cd0a003dc2808..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 627 zcmV-(0*w8MP);6)7{KXyE5*EFxR73)XlBgImf#HdSl8}Ksd=ni% z0g{Rs46Tkp7ARIn@Q|1g0U5>#8j7<(nnG;%h(YnlXkqe9k3+{rw!*D^^lV{bw%CY_ zVoOZU7f+opxQ1*fI8C%>e;+Q~5ev5pQQL&IbXP3h6VnUO*5=ejap`_x{)UJK+M0sG zC}8c40T}B;42*i+9booaA!?YpEC9YdGtr8yRS^LsLU`k|b>y@>y-=Jja(39njHqjC ze6nlskuKbrVJpcX?&mY8#Oan!DQB z|M1vk8e7;DG9W@^i|Q@Bxwi9ndi%&Y@!;nU#_DsEDV$)CA1o#+Lk0H43>rTsY*>8( z823-015=;6$|FVD7XLs1ieW_ zK~z}7#h1;FUBwlJzg6dS+Ym&nZMSC#Y|B5GH(-RAAcYZQ9s%BgQN}^y8F+#yPmp0I zHf;lvNiqnu-8Ob)gR$YB+KWL|oxj^4MRJrQmF~Ug?6dc(wSQ_|`STBd;?%3Vbi2?c zAb|un7(f7!63BqdGr8EJ$tGg5!NM2>4)6v`#$n}bHqXt^Pk-szIlV*InNCp=;u8qQP5ib2IAw$U7b0S^^G zy&uI6yKDxDaAQY;wh7a9>amLBSzw@2IorKgOPS`CTmw>>d{>E)H3M9bVY9{ExvK0MQdU zm43x7nBV(Tr$3yX{Qm9Fp+|Sz062B<{->R~otm)>fB7iO&l*7a>=o(VPtxe)=>zoF zkB3E}StJPXAbUu7lki47yt8bHGZ%%k>@1wc{u`+U2TCcPCc3qDEfz3(`w_Q~sa-01v;Z6DjJu8i6G8l#i01EFz@H+DgNfKPH`er4E+w z(T~UI*+cx~ZgIQ&61?@ns`_txJk-Yg*H354;3+|;;>gwD?%@)^g?Hxp_c;IOKrg+! z%KuHze79J2S&2<_yR_r+2obp0}~xz^6z8z>|+Pf8(bQw?Q6%X|+LRt7;rg8q#$THDnRXb3F`4H%@lEnBBG4w^+Kd z5-G9zE#%MM4x}o(Ya2E_H(#w)VJ6#W;$!?ilV8$GQ_j^*@zIYGEJp37aTbiazdDEt zK{cO_Sza0&n(0A)8$eA)KS`!oDx2}en4FIHG)*~Y25{09lRDoLe=p`r{;z!bg$BovB>t~gB55w~|L1T#|HIYEiR{1A mm(i#f%J0e77^9QO{>QHq>B+|WvhxW50000DSry^7odplSvNn+hu+GdHy)QK2F?C$HG5 z!d3~a!V1U+3F|8Y3;nDA{o-C@9zzrKDK}xwt{K19`Se z86_nJR{Hwo<>h+i#(Mch>H3D2mX`VkM*2oZx=P7{9O-#x!EwNQn0$BtHP6qmLm5Rd1sY@-CA1Az=#^1qQAi7tkhHMA>m^>YcS^U|=foba4!^5X_x? zI!nY+q;3DJmnU;4P3TZGJXXQT%qGh8N@-WoL#I2hj5`+eKV+6TICn=N$Gg(i(g$0e z3?e(66gvI(s7RI?&3rd+-6#9I!j2vXXRfrX{dan$)!RdlXTR?8^PBjbF?!t(+aJr< zY*^$F)0uI_JejR+*$UZDEeb2_86-5n*W0lui65O;Qm&+y`BX78Y|ixN3Eg`Z8BEY+ z{9Cs!+c!gekH(^oveUacuvI3LS^PVTR^{F9Tx;rfl*1ic-pc;^ z&&Bq7iQMK5TUR-WuGQ~+A^n9T;wo>i&*24gOr8c^e|zZAp5=etu9pi{iB{iY{~BSb zdT~{kT~`Qu)^+g|`|#{-N}QqRBe z@|}2@{o&8R8VR+$L_Ow B)_?#2 diff --git a/src/com/magento/idea/magento2plugin/icons/xml_reference@2x.png b/src/com/magento/idea/magento2plugin/icons/xml_reference@2x.png deleted file mode 100644 index 0b919a7aad5b32ef7a0439aedbe7d979c4fce116..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2192 zcmZuzdpy(YAODUYGWv~bLeY?HvCSnrZEX{FTw+4*Oy+)@%{C0(uTHTLxy^K$bO@6= zh|-1TDAax{(uL@Uh?Q&QocV3lIp=qKUa!ydd_JG&{kgn9&p*#ko*vGt!TMkT09L!Y zki6w5Od+dOboKFBdfb5Qo zpwm#)NP2h_ibG?_(Exzw;N&VTicN)aXo*QI9EV{16@ioM3OCvq_7%cTAQ%UbJz5@_ImjfI$+skbC$9#>R?5f3EL+(indhN@9Iy zCFh6cP#I_|lqLHA1+n9z|7!0)q7*mZ!oITlRtzs64bG7nMP<{OK6H8_(Oxk-m@ADM z6XhL6jZDX*{~PgFr+7t5+-_!El$@)A5zz{d{vY3WJRYr}`)~BW&GxHTK3pPLUg?jA zB7za99s&TUhPsmMeFD@wi-NO!eRV}E2^9pJ67G_oG_tf{jcdGss&!n4MAD*6%zEx7 zkRX&Seumb?BA9x$=sbLqY;$VDzBS-%tZC?06Wbf^8__mgeo15Bs^Lz1Z?PBD?2&kfE>Iov@*68}YnDwSgbvNv2Dt>d^4xo--M*N>>cJSPM?w z;o!ZM`#UX^&Ogu2xofelm+=^Ho=~E*zHnbq(^!mYUqyM%58g^E-TK~_{$AjKO<3c- zS@n@acRn;%gOSg!?Qofj=VN3e5Z$xC95o>98zC6-Y#>;~nXNm0Gz-h_uX3u9rJ3)j ze^YjL zZOJKdSnqS{F`%1A07Mf`j@*AN+_#{q?FKL{@f<_}x8C`mjGP-XNDlSHJ8KBAslkH2ZjgM)-f3;t{ ze_C8bFLQ}Qbcv8fsP;4Pq;no#n=0_mk?jTA!O<@_^FWs;ic}ArfC4$vS@qtoTXCC| zik&Yp2X4+BfY^9K$&c2n?qANozOq9TG;z-MRR60fk9CqcE<3h7+F=c3U^N8H4DDdA5hn-W|6z!~l3mrn-$91o~k4(Oh*d*F2lwsPd9fvGr91B$Ea z5Yikab^RAw%Op=-^|{Mu)+|_E%11|oAcEw3n2}pu(?*DJ*n~6 zIk6~9v!URJ*S2pViTN3jnSmc$Bgw8C2o}H5lVj(l(bV6zv z!q)J86H&Tn%+;T$G*DHU-si$H93LYOw|ST)=JpM8s%1Uar6$XjWOVKxrfg1MAFPdP z55Bn&2%bkqBJNq0!$-rU{^Ai|cl`Jk&2o4jZdG?Ju0Cj~TTK96Dqv!1Ez+#(vh<{9 zQvlqvR9Il{WKIF(Uy>6iI0ddR8wx30d z^}=VEwXh+?7`C>#j=?bNxn0Xnj1I90t(a7K55THed;3F&d^|{pyC&bN2T43Oq*l%H z?cgd|FD^V8%2M^6fwj}>c=)DB{(GYoSWd3=Il6tP)hQhWtR+hXgNdNKQ$uX%jPcn*XsIaF@ zNk&1aTiARnIAVURGvxObz}qYIQLgisi@Z8*sRNnZ-VQO9;7;lup|Ehy!XJd diff --git a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java deleted file mode 100644 index 945f36f3a..000000000 --- a/src/com/magento/idea/magento2plugin/php/inspections/MagentoApiInspection.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.magento.idea.magento2plugin.php.inspections; - -import com.intellij.codeInspection.ProblemHighlightType; -import com.intellij.codeInspection.ProblemsHolder; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementVisitor; -import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment; -import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag; -import com.jetbrains.php.lang.inspections.PhpInspection; -import com.jetbrains.php.lang.psi.elements.*; -import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; -import com.magento.idea.magento2plugin.project.Settings; -import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; -import com.magento.idea.magento2plugin.php.module.MagentoModule; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 12/4/15. - */ -public class MagentoApiInspection extends PhpInspection { - public static final String API_TAG = "@api"; - - @NotNull - @Override - public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean isOnTheFly) { - - return new ApiInspectionVisitor(problemsHolder); - } - - private class ApiInspectionVisitor extends PhpElementVisitor { - - private ProblemsHolder problemsHolder; - - public ApiInspectionVisitor(@NotNull ProblemsHolder problemsHolder) { - super(); - - this.problemsHolder = problemsHolder; - } - - @Override - public void visitPhpMethodReference(MethodReference reference) { - if (!Settings.isEnabled(reference.getProject())) { - return; - } - - PsiElement referencedElement = reference.resolve(); - - if(referencedElement instanceof Method) { - PhpClass phpClass = ((Method) referencedElement).getContainingClass(); - - if (phpClass == null) { - return; - } - - if (!MagentoApiInspection.isValidReference(phpClass, reference.getElement()) - && !MagentoApiInspection.isValidReference((Method) referencedElement, reference.getElement())) { - problemsHolder.registerProblem(reference, "Method #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } - } - } - - @Override - public void visitPhpClassReference(ClassReference reference) { - if (!Settings.isEnabled(reference.getProject())) { - return; - } - PsiElement referencedElement = reference.resolve(); - - if(referencedElement instanceof PhpClass) { - if (!MagentoApiInspection.isValidReference((PhpClass) referencedElement, reference.getElement())) { - problemsHolder.registerProblem(reference, "Class #ref is not in module API", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } - } - } - } - - private static boolean isValidReference(PhpNamedElement referencedElement, PsiElement contextElement) { - MagentoModule referenceSourceModule = getMagentoModule(referencedElement); - MagentoModule currentModule = getMagentoModule(contextElement); - - - if (!areDifferentModules(referenceSourceModule, currentModule)) { - return true; - } - - PhpDocComment docComment = referencedElement.getDocComment(); - if(docComment == null) { - return false; - } - - PhpDocTag[] elements = docComment.getTagElementsByName(API_TAG); - return elements.length > 0; - } - - private static MagentoModule getMagentoModule(PsiElement element) { - MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(element.getProject()); - return magentoComponentManager.getComponentOfTypeForFile(element.getContainingFile(), MagentoModule.class); - } - - private static boolean areDifferentModules(MagentoModule magentoModule, MagentoModule currentPackage) { - if (magentoModule == null) { - return false; - } - - return magentoModule != currentPackage; - } -} diff --git a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java b/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java deleted file mode 100644 index 9b1c0cbbc..000000000 --- a/src/com/magento/idea/magento2plugin/php/inspections/ObjectManagerInspection.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.magento.idea.magento2plugin.php.inspections; - -import com.intellij.codeInspection.ProblemHighlightType; -import com.intellij.codeInspection.ProblemsHolder; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementVisitor; -import com.intellij.psi.PsiReference; -import com.jetbrains.php.lang.inspections.PhpInspection; -import com.jetbrains.php.lang.psi.elements.ClassReference; -import com.jetbrains.php.lang.psi.elements.Method; -import com.jetbrains.php.lang.psi.elements.MethodReference; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.jetbrains.php.lang.psi.visitors.PhpElementVisitor; -import com.magento.idea.magento2plugin.project.Settings; -import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; -import com.magento.idea.magento2plugin.php.module.MagentoModule; -import com.magento.idea.magento2plugin.php.util.MagentoTypes; -import org.jetbrains.annotations.NotNull; - -/** - * Created by dkvashnin on 12/18/15. - */ -public class ObjectManagerInspection extends PhpInspection { - @NotNull - @Override - public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder problemsHolder, boolean b) { - return new OMInspectionVisitor(problemsHolder); - } - - private class OMInspectionVisitor extends PhpElementVisitor { - - private ProblemsHolder problemsHolder; - - public OMInspectionVisitor(@NotNull ProblemsHolder problemsHolder) { - super(); - this.problemsHolder = problemsHolder; - } - - @Override - public void visitPhpMethodReference(MethodReference reference) { - if (!Settings.isEnabled(reference.getProject())) { - return; - } - PsiElement referencedElement = reference.resolve(); - - if(referencedElement instanceof Method) { - MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(referencedElement.getProject()); - if (magentoComponentManager.getComponentOfTypeForFile(reference.getContainingFile(), MagentoModule.class) == null) { - return; - } - - PhpClass phpClass = ((Method) referencedElement).getContainingClass(); - - verifyPhpClass(phpClass, reference); - } - } - - @Override - public void visitPhpClassReference(ClassReference reference) { - if (!Settings.isEnabled(reference.getProject())) { - return; - } - PsiElement referencedElement = reference.resolve(); - - if(referencedElement instanceof PhpClass) { - MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(referencedElement.getProject()); - if (magentoComponentManager.getComponentOfTypeForFile(reference.getContainingFile(), MagentoModule.class) == null) { - return; - } - - verifyPhpClass((PhpClass)referencedElement, reference); - } - } - - private void verifyPhpClass(PhpClass phpClass, PsiReference reference) { - if (phpClass == null) { - return; - } - - if (phpClass.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { - registerProblem(reference); - return; - } - - for (PhpClass implementedInterface : phpClass.getImplementedInterfaces()) { - if (implementedInterface.getPresentableFQN().equals(MagentoTypes.OBJECT_MANAGER_TYPE)) { - registerProblem(reference); - return; - } - } - } - - private void registerProblem(PsiReference reference) { - problemsHolder.registerProblem(reference, "ObjectManager is not recommended to use in module", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } - } -} diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form b/src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form deleted file mode 100644 index 4b6cc17a1..000000000 --- a/src/com/magento/idea/magento2plugin/php/tool/ModuleTool.form +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java b/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java deleted file mode 100644 index 9521fb957..000000000 --- a/src/com/magento/idea/magento2plugin/php/tool/ModuleToolWindowFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.magento.idea.magento2plugin.php.tool; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowFactory; -import com.intellij.ui.content.Content; -import com.intellij.ui.content.ContentFactory; -import com.magento.idea.magento2plugin.php.module.ComposerPackageModel; -import com.magento.idea.magento2plugin.php.module.MagentoComponentManager; -import com.magento.idea.magento2plugin.php.module.MagentoModule; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import java.util.HashMap; -import java.util.Map; - -/** - * Created by dkvashnin on 12/7/15. - */ -public class ModuleToolWindowFactory implements ToolWindowFactory { - private JPanel windowContent; - private JTree modulesTree; - private ToolWindow myToolWindow; - - private static final String UNDEFINED_VENDOR = "Undefined"; - - @Override - public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { - myToolWindow = toolWindow; - initializeModulesTree(project); - ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); - Content content = contentFactory.createContent(windowContent, "", false); - toolWindow.getContentManager().addContent(content); - } - - private void initializeModulesTree(Project project) { - MagentoComponentManager magentoComponentManager = MagentoComponentManager.getInstance(project); - - Map vendorNodes = new HashMap<>(); - - DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Project modules"); - - modulesTree.setModel(new DefaultTreeModel(rootNode)); - - for (MagentoModule magentoModule: magentoComponentManager.getAllComponentsOfType(MagentoModule.class)) { - ComposerPackageModel packageModel = magentoModule.getComposerModel(); - if (packageModel == null) { - continue; - } - - String vendorName = packageModel.getVendor(); - if (vendorName == null) { - vendorName = UNDEFINED_VENDOR; - } - - if (!vendorNodes.containsKey(vendorName)) { - vendorNodes.put(vendorName, new DefaultMutableTreeNode(vendorName)); - rootNode.add(vendorNodes.get(vendorName)); - } - - vendorNodes.get(vendorName).add(new DefaultMutableTreeNode(magentoModule.getMagentoName())); - } - } -} \ No newline at end of file diff --git a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java b/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java deleted file mode 100644 index 2221bda0a..000000000 --- a/src/com/magento/idea/magento2plugin/php/util/MagentoTypes.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.magento.idea.magento2plugin.php.util; - -/** - * Created by dkvashnin on 12/18/15. - */ -public class MagentoTypes { - public static final String BLOCK_TYPE = "Magento\\Framework\\View\\Element\\BlockInterface"; - public static final String OBSERVER_TYPE = "Magento\\Framework\\Event\\ObserverInterface"; - public static final String OBJECT_MANAGER_TYPE = "Magento\\Framework\\ObjectManagerInterface"; - public static final String EVENT_MANAGER_TYPE = "Magento\\Framework\\Event\\ManagerInterface"; -} diff --git a/src/inspectionDescriptions/MagentoApiInspection.html b/src/inspectionDescriptions/MagentoApiInspection.html deleted file mode 100644 index 02a3c1db6..000000000 --- a/src/inspectionDescriptions/MagentoApiInspection.html +++ /dev/null @@ -1,5 +0,0 @@ - - -Non Module public API usage. - - \ No newline at end of file diff --git a/src/inspectionDescriptions/ObjectManagerInspection.html b/src/inspectionDescriptions/ObjectManagerInspection.html deleted file mode 100644 index 5c82c6735..000000000 --- a/src/inspectionDescriptions/ObjectManagerInspection.html +++ /dev/null @@ -1,5 +0,0 @@ - - -ObjectManager usage in Module scope - - \ No newline at end of file From d0a4b19cf5d30d52f3bd7045aabf439ee4a39fb1 Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Fri, 8 Dec 2017 17:38:09 +0200 Subject: [PATCH 47/51] Reference for file path declared in XMl/JavaScript are broken --- .../provider/FilePathReferenceProvider.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java index 68109764f..a2a57d98b 100644 --- a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java @@ -1,6 +1,5 @@ package com.magento.idea.magento2plugin.reference.provider; -import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.*; import com.intellij.psi.*; @@ -8,6 +7,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.lang.PhpFileType; import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; import gnu.trove.THashMap; @@ -33,6 +33,7 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu return PsiReference.EMPTY_ARRAY; } + // Find all files based on provided path Collection files = getFiles(element); if (!(files.size() > 0)) { return PsiReference.EMPTY_ARRAY; @@ -92,12 +93,9 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu } if (psiPathElements.size() > 0) { - psiPathElements.forEach(new BiConsumer>() { - @Override - public void accept(TextRange textRange, List psiElements) { - psiReferences.add(new PolyVariantReferenceBase(element, textRange, psiElements)); - } - }); + psiPathElements.forEach(((textRange, psiElements) -> + psiReferences.add(new PolyVariantReferenceBase(element, textRange, psiElements)) + )); } } @@ -141,7 +139,7 @@ private Collection getFiles(@NotNull PsiElement element) Collection vfs = getModuleSourceFiles(element); if (null != vfs) { for (VirtualFile vf : vfs) { - Collection vfChildren = getAllSubFiles(vf.findChild("view")); + Collection vfChildren = getAllSubFiles(vf); if (null != vfChildren) { vfChildren.removeIf(f -> { if (!f.isDirectory()) { @@ -171,7 +169,7 @@ private Collection getModuleFile(@NotNull PsiElement element) .getContainingFiles(ModuleNameIndex.KEY, moduleName, GlobalSearchScope.getScopeRestrictedByFileTypes( GlobalSearchScope.allScope(element.getProject()), - XmlFileType.INSTANCE + PhpFileType.INSTANCE ) ); } @@ -182,10 +180,10 @@ private Collection getModuleSourceFiles(@NotNull PsiElement element if (null == virtualFiles) { return null; } - virtualFiles.removeIf(vf -> !(vf != null && vf.getParent() != null && vf.getParent().getParent() != null)); + virtualFiles.removeIf(vf -> !(vf != null && vf.getParent() != null)); Collection sourceVfs = new ArrayList<>(); for (VirtualFile vf : virtualFiles) { - sourceVfs.add(vf.getParent().getParent()); + sourceVfs.add(vf.getParent()); } return sourceVfs; } @@ -223,10 +221,6 @@ private Collection getAllSubFiles(VirtualFile virtualFile) { Collection list = new ArrayList<>(); - if (null == virtualFile) { - return list; - } - VfsUtilCore.visitChildrenRecursively(virtualFile, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile file) { From b8595a884b76d080e9ce3c284534ff47e5b44fa9 Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Fri, 8 Dec 2017 17:38:09 +0200 Subject: [PATCH 48/51] Reference for file path declared in XMl/JavaScript are broken --- .../provider/FilePathReferenceProvider.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java index 68109764f..a2a57d98b 100644 --- a/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/reference/provider/FilePathReferenceProvider.java @@ -1,6 +1,5 @@ package com.magento.idea.magento2plugin.reference.provider; -import com.intellij.ide.highlighter.XmlFileType; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.*; import com.intellij.psi.*; @@ -8,6 +7,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.ProcessingContext; import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.lang.PhpFileType; import com.magento.idea.magento2plugin.reference.xml.PolyVariantReferenceBase; import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; import gnu.trove.THashMap; @@ -33,6 +33,7 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu return PsiReference.EMPTY_ARRAY; } + // Find all files based on provided path Collection files = getFiles(element); if (!(files.size() > 0)) { return PsiReference.EMPTY_ARRAY; @@ -92,12 +93,9 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu } if (psiPathElements.size() > 0) { - psiPathElements.forEach(new BiConsumer>() { - @Override - public void accept(TextRange textRange, List psiElements) { - psiReferences.add(new PolyVariantReferenceBase(element, textRange, psiElements)); - } - }); + psiPathElements.forEach(((textRange, psiElements) -> + psiReferences.add(new PolyVariantReferenceBase(element, textRange, psiElements)) + )); } } @@ -141,7 +139,7 @@ private Collection getFiles(@NotNull PsiElement element) Collection vfs = getModuleSourceFiles(element); if (null != vfs) { for (VirtualFile vf : vfs) { - Collection vfChildren = getAllSubFiles(vf.findChild("view")); + Collection vfChildren = getAllSubFiles(vf); if (null != vfChildren) { vfChildren.removeIf(f -> { if (!f.isDirectory()) { @@ -171,7 +169,7 @@ private Collection getModuleFile(@NotNull PsiElement element) .getContainingFiles(ModuleNameIndex.KEY, moduleName, GlobalSearchScope.getScopeRestrictedByFileTypes( GlobalSearchScope.allScope(element.getProject()), - XmlFileType.INSTANCE + PhpFileType.INSTANCE ) ); } @@ -182,10 +180,10 @@ private Collection getModuleSourceFiles(@NotNull PsiElement element if (null == virtualFiles) { return null; } - virtualFiles.removeIf(vf -> !(vf != null && vf.getParent() != null && vf.getParent().getParent() != null)); + virtualFiles.removeIf(vf -> !(vf != null && vf.getParent() != null)); Collection sourceVfs = new ArrayList<>(); for (VirtualFile vf : virtualFiles) { - sourceVfs.add(vf.getParent().getParent()); + sourceVfs.add(vf.getParent()); } return sourceVfs; } @@ -223,10 +221,6 @@ private Collection getAllSubFiles(VirtualFile virtualFile) { Collection list = new ArrayList<>(); - if (null == virtualFile) { - return list; - } - VfsUtilCore.visitChildrenRecursively(virtualFile, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile file) { From 13732b702cd211593b22955d62e172229e75223f Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Fri, 8 Dec 2017 18:35:36 +0200 Subject: [PATCH 49/51] Move change notes to CHANGELOG.md, update plugin description, update version --- CHANGELOG.md | 78 ++++++++++++++ META-INF/plugin.xml | 242 +++++++++++++------------------------------- README.md | 41 ++------ 3 files changed, 161 insertions(+), 200 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..5640a9553 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,78 @@ +0.2.3 +============= +* Features: + * Added JavaScript reference contributor + * Support references for each part of FQN of PHP class, methods, constants + * Support reference from XML/JavaScript for module name + * Support reference from XML/JavaScript for module element path (e.g. Magento_Catalog::product/list/addto/compare.phtml) + * Added project detector + * Move configuration section to "Languages & Frameworks > Php > Magento" + * Remove deprecated elements + +0.2.2 +============= +* Features: + * Added Module name to configuration tooltip +* Fixed bugs: + * Fixed "Project disposed" exception + +0.2.1 +============= +* Features: + * added module name for "Goto configuration" labels + +0.2.0 +============= +* Features: + * WebApi routes + * nicer "Goto configuration" labels + * plugin settings (manual reindex, URN generation, plugin on/off) + +0.1 +============= +* Features: + * Context type completion for: + * Observers completion only for ObserverInterface impl in events.xml + * Blocks completion only for BlockInterface name in layouts.xml + * Preference configuration in di.xml + * Type hinting for object arguments in di.xml + * @api usage inspection in Module context + * ObjectManager usage inspection in Module context + * virtualType arguments resolution + * webapi.xml interface/method completion/references + * Support for old people using PhpStorm 8 or JDK1.7 + +0.0.9 +============= +* Features: + * Added Reference and completion support for layouts + * block: class, before, after + * referenceBlock: name + * move: element, destination, before, after + * remove: name + * update: handle + * referenceContainer: name + * Line marker reference for php class to Layout configuration + +0.0.8 +============= +* Features: + * Added Line marker reference for php class/interface to DI configuration + * Added Line marker reference to plugins + +0.0.7 +============= +* Features: + * Added reference to configuration and observers (classes or virtualType) + * Added reference to observers from configuration + * Added reference to event dispatch from configuration + +0.0.6 +============= +* Features: + * Added reference and completion support for virtual types/classes/arguments in DI configuration + +0.0.5 +============= +* Features: + * Added reference support for classes/interfaces in DI configuration \ No newline at end of file diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index 2dc7afcfd..efb2047a6 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -1,176 +1,80 @@ - com.magento.idea.magento2plugin - Magento PhpStorm - 0.2.2 - Dmytro Kvashnin + com.magento.idea.magento2plugin + Magento PhpStorm + 0.2.3 + Magento Inc. - -

          Features

          -
          -

          Configuration smart completion and references

          -
            -
          • di.xml
          • -
          • layouts
          • -
          • events.xml
          • -
          • webapi.xml
          • -
          - -

          Inspections

          -
            -
          • @api usage
          • -
          • ObjectManager usage
          • -
          - -

          Code helpers

          -
            -
          • "Navigate to configuration" reference in scope of class/interface
          • -
          • "Go to plugin" reference in scope of class/interface and method
          • -
          • "Navigate to Web API configuration" reference in scope of class/interface and method
          • -
          + - 0.2.1 -
            -
          • added module name for "Goto configuration" labels
          • -
          -

          0.2.0

          -
            -
          • WebApi routes
          • -
          • nicer "Goto configuration" labels
          • -
          • plugin settings (manual reindex, URN generation, plugin on/off)
          • -
          - -

          0.1

          -
            -
          • Context type completion for:
            - - Observers completion only for ObserverInterface impl in events.xml
            - - Blocks completion only for BlockInterface name in layouts.xml
            - - Preference configuration in di.xml
            - - Type hinting for object arguments in di.xml
            -
          • -
          • @api usage inspection in Module context
          • -
          • ObjectManager usage inspection in Module context
          • -
          • virtualType arguments resolution
          • -
          • webapi.xml interface/method completion/references
          • -
          • Support for old people using PhpStorm 8 or JDK1.7
          • -
          - -

          0.0.9

          -
            -
          • Added Reference and completion support for layouts
            - - block: class, before, after
            - - referenceBlock: name
            - - move: element, destination, before, after
            - - remove: name
            - - update: handle
            - - referenceContainer: name
          • -
          • Line marker reference for php class to Layout configuration
          • -
          - -

          0.0.8

          -
            -
          • Added Line marker reference for php class/interface to DI configuration
          • -
          • Added Line marker reference to plugins
          • -
          - -

          0.0.7

          -
            -
          • Added reference to configuration and observers (classes or virtualType)
          • -
          • Added reference to observers from configuration -
          • Added reference to event dispatch from configuration
          • -
          - -

          0.0.6

          -
            -
          • Added reference and completion support for virtual types/classes/arguments in DI configuration
          • -
          - -

          0.0.5

          -
            -
          • Added reference support for classes/interfaces in DI configuration
          • -
          + here ]]> - - - - - - - - com.jetbrains.php - JavaScript - com.intellij.modules.platform - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
          + + + + + + + com.jetbrains.php + JavaScript + com.intellij.modules.platform + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          diff --git a/README.md b/README.md index 2809cfa26..5540e25ee 100644 --- a/README.md +++ b/README.md @@ -8,43 +8,22 @@ This is a plugin for Magento 2 development in the PhpStorm IDE. It is available ## Installation 1. Go to Settings / Preferences in the PhpStorm IDE - 2. Navigate to "Plugins" - 3. Click the "Browse repositories..." button and search for "Magento2" - 4. Install the plugin and restart PhpStorm - -5. Go to Settings / Preferences / Other Settings / Magento2 plugin in the PhpStorm IDE - +5. Go to Settings / Preferences / Languages & Frameworks / PHP / Magento in the PhpStorm IDE 6. Check "Enable" and "OK" button. ## Works with -* PhpStorm >= 8.0.3 -* JRE >= 1.7 - -

          Features

          - -

          Configuration smart completion and references

          -
            -
          • di.xml
          • -
          • layouts
          • -
          • events.xml
          • -
          • webapi.xml
          • -
          - -

          Inspections

          -
            -
          • @api usage
          • -
          • ObjectManager usage
          • -
          - -

          Code helpers

          -
            -
          • "Navigate to configuration" reference in scope of class/interface
          • -
          • "Go to plugin" reference in scope of class/interface and method
          • -
          • "Navigate to Web API configuration" reference in scope of class/interface and method
          • -
          +* PhpStorm >= 2017.2 +* JRE >= 1.8 + +## Features + +* Configuration smart completion and references for XML/JavaScript files +* "Navigate to configuration" reference in scope of class/interface +* "Go to plugin" reference in scope of class/interface and method +* "Navigate to Web API configuration" reference in scope of class/interface and method ## License From 9a05faeb98e8d8d7a32ade5bfc8c4240469938ff Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Fri, 8 Dec 2017 18:38:56 +0200 Subject: [PATCH 50/51] Move change notes to CHANGELOG.md, update plugin description, update version --- META-INF/plugin.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml index efb2047a6..8ec00a3cc 100644 --- a/META-INF/plugin.xml +++ b/META-INF/plugin.xml @@ -45,7 +45,6 @@ - From f6ca13572ed3b43356a5185be3dde728d28faf81 Mon Sep 17 00:00:00 2001 From: Volodymyr Klymenko Date: Fri, 15 Dec 2017 16:26:51 +0200 Subject: [PATCH 51/51] XMl completion contributor improvements - completion for php classes and class elements (properties, methods, constants) - module name completion - file path completion --- .../provider/CompositeCompletionProvider.java | 2 +- .../EventNameCompletionContributor.java | 2 +- .../provider/FilePathCompletionProvider.java | 114 ++++++++++++++++++ .../LayoutBlockCompletionContributor.java | 2 +- .../LayoutContainerCompletionContributor.java | 2 +- .../LayoutUpdateCompletionContributor.java | 2 +- .../ModuleNameCompletionProvider.java | 41 +++++++ .../provider/PhpClassCompletionProvider.java | 106 ++++++++++++++++ .../PhpClassMemberCompletionProvider.java | 2 +- ...ConstructorArgumentCompletionProvider.java | 2 +- ...PhpServiceMethodCompletionContributor.java | 2 +- .../VirtualTypeCompletionProvider.java | 2 +- .../xml/XmlCompletionContributor.java | 17 +-- .../provider/PhpClassCompletionProvider.java | 73 ----------- .../magento2plugin/php/util/PhpRegex.java | 8 +- .../reference/js/JsReferenceContributor.java | 6 +- .../provider/PhpClassReferenceProvider.java | 2 +- .../stubs/indexes/ModuleNameIndex.java | 42 +++++-- .../idea/magento2plugin/util/RegExUtil.java | 11 ++ .../idea/magento2plugin/util/VfsUtil.java | 40 ++++++ .../util/magento/FileBasedIndexUtil.java | 69 +++++++++++ 21 files changed, 442 insertions(+), 105 deletions(-) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/CompositeCompletionProvider.java (93%) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/EventNameCompletionContributor.java (94%) create mode 100644 src/com/magento/idea/magento2plugin/completion/provider/FilePathCompletionProvider.java rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/LayoutBlockCompletionContributor.java (95%) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/LayoutContainerCompletionContributor.java (95%) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/LayoutUpdateCompletionContributor.java (95%) create mode 100644 src/com/magento/idea/magento2plugin/completion/provider/ModuleNameCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/completion/provider/PhpClassCompletionProvider.java rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/PhpClassMemberCompletionProvider.java (97%) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/PhpConstructorArgumentCompletionProvider.java (96%) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/PhpServiceMethodCompletionContributor.java (95%) rename src/com/magento/idea/magento2plugin/completion/{xml => }/provider/VirtualTypeCompletionProvider.java (95%) delete mode 100644 src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java create mode 100644 src/com/magento/idea/magento2plugin/util/RegExUtil.java create mode 100644 src/com/magento/idea/magento2plugin/util/VfsUtil.java create mode 100644 src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/CompositeCompletionProvider.java similarity index 93% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java rename to src/com/magento/idea/magento2plugin/completion/provider/CompositeCompletionProvider.java index cd05299c8..6bdfcc008 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/CompositeCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/CompositeCompletionProvider.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/EventNameCompletionContributor.java similarity index 94% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java rename to src/com/magento/idea/magento2plugin/completion/provider/EventNameCompletionContributor.java index fa5e1f2e5..0b3fefe59 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/EventNameCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/EventNameCompletionContributor.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/provider/FilePathCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/FilePathCompletionProvider.java new file mode 100644 index 000000000..8ec081d97 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/provider/FilePathCompletionProvider.java @@ -0,0 +1,114 @@ +package com.magento.idea.magento2plugin.completion.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.magento.idea.magento2plugin.util.RegExUtil; +import com.magento.idea.magento2plugin.util.VfsUtil; +import com.magento.idea.magento2plugin.util.magento.FileBasedIndexUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FilePathCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + + String prefix = result.getPrefixMatcher().getPrefix(); + + String filePath; + String filePathPrefix; + boolean removeFileExtension = false; + + Pattern pattern = Pattern.compile( + "(" + RegExUtil.Magento.MODULE_NAME + "(\\W+))(" + RegExUtil.FILE_PATH + ")?" + ); + Matcher matcher = pattern.matcher(prefix); + if (matcher.find()) { + filePathPrefix = matcher.group(1); + removeFileExtension = matcher.group(2).equals("/"); + filePath = matcher.group(3) != null ? matcher.group(3) : ""; + } else { + pattern = Pattern.compile("(" + RegExUtil.FILE_PATH + ")+"); + matcher = pattern.matcher(prefix); + if (!matcher.find()) { + return; + } + filePathPrefix = ""; + filePath = matcher.group(1); + } + + // find all view virtual files + Collection viewVfs = findViewVfs(parameters, result); + + for (VirtualFile vf:viewVfs) { + for (VirtualFile file : VfsUtil.getAllSubFiles(vf)) { + String label = file.getPath().replace(vf.getPath(), ""); + + pattern = label.matches("(/[\\w-]+){2}/template/.*") + //e.g. (adminhtml|frontend|base|*)/(web|layout|*)/template/{whatever client typed} + ? Pattern.compile("^((/[\\w-]+){3}/)" + filePath) + //e.g. (adminhtml|frontend|base|*)/(web|layout|*)/{whatever client typed} + : Pattern.compile("^((/[\\w-]+){2}/)" + filePath); + + matcher = pattern.matcher(label); + if (!matcher.find()) { + continue; + } + + //remove prefix + label = label.replace(matcher.group(0), ""); + boolean lastPathSegment = !(label.indexOf("/", 1) > 0); + label = lastPathSegment ? label : label.substring(0, label.indexOf("/", 1)); + label = filePathPrefix + filePath + label; + label = !removeFileExtension ? label : (label.lastIndexOf(".") > 0 + ? label.substring(0, label.lastIndexOf(".")) + : label + ); + + result.addElement( + LookupElementBuilder + .create(label) + .withIcon(lastPathSegment ? file.getFileType().getIcon() : AllIcons.Nodes.Folder) + ); + } + } + } + + private Collection findViewVfs(CompletionParameters parameters, CompletionResultSet result) + { + Collection viewVfs = new ArrayList<>(); + + Pattern pattern = Pattern.compile(RegExUtil.Magento.MODULE_NAME); + Matcher matcher = pattern.matcher(result.getPrefixMatcher().getPrefix()); + + if (matcher.find()) { + viewVfs.addAll( + FileBasedIndexUtil.findViewVfsByModuleName(matcher.group(0), parameters.getPosition().getProject()) + ); + } else { + VirtualFile moduleVf = + VfsUtil.findVfUp(parameters.getOriginalFile().getVirtualFile(), "registration.php"); + + viewVfs.addAll( + FileBasedIndexUtil.findViewVfsByModuleVf(moduleVf, parameters.getPosition().getProject()) + ); + } + + return viewVfs; + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java similarity index 95% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java rename to src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java index f852e471e..597b3792b 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutBlockCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/LayoutBlockCompletionContributor.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java similarity index 95% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java rename to src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java index 38845a2f1..10b1cf23f 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutContainerCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/LayoutContainerCompletionContributor.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java similarity index 95% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java rename to src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java index ae5d7d8f9..ec53421b6 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/LayoutUpdateCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/LayoutUpdateCompletionContributor.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/provider/ModuleNameCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/ModuleNameCompletionProvider.java new file mode 100644 index 000000000..70770236b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/provider/ModuleNameCompletionProvider.java @@ -0,0 +1,41 @@ +package com.magento.idea.magento2plugin.completion.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.icons.AllIcons; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.intellij.util.indexing.FileBasedIndex; +import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public class ModuleNameCompletionProvider extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + String prefix = result.getPrefixMatcher().getPrefix(); + + Collection moduleNames + = FileBasedIndex.getInstance().getAllKeys(ModuleNameIndex.KEY, position.getProject()); + + + moduleNames.removeIf(m -> !m.startsWith(prefix)); + for (String moduleName : moduleNames) { + result.addElement( + LookupElementBuilder + .create(moduleName) + .withIcon(AllIcons.Modules.ModulesNode) + ); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/provider/PhpClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/PhpClassCompletionProvider.java new file mode 100644 index 000000000..627c6e510 --- /dev/null +++ b/src/com/magento/idea/magento2plugin/completion/provider/PhpClassCompletionProvider.java @@ -0,0 +1,106 @@ +package com.magento.idea.magento2plugin.completion.provider; + +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ProcessingContext; +import com.jetbrains.php.PhpIcons; +import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import com.jetbrains.php.lang.psi.elements.PhpNamespace; +import com.magento.idea.magento2plugin.php.util.PhpRegex; +import gnu.trove.THashSet; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class PhpClassCompletionProvider extends CompletionProvider { + + final private static String PHP_CLASS_COMPLETION_REGEX + = "\\\\?" + PhpRegex.CLASS_NAME + "\\\\?"; + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + PsiElement position = parameters.getPosition().getOriginalElement(); + if (position == null) { + return; + } + String prefix = result.getPrefixMatcher().getPrefix(); + Matcher matcher = Pattern.compile(PHP_CLASS_COMPLETION_REGEX).matcher(prefix); + if (!matcher.matches()) { + return; + } + + String className = prefix.lastIndexOf(92) < 0 ? prefix : prefix.substring(prefix.lastIndexOf(92) + 1); + String namespace = prefix.lastIndexOf(92) < 0 ? "" : prefix.substring(0, prefix.lastIndexOf(92)); + + PhpIndex phpIndex = PhpIndex.getInstance(parameters.getPosition().getProject()); + + final Collection phpClasses = new THashSet<>(); + Collection namespaceNames = new ArrayList<>(); + + if (!className.isEmpty()) { + // case for input: "SomeClassOrNamespace" + + // add classes + Collection classNames = phpIndex.getAllClassNames(new CamelHumpMatcher(className)); + for (String cName: classNames) { + phpClasses.addAll(phpIndex.getClassesByName(cName)); + } + // add interfaces + Collection interfaceNames = phpIndex.getAllInterfaceNames(); + interfaceNames.removeIf(i -> !i.contains(className)); + for (String iName: interfaceNames) { + phpClasses.addAll(phpIndex.getInterfacesByName(iName)); + } + if (!namespace.isEmpty()) { + phpClasses.removeIf(c -> !c.getPresentableFQN().startsWith(namespace)); + } else { + namespaceNames = phpIndex.getChildNamespacesByParentName("\\"); + namespaceNames.removeIf(n -> !n.contains(prefix)); + } + } else { + // case for input: "Some\Namespace\ + ^+" + + // add namespaces + Collection namespaces = phpIndex.getNamespacesByName(("\\" + namespace).toLowerCase()); + for (PhpNamespace nsp: namespaces) { + phpClasses.addAll(PsiTreeUtil.getChildrenOfTypeAsList(nsp.getStatements(), PhpClass.class)); + } + + // add namespaces and classes (string representation) + namespaceNames + = phpIndex.getChildNamespacesByParentName("\\".concat(namespace).concat("\\").toLowerCase()); + namespaceNames + = namespaceNames.stream().map(n -> namespace.concat("\\").concat(n)).collect(Collectors.toList()); + } + + // add all above founded items to lookup builder + // order is important (items with the same name override each other), add classes first + for (PhpClass phpClass : phpClasses) { + result.addElement( + LookupElementBuilder + .create(phpClass.getPresentableFQN()) + .withIcon(phpClass.getIcon()) + ); + } + + for (String nsName : namespaceNames) { + result.addElement( + LookupElementBuilder + .create(nsName) + .withIcon(PhpIcons.NAMESPACE) + ); + } + } +} diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/PhpClassMemberCompletionProvider.java similarity index 97% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java rename to src/com/magento/idea/magento2plugin/completion/provider/PhpClassMemberCompletionProvider.java index 44fed2b4e..3251e9fd6 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassMemberCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/PhpClassMemberCompletionProvider.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/PhpConstructorArgumentCompletionProvider.java similarity index 96% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java rename to src/com/magento/idea/magento2plugin/completion/provider/PhpConstructorArgumentCompletionProvider.java index 29a8cdaed..5f2e082b9 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpConstructorArgumentCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/PhpConstructorArgumentCompletionProvider.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/provider/PhpServiceMethodCompletionContributor.java similarity index 95% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java rename to src/com/magento/idea/magento2plugin/completion/provider/PhpServiceMethodCompletionContributor.java index 45f6c62f0..3ac23789c 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpServiceMethodCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/PhpServiceMethodCompletionContributor.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java similarity index 95% rename from src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java rename to src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java index 40919919e..d8810d828 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/VirtualTypeCompletionProvider.java +++ b/src/com/magento/idea/magento2plugin/completion/provider/VirtualTypeCompletionProvider.java @@ -1,4 +1,4 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; +package com.magento.idea.magento2plugin.completion.provider; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionProvider; diff --git a/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java b/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java index a561da568..eec8d9eaa 100644 --- a/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java +++ b/src/com/magento/idea/magento2plugin/completion/xml/XmlCompletionContributor.java @@ -4,8 +4,7 @@ import com.intellij.codeInsight.completion.CompletionType; import com.intellij.patterns.XmlPatterns; import com.intellij.psi.xml.XmlTokenType; -import com.magento.idea.magento2plugin.completion.xml.provider.*; -import com.magento.idea.magento2plugin.php.util.PhpRegex; +import com.magento.idea.magento2plugin.completion.provider.*; import static com.intellij.patterns.PlatformPatterns.psiElement; import static com.intellij.patterns.StandardPatterns.string; @@ -14,19 +13,21 @@ public class XmlCompletionContributor extends CompletionContributor { public XmlCompletionContributor() { - extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) - .withText(string().matches(PhpRegex.Xml.CLASS_ELEMENT)), + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN), new CompositeCompletionProvider( new PhpClassCompletionProvider(), - new PhpClassMemberCompletionProvider() + new PhpClassMemberCompletionProvider(), + new ModuleNameCompletionProvider(), + new FilePathCompletionProvider() ) ); - extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_DATA_CHARACTERS) - .withText(string().matches(PhpRegex.Xml.CLASS_ELEMENT)), + extend(CompletionType.BASIC, psiElement(XmlTokenType.XML_DATA_CHARACTERS), new CompositeCompletionProvider( new PhpClassCompletionProvider(), - new PhpClassMemberCompletionProvider() + new PhpClassMemberCompletionProvider(), + new ModuleNameCompletionProvider(), + new FilePathCompletionProvider() ) ); diff --git a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java b/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java deleted file mode 100644 index 9a9885eb7..000000000 --- a/src/com/magento/idea/magento2plugin/completion/xml/provider/PhpClassCompletionProvider.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.magento.idea.magento2plugin.completion.xml.provider; - -import com.intellij.codeInsight.completion.CompletionParameters; -import com.intellij.codeInsight.completion.CompletionProvider; -import com.intellij.codeInsight.completion.CompletionResultSet; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.ProcessingContext; -import com.jetbrains.php.PhpIcons; -import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.jetbrains.php.lang.psi.elements.PhpNamespace; -import com.magento.idea.magento2plugin.php.util.PhpRegex; -import gnu.trove.THashSet; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class PhpClassCompletionProvider extends CompletionProvider { - - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result) { - PsiElement position = parameters.getPosition().getOriginalElement(); - if (position == null) { - return; - } - - String prefix = result.getPrefixMatcher().getPrefix(); - prefix = prefix.startsWith("\\") ? prefix : "\\" + prefix; - - Matcher matcher = Pattern.compile(PhpRegex.Xml.CLASS_NAME).matcher(prefix); - - if (!matcher.matches()) { - return; - } - - String prefixShortName = prefix.substring(prefix.lastIndexOf(92) + 1); - String namespace = prefix.substring(0, prefix.lastIndexOf(92)); - namespace = namespace.startsWith("\\") ? namespace : "\\" + namespace; - - PhpIndex phpIndex = PhpIndex.getInstance(parameters.getPosition().getProject()); - - final Collection phpClasses = new THashSet<>(); - for (PhpNamespace phpNamespace : phpIndex.getNamespacesByName(namespace.toLowerCase())) { - phpClasses.addAll(PsiTreeUtil.getChildrenOfTypeAsList(phpNamespace.getStatements(), PhpClass.class)); - } - phpClasses.removeIf(c -> !c.getName().contains(prefixShortName)); - - for (PhpClass phpClass : phpClasses) { - result.addElement( - LookupElementBuilder - .create(phpClass.getPresentableFQN()) - .withIcon(phpClass.getIcon()) - ); - } - - final Collection namespaces = phpIndex.getChildNamespacesByParentName(namespace + "\\"); - for (String namespaceName : namespaces) { - if (namespaceName.contains(prefixShortName)) { - result.addElement( - LookupElementBuilder - .create(namespace.substring(1) + "\\" + namespaceName) - .withIcon(PhpIcons.NAMESPACE) - ); - } - } - } -} diff --git a/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java b/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java index 54f1b6481..50350c3fa 100644 --- a/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java +++ b/src/com/magento/idea/magento2plugin/php/util/PhpRegex.java @@ -1,12 +1,14 @@ package com.magento.idea.magento2plugin.php.util; public class PhpRegex { + + public static final String CLASS_NAME + = "[A-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(\\\\[A-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*"; + public static class Xml { - public static final String CLASS_NAME - = "\\\\?([A-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(\\\\[A-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*)"; public static final String CLASS_MEMBER_NAME = "::\\$?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)(\\(\\))?"; - public static final String CLASS_ELEMENT = CLASS_NAME + "(" + CLASS_MEMBER_NAME + ")?.*"; + public static final String CLASS_ELEMENT = "\\\\?" + PhpRegex.CLASS_NAME + "(" + CLASS_MEMBER_NAME + ")?.*"; } } diff --git a/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java b/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java index df12ccd60..c424375c1 100644 --- a/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java +++ b/src/com/magento/idea/magento2plugin/reference/js/JsReferenceContributor.java @@ -4,6 +4,7 @@ import com.intellij.psi.*; import com.magento.idea.magento2plugin.reference.provider.FilePathReferenceProvider; import com.magento.idea.magento2plugin.reference.provider.ModuleNameReferenceProvider; +import com.magento.idea.magento2plugin.util.RegExUtil; import org.jetbrains.annotations.NotNull; import static com.intellij.patterns.StandardPatterns.string; @@ -12,12 +13,13 @@ public class JsReferenceContributor extends PsiReferenceContributor { @Override public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { registrar.registerReferenceProvider( - JSPatterns.jsLiteralExpression().withText(string().matches(".*[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+.*")), + JSPatterns.jsLiteralExpression() + .withText(string().matches(".*" + RegExUtil.Magento.MODULE_NAME + ".*")), new ModuleNameReferenceProvider() ); registrar.registerReferenceProvider( - JSPatterns.jsLiteralExpression().withText(string().matches(".*\\W([\\w-]+/)*[\\w\\.-]+.*")), + JSPatterns.jsLiteralExpression().withText(string().matches(".*\\W" + RegExUtil.FILE_PATH + ".*")), new FilePathReferenceProvider() ); } diff --git a/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java b/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java index 5eb0b258a..7cb7c4e1a 100644 --- a/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java +++ b/src/com/magento/idea/magento2plugin/reference/provider/PhpClassReferenceProvider.java @@ -27,7 +27,7 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu String origValue = element.getText(); - Pattern pattern = Pattern.compile(PhpRegex.Xml.CLASS_NAME); + Pattern pattern = Pattern.compile(PhpRegex.CLASS_NAME); Matcher matcher = pattern.matcher(origValue); if (!matcher.find()) { return PsiReference.EMPTY_ARRAY; diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java index 6500440b3..de77915b4 100644 --- a/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/ModuleNameIndex.java @@ -5,6 +5,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.indexing.*; +import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpFileType; @@ -16,22 +17,24 @@ import java.util.HashMap; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -public class ModuleNameIndex extends ScalarIndexExtension { - public static final ID KEY = +public class ModuleNameIndex extends FileBasedIndexExtension { + public static final ID KEY = ID.create("com.magento.idea.magento2plugin.stubs.indexes.module_name"); @NotNull @Override - public ID getName() { + public ID getName() { return KEY; } @NotNull @Override - public DataIndexer getIndexer() { + public DataIndexer getIndexer() { return inputData -> { - Map map = new HashMap<>(); + Map map = new HashMap<>(); PsiFile psiFile = inputData.getPsiFile(); if (!Settings.isEnabled(psiFile.getProject())) { @@ -46,10 +49,26 @@ public DataIndexer getIndexer() { PsiElement firstParameter = parameterList.getFirstPsiChild(); if (firstParameter != null && firstParameter instanceof ClassConstantReference) { String constantName = ((ClassConstantReference) firstParameter).getName(); - if (constantName != null && constantName.equalsIgnoreCase("module")) { - PsiElement moduleName = ((ClassConstantReference) firstParameter).getNextPsiSibling(); - if (moduleName != null && moduleName instanceof StringLiteralExpression) { - map.put(StringUtil.unquoteString(moduleName.getText()), null); + if (constantName != null) { + PsiElement moduleNameEl = ((ClassConstantReference) firstParameter).getNextPsiSibling(); + if (moduleNameEl != null && moduleNameEl instanceof StringLiteralExpression) { + String moduleName = StringUtil.unquoteString(moduleNameEl.getText()); + + PsiElement modulePathEl = + ((StringLiteralExpression) moduleNameEl).getNextPsiSibling(); + if (modulePathEl != null) { + Pattern pattern = Pattern.compile( + "__DIR__(\\s*[.,]\\s*[\\'\\\"]((/[\\w-]+)+)/?[\\'\\\"])?" + ); + Matcher matcher = pattern.matcher(modulePathEl.getText()); + if (matcher.find()) { + String modulePath = matcher.group(2); + map.put( + moduleName, + modulePath == null ? "" : modulePath + ); + } + } } } } @@ -67,6 +86,11 @@ public KeyDescriptor getKeyDescriptor() { return new EnumeratorStringDescriptor(); } + @NotNull + public DataExternalizer getValueExternalizer() { + return EnumeratorStringDescriptor.INSTANCE; + } + @NotNull @Override public FileBasedIndex.InputFilter getInputFilter() { diff --git a/src/com/magento/idea/magento2plugin/util/RegExUtil.java b/src/com/magento/idea/magento2plugin/util/RegExUtil.java new file mode 100644 index 000000000..dfd85e14c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/util/RegExUtil.java @@ -0,0 +1,11 @@ +package com.magento.idea.magento2plugin.util; + +public class RegExUtil { + + public static final String FILE_PATH = "[\\w-]+(/[\\w-]*)*"; + + public static class Magento { + public static final String MODULE_NAME + = "[A-Z][a-zA-Z0-9]+_[A-Z][a-zA-Z0-9]+"; + } +} diff --git a/src/com/magento/idea/magento2plugin/util/VfsUtil.java b/src/com/magento/idea/magento2plugin/util/VfsUtil.java new file mode 100644 index 000000000..a9a7c7f2b --- /dev/null +++ b/src/com/magento/idea/magento2plugin/util/VfsUtil.java @@ -0,0 +1,40 @@ +package com.magento.idea.magento2plugin.util; + +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; + +public class VfsUtil { + + public static VirtualFile findVfUp(VirtualFile item, String searchItemName) + { + if (item.getParent() != null) { + VirtualFile vf = VfsUtilCore.findRelativeFile(searchItemName, item.getParent()); + if (vf != null && !vf.isDirectory()) { + return vf; + } + } + return findVfUp(item.getParent(), searchItemName); + } + + public static Collection getAllSubFiles(VirtualFile virtualFile) + { + Collection list = new ArrayList<>(); + + VfsUtilCore.visitChildrenRecursively(virtualFile, new VirtualFileVisitor() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (!file.isDirectory()) { + list.add(file); + } + return super.visitFile(file); + } + }); + + return list; + } +} diff --git a/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java b/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java new file mode 100644 index 000000000..4537c3d1c --- /dev/null +++ b/src/com/magento/idea/magento2plugin/util/magento/FileBasedIndexUtil.java @@ -0,0 +1,69 @@ +package com.magento.idea.magento2plugin.util.magento; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.indexing.FileBasedIndex; +import com.jetbrains.php.lang.PhpFileType; +import com.magento.idea.magento2plugin.stubs.indexes.ModuleNameIndex; +import com.magento.idea.magento2plugin.util.RegExUtil; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FileBasedIndexUtil { + + public static Collection findViewVfsByModuleName(String moduleName, Project project) + { + Collection viewVfs = new ArrayList<>(); + + Pattern pattern = Pattern.compile(RegExUtil.Magento.MODULE_NAME); + Matcher matcher = pattern.matcher(moduleName); + if (!matcher.find()) { + return viewVfs; + } + + Collection moduleVfs = + FileBasedIndex.getInstance().getContainingFiles(ModuleNameIndex.KEY, moduleName, + GlobalSearchScope.getScopeRestrictedByFileTypes( + GlobalSearchScope.allScope(project), + PhpFileType.INSTANCE + ) + ); + + for (VirtualFile moduleVf : moduleVfs) { + viewVfs.addAll(getValues(moduleName, moduleVf, project)); + } + return viewVfs; + } + + public static Collection findViewVfsByModuleVf(VirtualFile moduleVf, Project project) + { + Collection viewVfs = new ArrayList<>(); + + for (String moduleName : FileBasedIndex.getInstance().getAllKeys(ModuleNameIndex.KEY, project)) { + viewVfs.addAll(getValues(moduleName, moduleVf, project)); + } + return viewVfs; + } + + private static Collection getValues(String moduleName, VirtualFile moduleVf, Project project) + { + Collection viewVfs = new ArrayList<>(); + FileBasedIndex.getInstance() + .processValues( + ModuleNameIndex.KEY, moduleName, moduleVf, + (file, value) -> { + VirtualFile viewVf = file.getParent().findFileByRelativePath(value.concat("/view")); + if (viewVf != null) { + viewVfs.add(viewVf); + } + return false; + }, + GlobalSearchScope.fileScope(project, moduleVf) + ); + return viewVfs; + } +}