From c91b7ae9952bfb5382b0e3c0a973d9084cec4edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Paku=C5=82a?= Date: Fri, 13 Oct 2023 15:01:54 +0200 Subject: [PATCH] Validate interface method access type --- .../core/compiler/ast/parser/Messages.java | 1 + .../ast/parser/PHPProblemIdentifier.java | 2 +- .../compiler/ast/parser/messages.properties | 3 +- .../ast/visitor/ValidatorVisitor.java | 34 +++++++++++++++++++ .../php7/interfaceMethodAccessType.pdtt | 14 ++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tests/org.eclipse.php.core.tests/workspace/errors/php7/interfaceMethodAccessType.pdtt diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/Messages.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/Messages.java index c6fd5ab25a..e45c42d8e4 100644 --- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/Messages.java +++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/Messages.java @@ -70,6 +70,7 @@ public class Messages extends NLS { public static String EnumCaseInClass; public static String EnumCaseWithType; public static String EnumCaseWithoutType; + public static String IntefaceMethodAccessType; static { // initialize resource bundle diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/PHPProblemIdentifier.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/PHPProblemIdentifier.java index 508d09edf4..d68408f3f5 100644 --- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/PHPProblemIdentifier.java +++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/PHPProblemIdentifier.java @@ -23,7 +23,7 @@ */ public enum PHPProblemIdentifier implements IProblemIdentifier, IProblemIdentifierExtension { - SYNTAX, USE_STATEMENTS /* deprecated */, AbstractMethodInAbstractClass, BodyForAbstractMethod, MethodRequiresBody, AbstractMethodsInConcreteClass, UndefinedType, ClassExtendFinalClass, CannotInstantiateType, ImportNotFound, DuplicateImport, UnusedImport, UnnecessaryImport, DuplicateDeclaration, DuplicateMethodDeclaration, DuplicateConstantDeclaration, DuplicateFieldDeclaration, AbstractMethodMustBeImplemented, SuperclassMustBeAClass, SuperInterfaceMustBeAnInterface, CannotUseTypeAsTrait, NestedNamespaceDeclarations, InvalidConstantExpression, ReassignAutoGlobalVariable, CannotUseReservedWord, UndefinedVariable, UnusedVariable, UnexpectedNamespaceDeclaration, FirstClassMustMatchFileName, InvalidClassBodyStatement + SYNTAX, USE_STATEMENTS /* deprecated */, AbstractMethodInAbstractClass, BodyForAbstractMethod, MethodRequiresBody, AbstractMethodsInConcreteClass, UndefinedType, ClassExtendFinalClass, CannotInstantiateType, ImportNotFound, DuplicateImport, UnusedImport, UnnecessaryImport, DuplicateDeclaration, DuplicateMethodDeclaration, DuplicateConstantDeclaration, DuplicateFieldDeclaration, AbstractMethodMustBeImplemented, SuperclassMustBeAClass, SuperInterfaceMustBeAnInterface, CannotUseTypeAsTrait, NestedNamespaceDeclarations, InvalidConstantExpression, ReassignAutoGlobalVariable, CannotUseReservedWord, UndefinedVariable, UnusedVariable, UnexpectedNamespaceDeclaration, FirstClassMustMatchFileName, InvalidClassBodyStatement, InterfaceAccessTypeMustBeOmmited ; diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/messages.properties b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/messages.properties index c1ac892aa0..a4819c5ef8 100644 --- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/messages.properties +++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/parser/messages.properties @@ -44,4 +44,5 @@ FirstTypeMustMatchFileName=The declared {0} "{1}" must be named to "{2}" PropertyInEnum=Enum may not include properties EnumCaseInClass=Enum case can only be used in enums EnumCaseWithType=Case {0} of non-backed enum {1} must not have a value -EnumCaseWithoutType=Case {0} of backed enum {1} must have a value \ No newline at end of file +EnumCaseWithoutType=Case {0} of backed enum {1} must have a value +IntefaceMethodAccessType=Access type for interface method {0} must be omitted \ No newline at end of file diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/visitor/ValidatorVisitor.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/visitor/ValidatorVisitor.java index 9b7fc3897f..e8d5d4ca46 100644 --- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/visitor/ValidatorVisitor.java +++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/compiler/ast/visitor/ValidatorVisitor.java @@ -21,6 +21,7 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.dltk.annotations.NonNull; import org.eclipse.dltk.ast.ASTNode; +import org.eclipse.dltk.ast.declarations.Declaration; import org.eclipse.dltk.ast.declarations.ModuleDeclaration; import org.eclipse.dltk.ast.declarations.TypeDeclaration; import org.eclipse.dltk.ast.expressions.Expression; @@ -66,10 +67,15 @@ public class ValidatorVisitor extends PHPASTVisitor implements IValidatorVisitor private static final String EMPTY = ""; //$NON-NLS-1$ private static final String PAAMAYIM_NEKUDOTAIM = "::"; //$NON-NLS-1$ + private static final String CALL = "()"; //$NON-NLS-1$ private static final String NAMESPACE_RESOLVER = "NAMESPACE_RESOLVER"; //$NON-NLS-1$ private static final List TYPE_SKIP = new ArrayList<>(); private static final List COMMENT_TYPE_SKIP = new ArrayList<>(); + private static final String ACCESS_ABSTRACT = "abstract"; //$NON-NLS-1$ + private static final String ACCESS_PRIVATE = "private"; //$NON-NLS-1$ + private static final String ACCESS_PROTECTED = "protected"; //$NON-NLS-1$ + private static final int ALLOW_ARRAY = 1; private static final int ALLOW_NEW = 2; @@ -244,11 +250,39 @@ public boolean visit(PHPMethodDeclaration s) throws Exception { PHPProblemIdentifier.DuplicateMethodDeclaration, new String[] { s.getName() }, ProblemSeverities.Error); } else { + if (parentType instanceof InterfaceDeclaration) { + checkInterfaceMethodMofiers((InterfaceDeclaration) parentType, s); + + } childs.put(id, s); } return super.visit(s); } + private void checkInterfaceMethodMofiers(InterfaceDeclaration parentType, PHPMethodDeclaration s) { + if (PHPFlags.isAbstract(s.getModifiers()) && s.getBody().end() - s.getBody().start() == 1) { + reportAccessProblem(parentType, s, ACCESS_ABSTRACT); + } + if (PHPFlags.isPrivate(s.getModifiers())) { + reportAccessProblem(parentType, s, ACCESS_PRIVATE); + } + if (PHPFlags.isProtected(s.getModifiers())) { + reportAccessProblem(parentType, s, ACCESS_PROTECTED); + } + + } + + private void reportAccessProblem(TypeDeclaration parentType, Declaration s, String key) { + int indexOf = context.getSourceContents().substring(s.start(), s.getNameStart()).toLowerCase().indexOf(key); + if (indexOf >= 0) { + reportProblem(s.start() + indexOf, s.start() + indexOf + 8, Messages.IntefaceMethodAccessType, + PHPProblemIdentifier.InterfaceAccessTypeMustBeOmmited, + new String[] { parentType.getName() + PAAMAYIM_NEKUDOTAIM + s.getName() + CALL }, + ProblemSeverities.Error); + } + + } + @Override public boolean visit(PHPFieldDeclaration s) throws Exception { currentDeclaration = s; diff --git a/tests/org.eclipse.php.core.tests/workspace/errors/php7/interfaceMethodAccessType.pdtt b/tests/org.eclipse.php.core.tests/workspace/errors/php7/interfaceMethodAccessType.pdtt new file mode 100644 index 0000000000..094719ea7a --- /dev/null +++ b/tests/org.eclipse.php.core.tests/workspace/errors/php7/interfaceMethodAccessType.pdtt @@ -0,0 +1,14 @@ +--TEST-- +Test interface problems +--FILE-- + +--EXPECT-- +[line=3, start=39, end=47] Access type for interface method TestInterfaceAccess::f1() must be omitted +[line=4, start=64, end=72] Access type for interface method TestInterfaceAccess::f2() must be omitted +[line=5, start=90, end=98] Access type for interface method TestInterfaceAccess::f3() must be omitted