From df846bea7b74bfdf0938389f380dfedf1cd1f9e5 Mon Sep 17 00:00:00 2001 From: Daniel Espendiller Date: Sun, 9 Aug 2015 10:31:37 +0200 Subject: [PATCH] add testing for doctrine types in yaml and provide navigation #555 --- .../DoctrineStaticTypeLookupBuilder.java | 56 +++++++++++++-- .../yaml/YamlGoToKnownDeclarationHandler.java | 22 ++++-- ...ymfonyLightCodeInsightFixtureTestCase.java | 11 ++- .../yaml/doctrine/DoctrineOrmYamlTest.java | 69 +++++++++++++++++++ .../yaml/doctrine/fixtures/DoctrineTypes.php | 25 +++++++ 5 files changed, 169 insertions(+), 14 deletions(-) create mode 100644 tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/DoctrineOrmYamlTest.java create mode 100644 tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/fixtures/DoctrineTypes.php diff --git a/src/fr/adrienbrault/idea/symfony2plugin/config/doctrine/DoctrineStaticTypeLookupBuilder.java b/src/fr/adrienbrault/idea/symfony2plugin/config/doctrine/DoctrineStaticTypeLookupBuilder.java index f6ad2af32..f12c77515 100644 --- a/src/fr/adrienbrault/idea/symfony2plugin/config/doctrine/DoctrineStaticTypeLookupBuilder.java +++ b/src/fr/adrienbrault/idea/symfony2plugin/config/doctrine/DoctrineStaticTypeLookupBuilder.java @@ -3,6 +3,7 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; import com.jetbrains.php.PhpIndex; import com.jetbrains.php.lang.psi.elements.PhpClass; import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons; @@ -10,6 +11,7 @@ import fr.adrienbrault.idea.symfony2plugin.util.completion.annotations.AnnotationMethodInsertHandler; import fr.adrienbrault.idea.symfony2plugin.util.completion.annotations.AnnotationTagInsertHandler; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -22,22 +24,62 @@ public class DoctrineStaticTypeLookupBuilder { public static Collection getTypes(@NotNull Project project) { - Map lookupElements = new HashMap(); + final Collection lookupElements = new ArrayList(); + + visitCustomTypes(project, new ColumnTypeVisitor() { + @Override + public void visit(@NotNull String name, @Nullable PhpClass phpClass, @Nullable PsiElement psiElement) { + LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name).withIcon(Symfony2Icons.DOCTRINE); + + if(phpClass != null) { + lookupElementBuilder = lookupElementBuilder.withTypeText(phpClass.getName(), true); + } + + lookupElements.add(lookupElementBuilder); + } + }); + + return lookupElements; + } + + public static void visitCustomTypes(@NotNull Project project, @NotNull ColumnTypeVisitor visitor) { + + Set found = new HashSet(); for (PhpClass phpClass : PhpIndex.getInstance(project).getAllSubclasses("\\Doctrine\\DBAL\\Types\\Type")) { - String getName = PhpElementsUtil.getMethodReturnAsString(phpClass, "getName"); - if(getName != null) { - lookupElements.put(getName, LookupElementBuilder.create(getName).withIcon(Symfony2Icons.DOCTRINE).withTypeText(phpClass.getName(), true)); + String name = PhpElementsUtil.getMethodReturnAsString(phpClass, "getName"); + if(name != null) { + found.add(name); + visitor.visit(name, phpClass, phpClass.findMethodByName("getName")); } } for (String s : Arrays.asList("id", "string", "integer", "smallint", "bigint", "boolean", "decimal", "date", "time", "datetime", "text", "array", "float")) { - if(!lookupElements.containsKey(s)) { - lookupElements.put(s, LookupElementBuilder.create(s).withIcon(Symfony2Icons.DOCTRINE)); + if(!found.contains(s)) { + visitor.visit(s, null, null); } } - return lookupElements.values(); + } + + private interface ColumnTypeVisitor { + void visit(@NotNull String name, @Nullable PhpClass phpClass, @Nullable PsiElement psiElement); + } + + public static Collection getColumnTypesTargets(@NotNull Project project, final @NotNull String contents) { + + final Collection targets = new ArrayList(); + + visitCustomTypes(project, new ColumnTypeVisitor() { + @Override + public void visit(@NotNull String name, @Nullable PhpClass phpClass, @Nullable PsiElement psiElement) { + if(name.equals(contents) && phpClass != null) { + targets.add(phpClass); + } + } + }); + + return targets; } public ArrayList getNullAble() { diff --git a/src/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlGoToKnownDeclarationHandler.java b/src/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlGoToKnownDeclarationHandler.java index ef5904643..991bdcbf9 100644 --- a/src/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlGoToKnownDeclarationHandler.java +++ b/src/fr/adrienbrault/idea/symfony2plugin/config/yaml/YamlGoToKnownDeclarationHandler.java @@ -9,30 +9,26 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.php.PhpIndex; -import com.jetbrains.php.completion.PhpLookupElement; 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 fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent; import fr.adrienbrault.idea.symfony2plugin.config.EventDispatcherSubscriberUtil; -import fr.adrienbrault.idea.symfony2plugin.dic.XmlTagParser; +import fr.adrienbrault.idea.symfony2plugin.config.doctrine.DoctrineStaticTypeLookupBuilder; import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper; import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil; import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils; import fr.adrienbrault.idea.symfony2plugin.util.SymfonyBundleUtil; -import fr.adrienbrault.idea.symfony2plugin.util.controller.ControllerIndex; import fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil; import fr.adrienbrault.idea.symfony2plugin.util.dict.SymfonyBundle; -import fr.adrienbrault.idea.symfony2plugin.util.service.ServiceXmlParserFactory; import fr.adrienbrault.idea.symfony2plugin.util.yaml.YamlHelper; import org.apache.commons.lang.StringUtils; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.yaml.psi.YAMLCompoundValue; import org.jetbrains.yaml.psi.YAMLKeyValue; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; /** @@ -94,9 +90,23 @@ public PsiElement[] getGotoDeclarationTargets(PsiElement psiElement, int i, Edit this.getArrayMethodGoto(psiElement, results); } + if(YamlElementPatternHelper.getOrmSingleLineScalarKey("type").accepts(psiElement)) { + this.getOrmTypesNavigation(psiElement, results); + } + return results.toArray(new PsiElement[results.size()]); } + private void getOrmTypesNavigation(@NotNull PsiElement psiElement, @NotNull List results) { + + String text = PsiElementUtils.trimQuote(psiElement.getText()); + if(StringUtils.isBlank(text)) { + return; + } + + results.addAll(DoctrineStaticTypeLookupBuilder.getColumnTypesTargets(psiElement.getProject(), text)); + } + private void getArrayMethodGoto(PsiElement psiElement, List results) { String text = PsiElementUtils.trimQuote(psiElement.getText()); diff --git a/tests/fr/adrienbrault/idea/symfony2plugin/tests/SymfonyLightCodeInsightFixtureTestCase.java b/tests/fr/adrienbrault/idea/symfony2plugin/tests/SymfonyLightCodeInsightFixtureTestCase.java index 85e3be13a..ea4d8eb73 100644 --- a/tests/fr/adrienbrault/idea/symfony2plugin/tests/SymfonyLightCodeInsightFixtureTestCase.java +++ b/tests/fr/adrienbrault/idea/symfony2plugin/tests/SymfonyLightCodeInsightFixtureTestCase.java @@ -117,9 +117,18 @@ public void assertNavigationMatchWithParent(LanguageFileType languageFileType, S assertNavigationMatch(languageFileType, configureByText, PlatformPatterns.psiElement().withParent(PlatformPatterns.psiElement(iElementType))); } - public void assertNavigationMatch(LanguageFileType languageFileType, String configureByText, ElementPattern pattern) { + public void assertNavigationMatch(String filename, String configureByText, ElementPattern pattern) { + myFixture.configureByText(filename, configureByText); + assertNavigationMatch(pattern); + } + public void assertNavigationMatch(LanguageFileType languageFileType, String configureByText, ElementPattern pattern) { myFixture.configureByText(languageFileType, configureByText); + assertNavigationMatch(pattern); + } + + private void assertNavigationMatch(ElementPattern pattern) { + PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); Set targetStrings = new HashSet(); diff --git a/tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/DoctrineOrmYamlTest.java b/tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/DoctrineOrmYamlTest.java new file mode 100644 index 000000000..8e3e4b01c --- /dev/null +++ b/tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/DoctrineOrmYamlTest.java @@ -0,0 +1,69 @@ +package fr.adrienbrault.idea.symfony2plugin.tests.config.yaml.doctrine; + +import com.intellij.patterns.PlatformPatterns; +import com.jetbrains.php.lang.psi.elements.PhpClass; +import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; + +import java.io.File; + +/** + * @author Daniel Espendiller + */ +public class DoctrineOrmYamlTest extends SymfonyLightCodeInsightFixtureTestCase { + + public void setUp() throws Exception { + super.setUp(); + myFixture.configureFromExistingVirtualFile(myFixture.copyFileToProject("DoctrineTypes.php")); + } + + public String getTestDataPath() { + return new File(this.getClass().getResource("fixtures").getFile()).getAbsolutePath(); + } + + /** + * @see fr.adrienbrault.idea.symfony2plugin.config.yaml.YamlCompletionContributor + */ + public void testDoctrineOrmFieldCompletion() { + + assertCompletionContains("foo.orm.yml", "foo:\n" + + " fields:\n" + + " field_1:\n" + + " type: ", + "BAR", "foo_const", "id" + ); + + assertCompletionContains("foo.orm.yml", "foo:\n" + + " id:\n" + + " field_1:\n" + + " type: ", + "BAR", "foo_const", "id" + ); + } + + /** + * @see fr.adrienbrault.idea.symfony2plugin.config.yaml.YamlGoToKnownDeclarationHandler + */ + public void testDoctrineOrmFieldNavigation() { + + assertNavigationMatch("foo.orm.yml", "foo:\n" + + " fields:\n" + + " field_1:\n" + + " type: BAR", + PlatformPatterns.psiElement(PhpClass.class) + ); + + assertNavigationMatch("foo.orm.yml", "foo:\n" + + " fields:\n" + + " field_1:\n" + + " type: foo_const", + PlatformPatterns.psiElement(PhpClass.class) + ); + + assertNavigationMatch("foo.orm.yml", "foo:\n" + + " id:\n" + + " field_1:\n" + + " type: BAR", + PlatformPatterns.psiElement(PhpClass.class) + ); + } +} diff --git a/tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/fixtures/DoctrineTypes.php b/tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/fixtures/DoctrineTypes.php new file mode 100644 index 000000000..2a9122bd1 --- /dev/null +++ b/tests/fr/adrienbrault/idea/symfony2plugin/tests/config/yaml/doctrine/fixtures/DoctrineTypes.php @@ -0,0 +1,25 @@ +