Skip to content

Commit c5c6174

Browse files
committed
Added support for @Persistent annotation
1 parent 16165e4 commit c5c6174

File tree

5 files changed

+154
-87
lines changed

5 files changed

+154
-87
lines changed

META-INF/plugin.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
groupName="Nette"
4444
implementationClass="cz.juzna.intellij.nette.inspections.NonPublicInjectInspection"
4545
level="ERROR" enabledByDefault="true"/>
46+
<localInspection language="PHP" shortName="NonPublicPersistent" id="NonPublicPersistent" displayName="Non-public @persistent property"
47+
groupName="Nette"
48+
implementationClass="cz.juzna.intellij.nette.inspections.NonPublicPersistentInspection"
49+
level="ERROR" enabledByDefault="true"/>
4650
<localInspection language="PHP" shortName="CreateComponentReturnFormType" id="CreateComponentReturnFormType" displayName="Form return type of createComponent*"
4751
groupName="Nette"
4852
implementationClass="cz.juzna.intellij.nette.inspections.CreateComponentReturnFormTypeInspection"

src/cz/juzna/intellij/nette/completion/PhpDocCompletionContributor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,21 @@
66
import com.intellij.patterns.PlatformPatterns;
77
import com.intellij.psi.PsiElement;
88
import com.intellij.util.ProcessingContext;
9+
import com.jetbrains.php.PhpIndex;
910
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
1011
import com.jetbrains.php.lang.parser.PhpElementTypes;
1112
import com.jetbrains.php.lang.psi.PhpPsiUtil;
1213
import com.jetbrains.php.lang.psi.elements.Field;
1314
import com.jetbrains.php.lang.psi.elements.GroupStatement;
15+
import com.jetbrains.php.lang.psi.elements.PhpClass;
1416
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
17+
import com.jetbrains.php.lang.psi.resolve.types.PhpType;
1518
import org.jetbrains.annotations.NotNull;
1619

1720
public class PhpDocCompletionContributor extends CompletionContributor {
1821

22+
private static PhpType presenterComponent = new PhpType().add("Nette\\Application\\UI\\PresenterComponent");
23+
1924
public PhpDocCompletionContributor() {
2025
this.extend(CompletionType.BASIC, PlatformPatterns.or(
2126
PlatformPatterns.psiElement().withSuperParent(3, PhpDocComment.class),
@@ -44,6 +49,10 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
4449
}
4550
if (field.getModifier().isPublic()) {
4651
result.addElement(LookupElementBuilder.create("inject").withBoldness(true));
52+
PhpClass cls = field.getContainingClass();
53+
if (cls != null && presenterComponent.isConvertibleFrom(cls.getType(), PhpIndex.getInstance(field.getProject()))) {
54+
result.addElement(LookupElementBuilder.create("persistent").withBoldness(true));
55+
}
4756
}
4857
}
4958
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package cz.juzna.intellij.nette.inspections;
2+
3+
import com.intellij.codeInspection.*;
4+
import com.intellij.lang.ASTNode;
5+
import com.intellij.openapi.project.Project;
6+
import com.intellij.psi.PsiElement;
7+
import com.intellij.psi.PsiFile;
8+
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
9+
import com.jetbrains.php.lang.lexer.PhpTokenTypes;
10+
import com.jetbrains.php.lang.psi.PhpPsiElementFactory;
11+
import com.jetbrains.php.lang.psi.elements.Field;
12+
import com.jetbrains.php.lang.psi.elements.PhpModifierList;
13+
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
14+
import org.jetbrains.annotations.Nls;
15+
import org.jetbrains.annotations.NotNull;
16+
import org.jetbrains.annotations.Nullable;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
21+
abstract public class NonPublicFieldInspection extends LocalInspectionTool {
22+
23+
abstract protected String getProblemDescription();
24+
25+
abstract protected String getFixName();
26+
27+
abstract protected boolean isInvalid(Field field);
28+
29+
30+
@Nullable
31+
@Override
32+
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
33+
34+
NonPublicFieldVisitor visitor = new NonPublicFieldVisitor(manager, isOnTheFly);
35+
file.accept(visitor);
36+
ProblemDescriptor[] problems = new ProblemDescriptor[visitor.getProblems().size()];
37+
38+
return visitor.getProblems().toArray(problems);
39+
}
40+
41+
private class NonPublicFieldVisitor extends PsiRecursiveElementWalkingVisitor {
42+
private final InspectionManager inspectionManager;
43+
private final boolean isOnTheFly;
44+
private Collection<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
45+
46+
public NonPublicFieldVisitor(InspectionManager inspectionManager, boolean isOnTheFly) {
47+
this.inspectionManager = inspectionManager;
48+
this.isOnTheFly = isOnTheFly;
49+
}
50+
51+
public Collection<ProblemDescriptor> getProblems() {
52+
return problems;
53+
}
54+
55+
@Override
56+
public void visitElement(PsiElement element) {
57+
if (element instanceof Field && isInvalid((Field) element)) {
58+
problems.add(inspectionManager.createProblemDescriptor(element, getProblemDescription(), new NonPublicPropertyFix(getFixName()), ProblemHighlightType.ERROR, isOnTheFly));
59+
}
60+
super.visitElement(element);
61+
}
62+
63+
}
64+
65+
private class NonPublicPropertyFix implements LocalQuickFix {
66+
67+
private String name;
68+
69+
public NonPublicPropertyFix(String name) {
70+
this.name = name;
71+
}
72+
73+
@Nls
74+
@NotNull
75+
@Override
76+
public String getName() {
77+
return name;
78+
}
79+
80+
@NotNull
81+
@Override
82+
public String getFamilyName() {
83+
return "Nette";
84+
}
85+
86+
@Override
87+
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor problemDescriptor) {
88+
if (!(problemDescriptor.getStartElement() instanceof Field)) {
89+
return;
90+
}
91+
Field field = (Field) problemDescriptor.getStartElement();
92+
PhpPsiElement element = ((PhpPsiElement) field.getParent()).getFirstPsiChild();
93+
if (element == null || !(element instanceof PhpModifierList)) {
94+
return;
95+
}
96+
for (ASTNode node : element.getNode().getChildren(PhpTokenTypes.tsMODIFIERS)) {
97+
if (node.getElementType() == PhpTokenTypes.kwPRIVATE || node.getElementType() == PhpTokenTypes.kwPROTECTED) {
98+
node.getTreeParent().replaceChild(node, PhpPsiElementFactory.createFromText(project, PhpTokenTypes.kwPUBLIC, "public").getNode());
99+
break;
100+
}
101+
}
102+
103+
}
104+
}
105+
106+
}
Lines changed: 11 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,24 @@
11
package cz.juzna.intellij.nette.inspections;
22

3-
import com.intellij.codeInspection.*;
4-
import com.intellij.lang.ASTNode;
5-
import com.intellij.openapi.project.Project;
6-
import com.intellij.psi.PsiElement;
7-
import com.intellij.psi.PsiFile;
8-
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
9-
import com.jetbrains.php.lang.lexer.PhpTokenTypes;
10-
import com.jetbrains.php.lang.psi.PhpPsiElementFactory;
113
import com.jetbrains.php.lang.psi.elements.Field;
12-
import com.jetbrains.php.lang.psi.elements.PhpModifierList;
13-
import com.jetbrains.php.lang.psi.elements.PhpPsiElement;
14-
import org.jetbrains.annotations.Nls;
15-
import org.jetbrains.annotations.NotNull;
16-
import org.jetbrains.annotations.Nullable;
174

18-
import java.util.ArrayList;
19-
import java.util.Collection;
5+
public class NonPublicInjectInspection extends NonPublicFieldInspection {
206

21-
22-
public class NonPublicInjectInspection extends LocalInspectionTool {
23-
24-
25-
@Nullable
267
@Override
27-
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
28-
29-
NonPublicFieldVisitor visitor = new NonPublicFieldVisitor(manager, isOnTheFly);
30-
file.accept(visitor);
31-
ProblemDescriptor[] problems = new ProblemDescriptor[visitor.getProblems().size()];
32-
33-
return visitor.getProblems().toArray(problems);
8+
protected String getProblemDescription() {
9+
return "@inject property must be public";
3410
}
3511

36-
private class NonPublicFieldVisitor extends PsiRecursiveElementWalkingVisitor {
37-
private final InspectionManager inspectionManager;
38-
private final boolean isOnTheFly;
39-
private Collection<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
40-
41-
public NonPublicFieldVisitor(InspectionManager inspectionManager, boolean isOnTheFly) {
42-
this.inspectionManager = inspectionManager;
43-
this.isOnTheFly = isOnTheFly;
44-
}
45-
46-
public Collection<ProblemDescriptor> getProblems() {
47-
return problems;
48-
}
49-
50-
@Override
51-
public void visitElement(PsiElement element) {
52-
if (element instanceof Field && isInvalid((Field) element)) {
53-
problems.add(inspectionManager.createProblemDescriptor(element, "@inject property must be public", new NonPublicPropertyFix(), ProblemHighlightType.ERROR, isOnTheFly));
54-
}
55-
super.visitElement(element);
56-
}
57-
58-
private boolean isInvalid(Field field) {
59-
return !field.getModifier().isPublic()
60-
&& field.getDocComment() != null
61-
&& field.getDocComment().getText().contains("@inject");
62-
}
63-
12+
@Override
13+
protected String getFixName() {
14+
return "Make @inject property public";
6415
}
6516

66-
private class NonPublicPropertyFix implements LocalQuickFix {
67-
@Nls
68-
@NotNull
69-
@Override
70-
public String getName() {
71-
return "Make @inject property public";
72-
}
73-
74-
@NotNull
75-
@Override
76-
public String getFamilyName() {
77-
return "Nette";
78-
}
79-
80-
@Override
81-
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor problemDescriptor) {
82-
if (!(problemDescriptor.getStartElement() instanceof Field)) {
83-
return;
84-
}
85-
Field field = (Field) problemDescriptor.getStartElement();
86-
PhpPsiElement element = ((PhpPsiElement) field.getParent()).getFirstPsiChild();
87-
if (element == null || !(element instanceof PhpModifierList)) {
88-
return;
89-
}
90-
for (ASTNode node : element.getNode().getChildren(PhpTokenTypes.tsMODIFIERS)) {
91-
if (node.getElementType() == PhpTokenTypes.kwPRIVATE || node.getElementType() == PhpTokenTypes.kwPROTECTED) {
92-
node.getTreeParent().replaceChild(node, PhpPsiElementFactory.createFromText(project, PhpTokenTypes.kwPUBLIC, "public").getNode());
93-
break;
94-
}
95-
}
96-
97-
}
17+
@Override
18+
protected boolean isInvalid(Field field) {
19+
return !field.getModifier().isPublic()
20+
&& field.getDocComment() != null
21+
&& field.getDocComment().getText().contains("@inject");
9822
}
9923

10024
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package cz.juzna.intellij.nette.inspections;
2+
3+
import com.jetbrains.php.lang.psi.elements.Field;
4+
5+
public class NonPublicPersistentInspection extends NonPublicFieldInspection {
6+
7+
@Override
8+
protected String getProblemDescription() {
9+
return "@persistent property must be public";
10+
}
11+
12+
@Override
13+
protected String getFixName() {
14+
return "Make @persistent property public";
15+
}
16+
17+
@Override
18+
protected boolean isInvalid(Field field) {
19+
return !field.getModifier().isPublic()
20+
&& field.getDocComment() != null
21+
&& field.getDocComment().getText().contains("@persistent");
22+
}
23+
24+
}

0 commit comments

Comments
 (0)