Lines 1039-1079
Link Here
|
1039 |
EnumSet<PhpElementKind> typeKinds, EnumSet<PhpElementKind> memberKinds) { |
1039 |
EnumSet<PhpElementKind> typeKinds, EnumSet<PhpElementKind> memberKinds) { |
1040 |
final Set<TypeMemberElement> directTypes = new LinkedHashSet<>(); |
1040 |
final Set<TypeMemberElement> directTypes = new LinkedHashSet<>(); |
1041 |
if (typeKinds.contains(PhpElementKind.CLASS) && (typeElement instanceof ClassElement)) { |
1041 |
if (typeKinds.contains(PhpElementKind.CLASS) && (typeElement instanceof ClassElement)) { |
1042 |
final Set<TypeMemberElement> classTypes = new LinkedHashSet<>(); |
1042 |
ClassElement classElement = (ClassElement) typeElement; |
1043 |
QualifiedName superClassName; |
1043 |
QualifiedName superClassName; |
1044 |
Collection<QualifiedName> possibleFQSuperClassNames = ((ClassElement) typeElement).getPossibleFQSuperClassNames(); |
1044 |
Collection<QualifiedName> possibleFQSuperClassNames = classElement.getPossibleFQSuperClassNames(); |
1045 |
if (possibleFQSuperClassNames.size() == 1) { |
1045 |
if (possibleFQSuperClassNames.size() == 1) { |
1046 |
superClassName = possibleFQSuperClassNames.iterator().next(); |
1046 |
superClassName = possibleFQSuperClassNames.iterator().next(); |
1047 |
} else { |
1047 |
} else { |
1048 |
superClassName = ((ClassElement) typeElement).getSuperClassName(); |
1048 |
superClassName = classElement.getSuperClassName(); |
1049 |
} |
1049 |
} |
1050 |
if (superClassName != null) { |
1050 |
Set<TypeMemberElement> classTypes = getDirectInheritedClassTypes(superClassName, memberKinds, typeElement); |
1051 |
classTypes.addAll(extendedQuery.getFields(NameKind.exact(superClassName), NameKind.empty())); |
|
|
1052 |
classTypes.addAll(extendedQuery.getMethods(NameKind.exact(superClassName), NameKind.empty())); |
1053 |
classTypes.addAll(extendedQuery.getTypeConstants(NameKind.exact(superClassName), NameKind.empty())); |
1054 |
if (memberKinds.size() != 1) { |
1055 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer(getTypeMembers(NameKind.exact(superClassName), NameKind.empty()))); |
1056 |
} else { |
1057 |
switch(memberKinds.iterator().next()) { |
1058 |
case METHOD: |
1059 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer( |
1060 |
getMethodsImpl(NameKind.exact(superClassName), NameKind.empty(), EnumSet.of(PhpElementKind.CLASS)))); |
1061 |
break; |
1062 |
case FIELD: |
1063 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer(getFields(NameKind.exact(superClassName), NameKind.empty()))); |
1064 |
break; |
1065 |
case TYPE_CONSTANT: |
1066 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer( |
1067 |
getTypeConstantsImpl(NameKind.exact(superClassName), NameKind.empty(), EnumSet.of(PhpElementKind.CLASS)))); |
1068 |
break; |
1069 |
default: |
1070 |
//no-op |
1071 |
} |
1072 |
} |
1073 |
if (classTypes.isEmpty()) { |
1074 |
insertEmptyElement(classTypes, getClasses(NameKind.exact(superClassName))); |
1075 |
} |
1076 |
} |
1077 |
directTypes.addAll(classTypes); |
1051 |
directTypes.addAll(classTypes); |
1078 |
} |
1052 |
} |
1079 |
if (typeKinds.contains(PhpElementKind.IFACE)) { |
1053 |
if (typeKinds.contains(PhpElementKind.IFACE)) { |
Lines 1140-1145
Link Here
|
1140 |
return directTypes; |
1114 |
return directTypes; |
1141 |
} |
1115 |
} |
1142 |
|
1116 |
|
|
|
1117 |
private Set<TypeMemberElement> getDirectMixinTypeMembers(final TypeElement typeElement, |
1118 |
EnumSet<PhpElementKind> typeKinds, EnumSet<PhpElementKind> memberKinds) { |
1119 |
final Set<TypeMemberElement> directTypes = new LinkedHashSet<>(); |
1120 |
if (typeKinds.contains(PhpElementKind.CLASS) && (typeElement instanceof ClassElement)) { |
1121 |
ClassElement classElement = (ClassElement) typeElement; |
1122 |
Collection<QualifiedName> mixinNames = classElement.getFQMixinClassNames(); |
1123 |
mixinNames.stream() |
1124 |
.map(mixinName -> getDirectInheritedClassTypes(mixinName, memberKinds, typeElement)) |
1125 |
.forEach(classTypes -> directTypes.addAll(classTypes)); |
1126 |
} |
1127 |
return directTypes; |
1128 |
} |
1129 |
|
1130 |
private Set<TypeMemberElement> getDirectInheritedClassTypes(QualifiedName superClassName, EnumSet<PhpElementKind> memberKinds, final TypeElement typeElement) { |
1131 |
final Set<TypeMemberElement> classTypes = new LinkedHashSet<>(); |
1132 |
if (superClassName != null) { |
1133 |
classTypes.addAll(extendedQuery.getFields(NameKind.exact(superClassName), NameKind.empty())); |
1134 |
classTypes.addAll(extendedQuery.getMethods(NameKind.exact(superClassName), NameKind.empty())); |
1135 |
classTypes.addAll(extendedQuery.getTypeConstants(NameKind.exact(superClassName), NameKind.empty())); |
1136 |
if (memberKinds.size() != 1) { |
1137 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer(getTypeMembers(NameKind.exact(superClassName), NameKind.empty()))); |
1138 |
} else { |
1139 |
switch (memberKinds.iterator().next()) { |
1140 |
case METHOD: |
1141 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer( |
1142 |
getMethodsImpl(NameKind.exact(superClassName), NameKind.empty(), EnumSet.of(PhpElementKind.CLASS)))); |
1143 |
break; |
1144 |
case FIELD: |
1145 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer(getFields(NameKind.exact(superClassName), NameKind.empty()))); |
1146 |
break; |
1147 |
case TYPE_CONSTANT: |
1148 |
classTypes.addAll(ElementFilter.forFiles(typeElement.getFileObject()).prefer( |
1149 |
getTypeConstantsImpl(NameKind.exact(superClassName), NameKind.empty(), EnumSet.of(PhpElementKind.CLASS)))); |
1150 |
break; |
1151 |
default: |
1152 |
//no-op |
1153 |
} |
1154 |
} |
1155 |
if (classTypes.isEmpty()) { |
1156 |
insertEmptyElement(classTypes, getClasses(NameKind.exact(superClassName))); |
1157 |
} |
1158 |
} |
1159 |
return classTypes; |
1160 |
} |
1161 |
|
1143 |
private void insertEmptyElement(final Set<TypeMemberElement> where, final Set<? extends TypeElement> exactTypeName) { |
1162 |
private void insertEmptyElement(final Set<TypeMemberElement> where, final Set<? extends TypeElement> exactTypeName) { |
1144 |
TypeElement exactType = ModelUtils.getFirst(exactTypeName); |
1163 |
TypeElement exactType = ModelUtils.getFirst(exactTypeName); |
1145 |
if (exactType != null) { |
1164 |
if (exactType != null) { |
Lines 1243-1248
Link Here
|
1243 |
new LinkedHashSet<>(getDeclaredTypeMembers(typeElement)), typeKinds, memberKinds); |
1262 |
new LinkedHashSet<>(getDeclaredTypeMembers(typeElement)), typeKinds, memberKinds); |
1244 |
} |
1263 |
} |
1245 |
|
1264 |
|
|
|
1265 |
private Set<TypeMemberElement> getAllMixinTypeMembers(TypeElement typeElement) { |
1266 |
final EnumSet<PhpElementKind> typeKinds = EnumSet.of(PhpElementKind.CLASS); |
1267 |
final EnumSet<PhpElementKind> memberKinds = EnumSet.of( |
1268 |
PhpElementKind.METHOD, |
1269 |
PhpElementKind.FIELD, |
1270 |
PhpElementKind.TYPE_CONSTANT |
1271 |
); |
1272 |
return getMixinTypeMembers(typeElement, new LinkedHashSet<>(), |
1273 |
new LinkedHashSet<>(getDeclaredTypeMembers(typeElement)), typeKinds, memberKinds); |
1274 |
} |
1275 |
|
1246 |
@Override |
1276 |
@Override |
1247 |
public Set<TypeMemberElement> getInheritedTypeMembers(final TypeElement typeElement) { |
1277 |
public Set<TypeMemberElement> getInheritedTypeMembers(final TypeElement typeElement) { |
1248 |
final EnumSet<PhpElementKind> typeKinds = EnumSet.of( |
1278 |
final EnumSet<PhpElementKind> typeKinds = EnumSet.of( |
Lines 1263-1268
Link Here
|
1263 |
public Set<TypeMemberElement> getAccessibleTypeMembers(TypeElement typeElement, TypeElement calledFromEnclosingType) { |
1293 |
public Set<TypeMemberElement> getAccessibleTypeMembers(TypeElement typeElement, TypeElement calledFromEnclosingType) { |
1264 |
final long start = (LOG.isLoggable(Level.FINE)) ? System.currentTimeMillis() : 0; |
1294 |
final long start = (LOG.isLoggable(Level.FINE)) ? System.currentTimeMillis() : 0; |
1265 |
final Set<TypeMemberElement> allTypeMembers = getAllTypeMembers(typeElement); |
1295 |
final Set<TypeMemberElement> allTypeMembers = getAllTypeMembers(typeElement); |
|
|
1296 |
Set<TypeMemberElement> retval = getAccessibleTypeMembers(typeElement, calledFromEnclosingType, allTypeMembers); |
1297 |
if (LOG.isLoggable(Level.FINE)) { |
1298 |
logQueryTime("Set<TypeMemberElement> getAccessibleTypeMembers", NameKind.exact(typeElement.getFullyQualifiedName()), start); //NOI18N |
1299 |
} |
1300 |
return Collections.unmodifiableSet(retval); |
1301 |
} |
1302 |
|
1303 |
private Set<TypeMemberElement> getAccessibleTypeMembers(TypeElement typeElement, TypeElement calledFromEnclosingType, final Set<TypeMemberElement> allTypeMembers) { |
1266 |
Collection<TypeElement> subTypes = Collections.emptySet(); |
1304 |
Collection<TypeElement> subTypes = Collections.emptySet(); |
1267 |
if (calledFromEnclosingType != null) { |
1305 |
if (calledFromEnclosingType != null) { |
1268 |
if (typeElement instanceof TraitElement |
1306 |
if (typeElement instanceof TraitElement |
Lines 1275-1282
Link Here
|
1275 |
retval.addAll(filterForAccessible.filter(allTypeMembers)); |
1313 |
retval.addAll(filterForAccessible.filter(allTypeMembers)); |
1276 |
ElementFilter allOf = ElementFilter.allOf(ElementFilter.forVirtualExtensions(), ElementFilter.forMembersOfTypeName(typeElement)); |
1314 |
ElementFilter allOf = ElementFilter.allOf(ElementFilter.forVirtualExtensions(), ElementFilter.forMembersOfTypeName(typeElement)); |
1277 |
retval.addAll(allOf.filter(allTypeMembers)); |
1315 |
retval.addAll(allOf.filter(allTypeMembers)); |
|
|
1316 |
return retval; |
1317 |
} |
1318 |
|
1319 |
@Override |
1320 |
public Set<TypeMemberElement> getAccessibleMixinTypeMembers(TypeElement typeElement, TypeElement calledFromEnclosingType) { |
1321 |
final long start = (LOG.isLoggable(Level.FINE)) ? System.currentTimeMillis() : 0; |
1322 |
final Set<TypeMemberElement> allTypeMembers = getAllMixinTypeMembers(typeElement); |
1323 |
Set<TypeMemberElement> retval = getAccessibleTypeMembers(typeElement, calledFromEnclosingType, allTypeMembers); |
1278 |
if (LOG.isLoggable(Level.FINE)) { |
1324 |
if (LOG.isLoggable(Level.FINE)) { |
1279 |
logQueryTime("Set<PhpElement> getAccessibleTypeMembers", NameKind.exact(typeElement.getFullyQualifiedName()), start); //NOI18N |
1325 |
logQueryTime("Set<TypeMemberElement> getAccessibleMixinTypeMembers", NameKind.exact(typeElement.getFullyQualifiedName()), start); // NOI18N |
1280 |
} |
1326 |
} |
1281 |
return Collections.unmodifiableSet(retval); |
1327 |
return Collections.unmodifiableSet(retval); |
1282 |
} |
1328 |
} |
Lines 1293-1298
Link Here
|
1293 |
return forPrefereMethodImplementation(retval).filter(retval); |
1339 |
return forPrefereMethodImplementation(retval).filter(retval); |
1294 |
} |
1340 |
} |
1295 |
|
1341 |
|
|
|
1342 |
private Set<TypeMemberElement> getMixinTypeMembers(final TypeElement typeElement, final Set<TypeElement> recursionPrevention, |
1343 |
Set<TypeMemberElement> retval, EnumSet<PhpElementKind> typeKinds, EnumSet<PhpElementKind> memberKinds) { |
1344 |
if (recursionPrevention.add(typeElement)) { |
1345 |
final Set<TypeMemberElement> typeMembers = getDirectMixinTypeMembers(typeElement, typeKinds, memberKinds); |
1346 |
retval.addAll(forEmptyElements().filter(forComparingNonAbstractNameKinds(retval).reverseFilter(typeMembers))); |
1347 |
Set<TypeElement> types = toTypes(typeMembers); |
1348 |
types.addAll(getDirectInheritedTypes(typeElement)); |
1349 |
types.forEach(type -> retval.addAll(getMixinTypeMembers(type, recursionPrevention, retval, typeKinds, memberKinds))); |
1350 |
} |
1351 |
return forPrefereMethodImplementation(retval).filter(retval); |
1352 |
} |
1353 |
|
1296 |
@Override |
1354 |
@Override |
1297 |
public Set<MethodElement> getAllMethods(final Exact typeQuery, final NameKind methodQuery) { |
1355 |
public Set<MethodElement> getAllMethods(final Exact typeQuery, final NameKind methodQuery) { |
1298 |
Set<MethodElement> retval = new HashSet<>(); |
1356 |
Set<MethodElement> retval = new HashSet<>(); |