From c55b399b59f3e0b35ea161d59b59889fcb6fbc94 Mon Sep 17 00:00:00 2001 From: Sergey Kapralov Date: Thu, 18 Nov 2021 21:35:56 +0300 Subject: [PATCH] Hacked through the problem of missing package info for a class from annotation, when the class is generated with the same compiler session --- .../basic/InferredAliasGenerator.java | 5 +- .../InferredImplementationGenerator.java | 5 +- .../oo/inference/hack/Hacks.java | 60 ++++++++++++++++++- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredAliasGenerator.java b/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredAliasGenerator.java index 8bdefae5..eaec10cf 100644 --- a/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredAliasGenerator.java +++ b/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredAliasGenerator.java @@ -73,10 +73,11 @@ public boolean process(Set annotations, RoundEnvironment .map(e -> (VariableElement) e) .map(e -> new ArgumentFromVariableElement(e)); String packageName = ((PackageElement)elem.getEnclosingElement()).getQualifiedName().toString(); - DeclaredType usingValue = Hacks.extractType(anno::using); + DeclaredType usingValue = (DeclaredType) Hacks.extractType(anno::using); + Type inferredImplementation = usingValue.asElement().getSimpleName().toString().equals("Object") ? new TypeReferential(packageName, iface.asElement().getSimpleName().toString() + "Inferred") - : new TypeFromDeclaredType(usingValue); + : Hacks.deduceInferenceImplementation(roundEnv).getOrElse(usingValue.asElement().getSimpleName().toString(), new TypeFromDeclaredType(usingValue)); String aliasName = anno.value(); InferredAliasModel model = new InferredAliasModel( new TypeReferential(packageName, aliasName), diff --git a/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredImplementationGenerator.java b/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredImplementationGenerator.java index 479e2675..cf2273c7 100644 --- a/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredImplementationGenerator.java +++ b/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/basic/InferredImplementationGenerator.java @@ -67,12 +67,13 @@ public boolean process(Set annotations, RoundEnvironment .map(e -> (PackageElement) e)) { GenerateInferred anno = pe.getAnnotation(GenerateInferred.class); - DeclaredType iface = Hacks.extractType(anno::value); + DeclaredType iface = (DeclaredType) Hacks.extractType(anno::value); String packageName = pe.getQualifiedName().toString(); String inferredImplementationName = iface.asElement().getSimpleName().toString() + "Inferred"; + Type generatedType = new TypeReferential(packageName, inferredImplementationName); InferredClassModel model = new InferredClassModel( - new TypeReferential(packageName, inferredImplementationName), + generatedType, new TypeFromDeclaredType(iface), List.of(iface.asElement()) .flatMap(i -> i.getEnclosedElements()) diff --git a/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/hack/Hacks.java b/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/hack/Hacks.java index 1b500ee3..03e59750 100644 --- a/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/hack/Hacks.java +++ b/oo-inference/inference-basic/src/main/java/com/pragmaticobjects/oo/inference/hack/Hacks.java @@ -25,18 +25,74 @@ */ package com.pragmaticobjects.oo.inference.hack; +import com.pragmaticobjects.oo.inference.api.GenerateInferred; +import com.pragmaticobjects.oo.meta.model.Type; +import com.pragmaticobjects.oo.meta.model.TypeReferential; +import io.vavr.collection.HashMap; + +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.MirroredTypeException; +import javax.lang.model.type.TypeMirror; +import java.lang.annotation.Annotation; +import java.util.Map; import java.util.function.Supplier; +import java.util.stream.Collectors; public class Hacks { - public static DeclaredType extractType(Supplier> classSupplier) { + public static TypeMirror extractType(Supplier> classSupplier) { try { Class clazz = classSupplier.get(); throw new RuntimeException("Expected to be failed till that moment - " + clazz.getName()); } catch (MirroredTypeException mte) { - DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror(); + TypeMirror classTypeMirror = mte.getTypeMirror(); return classTypeMirror; } } + + + private static AnnotationMirror getAnnotationMirror(Element element, Class clazz) { + String clazzName = clazz.getName(); + for(AnnotationMirror m : element.getAnnotationMirrors()) { + if(m.getAnnotationType().toString().equals(clazzName)) { + return m; + } + } + throw new NullPointerException(); + } + + private static AnnotationValue getAnnotationValue(AnnotationMirror annotationMirror, String key) { + for(Map.Entry entry : annotationMirror.getElementValues().entrySet() ) { + if(entry.getKey().getSimpleName().toString().equals(key)) { + return entry.getValue(); + } + } + throw new NullPointerException( + annotationMirror.getElementValues().keySet().stream() + .map(s -> s.toString()) + .collect(Collectors.joining(",")) + ); + } + + + public static TypeMirror extractType2(Element foo, Class anno, String field) { + AnnotationMirror am = getAnnotationMirror(foo, anno); + AnnotationValue av = getAnnotationValue(am, field); + return (TypeMirror) av.getValue(); + } + + public static io.vavr.collection.Map deduceInferenceImplementation(RoundEnvironment roundEnv) { + return roundEnv.getElementsAnnotatedWith(GenerateInferred.class).stream() + .map(e -> (PackageElement) e) + .map(pe -> { + GenerateInferred anno = pe.getAnnotation(GenerateInferred.class); + DeclaredType iface = (DeclaredType) Hacks.extractType(anno::value); + String packageName = pe.getQualifiedName().toString(); + String inferredImplementationName = iface.asElement().getSimpleName().toString() + "Inferred"; + Type generatedType = new TypeReferential(packageName, inferredImplementationName); + return generatedType; + }) + .collect(HashMap.collector(t -> t.name(), t -> t)); + } }