Skip to content

Commit

Permalink
Merge pull request apache#3327 from junichi11/netbeans-2472-overridin…
Browse files Browse the repository at this point in the history
…g-properties

[NETBEANS-2472] Mark overriding/overridden constants and properties as annotations
  • Loading branch information
junichi11 authored Nov 22, 2021
2 parents ae0b68e + 898ebb0 commit 1e86a06
Show file tree
Hide file tree
Showing 13 changed files with 847 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ CAP_Implements=Implements
CAP_Overrides=Overrides
#{0}: implements/overrides what
TP_Implements=Implements method from : {0}
TP_Overrides=Overrides method from: {0}
TP_Overrides=Overrides from: {0}
TP_HasImplementations=Has Implementations
TP_IsOverridden=Is Overridden

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
import org.netbeans.modules.php.editor.api.elements.ElementFilter;
import org.netbeans.modules.php.editor.api.elements.MethodElement;
import org.netbeans.modules.php.editor.api.elements.PhpElement;
import org.netbeans.modules.php.editor.api.elements.TypeConstantElement;
import org.netbeans.modules.php.editor.api.elements.TypeElement;
import org.netbeans.modules.php.editor.model.ClassConstantElement;
import org.netbeans.modules.php.editor.model.FieldElement;
import org.netbeans.modules.php.editor.model.MethodScope;
import org.netbeans.modules.php.editor.model.ModelElement;
import org.netbeans.modules.php.editor.model.Scope;
Expand All @@ -49,13 +52,23 @@
* @author Radek Matous
*/
public class OverridingMethodsImpl implements OverridingMethods {

private String classSignatureForInheritedMethods = ""; //NOI18N
private String classSignatureForInheritedByMethods = ""; //NOI18N
private String classSignatureForInheritedByTypes = ""; //NOI18N
private String classSignatureForInheritedFields = ""; //NOI18N
private String classSignatureForInheritedByFields = ""; //NOI18N
private String classSignatureForInheritedClassConstants = ""; //NOI18N
private String classSignatureForInheritedByClassConstants = ""; //NOI18N
/** just very simple implementation for now*/
private Set<MethodElement> inheritedMethods = Collections.emptySet();
private Set<MethodElement> inheritedByMethods = Collections.emptySet();
private Set<TypeElement> inheritedByTypes = new LinkedHashSet<>();
private Set<org.netbeans.modules.php.editor.api.elements.FieldElement> inheritedFields = Collections.emptySet();
private Set<org.netbeans.modules.php.editor.api.elements.FieldElement> inheritedByFields = Collections.emptySet();
private Set<TypeConstantElement> inheritedClassConstants = Collections.emptySet();
private Set<TypeConstantElement> inheritedByClassConstants = Collections.emptySet();

@Override
public Collection<? extends AlternativeLocation> overrides(ParserResult info, ElementHandle handle) {
assert handle instanceof ModelElement;
Expand All @@ -68,6 +81,24 @@ public Collection<? extends AlternativeLocation> overrides(ParserResult info, El
retval.add(MethodLocation.newInstance(methodElement));
}
return retval;
} else if (handle instanceof FieldElement) {
FieldElement field = (FieldElement) handle;
final ElementFilter fieldNameFilter = ElementFilter.forName(NameKind.exact(field.getName()));
Set<org.netbeans.modules.php.editor.api.elements.FieldElement> overridenFields = fieldNameFilter.filter(getInheritedFields(info, field));
List<AlternativeLocation> retval = new ArrayList<>();
for (org.netbeans.modules.php.editor.api.elements.FieldElement fieldElement : overridenFields) {
retval.add(FieldLocation.newInstance(fieldElement));
}
return retval;
} else if (handle instanceof ClassConstantElement) {
ClassConstantElement constant = (ClassConstantElement) handle;
final ElementFilter constantNameFilter = ElementFilter.forName(NameKind.exact(constant.getName()));
Set<TypeConstantElement> overridenConstants = constantNameFilter.filter(getInheritedClassConstants(info, constant));
List<AlternativeLocation> retval = new ArrayList<>();
for (TypeConstantElement constantElement : overridenConstants) {
retval.add(ClassConstantLocation.newInstance(constantElement));
}
return retval;
}
return null;
}
Expand All @@ -90,6 +121,30 @@ public Collection<? extends AlternativeLocation> overriddenBy(ParserResult info,
retval.add(TypeLocation.newInstance(typeElement));
}
return retval;
} else if (handle instanceof FieldElement) {
FieldElement field = (FieldElement) handle;
final ElementFilter fieldFilter = ElementFilter.allOf(
ElementFilter.forName(NameKind.exact(field.getName())),
ElementFilter.forPrivateModifiers(false)
);
final Set<org.netbeans.modules.php.editor.api.elements.FieldElement> overridenByFields = fieldFilter.filter(getInheritedByFields(info, field));
List<AlternativeLocation> retval = new ArrayList<>();
for (org.netbeans.modules.php.editor.api.elements.FieldElement fieldElement : overridenByFields) {
retval.add(FieldLocation.newInstance(fieldElement));
}
return retval;
} else if (handle instanceof ClassConstantElement) {
ClassConstantElement constant = (ClassConstantElement) handle;
final ElementFilter constantFilter = ElementFilter.allOf(
ElementFilter.forName(NameKind.exact(constant.getName())),
ElementFilter.forPrivateModifiers(false)
);
final Set<TypeConstantElement> overridenByConstants = constantFilter.filter(getInheritedByClassConstants(info, constant));
List<AlternativeLocation> retval = new ArrayList<>();
for (TypeConstantElement constantElement : overridenByConstants) {
retval.add(ClassConstantLocation.newInstance(constantElement));
}
return retval;
}

return null;
Expand All @@ -114,9 +169,48 @@ private Set<MethodElement> getInheritedMethods(final ParserResult info, final Me
inheritedMethods = index.getInheritedMethods(typeScope);
}
classSignatureForInheritedMethods = signature;
return inheritedMethods;
return Collections.unmodifiableSet(inheritedMethods);
}

/**
* Get inherited fields.
*
* @param info the parser result
* @param field the filed
* @return the inherited fields
*/
private Set<org.netbeans.modules.php.editor.api.elements.FieldElement> getInheritedFields(final ParserResult info, final FieldElement field) {
Scope inScope = field.getInScope();
assert inScope instanceof TypeScope;
TypeScope typeScope = (TypeScope) inScope;
final String signature = typeScope.getIndexSignature();
if (signature != null && !signature.equals(classSignatureForInheritedFields)) {
Index index = ElementQueryFactory.getIndexQuery(info);
inheritedFields = index.getInheritedFields(typeScope);
}
classSignatureForInheritedFields = signature;
return Collections.unmodifiableSet(inheritedFields);
}

/**
* Get inherited class constants.
*
* @param info the parser result
* @param constant the constant
* @return the inherited constants
*/
private Set<TypeConstantElement> getInheritedClassConstants(final ParserResult info, final ClassConstantElement constant) {
Scope inScope = constant.getInScope();
assert inScope instanceof TypeScope;
TypeScope typeScope = (TypeScope) inScope;
final String signature = typeScope.getIndexSignature();
if (signature != null && !signature.equals(classSignatureForInheritedClassConstants)) {
Index index = ElementQueryFactory.getIndexQuery(info);
inheritedClassConstants = index.getInheritedTypeConstants(typeScope);
}
classSignatureForInheritedClassConstants = signature;
return Collections.unmodifiableSet(inheritedClassConstants);
}

/**
* @return the inheritedByTypes
Expand All @@ -128,7 +222,7 @@ private Set<TypeElement> getInheritedByTypes(final ParserResult info, final Type
inheritedByTypes = index.getInheritedByTypes(type);
}
classSignatureForInheritedByTypes = signature;
return inheritedByTypes;
return Collections.unmodifiableSet(inheritedByTypes);
}

/**
Expand All @@ -147,9 +241,48 @@ private Set<MethodElement> getInheritedByMethods(final ParserResult info, final
}
}
classSignatureForInheritedByMethods = signature;
return inheritedByMethods;
return Collections.unmodifiableSet(inheritedByMethods);
}

/**
* @return the inheritedByFields
*/
private Set<org.netbeans.modules.php.editor.api.elements.FieldElement> getInheritedByFields(final ParserResult info, final FieldElement field) {
Scope inScope = field.getInScope();
assert inScope instanceof TypeScope;
TypeScope typeScope = (TypeScope) inScope;
final String signature = ((TypeScope) inScope).getIndexSignature();
if (signature != null && !signature.equals(classSignatureForInheritedByFields)) {
Index index = ElementQueryFactory.getIndexQuery(info);
inheritedByFields = new HashSet<>();
for (TypeElement nextType : getInheritedByTypes(info, typeScope)) {
inheritedByFields.addAll(index.getDeclaredFields(nextType));
}
}
classSignatureForInheritedByFields = signature;
return Collections.unmodifiableSet(inheritedByFields);
}

/**
* @return the inheritedByClassConstants
*/
private Set<TypeConstantElement> getInheritedByClassConstants(final ParserResult info, final ClassConstantElement constant) {
Scope inScope = constant.getInScope();
assert inScope instanceof TypeScope;
TypeScope typeScope = (TypeScope) inScope;
final String signature = ((TypeScope) inScope).getIndexSignature();
if (signature != null && !signature.equals(classSignatureForInheritedByClassConstants)) {
Index index = ElementQueryFactory.getIndexQuery(info);
inheritedByClassConstants = new HashSet<>();
for (TypeElement nextType : getInheritedByTypes(info, typeScope)) {
inheritedByClassConstants.addAll(index.getDeclaredTypeConstants(nextType));
}
}
classSignatureForInheritedByClassConstants = signature;
return Collections.unmodifiableSet(inheritedByClassConstants);
}

//~ inner classes
private static final class MethodLocation extends DeclarationFinderImpl.AlternativeLocationImpl {

public static MethodLocation newInstance(PhpElement modelElement) {
Expand Down Expand Up @@ -177,6 +310,7 @@ public String getDisplayHtml(HtmlFormatter formatter) {
return sb.toString();
}
}

private static final class TypeLocation extends DeclarationFinderImpl.AlternativeLocationImpl {

public static TypeLocation newInstance(PhpElement modelElement) {
Expand Down Expand Up @@ -204,4 +338,60 @@ public String getDisplayHtml(HtmlFormatter formatter) {
}
}

private static final class FieldLocation extends DeclarationFinderImpl.AlternativeLocationImpl {

public static FieldLocation newInstance(PhpElement modelElement) {
FileObject fileObject = modelElement.getFileObject();
DeclarationLocation declarationLocation = fileObject == null ? DeclarationLocation.NONE : new DeclarationLocation(fileObject, modelElement.getOffset(), modelElement);
return new FieldLocation(modelElement, declarationLocation);
}

private FieldLocation(PhpElement modelElement, DeclarationLocation declaration) {
super(modelElement, declaration);
}

@Override
public String getDisplayHtml(HtmlFormatter formatter) {
StringBuilder sb = new StringBuilder(30);
org.netbeans.modules.php.editor.api.elements.FieldElement field = (org.netbeans.modules.php.editor.api.elements.FieldElement) getElement();
final TypeElement type = field.getType();
sb.append(type.getFullyQualifiedName().toNotFullyQualified().toString());
final FileObject fileObject = type.getFileObject();
if (fileObject != null) {
sb.append(" ("); // NOI18N
sb.append(fileObject.getNameExt());
sb.append(")"); // NOI18N
}
return sb.toString();
}
}

private static final class ClassConstantLocation extends DeclarationFinderImpl.AlternativeLocationImpl {

public static ClassConstantLocation newInstance(PhpElement modelElement) {
FileObject fileObject = modelElement.getFileObject();
DeclarationLocation declarationLocation = fileObject == null ? DeclarationLocation.NONE : new DeclarationLocation(fileObject, modelElement.getOffset(), modelElement);
return new ClassConstantLocation(modelElement, declarationLocation);
}

private ClassConstantLocation(PhpElement modelElement, DeclarationLocation declaration) {
super(modelElement, declaration);
}

@Override
public String getDisplayHtml(HtmlFormatter formatter) {
StringBuilder sb = new StringBuilder(30);
TypeConstantElement constant = (TypeConstantElement) getElement();
final TypeElement type = constant.getType();
sb.append(type.getFullyQualifiedName().toNotFullyQualified().toString());
final FileObject fileObject = type.getFileObject();
if (fileObject != null) {
sb.append(" ("); // NOI18N
sb.append(fileObject.getNameExt());
sb.append(")"); // NOI18N
}
return sb.toString();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,7 @@ public Set<MethodElement> getAccessibleStaticMethods(final TypeElement typeEleme
}

private Set<TypeConstantElement> getNotPrivateTypeConstants(TypeElement oneType) {
return ElementFilter.forPublicModifiers(true).filter(getDeclaredTypeConstants(oneType));
return ElementFilter.forPrivateModifiers(false).filter(getDeclaredTypeConstants(oneType));
}

private Set<FieldElement> getNotPrivateFields(ClassElement oneClass) {
Expand All @@ -1391,15 +1391,10 @@ public Set<FieldElement> getInheritedFields(final TypeElement classElement) {
final long start = (LOG.isLoggable(Level.FINE)) ? System.currentTimeMillis() : 0;
final Set<FieldElement> retval = new HashSet<>();
final Set<ClassElement> inheritedClasses = getInheritedClasses(classElement);
final Set<String> declaredFieldNames = toNames(getDeclaredFields(classElement));
for (ClassElement oneClass : inheritedClasses) {
final Set<FieldElement> fields = getNotPrivateFields(oneClass);
for (final FieldElement fieldElement : fields) {
final String fieldName = fieldElement.getName();
if (!declaredFieldNames.contains(fieldName)) {
retval.add(fieldElement);
declaredFieldNames.add(fieldName);
}
retval.add(fieldElement);
}
}
if (LOG.isLoggable(Level.FINE)) {
Expand All @@ -1414,15 +1409,10 @@ public Set<TypeConstantElement> getInheritedTypeConstants(TypeElement typeElemen
final long start = (LOG.isLoggable(Level.FINE)) ? System.currentTimeMillis() : 0;
final Set<TypeConstantElement> retval = new HashSet<>();
final Set<? extends TypeElement> inheritedTypes = getInheritedTypes(typeElement);
final Set<String> declaredConstantNames = toNames(getDeclaredTypeConstants(typeElement));
for (TypeElement oneType : inheritedTypes) {
final Set<TypeConstantElement> constants = getNotPrivateTypeConstants(oneType);
for (final TypeConstantElement constantElement : constants) {
final String constantName = constantElement.getName();
if (!declaredConstantNames.contains(constantName)) {
retval.add(constantElement);
declaredConstantNames.add(constantName);
}
retval.add(constantElement);
}
}
if (LOG.isLoggable(Level.FINE)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Overridden]

[Constant]
IMPLICIT_PUBLIC_PARENT_CONST (ChildClass1.php)(ChildClass2.php)
PROTECTED_PARENT_CONST (ChildClass1.php)(ChildClass2.php)
PUBLIC_PARENT_CONST (ChildClass1.php)(ChildClass2.php)
[Field]
$protectedParentClassField (ChildClass2.php)
$protectedStaticParentClassField (ChildClass2.php)
$publicParentClassField (ChildClass2.php)
$publicStaticParentClassField (ChildClass2.php)
[Method]
protectedParentClassMethod (ChildClass2.php)
protectedStaticParentClassMethod (ChildClass2.php)
publicParentClassMethod (ChildClass2.php)
publicStaticParentClassMethod (ChildClass2.php)
[Type]
ParentClass (ChildClass1.php)(ChildClass2.php)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Overring]

[Constant]
IMPLICIT_PUBLIC_PARENT_CONST (ParentClass.php)
PROTECTED_PARENT_CONST (ParentClass.php)
PUBLIC_PARENT_CONST (ParentClass.php)
[Field]
$protectedParentClassField (ParentClass.php)
$protectedStaticParentClassField (ParentClass.php)
$publicParentClassField (ParentClass.php)
$publicStaticParentClassField (ParentClass.php)
[Method]
protectedParentClassMethod (ParentClass.php)
protectedStaticParentClassMethod (ParentClass.php)
publicParentClassMethod (ParentClass.php)
publicStaticParentClassMethod (ParentClass.php)
Loading

0 comments on commit 1e86a06

Please sign in to comment.