Skip to content

Commit 3b31476

Browse files
committed
Initial commit
0 parents  commit 3b31476

File tree

5 files changed

+178
-0
lines changed

5 files changed

+178
-0
lines changed

META-INF/plugin.xml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<idea-plugin version="2">
2+
<id>fr.adrienbrault.idea.symfony2plugin</id>
3+
<name>Symfony2 Plugin</name>
4+
<version>0.1.0</version>
5+
<vendor email="adrien.brault@gmail.com" url="http://adrienbrault.fr">Adrien Brault</vendor>
6+
7+
<description><![CDATA[
8+
Symfony2 plugin.
9+
10+
Currently detect ContainerInterface::get() result type.
11+
]]></description>
12+
13+
<change-notes><![CDATA[
14+
15+
]]>
16+
</change-notes>
17+
18+
<!-- please see http://confluence.jetbrains.net/display/IDEADEV/Build+Number+Ranges for description -->
19+
<idea-version since-build="107.105"/>
20+
21+
<extensions defaultExtensionNs="com.intellij">
22+
<php.typeProvider implementation="fr.adrienbrault.idea.symfony2plugin.SymfonyContainerTypeProvider"/>
23+
</extensions>
24+
25+
<depends>com.jetbrains.php</depends>
26+
<depends>com.intellij.modules.platform</depends>
27+
</idea-plugin>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package fr.adrienbrault.idea.symfony2plugin;
2+
3+
import com.intellij.openapi.project.Project;
4+
import com.intellij.psi.PsiElement;
5+
import com.jetbrains.php.lang.psi.elements.impl.MethodImpl;
6+
import com.jetbrains.php.lang.psi.elements.impl.MethodReferenceImpl;
7+
import com.jetbrains.php.lang.psi.elements.impl.StringLiteralExpressionImpl;
8+
import com.jetbrains.php.lang.psi.resolve.types.PhpType;
9+
import com.jetbrains.php.lang.psi.resolve.types.PhpTypeProvider;
10+
import org.jetbrains.annotations.Nullable;
11+
import org.w3c.dom.*;
12+
import org.xml.sax.SAXException;
13+
14+
import javax.xml.parsers.*;
15+
import java.io.File;
16+
import java.io.IOException;
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
20+
/**
21+
* @author Adrien Brault <adrien.brault@gmail.com>
22+
*/
23+
public class SymfonyContainerTypeProvider implements PhpTypeProvider {
24+
25+
@Nullable
26+
@Override
27+
public PhpType getType(PsiElement e) {
28+
if (!isContainerGetCall(e)) {
29+
return null;
30+
}
31+
32+
String serviceId = getServiceId((MethodReferenceImpl) e);
33+
if (null == serviceId) {
34+
return null;
35+
}
36+
37+
Map<String, String> serviceMap = getServicesMap(e.getProject());
38+
String serviceClass = serviceMap.get(serviceId);
39+
40+
if (null == serviceClass) {
41+
return null;
42+
}
43+
44+
return new PhpType().add(serviceClass);
45+
}
46+
47+
private boolean isContainerGetCall(PsiElement e) {
48+
if (!(e instanceof MethodReferenceImpl)) {
49+
return false;
50+
}
51+
52+
MethodReferenceImpl methodRefImpl = (MethodReferenceImpl) e;
53+
if (null == e.getReference()) {
54+
return false;
55+
}
56+
57+
PsiElement resolvedReference = methodRefImpl.getReference().resolve();
58+
if (!(resolvedReference instanceof MethodImpl)) {
59+
return false;
60+
}
61+
62+
MethodImpl methodImpl = (MethodImpl) resolvedReference;
63+
String methodFQN = methodImpl.getFQN(); // Something like "\Symfony\Bundle\FrameworkBundle\Controller\Controller.get"
64+
if (null == methodFQN) {
65+
return false;
66+
}
67+
68+
if (methodFQN.equals("\\Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller.get")
69+
|| methodFQN.equals("\\Symfony\\Component\\DependencyInjection\\ContainerInterface.get")) {
70+
return true;
71+
}
72+
73+
return false;
74+
}
75+
76+
private String getServiceId(MethodReferenceImpl e) {
77+
String serviceId = null;
78+
79+
PsiElement[] parameters = e.getParameters();
80+
if (parameters.length > 0 && parameters[0] instanceof StringLiteralExpressionImpl) {
81+
serviceId = parameters[0].getText(); // quoted string
82+
serviceId = serviceId.substring(1, serviceId.length() - 1);
83+
}
84+
85+
return serviceId;
86+
}
87+
88+
private Map<String, String> cachedServiceMap;
89+
private long cachedServiceMapLastModified;
90+
91+
private Map<String, String>getServicesMap(Project project) {
92+
Map<String, String> map = new HashMap<String, String>();
93+
94+
String defaultServiceMapFilePath = project.getBasePath() + "/app/cache/dev/appDevDebugProjectContainer.xml";
95+
File xmlFile = new File(defaultServiceMapFilePath);
96+
if (!xmlFile.exists()) {
97+
return map;
98+
}
99+
100+
long xmlFileLastModified = xmlFile.lastModified();
101+
if (xmlFileLastModified == cachedServiceMapLastModified) {
102+
return cachedServiceMap;
103+
}
104+
105+
Document doc = null;
106+
try {
107+
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
108+
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
109+
doc = dBuilder.parse(xmlFile);
110+
} catch (SAXException e) {
111+
e.printStackTrace();
112+
113+
return map;
114+
} catch (IOException e) {
115+
e.printStackTrace();
116+
117+
return map;
118+
} catch (ParserConfigurationException e) {
119+
e.printStackTrace();
120+
121+
return map;
122+
}
123+
124+
NodeList servicesNodes = doc.getElementsByTagName("service");
125+
for (int i = 0; i < servicesNodes.getLength(); i++) {
126+
Element node = (Element) servicesNodes.item(i);
127+
map.put(node.getAttribute("id"), "\\" + node.getAttribute("class"));
128+
}
129+
130+
cachedServiceMap = map;
131+
cachedServiceMapLastModified = xmlFileLastModified;
132+
133+
return map;
134+
}
135+
136+
}

symfony2-plugin.iml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="PLUGIN_MODULE" version="4">
3+
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/META-INF/plugin.xml" />
4+
<component name="NewModuleRootManager" inherit-compiler-output="true">
5+
<exclude-output />
6+
<content url="file://$MODULE_DIR$">
7+
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
8+
</content>
9+
<orderEntry type="inheritedJdk" />
10+
<orderEntry type="sourceFolder" forTests="false" />
11+
<orderEntry type="library" scope="PROVIDED" name="php-openapi" level="project" />
12+
<orderEntry type="library" scope="PROVIDED" name="php" level="project" />
13+
</component>
14+
</module>
15+

symfony2-plugin.jar

4 KB
Binary file not shown.

0 commit comments

Comments
 (0)