diff --git a/README.md b/README.md index 9982e772b..6803f6fd5 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Building, debugging and other * Choose `View > Tool Windows > Gradle` * Double click `idea-php-symfony2-plugin > Tasks > intellij > runIde` -If you are having difficulties, consult the documentation: http://confluence.jetbrains.com/display/PhpStorm/Setting-up+environment+for+PhpStorm+plugin+development +If you are having difficulties, consult the documentation: https://plugins.jetbrains.com/docs/intellij/phpstorm.html * Want to sponsor my development? Nice! You can sponsor me via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5ZTGW6H4Y7MT8) or [Github](https://github.com/sponsors/Haehnchen). Github matches your donation so the total donation will be doubled. diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/ui/ServiceArgumentSelectionDialog.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/ui/ServiceArgumentSelectionDialog.java index b307415ca..5663a1a61 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/ui/ServiceArgumentSelectionDialog.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/action/ui/ServiceArgumentSelectionDialog.java @@ -20,6 +20,7 @@ import java.awt.*; import java.awt.event.KeyEvent; import java.util.ArrayList; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -29,7 +30,7 @@ public class ServiceArgumentSelectionDialog extends JDialog { private final Project project; - private final Map> arguments; + private final Map> arguments = new HashMap<>(); private final Callback callback; private JPanel panel1; private JButton generateButton; @@ -41,7 +42,7 @@ public class ServiceArgumentSelectionDialog extends JDialog { public ServiceArgumentSelectionDialog(Project project, Map> arguments, Callback callback) { this.project = project; - this.arguments = arguments; + this.arguments.putAll(arguments); this.callback = callback; } diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/completion/lookup/ClassConstantLookupElementAbstract.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/completion/lookup/ClassConstantLookupElementAbstract.java index 985e523e5..7f682f2fd 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/completion/lookup/ClassConstantLookupElementAbstract.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/completion/lookup/ClassConstantLookupElementAbstract.java @@ -11,12 +11,15 @@ * @author Daniel Espendiller */ abstract public class ClassConstantLookupElementAbstract extends LookupElement implements ClassConstantInsertHandler.ClassConstantLookupElementInterface { - @NotNull protected final PhpClass phpClass; + @NotNull + String phpClassName; + public ClassConstantLookupElementAbstract(@NotNull PhpClass phpClass) { this.phpClass = phpClass; + this.phpClassName = phpClass.getName(); } @Override @@ -30,7 +33,7 @@ public void renderElement(LookupElementPresentation presentation) { @NotNull @Override public String getLookupString() { - return phpClass.getName(); + return this.phpClassName; } @NotNull @@ -45,7 +48,7 @@ public PhpClass getPhpClass() { } @Override - public void handleInsert(InsertionContext context) { + public void handleInsert(@NotNull InsertionContext context) { ClassConstantInsertHandler.getInstance().handleInsert(context, this); } } diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/dict/DoctrineEntityLookupElement.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/dict/DoctrineEntityLookupElement.java index 1dbe4d6ee..27c7348fe 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/dict/DoctrineEntityLookupElement.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/dict/DoctrineEntityLookupElement.java @@ -14,9 +14,8 @@ * @author Daniel Espendiller */ public class DoctrineEntityLookupElement extends LookupElement { - private final String entityName; - private final PhpClass className; + private final String className; private boolean useClassNameAsLookupString = false; private DoctrineTypes.Manager manager; private boolean isWeak = false; @@ -26,14 +25,14 @@ public DoctrineEntityLookupElement(String entityName, PhpClass className, boolea this.useClassNameAsLookupString = useClassNameAsLookupString; } - public DoctrineEntityLookupElement(String entityName, PhpClass className, boolean useClassNameAsLookupString, boolean isWeak) { - this(entityName, className, useClassNameAsLookupString); + public DoctrineEntityLookupElement(String entityName, PhpClass phpClass, boolean useClassNameAsLookupString, boolean isWeak) { + this(entityName, phpClass, useClassNameAsLookupString); this.isWeak = isWeak; } - public DoctrineEntityLookupElement(String entityName, PhpClass className) { + public DoctrineEntityLookupElement(String entityName, PhpClass phpClass) { this.entityName = entityName; - this.className = className; + this.className = StringUtils.stripStart(phpClass.getFQN(), "\\"); } public DoctrineEntityLookupElement withManager(DoctrineTypes.Manager manager) { @@ -44,46 +43,42 @@ public DoctrineEntityLookupElement withManager(DoctrineTypes.Manager manager) { @NotNull @Override public String getLookupString() { - - if(this.useClassNameAsLookupString) { - return StringUtils.stripStart(this.className.getPresentableFQN(), "\\"); + if (this.useClassNameAsLookupString) { + return this.className; } return entityName; } - public void renderElement(LookupElementPresentation presentation) { - - if(this.useClassNameAsLookupString) { - presentation.setItemText(className.getPresentableFQN()); + public void renderElement(@NotNull LookupElementPresentation presentation) { + if (this.useClassNameAsLookupString) { + presentation.setItemText(className); presentation.setTypeText(getLookupString()); } else { presentation.setItemText(getLookupString()); - presentation.setTypeText(className.getPresentableFQN()); + presentation.setTypeText(className); } presentation.setTypeGrayed(true); - if(isWeak) { + if (isWeak) { // @TODO: remove weak presentation.setIcon(getWeakIcon()); } else { presentation.setIcon(getIcon()); } - - } @Nullable private Icon getWeakIcon() { - if(manager == null) { + if (manager == null) { return null; } - if(manager == DoctrineTypes.Manager.ORM) { + if (manager == DoctrineTypes.Manager.ORM) { return Symfony2Icons.DOCTRINE_WEAK; } - if(manager == DoctrineTypes.Manager.MONGO_DB || manager == DoctrineTypes.Manager.COUCH_DB) { + if (manager == DoctrineTypes.Manager.MONGO_DB || manager == DoctrineTypes.Manager.COUCH_DB) { return Symfony2Icons.NO_SQL; } @@ -92,20 +87,19 @@ private Icon getWeakIcon() { @Nullable private Icon getIcon() { - if(manager == null) { + if (manager == null) { return null; } - if(manager == DoctrineTypes.Manager.ORM) { + if (manager == DoctrineTypes.Manager.ORM) { return Symfony2Icons.DOCTRINE; } - if(manager == DoctrineTypes.Manager.MONGO_DB || manager == DoctrineTypes.Manager.COUCH_DB) { + if (manager == DoctrineTypes.Manager.MONGO_DB || manager == DoctrineTypes.Manager.COUCH_DB) { return Symfony2Icons.NO_SQL; } return null; } - } diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/metadata/lookup/DoctrineRepositoryLookupElement.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/metadata/lookup/DoctrineRepositoryLookupElement.java index b715237c0..dd69929ba 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/metadata/lookup/DoctrineRepositoryLookupElement.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/doctrine/metadata/lookup/DoctrineRepositoryLookupElement.java @@ -14,17 +14,19 @@ * @author Daniel Espendiller */ public class DoctrineRepositoryLookupElement extends LookupElement { - @NotNull - private final PhpClass phpClass; + private final @NotNull String phpClassPresentableFQN; + + private final @NotNull String phpClassName; private DoctrineRepositoryLookupElement(@NotNull PhpClass phpClass) { - this.phpClass = phpClass; + this.phpClassName = phpClass.getName(); + this.phpClassPresentableFQN = phpClass.getPresentableFQN(); } @Override public void renderElement(LookupElementPresentation presentation) { - presentation.setItemText(phpClass.getName()); - presentation.setTypeText(phpClass.getPresentableFQN()); + presentation.setItemText(phpClassName); + presentation.setTypeText(phpClassPresentableFQN); presentation.setTypeGrayed(true); presentation.setIcon(Symfony2Icons.DOCTRINE); } @@ -32,7 +34,7 @@ public void renderElement(LookupElementPresentation presentation) { @NotNull @Override public String getLookupString() { - return StringUtils.stripStart(phpClass.getPresentableFQN(), "\\"); + return StringUtils.stripStart(phpClassPresentableFQN, "\\"); } public static DoctrineRepositoryLookupElement create(@NotNull PhpClass phpClass) { diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/TwigAttributeIndex.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/TwigAttributeIndex.java new file mode 100644 index 000000000..ec79956ff --- /dev/null +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/indexes/TwigAttributeIndex.java @@ -0,0 +1,102 @@ +package fr.adrienbrault.idea.symfony2plugin.stubs.indexes; + +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; +import com.jetbrains.php.lang.psi.PhpFile; +import com.jetbrains.php.lang.psi.PhpPsiUtil; +import com.jetbrains.php.lang.psi.elements.*; +import fr.adrienbrault.idea.symfony2plugin.util.PhpPsiAttributesUtil; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Daniel Espendiller + */ +public class TwigAttributeIndex extends FileBasedIndexExtension { + public static final ID KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.twig_attribute_extension.index"); + + @Override + public @NotNull ID getName() { + return KEY; + } + + @Override + public @NotNull DataIndexer getIndexer() { + return new TwigAttributeIndexer(); + } + + @Override + public @NotNull KeyDescriptor getKeyDescriptor() { + return EnumeratorStringDescriptor.INSTANCE; + } + + @Override + public @NotNull DataExternalizer getValueExternalizer() { + return EnumeratorStringDescriptor.INSTANCE; + } + + @Override + public @NotNull FileBasedIndex.InputFilter getInputFilter() { + return virtualFile -> virtualFile.getFileType() == PhpFileType.INSTANCE; + } + + @Override + public boolean dependsOnFileContent() { + return true; + } + + @Override + public int getVersion() { + return 1; + } + + public static class TwigAttributeIndexer implements DataIndexer { + private static final String[] SUPPORTED_ATTRIBUTES = { + "\\Twig\\Attribute\\AsTwigFilter", + "\\Twig\\Attribute\\AsTwigFunction", + "\\Twig\\Attribute\\AsTwigTest", + }; + + @Override + public @NotNull Map map(@NotNull FileContent inputData) { + Map result = new HashMap<>(); + if (!(inputData.getPsiFile() instanceof PhpFile phpFile)) { + return result; + } + + for (PhpClass phpClass : PhpPsiUtil.findAllClasses(phpFile)) { + for (Method method : phpClass.getOwnMethods()) { + processMethodAttributes(phpClass, method, result); + } + } + + return result; + } + + private void processMethodAttributes(@NotNull PhpClass phpClass, @NotNull Method method, @NotNull Map result) { + for (PhpAttribute attribute : method.getAttributes()) { + String attributeFqn = attribute.getFQN(); + if (attributeFqn == null) { + continue; + } + + for (String supportedAttr : SUPPORTED_ATTRIBUTES) { + if (supportedAttr.equals(attributeFqn)) { + String nameAttribute = PhpPsiAttributesUtil.getAttributeValueByNameAsString(attribute, 0, "name"); + if (nameAttribute != null) { + result.put(nameAttribute, String.format("#M#C\\%s.%s", StringUtils.stripStart(phpClass.getFQN(), "\\"), method.getName())); + } + + break; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/util/IndexUtil.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/util/IndexUtil.java index e1af5bedf..dbaf8e727 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/util/IndexUtil.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/stubs/util/IndexUtil.java @@ -30,7 +30,8 @@ public static void forceReindex() { TwigIncludeStubIndex.KEY, TwigMacroFunctionStubIndex.KEY, TranslationStubIndex.KEY, - TwigBlockIndexExtension.KEY + TwigBlockIndexExtension.KEY, + TwigAttributeIndex.KEY }; for(ID id: indexIds) { diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/PhpTwigMethodLookupElement.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/PhpTwigMethodLookupElement.java index 994cedfda..7386e898d 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/PhpTwigMethodLookupElement.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/PhpTwigMethodLookupElement.java @@ -8,31 +8,36 @@ import fr.adrienbrault.idea.symfony2plugin.templating.util.TwigTypeResolveUtil; import fr.adrienbrault.idea.symfony2plugin.util.completion.TwigTypeInsertHandler; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Daniel Espendiller */ public class PhpTwigMethodLookupElement extends PhpLookupElement { + @Nullable + private String methodName; + PhpTwigMethodLookupElement(@NotNull PhpNamedElement namedElement) { super(namedElement); + + if (namedElement instanceof Method method) { + this.methodName = method.getName(); + } } @Override - public void handleInsert(InsertionContext context) { + public void handleInsert(@NotNull InsertionContext context) { TwigTypeInsertHandler.getInstance().handleInsert(context, this); } @Override - public void renderElement(LookupElementPresentation presentation) { + public void renderElement(@NotNull LookupElementPresentation presentation) { super.renderElement(presentation); - PhpNamedElement phpNamedElement = this.getNamedElement(); - // reset method to show full name again, which was stripped inside getLookupString - if(phpNamedElement instanceof Method && TwigTypeResolveUtil.isPropertyShortcutMethod((Method) phpNamedElement)) { - presentation.setItemText(phpNamedElement.getName()); + if (methodName != null && TwigTypeResolveUtil.isPropertyShortcutMethod(methodName)) { + presentation.setItemText(methodName); } - } @NotNull @@ -40,8 +45,8 @@ public String getLookupString() { String lookupString = super.getLookupString(); // remove property shortcuts eg getter / issers - if(this.getNamedElement() instanceof Method && TwigTypeResolveUtil.isPropertyShortcutMethod((Method) this.getNamedElement())) { - lookupString = TwigTypeResolveUtil.getPropertyShortcutMethodName((Method) this.getNamedElement()); + if (methodName != null && TwigTypeResolveUtil.isPropertyShortcutMethod(methodName)) { + lookupString = TwigTypeResolveUtil.getPropertyShortcutMethodName(methodName); } return lookupString; diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigExtensionParser.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigExtensionParser.java index ada0ec5f2..cc9281e20 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigExtensionParser.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigExtensionParser.java @@ -4,12 +4,16 @@ import com.intellij.openapi.util.Key; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.*; import com.jetbrains.php.PhpIcons; import com.jetbrains.php.PhpIndex; +import com.jetbrains.php.lang.PhpFileType; import com.jetbrains.php.lang.parser.PhpElementTypes; import com.jetbrains.php.lang.psi.PhpPsiUtil; import com.jetbrains.php.lang.psi.elements.*; +import fr.adrienbrault.idea.symfony2plugin.stubs.cache.FileIndexCaches; +import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigAttributeIndex; import fr.adrienbrault.idea.symfony2plugin.templating.dict.TwigExtension; import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil; import fr.adrienbrault.idea.symfony2plugin.util.PsiElementUtils; @@ -30,6 +34,15 @@ public class TwigExtensionParser { private static final Key>> FILTERS_CACHE = new Key<>("TWIG_EXTENSIONS_FILTERS"); private static final Key>> OPERATORS_CACHE = new Key<>("TWIG_EXTENSIONS_OPERATORS"); + private static final Key>>> TWIG_ATTRIBUTE_FUNCTION_INDEX = new Key<>("TWIG_ATTRIBUTE_FUNCTION_INDEX"); + private static final Key>> TWIG_ATTRIBUTE_FUNCTION_INDEX_NAMES = new Key<>("TWIG_ATTRIBUTE_FUNCTION_INDEX_NAMES"); + + private static final Key>>> TWIG_ATTRIBUTE_FILTER_INDEX = new Key<>("TWIG_ATTRIBUTE_FILTER_INDEX"); + private static final Key>> TWIG_ATTRIBUTE_FILTER_NAMES = new Key<>("TWIG_ATTRIBUTE_FILTER_NAMES"); + + private static final Key>>> TWIG_ATTRIBUTE_TEST_INDEX = new Key<>("TWIG_ATTRIBUTE_TEST_INDEX"); + private static final Key>> TWIG_ATTRIBUTE_TEST_NAMES = new Key<>("TWIG_ATTRIBUTE_FUNCTION_FILTER_NAMES"); + public enum TwigExtensionType { FUNCTION_METHOD, FUNCTION_NODE, SIMPLE_FUNCTION, FILTER, SIMPLE_TEST, OPERATOR } @@ -39,7 +52,7 @@ public static Map getFunctions(@NotNull Project project) return CachedValuesManager.getManager(project).getCachedValue( project, FUNCTION_CACHE, - () -> CachedValueProvider.Result.create(parseFunctions(TwigUtil.getTwigExtensionClasses(project)), PsiModificationTracker.MODIFICATION_COUNT), + () -> CachedValueProvider.Result.create(parseFunctions(project, TwigUtil.getTwigExtensionClasses(project)), PsiModificationTracker.MODIFICATION_COUNT), false ); } @@ -49,7 +62,7 @@ public static Map getFilters(@NotNull Project project) { return CachedValuesManager.getManager(project).getCachedValue( project, FILTERS_CACHE, - () -> CachedValueProvider.Result.create(parseFilters(TwigUtil.getTwigExtensionClasses(project)), PsiModificationTracker.MODIFICATION_COUNT), + () -> CachedValueProvider.Result.create(parseFilters(project, TwigUtil.getTwigExtensionClasses(project)), PsiModificationTracker.MODIFICATION_COUNT), false ); } @@ -59,7 +72,7 @@ public static Map getSimpleTest(@NotNull Project project) return CachedValuesManager.getManager(project).getCachedValue( project, TEST_CACHE, - () -> CachedValueProvider.Result.create(parseTests(TwigUtil.getTwigExtensionClasses(project)), PsiModificationTracker.MODIFICATION_COUNT), + () -> CachedValueProvider.Result.create(parseTests(project, TwigUtil.getTwigExtensionClasses(project)), PsiModificationTracker.MODIFICATION_COUNT), false ); } @@ -75,7 +88,7 @@ public static Map getOperators(@NotNull Project project) } @NotNull - private static Map parseFilters(@NotNull Collection phpClasses) { + private static Map parseFilters(@NotNull Project project, @NotNull Collection phpClasses) { Map extensions = new HashMap<>(); for (PhpClass phpClass : phpClasses) { @@ -92,11 +105,15 @@ private static Map parseFilters(@NotNull Collection> entry : FileIndexCaches.getStringDataCache(project, TWIG_ATTRIBUTE_FILTER_INDEX, TWIG_ATTRIBUTE_FILTER_NAMES, TwigAttributeIndex.KEY, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), PhpFileType.INSTANCE)).entrySet()) { + extensions.put(entry.getKey(), new TwigExtension(TwigExtensionType.FILTER, entry.getValue().getFirst())); + } + return Collections.unmodifiableMap(extensions); } @NotNull - private static Map parseFunctions(@NotNull Collection phpClasses) { + private static Map parseFunctions(@NotNull Project project, @NotNull Collection phpClasses) { Map extensions = new HashMap<>(); for (PhpClass phpClass : phpClasses) { @@ -113,11 +130,15 @@ private static Map parseFunctions(@NotNull Collection> entry : FileIndexCaches.getStringDataCache(project, TWIG_ATTRIBUTE_FUNCTION_INDEX, TWIG_ATTRIBUTE_FUNCTION_INDEX_NAMES, TwigAttributeIndex.KEY, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), PhpFileType.INSTANCE)).entrySet()) { + extensions.put(entry.getKey(), new TwigExtension(TwigExtensionType.FUNCTION_METHOD, entry.getValue().getFirst())); + } + return Collections.unmodifiableMap(extensions); } @NotNull - private static Map parseTests(@NotNull Collection phpClasses) { + private static Map parseTests(@NotNull Project project, @NotNull Collection phpClasses) { Map extensions = new HashMap<>(); for (PhpClass phpClass : phpClasses) { @@ -129,6 +150,10 @@ private static Map parseTests(@NotNull Collection> entry : FileIndexCaches.getStringDataCache(project, TWIG_ATTRIBUTE_TEST_INDEX, TWIG_ATTRIBUTE_TEST_NAMES, TwigAttributeIndex.KEY, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), PhpFileType.INSTANCE)).entrySet()) { + extensions.put(entry.getKey(), new TwigExtension(TwigExtensionType.SIMPLE_TEST, entry.getValue().getFirst())); + } + return Collections.unmodifiableMap(extensions); } diff --git a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigTypeResolveUtil.java b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigTypeResolveUtil.java index d5627df2a..f5e712521 100644 --- a/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigTypeResolveUtil.java +++ b/src/main/java/fr/adrienbrault/idea/symfony2plugin/templating/util/TwigTypeResolveUtil.java @@ -658,9 +658,12 @@ public static String getTypeDisplayName(Project project, Set types) { } public static boolean isPropertyShortcutMethod(Method method) { + return isPropertyShortcutMethod(method.getName()); + } - for(String shortcut: PROPERTY_SHORTCUTS) { - if(method.getName().startsWith(shortcut) && method.getName().length() > shortcut.length()) { + public static boolean isPropertyShortcutMethod(String methodName) { + for (String shortcut: PROPERTY_SHORTCUTS) { + if (methodName.startsWith(shortcut) && methodName.length() > shortcut.length()) { return true; } } @@ -669,9 +672,8 @@ public static boolean isPropertyShortcutMethod(Method method) { } public static boolean isPropertyShortcutMethodEqual(String methodName, String variableName) { - - for(String shortcut: PROPERTY_SHORTCUTS) { - if(methodName.equalsIgnoreCase(shortcut + variableName)) { + for (String shortcut: PROPERTY_SHORTCUTS) { + if (methodName.equalsIgnoreCase(shortcut + variableName)) { return true; } } @@ -688,11 +690,13 @@ public static boolean isPropertyShortcutMethodEqual(String methodName, String va */ @NotNull public static String getPropertyShortcutMethodName(@NotNull Method method) { - String methodName = method.getName(); + return getPropertyShortcutMethodName(method.getName()); + } - for(String shortcut: PROPERTY_SHORTCUTS) { + public static String getPropertyShortcutMethodName(@NotNull String methodName) { + for (String shortcut: PROPERTY_SHORTCUTS) { // strip possible property shortcut and make it lcfirst - if(method.getName().startsWith(shortcut) && method.getName().length() > shortcut.length()) { + if (methodName.startsWith(shortcut) && methodName.length() > shortcut.length()) { methodName = methodName.substring(shortcut.length()); return Character.toLowerCase(methodName.charAt(0)) + methodName.substring(1); } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 9f35223f0..8484fd6ce 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -270,6 +270,7 @@ + diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/TwigAttributeIndexTest.java b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/TwigAttributeIndexTest.java new file mode 100644 index 000000000..80f65d256 --- /dev/null +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/TwigAttributeIndexTest.java @@ -0,0 +1,26 @@ +package fr.adrienbrault.idea.symfony2plugin.tests.stubs.indexes; + +import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigAttributeIndex; +import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase; + +/** + * @author Daniel Espendiller + * @see fr.adrienbrault.idea.symfony2plugin.stubs.indexes.TwigAttributeIndex + */ +public class TwigAttributeIndexTest extends SymfonyLightCodeInsightFixtureTestCase { + public void setUp() throws Exception { + super.setUp(); + + myFixture.copyFileToProject("TwigAttributeIndex.php"); + } + + public void testThatValuesAreInIndex() { + assertIndexContainsKeyWithValue(TwigAttributeIndex.KEY, "product_number_filter", "#M#C\\App\\Twig\\AppExtension.formatProductNumberFilter"); + assertIndexContainsKeyWithValue(TwigAttributeIndex.KEY, "product_number_function", "#M#C\\App\\Twig\\AppExtension.formatProductNumberFunction"); + assertIndexContainsKeyWithValue(TwigAttributeIndex.KEY, "product_number_test", "#M#C\\App\\Twig\\AppExtension.formatProductNumberTest"); + } + + public String getTestDataPath() { + return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/fixtures"; + } +} diff --git a/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/fixtures/TwigAttributeIndex.php b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/fixtures/TwigAttributeIndex.php new file mode 100644 index 000000000..05c4d9cbe --- /dev/null +++ b/src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/stubs/indexes/fixtures/TwigAttributeIndex.php @@ -0,0 +1,25 @@ +