Skip to content

Commit

Permalink
big x
Browse files Browse the repository at this point in the history
  • Loading branch information
Postremus committed Feb 22, 2025
1 parent 2a788f1 commit 8aa599b
Showing 1 changed file with 63 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -730,17 +730,30 @@ public Supplier<Boolean> apply(ClassInfo classInfo) {

checkForDuplicateEndpoint(config, allServerMethods);

Map<DotName, Set<Type>> declaringClassToTypes = new HashMap<>();
Function<Type, DotName> typeToReturnName = new Function<Type, DotName>() {
@Override
public DotName apply(Type type) {
DotName typeName = type.name();
if (type.kind() == Type.Kind.CLASS && !typeName.toString().startsWith("java.lang.")) {
return typeName;
} else if (type.kind() == Type.Kind.PARAMETERIZED_TYPE
&& typeName.equals(DotName.createSimple(Class.class))) {
return type.asParameterizedType().arguments().get(0).name();
}
return null;
}
};

Map<DotName, Set<DotName>> declaringClassToReturnNames = new HashMap<>();
//now index possible sub resources. These are all classes that have method annotations
//that are not annotated @Path
Deque<ClassInfo> toScan = new ArrayDeque<>();
for (DotName methodAnnotation : result.getHttpAnnotationToMethod().keySet()) {
for (AnnotationInstance instance : index.getAnnotations(methodAnnotation)) {
MethodInfo method = instance.target().asMethod();
ClassInfo classInfo = method.declaringClass();
toScan.add(classInfo);
declaringClassToTypes.computeIfAbsent(method.declaringClass().name(), ignored -> new HashSet<>())
.add(method.returnType());
declaringClassToReturnNames.computeIfAbsent(classInfo.name(), ignored -> new HashSet<>())
.add(typeToReturnName.apply(method.returnType()));
}
}
//sub resources can also have just a path annotation
Expand All @@ -749,30 +762,18 @@ public Supplier<Boolean> apply(ClassInfo classInfo) {
if (instance.target().kind() == AnnotationTarget.Kind.METHOD) {
MethodInfo method = instance.target().asMethod();
ClassInfo classInfo = method.declaringClass();
toScan.add(classInfo);
declaringClassToTypes.computeIfAbsent(method.declaringClass().name(), ignored -> new HashSet<>())
.add(method.returnType());
declaringClassToReturnNames.computeIfAbsent(classInfo.name(), ignored -> new HashSet<>())
.add(typeToReturnName.apply(method.returnType()));
}
}

Map<DotName, Set<DotName>> declaringClassToReturnNames = new HashMap<>();
declaringClassToTypes.forEach((key, values) -> {
HashSet<DotName> returnNames = new HashSet<>();
values.forEach(value -> {
if (value.kind() == Type.Kind.CLASS) {
returnNames.add(value.name());
} else if (value.kind() == Type.Kind.PARAMETERIZED_TYPE
&& value.name().equals(DotName.createSimple(Class.class))) {
returnNames.add(value.asParameterizedType().arguments().get(0).name());
}
});
declaringClassToReturnNames.put(key, returnNames);
});
declaringClassToReturnNames.remove(null);

Map<DotName, Set<DotName>> declHierarchy = new HashMap<>();
List<DotName> parentSearch = new ArrayList<>();
parentSearch.addAll(declaringClassToReturnNames.keySet());
parentSearch.addAll(resourceClasses.stream().map(rc -> DotName.createSimple(rc.getClassName())).toList());
List<DotName> parentSearch = new ArrayList<>(declaringClassToReturnNames.keySet());
for (ResourceClass resourceClass : resourceClasses) {
parentSearch.add(DotName.createSimple(resourceClass.getClassName()));
}
for (DotName dotName : parentSearch) {
ArrayDeque<DotName> supsup = new ArrayDeque<>();
Set<DotName> allSuperTypesOfDecl = new HashSet<>();
Expand All @@ -799,64 +800,55 @@ public Supplier<Boolean> apply(ClassInfo classInfo) {
declHierarchy.put(dotName, allSuperTypesOfDecl);
}

Map<DotName, Set<DotName>> declSub = new HashMap<>();
parentSearch = new ArrayList<>();
parentSearch.addAll(declaringClassToReturnNames.keySet());
parentSearch.addAll(resourceClasses.stream().map(rc -> DotName.createSimple(rc.getClassName())).toList());
for (DotName dotName : parentSearch) {
Set<DotName> allSuperTypesOfDecl = new HashSet<>();
for (ClassInfo allKnownSubclass : index.getAllKnownSubclasses(dotName)) {
allSuperTypesOfDecl.add(allKnownSubclass.name());
}
for (ClassInfo allKnownSubclass : index.getAllKnownSubinterfaces(dotName)) {
allSuperTypesOfDecl.add(allKnownSubclass.name());
Function<DotName, Set<DotName>> filler = new Function<DotName, Set<DotName>>() {
@Override
public Set<DotName> apply(DotName dotName) {
if (dotName == null) {
return Collections.emptySet();
}

Set<DotName> all = new HashSet<>();
index.getAllKnownSubclasses(dotName).forEach(c -> all.add(c.name()));
index.getAllKnownSubinterfaces(dotName).forEach(c -> all.add(c.name()));
all.add(dotName);

return all;
}
};
Map<DotName, Set<DotName>> returnNameKnowSubNames = new HashMap<>();

allSuperTypesOfDecl.add(dotName);
declSub.put(dotName, allSuperTypesOfDecl);
ArrayDeque<DotName> declQueue = new ArrayDeque<>();
for (ResourceClass resourceClass : resourceClasses) {
declQueue.add(DotName.createSimple(resourceClass.getClassName()));
}
Set<DotName> seen = new HashSet<>();
while (!declQueue.isEmpty()) {
DotName poll = declQueue.poll();
if (!seen.add(poll)) {
continue;
}

{
ArrayDeque<DotName> declQueue = new ArrayDeque<>();
// start at the resource classes, work our way downwards the chain
declQueue.addAll(resourceClasses.stream().map(rc -> DotName.createSimple(rc.getClassName())).toList());
Set<DotName> seen = new HashSet<>();
while (!declQueue.isEmpty()) {
DotName poll = declQueue.poll();
if (!seen.add(poll)) {
continue;
}

List<DotName> methodReturnTypes = new ArrayList<>();
if (declHierarchy.containsKey(poll)) {
for (DotName dotName : declHierarchy.get(poll)) {
if (declaringClassToReturnNames.containsKey(dotName)) {
methodReturnTypes.addAll(declaringClassToReturnNames.get(dotName));
}
List<DotName> methodReturnTypes = new ArrayList<>();
if (declHierarchy.containsKey(poll)) {
for (DotName dotName : declHierarchy.get(poll)) {
if (declaringClassToReturnNames.containsKey(dotName)) {
methodReturnTypes.addAll(declaringClassToReturnNames.get(dotName));
}
}
}

// a
// b, a
for (DotName methodReturnType : methodReturnTypes) {
declHierarchy.forEach((key, sub) -> {
if (sub.contains(methodReturnType)) {
declQueue.addAll(sub);
}
});
}
for (DotName methodReturnType : methodReturnTypes) {
Set<DotName> decls = returnNameKnowSubNames.computeIfAbsent(methodReturnType, filler);
declQueue.addAll(decls);
}
}

// resource classes get index before
// seen.removeAll(resourceClasses.stream().map(rc -> DotName.createSimple(rc.getClassName())).toList());
// resource classes get indexed before already
seen.removeAll(resourceClasses.stream().map(rc -> DotName.createSimple(rc.getClassName())).toList());

if (true) {
toScan.clear();
for (DotName dotName : seen) {
if (!dotName.toString().startsWith("java.")) {
toScan.add(index.getClassByName(dotName));
}
}
for (DotName dotName : seen) {
if (!dotName.toString().startsWith("java.")) {
toScan.add(index.getClassByName(dotName));
}
}

Expand All @@ -871,34 +863,10 @@ public Supplier<Boolean> apply(ClassInfo classInfo) {
}
possibleSubResources.put(classInfo.name(), classInfo);

if (classInfo.isInterface()) {
int resourceClassImplCount = 0;
if (resourceClassNames == null) {
resourceClassNames = resourceClasses.stream().map(ResourceClass::getClassName)
.collect(Collectors.toSet());
}
for (ClassInfo impl : index.getAllKnownImplementors(classInfo.name())) {
if (resourceClassNames.contains(impl.name().toString())) {
resourceClassImplCount++;
}
}
if (resourceClassImplCount > 1) {
// this is the case were an interface doesn't denote a subresource, but it's simply used
// to share method and annotations between Resource classes
continue;
}
}

Optional<ResourceClass> endpoints = serverEndpointIndexer.createEndpoints(classInfo, false);
if (endpoints.isPresent()) {
subResourceClasses.add(endpoints.get());
}
//we need to also look for all subclasses and interfaces
//they may have type variables that need to be handled
if (false) {
toScan.addAll(index.getKnownDirectImplementors(classInfo.name()));
toScan.addAll(index.getKnownDirectSubclasses(classInfo.name()));
}
}

setupEndpointsResultProducer.produce(new SetupEndpointsResultBuildItem(resourceClasses, subResourceClasses,
Expand Down

0 comments on commit 8aa599b

Please sign in to comment.