diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/quickfix/CorrectClassNameCasingYamlLocalQuickFix.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/quickfix/CorrectClassNameCasingYamlLocalQuickFix.java new file mode 100644 index 000000000..e40176860 --- /dev/null +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/quickfix/CorrectClassNameCasingYamlLocalQuickFix.java @@ -0,0 +1,48 @@ +package fr.adrienbrault.idea.symfony2plugin.action.quickfix; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlPsiElementFactory; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.yaml.psi.YAMLKeyValue; + +public class CorrectClassNameCasingYamlLocalQuickFix implements LocalQuickFix { + + private final String replacementFQN; + + public CorrectClassNameCasingYamlLocalQuickFix(String replacementFQN) { + + this.replacementFQN = replacementFQN; + } + + @Nls(capitalization = Nls.Capitalization.Sentence) + @NotNull + @Override + public String getFamilyName() { + return "YAML"; + } + + @Nls(capitalization = Nls.Capitalization.Sentence) + @NotNull + @Override + public String getName() { + return "Use " + replacementFQN; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PsiElement psiElement1 = descriptor.getPsiElement(); + YAMLKeyValue replacement = YamlPsiElementFactory.createFromText( + project, + YAMLKeyValue.class, + "class: " + replacementFQN + ); + + if (replacement != null && replacement.getValue() != null) { + psiElement1.replace(replacement.getValue()); + } + } +} diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/codeInspection/service/ServiceDeprecatedClassesInspection.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/codeInspection/service/ServiceDeprecatedClassesInspection.java index 7ae03d9c6..00148572a 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/codeInspection/service/ServiceDeprecatedClassesInspection.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/codeInspection/service/ServiceDeprecatedClassesInspection.java @@ -140,7 +140,7 @@ public void visitElement(PsiElement element) { } else if(element.getNode().getElementType() == YAMLTokenTypes.TEXT) { // @service String text = element.getText(); - if(text != null && StringUtils.isNotBlank(text) && text.startsWith("@")) { + if(StringUtils.isNotBlank(text) && text.startsWith("@")) { this.problemRegistrar.attachDeprecatedProblem(element, text.substring(1), holder); this.problemRegistrar.attachServiceDeprecatedProblem(element, text.substring(1), holder); } diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/inspection/YamlClassInspection.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/inspection/YamlClassInspection.java index 4fbc5065e..58a8ba386 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/inspection/YamlClassInspection.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/dic/inspection/YamlClassInspection.java @@ -6,7 +6,9 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.psi.elements.PhpClass; import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; +import fr.adrienbrault.idea.symfony2plugin.action.quickfix.CorrectClassNameCasingYamlLocalQuickFix; import fr.adrienbrault.idea.symfony2plugin.config.yaml.YamlElementPatternHelper; import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver; import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil; @@ -20,6 +22,10 @@ * @author Daniel Espendiller */ public class YamlClassInspection extends LocalInspectionTool { + + public static final String MESSAGE_WRONG_CASING = "Wrong class casing"; + public static final String MESSAGE_MISSING_CLASS = "Missing class"; + @NotNull public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, boolean isOnTheFly) { if (!Symfony2ProjectComponent.isEnabled(holder.getProject())) { @@ -29,7 +35,7 @@ public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, bool return new PsiElementVisitor() { @Override public void visitElement(PsiElement psiElement) { - if(!((YamlElementPatternHelper.getSingleLineScalarKey("class", "factory_class").accepts(psiElement) || YamlElementPatternHelper.getParameterClassPattern().accepts(psiElement)) && YamlElementPatternHelper.getInsideServiceKeyPattern().accepts(psiElement))) { + if (!((YamlElementPatternHelper.getSingleLineScalarKey("class", "factory_class").accepts(psiElement) || YamlElementPatternHelper.getParameterClassPattern().accepts(psiElement)) && YamlElementPatternHelper.getInsideServiceKeyPattern().accepts(psiElement))) { super.visitElement(psiElement); return; } @@ -44,15 +50,18 @@ public void visitElement(PsiElement psiElement) { private void invoke(@NotNull final PsiElement psiElement, @NotNull ProblemsHolder holder) { String className = PsiElementUtils.getText(psiElement); - if(YamlHelper.isValidParameterName(className)) { + if (YamlHelper.isValidParameterName(className)) { String resolvedParameter = ContainerCollectionResolver.resolveParameter(psiElement.getProject(), className); - if(resolvedParameter != null && PhpIndex.getInstance(psiElement.getProject()).getAnyByFQN(resolvedParameter).size() > 0) { - return ; + if (resolvedParameter != null && PhpIndex.getInstance(psiElement.getProject()).getAnyByFQN(resolvedParameter).size() > 0) { + return; } } - if(PhpElementsUtil.getClassInterface(psiElement.getProject(), className) == null) { - holder.registerProblem(psiElement, "Missing Class", ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + PhpClass foundClass = PhpElementsUtil.getClassInterface(psiElement.getProject(), className); + if (foundClass == null) { + holder.registerProblem(psiElement, MESSAGE_MISSING_CLASS, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } else if (!foundClass.getPresentableFQN().equals(className)) { + holder.registerProblem(psiElement, MESSAGE_WRONG_CASING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new CorrectClassNameCasingYamlLocalQuickFix(foundClass.getPresentableFQN())); } } } diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/dic/inspection/YamlClassInspectionTest.java b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/dic/inspection/YamlClassInspectionTest.java index 97057f389..f32c4953a 100644 --- a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/dic/inspection/YamlClassInspectionTest.java +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/dic/inspection/YamlClassInspectionTest.java @@ -1,9 +1,8 @@ package fr.adrienbrault.idea.symfony2plugin.tests.dic.inspection; +import fr.adrienbrault.idea.symfony2plugin.dic.inspection.YamlClassInspection; import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; -import java.io.File; - /** * @author Daniel Espendiller * @see fr.adrienbrault.idea.symfony2plugin.dic.inspection.YamlClassInspection @@ -20,15 +19,26 @@ public String getTestDataPath() { } public void testInspectionForClass() { - assertLocalInspectionContains("services.yml", "services:\n class: Args\\FooBar", "Missing Class"); - assertLocalInspectionContains("services.yml", "services:\n class: 'Args\\FooBar'", "Missing Class"); - assertLocalInspectionContains("services.yml", "services:\n class: \"Args\\FooBar\"", "Missing Class"); - assertLocalInspectionContains("services.yml", "services:\n factory_class: Args\\FooBar", "Missing Class"); - assertLocalInspectionNotContains("services.yml", "services:\n factory_class: Args\\Foo", "Missing Class"); - - assertLocalInspectionContains("services.yml", "parameters:\n foo.class: Args\\FooBar", "Missing Class"); - assertLocalInspectionContains("services.yml", "parameters:\n foo.class: 'Args\\FooBar'", "Missing Class"); - assertLocalInspectionContains("services.yml", "parameters:\n foo.class: \"Args\\FooBar\"", "Missing Class"); - assertLocalInspectionNotContains("services.yml", "parameters:\n foo.class: Args\\Foo", "Missing Class"); + assertLocalInspectionContains("services.yml", "services:\n class: Args\\FooBar", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionContains("services.yml", "services:\n class: 'Args\\FooBar'", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionContains("services.yml", "services:\n class: \"Args\\FooBar\"", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionContains("services.yml", "services:\n factory_class: Args\\FooBar", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionNotContains("services.yml", "services:\n factory_class: Args\\Foo", YamlClassInspection.MESSAGE_MISSING_CLASS); + + assertLocalInspectionContains("services.yml", "parameters:\n foo.class: Args\\FooBar", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionContains("services.yml", "parameters:\n foo.class: 'Args\\FooBar'", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionContains("services.yml", "parameters:\n foo.class: \"Args\\FooBar\"", YamlClassInspection.MESSAGE_MISSING_CLASS); + assertLocalInspectionNotContains("services.yml", "parameters:\n foo.class: Args\\Foo", YamlClassInspection.MESSAGE_MISSING_CLASS); + + assertLocalInspectionContains("services.yml", "services:\n class: Args\\FoO", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionContains("services.yml", "services:\n class: 'Args\\FoO'", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionContains("services.yml", "services:\n class: \"Args\\FoO\"", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionContains("services.yml", "services:\n factory_class: Args\\FoO", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionNotContains("services.yml", "services:\n factory_class: Args\\Foo", YamlClassInspection.MESSAGE_WRONG_CASING); + + assertLocalInspectionContains("services.yml", "parameters:\n foo.class: Args\\FoO", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionContains("services.yml", "parameters:\n foo.class: 'Args\\FoO'", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionContains("services.yml", "parameters:\n foo.class: \"Args\\FoO\"", YamlClassInspection.MESSAGE_WRONG_CASING); + assertLocalInspectionNotContains("services.yml", "parameters:\n foo.class: Args\\Foo", YamlClassInspection.MESSAGE_WRONG_CASING); } } diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/twig/annotation/TemplateAnnotationAnnotatorTest.java b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/twig/annotation/TemplateAnnotationAnnotatorTest.java index a7d54d8cb..86e3c8b9f 100644 --- a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/twig/annotation/TemplateAnnotationAnnotatorTest.java +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/twig/annotation/TemplateAnnotationAnnotatorTest.java @@ -9,10 +9,8 @@ import com.jetbrains.php.lang.documentation.phpdoc.psi.tags.PhpDocTag; import de.espend.idea.php.annotation.extension.parameter.PhpAnnotationDocTagAnnotatorParameter; import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigUtil; -import fr.adrienbrault.idea.symfony2plugin.twig.annotation.TemplateAnnotationAnnotator; import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; - -import java.io.File; +import fr.adrienbrault.idea.symfony2plugin.twig.annotation.TemplateAnnotationAnnotator; /** * @author Daniel Espendiller