Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package fr.adrienbrault.idea.symfony2plugin.routing;

import com.intellij.codeInspection.LocalInspectionTool;
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.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.PhpClassMember;
import com.jetbrains.php.lang.psi.elements.PhpNamedElement;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.config.xml.XmlHelper;
import fr.adrienbrault.idea.symfony2plugin.config.yaml.YamlElementPatternHelper;
import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class RouteControllerDeprecatedInspection extends LocalInspectionTool {

@NotNull
public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) {
if(!Symfony2ProjectComponent.isEnabled(holder.getProject())) {
return super.buildVisitor(holder, isOnTheFly);
}

return new PsiElementVisitor() {
@Override
public void visitElement(@NotNull PsiElement element) {
if (XmlHelper.getRouteControllerPattern().accepts(element)) {
PsiElement parent = element.getParent();
if (parent != null) {
String text = RouteXmlReferenceContributor.getControllerText(parent);
if(text != null) {
extracted(element, text, holder);
}
}
} else if(YamlElementPatternHelper.getSingleLineScalarKey("_controller", "controller").accepts(element)) {
String text = PsiElementUtils.trimQuote(element.getText());
if (StringUtils.isNotBlank(text)) {
extracted(element, text, holder);
}
}

super.visitElement(element);
}
};
}

private void extracted(@NotNull PsiElement element, String text, @NotNull ProblemsHolder holder) {
for (PsiElement psiElement : RouteHelper.getMethodsOnControllerShortcut(element.getProject(), text)) {
if (!(psiElement instanceof PhpNamedElement)) {
continue;
}

// action is deprecated
if (((PhpNamedElement) psiElement).isDeprecated()) {
holder.registerProblem(element, "Symfony: Controller action is deprecated", ProblemHighlightType.LIKE_DEPRECATED);
break;
}

// class is deprecated
if (psiElement instanceof PhpClassMember) {
PhpClass containingClass = ((Method) psiElement).getContainingClass();
if (containingClass != null && containingClass.isDeprecated()) {
holder.registerProblem(element, "Symfony: Controller action is deprecated", ProblemHighlightType.LIKE_DEPRECATED);
break;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import fr.adrienbrault.idea.symfony2plugin.util.controller.ControllerIndex;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author Daniel Espendiller <daniel@espendiller.net>
Expand Down Expand Up @@ -43,20 +44,14 @@ private RouteActionReference(PsiElement psiElement) {

@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
PsiElement element = getElement();
PsiElement parent = element.getParent();

String text = null;
if(parent instanceof XmlText) {
// <route><default key="_controller">Fo<caret>o\Bar</default></route>
text = parent.getText();
} else if(parent instanceof XmlAttribute) {
// <route controller=""/>
text = ((XmlAttribute) parent).getValue();
public ResolveResult @NotNull [] multiResolve(boolean b) {
PsiElement parent = getElement().getParent();
if (parent == null) {
return new ResolveResult[0];
}

if(text == null || StringUtils.isBlank(text)) {
String text = getControllerText(parent);
if(text == null) {
return new ResolveResult[0];
}

Expand All @@ -71,4 +66,26 @@ public Object[] getVariants() {
return ControllerIndex.getControllerLookupElements(getElement().getProject()).toArray();
}
}

/**
* <default key="_controller">Fo<caret>o\Bar</default>
* <route controller=""/>
*/
@Nullable
public static String getControllerText(@NotNull PsiElement parent) {
String text = null;
if(parent instanceof XmlText) {
// <route><default key="_controller">Fo<caret>o\Bar</default></route>
text = parent.getText();
} else if(parent instanceof XmlAttribute) {
// <route controller=""/>
text = ((XmlAttribute) parent).getValue();
}

if (StringUtils.isBlank(text)) {
return null;
}

return text;
}
}
6 changes: 6 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,12 @@
language="PHP"
implementationClass="fr.adrienbrault.idea.symfony2plugin.templating.inspection.TemplateExistsAnnotationPhpAttributeLocalInspection"/>

<localInspection groupPath="Symfony" shortName="RouteControllerDeprecatedInspection" displayName="Deprecated Action"
groupName="Route"
enabledByDefault="true"
level="WARNING"
implementationClass="fr.adrienbrault.idea.symfony2plugin.routing.RouteControllerDeprecatedInspection"/>

<intentionAction>
<className>fr.adrienbrault.idea.symfony2plugin.intentions.php.PhpServiceIntention</className>
<category>PHP</category>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
<!-- tooltip end -->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package fr.adrienbrault.idea.symfony2plugin.tests.routing;

import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;

/**
* @author Daniel Espendiller <daniel@espendiller.net>
*
* @see fr.adrienbrault.idea.symfony2plugin.routing.RouteControllerDeprecatedInspection
*/
public class RouteControllerDeprecatedInspectionTest extends SymfonyLightCodeInsightFixtureTestCase {

public void setUp() throws Exception {
super.setUp();

myFixture.copyFileToProject("RouteControllerDeprecatedInspection.php");
}

protected String getTestDataPath() {
return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/routing/fixtures";
}

public void testDeprecatedRouteActionForYml() {
assertLocalInspectionContains("foobar.yml","" +
"blog_list:\n" +
" controller: App\\Controller\\BarController::foo<caret>bar",
"Symfony: Controller action is deprecated"
);

assertLocalInspectionContains("foobar.yml","" +
"blog_list:\n" +
" defaults: { _controller: App\\Controller\\BarController::foo<caret>bar }",
"Symfony: Controller action is deprecated"
);
}

public void testDeprecatedRouteActionForXml() {
assertLocalInspectionContains("foobar.xml",
"<routes>\n" +
" <route controller=\"App\\Controller\\BarController::foo<caret>bar\"/>\n" +
"</routes>",
"Symfony: Controller action is deprecated"
);

assertLocalInspectionContains("foobar.xml",
"<routes>\n" +
" <route>\n" +
" <default key=\"_controller\">App\\Controller\\BarController::foo<caret>bar</default>\n" +
" </route>\n" +
"</routes>",
"Symfony: Controller action is deprecated"
);
}

public void testDeprecatedRouteActionForClassMember() {
assertLocalInspectionContains("foobar.yml","" +
"blog_list:\n" +
" controller: App\\Controller\\CarController::foo<caret>bar",
"Symfony: Controller action is deprecated"
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Controller
{
class BarController
{
/**
* @deprecated
*/
public function foobar() {}
}

/**
* @deprecated
*/
class CarController
{
public function foobar() {}
}
}