Skip to content

Commit c9b3a7c

Browse files
authored
Merge pull request #1515 from Haehnchen/feature/annotation-constraint-message
support constraint message navigation and completion in annotations
2 parents 434a371 + 252b546 commit c9b3a7c

File tree

5 files changed

+161
-0
lines changed

5 files changed

+161
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package fr.adrienbrault.idea.symfony2plugin.translation.annotation;
2+
3+
import com.intellij.psi.PsiElement;
4+
import com.intellij.psi.PsiReference;
5+
import com.jetbrains.php.lang.psi.elements.StringLiteralExpression;
6+
import de.espend.idea.php.annotation.extension.PhpAnnotationCompletionProvider;
7+
import de.espend.idea.php.annotation.extension.PhpAnnotationReferenceProvider;
8+
import de.espend.idea.php.annotation.extension.parameter.AnnotationCompletionProviderParameter;
9+
import de.espend.idea.php.annotation.extension.parameter.AnnotationPropertyParameter;
10+
import de.espend.idea.php.annotation.extension.parameter.PhpAnnotationReferenceProviderParameter;
11+
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
12+
import fr.adrienbrault.idea.symfony2plugin.translation.TranslationReference;
13+
import fr.adrienbrault.idea.symfony2plugin.translation.dict.TranslationUtil;
14+
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
15+
import org.jetbrains.annotations.Nullable;
16+
17+
/**
18+
* Support "@FooConstraint(message="sss")"
19+
*
20+
* @author Daniel Espendiller <[email protected]>
21+
*/
22+
public class ConstraintMessageAnnotationReferences implements PhpAnnotationReferenceProvider, PhpAnnotationCompletionProvider {
23+
@Nullable
24+
@Override
25+
public PsiReference[] getPropertyReferences(AnnotationPropertyParameter parameter, PhpAnnotationReferenceProviderParameter phpAnnotationReferenceProviderParameter) {
26+
if (!Symfony2ProjectComponent.isEnabled(parameter.getProject()) || !PhpElementsUtil.isInstanceOf(parameter.getPhpClass(), "\\Symfony\\Component\\Validator\\Constraint")) {
27+
return new PsiReference[0];
28+
}
29+
30+
String propertyName = parameter.getPropertyName();
31+
if (propertyName == null || !propertyName.startsWith("message")) {
32+
return new PsiReference[0];
33+
}
34+
35+
PsiElement element = parameter.getElement();
36+
if (!(element instanceof StringLiteralExpression)) {
37+
return new PsiReference[0];
38+
}
39+
40+
return new PsiReference[] { new TranslationReference((StringLiteralExpression) element, "validators")};
41+
}
42+
43+
@Override
44+
public void getPropertyValueCompletions(AnnotationPropertyParameter parameter, AnnotationCompletionProviderParameter annotationCompletionProviderParameter) {
45+
if (!Symfony2ProjectComponent.isEnabled(parameter.getProject()) || !PhpElementsUtil.isInstanceOf(parameter.getPhpClass(), "\\Symfony\\Component\\Validator\\Constraint")) {
46+
return;
47+
}
48+
49+
String propertyName = parameter.getPropertyName();
50+
if (propertyName == null || !propertyName.startsWith("message")) {
51+
return;
52+
}
53+
54+
annotationCompletionProviderParameter
55+
.getResult()
56+
.addAllElements(TranslationUtil.getTranslationLookupElementsOnDomain(parameter.getProject(), "validators"));
57+
}
58+
}

src/main/resources/META-INF/plugin.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,10 @@
634634

635635
<!-- @IsGranted -->
636636
<PhpAnnotationReferenceProvider implementation="fr.adrienbrault.idea.symfony2plugin.security.IsGrantedAnnotationReferences"/>
637+
638+
<!-- @FooConstraint(message="sss") -->
639+
<PhpAnnotationReferenceProvider implementation="fr.adrienbrault.idea.symfony2plugin.translation.annotation.ConstraintMessageAnnotationReferences"/>
640+
<PhpAnnotationCompletionProvider implementation="fr.adrienbrault.idea.symfony2plugin.translation.annotation.ConstraintMessageAnnotationReferences"/>
637641
</extensions>
638642

639643
<extensions defaultExtensionNs="de.espend.idea.php.toolbox.extension">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package fr.adrienbrault.idea.symfony2plugin.tests.translation.annotation;
2+
3+
import com.intellij.patterns.PlatformPatterns;
4+
import com.jetbrains.php.lang.PhpFileType;
5+
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
6+
import fr.adrienbrault.idea.symfony2plugin.translation.annotation.ConstraintMessageAnnotationReferences;
7+
8+
/**
9+
* @author Daniel Espendiller <[email protected]>
10+
* @see ConstraintMessageAnnotationReferences
11+
*/
12+
public class ConstraintMessageAnnotationReferencesTest extends SymfonyLightCodeInsightFixtureTestCase {
13+
14+
public void setUp() throws Exception {
15+
super.setUp();
16+
17+
myFixture.copyFileToProject("classes.php");
18+
myFixture.copyFileToProject("validators.de.yml", "Resources/translations/validators.de.yml");
19+
}
20+
21+
public String getTestDataPath() {
22+
return "src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/translation/annotation/fixtures";
23+
}
24+
25+
public void testThatCompletionIsGivenForConstraintMessageInAnnotation() {
26+
assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
27+
"\n" +
28+
"use Symfony\\Component\\Validator\\Constraints as Assert;\n" +
29+
"\n" +
30+
"/**\n" +
31+
" * @Assert\\Email(message=\"symfony<caret>\")\n" +
32+
" */\n" +
33+
"class Foo\n" +
34+
"{\n" +
35+
"}",
36+
"symfony_great"
37+
);
38+
39+
assertCompletionContains(PhpFileType.INSTANCE, "<?php\n" +
40+
"\n" +
41+
"use Symfony\\Component\\Validator\\Constraints as Assert;\n" +
42+
"\n" +
43+
"/**\n" +
44+
" * @Assert\\Email(messages=\"symfony<caret>\")\n" +
45+
" */\n" +
46+
"class Foo\n" +
47+
"{\n" +
48+
"}",
49+
"symfony_great"
50+
);
51+
}
52+
53+
public void testThatNavigationIsGivenForConstraintMessageInAnnotation() {
54+
assertReferenceMatchOnParent(PhpFileType.INSTANCE, "<?php\n" +
55+
"\n" +
56+
"use Symfony\\Component\\Validator\\Constraints as Assert;\n" +
57+
"\n" +
58+
"/**\n" +
59+
" * @Assert\\Email(message=\"symfony<caret>_great\")\n" +
60+
" */\n" +
61+
"class Foo {}\n",
62+
PlatformPatterns.psiElement()
63+
);
64+
65+
assertReferenceMatchOnParent(PhpFileType.INSTANCE, "<?php\n" +
66+
"\n" +
67+
"use Symfony\\Component\\Validator\\Constraints as Assert;\n" +
68+
"\n" +
69+
"/**\n" +
70+
" * @Assert\\Email(messages=\"symfony<caret>_great\")\n" +
71+
" */\n" +
72+
"class Foo {}\n",
73+
PlatformPatterns.psiElement()
74+
);
75+
}
76+
}
77+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Symfony\Component\Validator
4+
{
5+
abstract class Constraint
6+
{
7+
public function __construct($options = null)
8+
{
9+
}
10+
}
11+
}
12+
13+
namespace Symfony\Component\Validator\Constraints
14+
{
15+
use Symfony\Component\Validator\Constraint;
16+
17+
class Email extends Constraint
18+
{
19+
public $message = 'This value is not a valid email address.';
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
symfony_great: 'YAML Symfony2 is really great'

0 commit comments

Comments
 (0)