Skip to content

Commit 6594d42

Browse files
committed
Add support for Enums (closes #8)
1 parent e30d180 commit 6594d42

File tree

8 files changed

+99
-17
lines changed

8 files changed

+99
-17
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [1.5.0] - 2025-07-30
4+
5+
### Added
6+
7+
- Enum support
8+
39
## [1.4.1] - 2025-07-05
410

511
### Added

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pluginGroup = org.nette.latte
44
pluginName = Latte Support
55
pluginRepositoryUrl = https://github.com/Rixafy/LatteSupport
66
# SemVer format -> https://semver.org
7-
pluginVersion = 1.4.1
7+
pluginVersion = 1.5.0
88

99
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1010
pluginSinceBuild = 222

src/main/java/org/nette/latte/completion/providers/LattePhpCompletionProvider.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,17 @@
55
import com.intellij.codeInsight.lookup.LookupElementBuilder;
66
import com.intellij.psi.PsiElement;
77
import com.intellij.util.ProcessingContext;
8+
import com.jetbrains.php.lang.psi.elements.*;
89
import org.nette.latte.completion.handlers.PhpVariableInsertHandler;
910
import org.nette.latte.php.NettePhpType;
1011
import org.nette.latte.psi.*;
11-
import org.nette.latte.psi.*;
1212
import org.nette.latte.psi.elements.BaseLattePhpElement;
1313
import org.nette.latte.utils.LatteTagsUtil;
1414
import org.nette.latte.utils.LatteTypesUtil;
1515
import org.nette.latte.utils.LatteUtil;
1616
import com.jetbrains.php.completion.PhpLookupElement;
1717
import com.jetbrains.php.completion.insert.PhpFieldInsertHandler;
1818
import com.jetbrains.php.completion.insert.PhpMethodInsertHandler;
19-
import com.jetbrains.php.lang.psi.elements.Field;
20-
import com.jetbrains.php.lang.psi.elements.Method;
21-
import com.jetbrains.php.lang.psi.elements.PhpClass;
22-
import com.jetbrains.php.lang.psi.elements.PhpModifier;
2319
import org.jetbrains.annotations.NotNull;
2420
import org.jetbrains.annotations.Nullable;
2521

@@ -103,6 +99,14 @@ private void attachPhpCompletions(
10399

104100
boolean isMagicPrefixed = result.getPrefixMatcher().getPrefix().startsWith("__");
105101
for (PhpClass phpClass : phpClasses) {
102+
if (isStatic) {
103+
for (PhpEnumCase enumCase : phpClass.getEnumCases()) {
104+
PhpLookupElement lookupItem = getPhpLookupElement(enumCase, enumCase.getName());
105+
lookupItem.handler = PhpFieldInsertHandler.getInstance();
106+
result.addElement(lookupItem);
107+
}
108+
}
109+
106110
for (Method method : phpClass.getMethods()) {
107111
PhpModifier modifier = method.getModifier();
108112
if (modifier.isPublic() && canShowCompletionElement(isStatic, modifier)) {

src/main/java/org/nette/latte/inspections/ConstantUsagesInspection.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.intellij.psi.PsiElement;
66
import com.intellij.psi.PsiFile;
77
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
8+
import com.jetbrains.php.lang.psi.elements.PhpEnumCase;
89
import org.nette.latte.php.NettePhpType;
910
import org.nette.latte.psi.LatteFile;
1011
import org.nette.latte.psi.LattePhpConstant;
@@ -63,6 +64,12 @@ public void visitElement(PsiElement element) {
6364
isFound = true;
6465
}
6566
}
67+
68+
for (PhpEnumCase enumCase : phpClass.getEnumCases()) {
69+
if (enumCase.getName().equals(constantName)) {
70+
isFound = true;
71+
}
72+
}
6673
}
6774

6875
if (!isFound) {

src/main/java/org/nette/latte/php/LattePhpTypeDetector.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ private static class Detector {
156156
return customFunction == null ? NettePhpType.MIXED : NettePhpType.create(customFunction.getFunctionReturnType());
157157
}
158158

159+
// Special handling for enum::cases() method
160+
if (name.equals("cases")) {
161+
for (PhpClass phpClass : phpClasses) {
162+
if (phpClass.isEnum()) {
163+
// Return array of the enum type instead of UnitEnum[]
164+
return NettePhpType.create(phpClass.getFQN() + "[]");
165+
}
166+
}
167+
}
168+
159169
List<String> types = new ArrayList<>();
160170
for (PhpClass phpClass : phpClasses) {
161171
for (Method phpMethod : phpClass.getMethods()) {
@@ -224,6 +234,17 @@ private static class Detector {
224234

225235
List<String> types = new ArrayList<>();
226236
for (PhpClass phpClass : phpClasses) {
237+
// Check for enum cases first
238+
if (phpClass.isEnum()) {
239+
for (com.jetbrains.php.lang.psi.elements.PhpEnumCase enumCase : phpClass.getEnumCases()) {
240+
if (enumCase.getName().equals(name)) {
241+
// For enum cases, the type is the enum class itself
242+
types.add(phpClass.getFQN());
243+
}
244+
}
245+
}
246+
247+
// Check for constants
227248
for (Field field : phpClass.getFields()) {
228249
if (field.isConstant() && field.getModifier().isPublic() && field.getName().equals(name)) {
229250
String foundType = field.getType().toString();
@@ -338,4 +359,4 @@ public void visitElement(@NotNull PsiElement element) {
338359
}
339360
}
340361

341-
}
362+
}

src/main/java/org/nette/latte/php/LattePhpUtil.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,29 @@ public static List<Field> getFieldsForPhpElement(@NotNull BaseLattePhpElement ps
140140
return fields;
141141
}
142142

143+
public static List<PhpEnumCase> getEnumCasesForPhpElement(@NotNull BaseLattePhpElement psiElement, @NotNull Project project) {
144+
List<PhpEnumCase> out = new ArrayList<>();
145+
NettePhpType phpType = psiElement.getPrevReturnType();
146+
String name = psiElement.getPhpElementName();
147+
148+
Collection<PhpClass> phpClasses = phpType.getPhpClasses(project);
149+
if (phpClasses.size() == 0) {
150+
return out;
151+
}
152+
153+
List<PhpEnumCase> enumCases = new ArrayList<>();
154+
for (PhpClass phpClass : phpClasses) {
155+
if (phpClass.isEnum()) {
156+
for (PhpEnumCase enumCase : phpClass.getEnumCases()) {
157+
if (enumCase.getName().equals(name)) {
158+
enumCases.add(enumCase);
159+
}
160+
}
161+
}
162+
}
163+
return enumCases;
164+
}
165+
143166
public static List<Method> getMethodsForPhpElement(@NotNull LattePhpMethod psiElement, Project project) {
144167
List<Method> out = new ArrayList<>();
145168
Collection<PhpClass> phpClasses = psiElement.getPrevReturnType().getPhpClasses(project);
@@ -239,4 +262,4 @@ public static String normalizeClassName(@Nullable String className) {
239262

240263
return normalized;
241264
}
242-
}
265+
}

src/main/java/org/nette/latte/reference/references/LattePhpConstantReference.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.nette.latte.php.LattePhpUtil;
1010
import com.jetbrains.php.lang.psi.elements.Field;
1111
import com.jetbrains.php.lang.psi.elements.PhpClass;
12+
import com.jetbrains.php.lang.psi.elements.PhpEnumCase;
1213
import org.jetbrains.annotations.NotNull;
1314
import org.jetbrains.annotations.Nullable;
1415

@@ -51,14 +52,26 @@ public ResolveResult[] multiResolve(boolean b) {
5152
}
5253
}
5354

55+
List<PhpEnumCase> enumCases = LattePhpUtil.getEnumCasesForPhpElement((BaseLattePhpElement) getElement(), project);
56+
for (PhpEnumCase enumCase : enumCases) {
57+
if (enumCase.getName().equals(name)) {
58+
results.add(new PsiElementResolveResult(enumCase));
59+
}
60+
}
61+
5462
return results.toArray(new ResolveResult[0]);
5563
}
5664

5765
@Nullable
5866
@Override
5967
public PsiElement resolve() {
6068
List<Field> fields = LattePhpUtil.getFieldsForPhpElement((BaseLattePhpElement) getElement(), project);
61-
return fields.size() > 0 ? fields.get(0) : null;
69+
if (fields.size() > 0) {
70+
return fields.get(0);
71+
}
72+
73+
List<PhpEnumCase> enumCases = LattePhpUtil.getEnumCasesForPhpElement((BaseLattePhpElement) getElement(), project);
74+
return enumCases.size() > 0 ? enumCases.get(0) : null;
6275
}
6376

6477
@NotNull
@@ -80,14 +93,23 @@ public boolean isReferenceTo(@NotNull PsiElement element) {
8093
}
8194
}
8295

83-
if (!(element instanceof Field)) {
84-
return false;
96+
if (element instanceof Field) {
97+
PhpClass originalClass = ((Field) element).getContainingClass();
98+
if (originalClass == null) {
99+
return false;
100+
}
101+
return LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), project, ((Field) element).getName());
85102
}
86-
PhpClass originalClass = ((Field) element).getContainingClass();
87-
if (originalClass == null) {
88-
return false;
103+
104+
if (element instanceof PhpEnumCase) {
105+
PhpClass originalClass = ((PhpEnumCase) element).getContainingClass();
106+
if (originalClass == null) {
107+
return false;
108+
}
109+
return LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), project, ((PhpEnumCase) element).getName());
89110
}
90-
return LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), project, ((Field) element).getName());
111+
112+
return false;
91113
}
92114

93115
@Override
@@ -98,4 +120,4 @@ public PsiElement handleElementRename(@NotNull String newName) {
98120
return getElement();
99121
}
100122

101-
}
123+
}

src/main/java/org/nette/latte/reference/references/LattePhpVariableReference.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.intellij.psi.*;
66
import org.nette.latte.php.LattePhpVariableUtil;
77
import org.nette.latte.php.NettePhpType;
8-
import org.nette.latte.psi.*;
98
import org.nette.latte.psi.elements.BaseLattePhpElement;
109
import org.nette.latte.utils.LattePhpCachedVariable;
1110
import org.nette.latte.utils.LatteUtil;

0 commit comments

Comments
 (0)