Skip to content

Commit 0b5cc44

Browse files
authored
Merge pull request #8139 from junichi11/php84-deprecated-attribute
PHP 8.4 Support: #[\Deprecated] Attribute
2 parents 56b8332 + 2490982 commit 0b5cc44

File tree

102 files changed

+7107
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+7107
-211
lines changed

php/php.editor/src/org/netbeans/modules/php/editor/CodeUtils.java

+5
Original file line numberDiff line numberDiff line change
@@ -901,4 +901,9 @@ public static boolean isDnfType(UnionType unionType) {
901901
}
902902
return false;
903903
}
904+
905+
public static boolean isTypeDeclaration(ASTNode node) {
906+
return node instanceof TypeDeclaration
907+
|| ((node instanceof ClassInstanceCreation) && ((ClassInstanceCreation) node).isAnonymous());
908+
}
904909
}

php/php.editor/src/org/netbeans/modules/php/editor/PredefinedSymbols.java

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public static enum VariableKind {
121121
public static enum Attributes {
122122
ATTRIBUTE("Attribute"), // NOI18N
123123
ALLOW_DYNAMIC_PROPERTIES("AllowDynamicProperties"), // NOI18N
124+
DEPRECATED("Deprecated"), // NOI18N
124125
OVERRIDE("Override"), // NOI18N
125126
RETURN_TYPE_WILL_CHANGE("ReturnTypeWillChange"), // NOI18N
126127
SENSITIVE_PARAMETER("SensitiveParameter"), // NOI18N

php/php.editor/src/org/netbeans/modules/php/editor/csl/SemanticAnalysis.java

+56-203
Large diffs are not rendered by default.

php/php.editor/src/org/netbeans/modules/php/editor/elements/CaseElementImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public static EnumCaseElement fromNode(final TypeElement type, CaseDeclaration n
125125
info.getAccessModifiers().toFlags(),
126126
fileQuery.getURL().toExternalForm(),
127127
fileQuery,
128-
VariousUtils.isDeprecatedFromPHPDoc(fileQuery.getResult().getProgram(), node),
128+
VariousUtils.isDeprecated(fileQuery.getResult().getModel().getFileScope(), fileQuery.getResult().getProgram(), node),
129129
isBacked
130130
);
131131
}

php/php.editor/src/org/netbeans/modules/php/editor/elements/FunctionElementImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public static FunctionElement fromNode(final NamespaceElement namespace, final F
104104
fullyQualifiedName.append(info.getName()), info.getRange().getStart(),
105105
fileQuery.getURL().toExternalForm(), fileQuery, BaseFunctionElementSupport.ParametersImpl.create(info.getParameters()),
106106
BaseFunctionElementSupport.ReturnTypesImpl.create(TypeResolverImpl.parseTypes(VariousUtils.getReturnType(fileQuery.getResult().getProgram(), node)), node.getReturnType()),
107-
VariousUtils.isDeprecatedFromPHPDoc(fileQuery.getResult().getProgram(), node));
107+
VariousUtils.isDeprecated(fileQuery.getResult().getModel().getFileScope(), fileQuery.getResult().getProgram(), node));
108108
}
109109

110110
private static boolean matchesQuery(final NameKind query, FunctionSignatureParser signParser) {

php/php.editor/src/org/netbeans/modules/php/editor/elements/MethodElementImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public static MethodElement fromNode(final TypeElement type, final MethodDeclara
238238
BaseFunctionElementSupport.ParametersImpl.create(info.getParameters()),
239239
BaseFunctionElementSupport.ReturnTypesImpl.create(
240240
TypeResolverImpl.parseTypes(VariousUtils.getReturnType(fileQuery.getResult().getProgram(), node.getFunction())), node.getFunction().getReturnType()),
241-
VariousUtils.isDeprecatedFromPHPDoc(fileQuery.getResult().getProgram(), node.getFunction()));
241+
VariousUtils.isDeprecated(fileQuery.getResult().getModel().getFileScope(), fileQuery.getResult().getProgram(), node.getFunction()));
242242
}
243243

244244
private static boolean matchesQuery(final NameKind query, MethodSignatureParser signParser) {

php/php.editor/src/org/netbeans/modules/php/editor/elements/TypeConstantElementImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public static Set<TypeConstantElement> fromNode(final TypeElement type, Constant
154154
retval.add(new TypeConstantElementImpl(
155155
type, info.getDeclaredType(), info.getName(), info.getValue(), info.getRange().getStart(),
156156
info.getAccessModifiers().toFlags(), fileQuery.getURL().toExternalForm(), fileQuery,
157-
VariousUtils.isDeprecatedFromPHPDoc(fileQuery.getResult().getProgram(), node)));
157+
VariousUtils.isDeprecated(fileQuery.getResult().getModel().getFileScope(), fileQuery.getResult().getProgram(), node)));
158158
}
159159
return retval;
160160
}

php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelBuilder.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ static EnumScopeImpl create(EnumDeclarationInfo nodeInfo, ModelBuilder context)
316316

317317
static MethodScopeImpl create(MethodDeclarationInfo nodeInfo, ModelBuilder context, ModelVisitor visitor) {
318318
String returnType = VariousUtils.getReturnType(context.getProgram(), nodeInfo.getOriginalNode().getFunction());
319-
boolean isDeprecated = VariousUtils.isDeprecatedFromPHPDoc(context.getProgram(), nodeInfo.getOriginalNode().getFunction());
319+
boolean isDeprecated = VariousUtils.isDeprecated(context.getFileScope(), context.getProgram(), nodeInfo.getOriginalNode());
320320
String qualifiedReturnType = VariousUtils.qualifyTypeNames(returnType, nodeInfo.getOriginalNode().getStartOffset(), context.getCurrentScope());
321321
MethodScopeImpl method = new MethodScopeImpl(context.getCurrentScope(), qualifiedReturnType, nodeInfo, visitor, isDeprecated);
322322
return method;
@@ -341,12 +341,12 @@ static FieldElementImpl create(SingleFieldDeclarationInfo nodeInfo, ModelBuilder
341341
}
342342

343343
static ClassConstantElementImpl create(ClassConstantDeclarationInfo clsConst, ModelBuilder context) {
344-
boolean isDeprecated = VariousUtils.isDeprecatedFromPHPDoc(context.getProgram(), clsConst.getOriginalNode());
344+
boolean isDeprecated = VariousUtils.isDeprecated(context.getFileScope(), context.getProgram(), clsConst.getConstantDeclaration());
345345
return new ClassConstantElementImpl(context.getCurrentScope(), clsConst, isDeprecated);
346346
}
347347

348348
static CaseElementImpl create(CaseDeclarationInfo enumCase, ModelBuilder context) {
349-
boolean isDeprecated = VariousUtils.isDeprecatedFromPHPDoc(context.getProgram(), enumCase.getOriginalNode());
349+
boolean isDeprecated = VariousUtils.isDeprecated(context.getFileScope(), context.getProgram(), enumCase.getCaseDeclaration());
350350
return new CaseElementImpl(context.getCurrentScope(), enumCase, isDeprecated);
351351
}
352352
}

php/php.editor/src/org/netbeans/modules/php/editor/model/impl/NamespaceScopeImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ FunctionScopeImpl createElement(Program program, FunctionDeclaration node) {
9494
qualifiedReturnType = VariousUtils.qualifyTypeNames(VariousUtils.getReturnType(program, node), returnType.getStartOffset(), this);
9595
}
9696
FunctionScopeImpl retval = new FunctionScopeImpl(this, FunctionDeclarationInfo.create(program, node),
97-
qualifiedReturnType, VariousUtils.isDeprecatedFromPHPDoc(program, node));
97+
qualifiedReturnType, VariousUtils.isDeprecated(getFileScope(), program, node));
9898
return retval;
9999
}
100100

php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java

+61
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@
3333
import java.util.Stack;
3434
import java.util.regex.Pattern;
3535
import org.netbeans.api.annotations.common.CheckForNull;
36+
import org.netbeans.api.annotations.common.NullAllowed;
3637
import org.netbeans.api.lexer.Token;
3738
import org.netbeans.api.lexer.TokenSequence;
3839
import org.netbeans.api.lexer.TokenUtilities;
3940
import org.netbeans.modules.php.api.util.StringUtils;
4041
import org.netbeans.modules.php.editor.CodeUtils;
42+
import org.netbeans.modules.php.editor.PredefinedSymbols.Attributes;
43+
import static org.netbeans.modules.php.editor.PredefinedSymbols.Attributes.DEPRECATED;
4144
import org.netbeans.modules.php.editor.api.AliasedName;
4245
import org.netbeans.modules.php.editor.api.PhpModifiers;
4346
import org.netbeans.modules.php.editor.api.QualifiedName;
@@ -69,6 +72,9 @@
6972
import org.netbeans.modules.php.editor.parser.astnodes.AnonymousObjectVariable;
7073
import org.netbeans.modules.php.editor.parser.astnodes.ArrayCreation;
7174
import org.netbeans.modules.php.editor.parser.astnodes.Assignment;
75+
import org.netbeans.modules.php.editor.parser.astnodes.Attribute;
76+
import org.netbeans.modules.php.editor.parser.astnodes.AttributeDeclaration;
77+
import org.netbeans.modules.php.editor.parser.astnodes.Attributed;
7278
import org.netbeans.modules.php.editor.parser.astnodes.ClassInstanceCreation;
7379
import org.netbeans.modules.php.editor.parser.astnodes.ClassInstanceCreationVariable;
7480
import org.netbeans.modules.php.editor.parser.astnodes.ClassName;
@@ -358,6 +364,61 @@ public static boolean isDeprecatedFromPHPDoc(Program root, ASTNode node) {
358364
return getDeprecatedDescriptionFromPHPDoc(root, node) != null;
359365
}
360366

367+
public static boolean isDeprecatedFromAttribute(FileScope fileScope, Program root, ASTNode node) {
368+
if (node instanceof Attributed) {
369+
List<Attribute> attributes = ((Attributed) node).getAttributes();
370+
for (Attribute attribute : attributes) {
371+
for (AttributeDeclaration attributeDeclaration : attribute.getAttributeDeclarations()) {
372+
String attributeName = CodeUtils.extractQualifiedName(attributeDeclaration.getAttributeName());
373+
if (isPredefinedAttributeName(DEPRECATED, attributeName, fileScope, attributeDeclaration.getStartOffset())) {
374+
return true;
375+
}
376+
}
377+
}
378+
}
379+
return false;
380+
}
381+
382+
public static boolean isDeprecated(FileScope fileScope, Program root, ASTNode node) {
383+
if (isDeprecatedFromAttribute(fileScope, root, node)) {
384+
return true;
385+
}
386+
return isDeprecatedFromPHPDoc(root, node);
387+
}
388+
389+
public static boolean isPredefinedAttributeName(Attributes attribute, String attributeName, FileScope fileScope, int offset) {
390+
if (attribute.getFqName().equals(attributeName)) {
391+
return true;
392+
}
393+
if (attribute.getName().equals(attributeName)) {
394+
List<? extends NamespaceScope> declaredNamespaces = new ArrayList<NamespaceScope>(fileScope.getDeclaredNamespaces());
395+
Collections.sort(declaredNamespaces, (n1, n2) -> -Integer.compare(n1.getOffset(), n2.getOffset()));
396+
NamespaceScope namespaceScope = null;
397+
for (NamespaceScope declaredNamespace : declaredNamespaces) {
398+
int namespaceOffset = declaredNamespace.getOffset();
399+
if (namespaceOffset < offset) {
400+
namespaceScope = declaredNamespace;
401+
break;
402+
}
403+
}
404+
// check FQ name because there may be `use \AttributeName;`
405+
if (isPredefinedAttributeName(attribute, attributeName, namespaceScope, offset)) {
406+
return true;
407+
}
408+
}
409+
return false;
410+
}
411+
412+
private static boolean isPredefinedAttributeName(Attributes attribute, String attributeName, @NullAllowed NamespaceScope namespaceScope, int offset) {
413+
if (namespaceScope != null) {
414+
QualifiedName fullyQualifiedName = VariousUtils.getFullyQualifiedName(QualifiedName.create(attributeName), offset, namespaceScope);
415+
if (attribute.getFqName().equals(fullyQualifiedName.toString())) {
416+
return true;
417+
}
418+
}
419+
return false;
420+
}
421+
361422
public static Map<String, Pair<String, List<Pair<QualifiedName, Boolean>>>> getParamTypesFromPHPDoc(Program root, ASTNode node) {
362423
Map<String, Pair<String, List<Pair<QualifiedName, Boolean>>>> retval = new HashMap<>();
363424
Comment comment = Utils.getCommentForNode(root, node);

php/php.editor/src/org/netbeans/modules/php/editor/model/nodes/CaseDeclarationInfo.java

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ public PhpModifiers getAccessModifiers() {
7777
return PhpModifiers.fromBitMask(caseDeclaration.getModifier());
7878
}
7979

80+
public CaseDeclaration getCaseDeclaration() {
81+
return caseDeclaration;
82+
}
83+
8084
@CheckForNull
8185
protected static String getCaseValue(Expression expr) {
8286
if (expr instanceof Scalar) {

php/php.editor/src/org/netbeans/modules/php/editor/model/nodes/ClassConstantDeclarationInfo.java

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ public PhpModifiers getAccessModifiers() {
103103
return PhpModifiers.fromBitMask(constantDeclaration.getModifier());
104104
}
105105

106+
public ConstantDeclaration getConstantDeclaration() {
107+
return constantDeclaration;
108+
}
109+
106110
@CheckForNull
107111
protected static String getConstantValue(Expression expr) {
108112
if (expr instanceof Scalar) {

php/php.editor/src/org/netbeans/modules/php/editor/resources/layer.xml

+1
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@
428428
<file name="org-netbeans-modules-php-editor-verification-IncorrectConstructorPropertyPromotionHintError.instance"/>
429429
<file name="org-netbeans-modules-php-editor-verification-FinalModifierHintError.instance"/>
430430
<file name="org-netbeans-modules-php-editor-verification-IncorrectFirstClassCallableSyntaxHintError.instance"/>
431+
<file name="org-netbeans-modules-php-editor-verification-IncorrectDeprecatedAttributeHintError.instance"/>
431432
<file name="org-netbeans-modules-php-editor-verification-IncorrectEnumHintError.instance"/>
432433
<file name="org-netbeans-modules-php-editor-verification-IncorrectListUnhandledError.instance"/>
433434
<file name="org-netbeans-modules-php-editor-verification-IncorrectMixedGroupUseHintError.instance"/>

0 commit comments

Comments
 (0)