You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ne...@apache.org on 2023/01/23 16:46:11 UTC
[netbeans] branch delivery updated: Improved method checks in enum declaration
This is an automated email from the ASF dual-hosted git repository.
neilcsmith pushed a commit to branch delivery
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/delivery by this push:
new 6b9c7a3a30a Improved method checks in enum declaration
new ec3ab743f84 Merge pull request #5341 from KacerCZ/php-enum-check-methods
6b9c7a3a30a is described below
commit 6b9c7a3a30ad176856b5f8bfa6debeec129453d0
Author: Tomas Prochazka <ka...@razdva.cz>
AuthorDate: Sun Jan 22 13:11:33 2023 +0100
Improved method checks in enum declaration
- Checks declaration of forbidden methods.
- Adds __invoke and __debugInfo to list of magic methods.
Docs
- https://www.php.net/manual/en/language.enumerations.listing.php
- https://www.php.net/manual/en/class.backedenum.php
- https://www.php.net/manual/en/language.enumerations.object-differences.php
- https://www.php.net/manual/en/language.oop5.magic.php
Closes #5086, closes #5094
---
.../modules/php/editor/PredefinedSymbols.java | 2 +
.../verification/IncorrectEnumHintError.java | 40 +++++++++-
.../IncorrectEnumHintError/testIncorrectEnums.php | 46 ++++++++++++
...testIncorrectEnums.php.testIncorrectEnums.hints | 87 ++++++++++++++++++++++
4 files changed, 172 insertions(+), 3 deletions(-)
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/PredefinedSymbols.java b/php/php.editor/src/org/netbeans/modules/php/editor/PredefinedSymbols.java
index 006641fed3c..440bc9592d9 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/PredefinedSymbols.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/PredefinedSymbols.java
@@ -101,6 +101,8 @@ public final class PredefinedSymbols {
"__sleep", // NOI18N
"__wakeup", // NOI18N
"__toString", // NOI18N
+ "__invoke", // NOI18N
+ "__debugInfo", // NOI18N
"__serialize", // NOI18N PHP 7.4
"__unserialize", // NOI18N PHP 7.4
})));
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/verification/IncorrectEnumHintError.java b/php/php.editor/src/org/netbeans/modules/php/editor/verification/IncorrectEnumHintError.java
index 1c0d10d3015..faa3dcf11ad 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/verification/IncorrectEnumHintError.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/verification/IncorrectEnumHintError.java
@@ -30,6 +30,7 @@ import org.netbeans.modules.csl.api.HintFix;
import org.netbeans.modules.csl.api.OffsetRange;
import org.netbeans.modules.csl.spi.support.CancelSupport;
import org.netbeans.modules.php.editor.CodeUtils;
+import org.netbeans.modules.php.editor.PredefinedSymbols;
import org.netbeans.modules.php.editor.model.EnumScope;
import org.netbeans.modules.php.editor.model.FieldElement;
import org.netbeans.modules.php.editor.model.FileScope;
@@ -57,8 +58,26 @@ import org.openide.util.NbBundle;
*/
public class IncorrectEnumHintError extends HintErrorRule {
+ private static final Map<String, String> FORBIDDEN_MAGIC_METHODS = new HashMap<>();
+ private static final Map<String, String> FORBIDDEN_BACKED_ENUM_METHODS = new HashMap<>();
+
private FileObject fileObject;
+ static {
+ for (String methodName : PredefinedSymbols.MAGIC_METHODS) {
+ // Methods __call, __callStatic and __invoke are allowed in enum.
+ if ("__call".equals(methodName) // NOI18N
+ || "__callStatic".equals(methodName) // NOI18N
+ || "__invoke".equals(methodName)) { // NOI18N
+ continue;
+ }
+ FORBIDDEN_MAGIC_METHODS.put(methodName.toLowerCase(), methodName);
+ }
+
+ FORBIDDEN_BACKED_ENUM_METHODS.put("from", "from"); // NOI18N
+ FORBIDDEN_BACKED_ENUM_METHODS.put("tryfrom", "tryFrom"); // NOI18N
+ }
+
@Override
@NbBundle.Messages("IncorrectEnumHintError.displayName=Incorrect Declaration of Enumeration")
public String getDisplayName() {
@@ -73,7 +92,11 @@ public class IncorrectEnumHintError extends HintErrorRule {
"# {0} - the trait name",
"IncorrectEnumHintError.incorrectEnumPropertiesWithTrait=Enum cannot have properties, but \"{0}\" has properties",
"IncorrectEnumHintError.incorrectEnumConstructor=Enum cannot have a constructor",
- })
+ "IncorrectEnumHintError.incorrectEnumMethodCases=Enum cannot redeclare method \"cases\"",
+ "# {0} - the method name",
+ "IncorrectEnumHintError.incorrectEnumMagicMethod=Enum cannot contain magic method method \"{0}\"",
+ "# {0} - the method name",
+ "IncorrectEnumHintError.incorrectBackedEnumMethod=Backed enum cannot redeclare method \"{0}\"",})
public void invoke(PHPRuleContext context, List<Hint> hints) {
PHPParseResult phpParseResult = (PHPParseResult) context.parserResult;
if (phpParseResult.getProgram() == null) {
@@ -113,7 +136,9 @@ public class IncorrectEnumHintError extends HintErrorRule {
return;
}
checkTraits(declaredEnum.getTraits(), declaredEnum, hints, checkVisitor.getUseTraits());
- checkConstructor(declaredEnum.getDeclaredMethods(), hints);
+ // Forbidden methods from traits are ignored by PHP
+ boolean isBackedEnum = declaredEnum.getBackingType() != null;
+ checkMethods(declaredEnum.getDeclaredMethods(), isBackedEnum, hints);
}
}
}
@@ -142,13 +167,22 @@ public class IncorrectEnumHintError extends HintErrorRule {
}
}
- private void checkConstructor(Collection<? extends MethodScope> methods, List<Hint> hints) {
+ private void checkMethods(Collection<? extends MethodScope> methods, boolean isBackedEnum, List<Hint> hints) {
for (MethodScope method : methods) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
if (method.isConstructor()) {
addHint(method, Bundle.IncorrectEnumHintError_incorrectEnumConstructor(), hints);
+ continue;
+ }
+ String methodName = method.getName().toLowerCase();
+ if ("cases".equals(methodName)) { // NOI18N
+ addHint(method, Bundle.IncorrectEnumHintError_incorrectEnumMethodCases(), hints);
+ } else if (FORBIDDEN_MAGIC_METHODS.containsKey(methodName)) {
+ addHint(method, Bundle.IncorrectEnumHintError_incorrectEnumMagicMethod(FORBIDDEN_MAGIC_METHODS.get(methodName)), hints);
+ } else if (isBackedEnum && FORBIDDEN_BACKED_ENUM_METHODS.containsKey(methodName)) {
+ addHint(method, Bundle.IncorrectEnumHintError_incorrectBackedEnumMethod(FORBIDDEN_BACKED_ENUM_METHODS.get(methodName)), hints);
}
}
}
diff --git a/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php b/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php
index 1c87b7710a5..67bb8b04d25 100644
--- a/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php
+++ b/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php
@@ -40,6 +40,52 @@ enum IncorrectConstructor {
}
}
+enum IncorrectMethods {
+ public function cases():array {}
+ public function __get($name) {}
+ public function __set($name,$value) {}
+ public function __isset($name) {}
+ public function __unset($name) {}
+ public function __sleep() {}
+ public function __wakeup() {}
+ public function __serialize() {}
+ public function __unserialize($array) {}
+ public function __toString() {}
+ public static function __set_state($state) {}
+ public function __clone() {}
+ public function __debugInfo() {}
+}
+
+enum IncorrectMethodsBacked: string {
+ public function cases():array {}
+ public function from(string|int $value):self {}
+ public function tryFrom(string|int $value):self {}
+}
+
+enum IncorrectMethodsCorrectCaseInMessage {
+ public function Cases():array {}
+ public function __GET($name) {}
+ public function __seT($name,$value) {}
+ public function __ISset($name) {}
+ public function __unSET($name) {}
+ public function __sleeP() {}
+ public function __wAkeup() {}
+ public function __Serialize() {}
+ public function __Unserialize($array) {}
+ public function __ToString() {}
+ public static function __Set_State($state) {}
+ public function __clONe() {}
+ public function __DebugInfo() {}
+}
+
+enum CorrectMethods {
+ public function from(string|int $value):self {}
+ public function tryFrom(string|int $value):self {}
+ public function __call($name,$args) {}
+ public static function __callStatic($name,$args) {}
+ public function __invoke() {}
+}
+
enum CorrectBackingTypeString: string {
case CASE_NAME;
}
diff --git a/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php.testIncorrectEnums.hints b/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php.testIncorrectEnums.hints
index 3ead2c1f278..36c0309db3a 100644
--- a/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php.testIncorrectEnums.hints
+++ b/php/php.editor/test/unit/data/testfiles/verification/IncorrectEnumHintError/testIncorrectEnums.php.testIncorrectEnums.hints
@@ -20,6 +20,93 @@ HINT:Enum cannot have properties
public function __construct() {
-----------
HINT:Enum cannot have a constructor
+ public function cases():array {}
+ -----
+HINT:Enum cannot redeclare method "cases"
+ public function __get($name) {}
+ -----
+HINT:Enum cannot contain magic method method "__get"
+ public function __set($name,$value) {}
+ -----
+HINT:Enum cannot contain magic method method "__set"
+ public function __isset($name) {}
+ -------
+HINT:Enum cannot contain magic method method "__isset"
+ public function __unset($name) {}
+ -------
+HINT:Enum cannot contain magic method method "__unset"
+ public function __sleep() {}
+ -------
+HINT:Enum cannot contain magic method method "__sleep"
+ public function __wakeup() {}
+ --------
+HINT:Enum cannot contain magic method method "__wakeup"
+ public function __serialize() {}
+ -----------
+HINT:Enum cannot contain magic method method "__serialize"
+ public function __unserialize($array) {}
+ -------------
+HINT:Enum cannot contain magic method method "__unserialize"
+ public function __toString() {}
+ ----------
+HINT:Enum cannot contain magic method method "__toString"
+ public static function __set_state($state) {}
+ -----------
+HINT:Enum cannot contain magic method method "__set_state"
+ public function __clone() {}
+ -------
+HINT:Enum cannot contain magic method method "__clone"
+ public function __debugInfo() {}
+ -----------
+HINT:Enum cannot contain magic method method "__debugInfo"
+ public function cases():array {}
+ -----
+HINT:Enum cannot redeclare method "cases"
+ public function from(string|int $value):self {}
+ ----
+HINT:Backed enum cannot redeclare method "from"
+ public function tryFrom(string|int $value):self {}
+ -------
+HINT:Backed enum cannot redeclare method "tryFrom"
+ public function Cases():array {}
+ -----
+HINT:Enum cannot redeclare method "cases"
+ public function __GET($name) {}
+ -----
+HINT:Enum cannot contain magic method method "__get"
+ public function __seT($name,$value) {}
+ -----
+HINT:Enum cannot contain magic method method "__set"
+ public function __ISset($name) {}
+ -------
+HINT:Enum cannot contain magic method method "__isset"
+ public function __unSET($name) {}
+ -------
+HINT:Enum cannot contain magic method method "__unset"
+ public function __sleeP() {}
+ -------
+HINT:Enum cannot contain magic method method "__sleep"
+ public function __wAkeup() {}
+ --------
+HINT:Enum cannot contain magic method method "__wakeup"
+ public function __Serialize() {}
+ -----------
+HINT:Enum cannot contain magic method method "__serialize"
+ public function __Unserialize($array) {}
+ -------------
+HINT:Enum cannot contain magic method method "__unserialize"
+ public function __ToString() {}
+ ----------
+HINT:Enum cannot contain magic method method "__toString"
+ public static function __Set_State($state) {}
+ -----------
+HINT:Enum cannot contain magic method method "__set_state"
+ public function __clONe() {}
+ -------
+HINT:Enum cannot contain magic method method "__clone"
+ public function __DebugInfo() {}
+ -----------
+HINT:Enum cannot contain magic method method "__debugInfo"
case C;
-------
HINT:"case" can only be in enums
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists