Skip to content

Commit 5f9de86

Browse files
authored
Fix TypeDef.of with overridden type arguments (#258)
* Fix `TypeDef.of` with overridden type arguments * Checkstyle
1 parent f907981 commit 5f9de86

File tree

6 files changed

+167
-6
lines changed

6 files changed

+167
-6
lines changed

sourcegen-model/src/main/java/io/micronaut/sourcegen/model/TypeDef.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,14 @@ private static TypeDef of(TypedElement typedElement, boolean erasure) {
341341
);
342342
}
343343
if (typedElement instanceof ClassElement classElement) {
344-
if (classElement.getFirstTypeArgument().isPresent()) {
345-
return TypeDef.parameterized(
346-
ClassTypeDef.of(classElement),
347-
classElement.getBoundGenericTypes().stream().map(TypeDef::of).toList()
348-
);
349-
} else {
344+
Map<String, ClassElement> typeArguments = classElement.getTypeArguments();
345+
if (typeArguments.isEmpty()) {
350346
return ClassTypeDef.of(classElement);
351347
}
348+
return TypeDef.parameterized(
349+
ClassTypeDef.of(classElement),
350+
typeArguments.values().stream().map(TypeDef::of).toList()
351+
);
352352
}
353353
throw new IllegalStateException("Unknown typed element: " + typedElement);
354354
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2017-2023 original authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micronaut.sourcegen.custom.example;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.Target;
22+
23+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
24+
25+
@Documented
26+
@Retention(RUNTIME)
27+
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
28+
public @interface GenerateMyRepository2 {
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2017-2023 original authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micronaut.sourcegen.custom.visitor;
17+
18+
import io.micronaut.core.annotation.Internal;
19+
import io.micronaut.core.annotation.NonNull;
20+
import io.micronaut.inject.ast.ClassElement;
21+
import io.micronaut.inject.visitor.TypeElementVisitor;
22+
import io.micronaut.inject.visitor.VisitorContext;
23+
import io.micronaut.sourcegen.custom.example.GenerateMyRepository1;
24+
import io.micronaut.sourcegen.custom.example.GenerateMyRepository2;
25+
import io.micronaut.sourcegen.generator.SourceGenerator;
26+
import io.micronaut.sourcegen.generator.SourceGenerators;
27+
import io.micronaut.sourcegen.model.ClassDef;
28+
import io.micronaut.sourcegen.model.ClassTypeDef;
29+
import io.micronaut.sourcegen.model.InterfaceDef;
30+
import io.micronaut.sourcegen.model.MethodDef;
31+
import io.micronaut.sourcegen.model.PropertyDef;
32+
import io.micronaut.sourcegen.model.TypeDef;
33+
34+
import javax.lang.model.element.Modifier;
35+
import java.util.List;
36+
import java.util.Optional;
37+
38+
@Internal
39+
public final class GenerateMyRepository2Visitor implements TypeElementVisitor<GenerateMyRepository2, Object> {
40+
41+
@Override
42+
public @NonNull VisitorKind getVisitorKind() {
43+
return VisitorKind.ISOLATING;
44+
}
45+
46+
@Override
47+
public void visitClass(ClassElement element, VisitorContext context) {
48+
SourceGenerator sourceGenerator = SourceGenerators.findByLanguage(context.getLanguage()).orElse(null);
49+
if (sourceGenerator == null) {
50+
return;
51+
}
52+
53+
InterfaceDef myRepositoryRef = InterfaceDef.builder(element.getPackageName() + ".MyRepository2")
54+
.addModifiers(Modifier.PUBLIC)
55+
56+
.addSuperinterface(TypeDef.of(
57+
element.withTypeArguments(
58+
List.of(
59+
context.getClassElement(Integer.class).get(),
60+
context.getClassElement(String.class).get()
61+
)
62+
)
63+
))
64+
.build();
65+
66+
sourceGenerator.write(myRepositoryRef, context, element);
67+
}
68+
69+
}

test-suite-custom-generators/src/main/resources/META-INF/services/io.micronaut.inject.visitor.TypeElementVisitor

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ io.micronaut.sourcegen.custom.visitor.GenerateMyBean2Visitor
44
io.micronaut.sourcegen.custom.visitor.GenerateMyBean3Visitor
55
io.micronaut.sourcegen.custom.visitor.GenerateInterfaceBuilder
66
io.micronaut.sourcegen.custom.visitor.GenerateMyRepository1Visitor
7+
io.micronaut.sourcegen.custom.visitor.GenerateMyRepository2Visitor
78
io.micronaut.sourcegen.custom.visitor.GenerateMyRecord1Visitor
89
io.micronaut.sourcegen.custom.visitor.GenerateMyRecord2Visitor
910
io.micronaut.sourcegen.custom.visitor.GenerateMyRecord3Visitor
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2017-2025 original authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micronaut.sourcegen.example;
17+
18+
import io.micronaut.sourcegen.custom.example.GenerateMyRepository2;
19+
20+
@GenerateMyRepository2
21+
public interface NumberRepository<N extends Number, T> {
22+
23+
N value(T number);
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2003-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.micronaut.sourcegen.example;
17+
18+
import org.junit.jupiter.api.Assertions;
19+
import org.junit.jupiter.api.Test;
20+
21+
import java.util.List;
22+
import java.util.Optional;
23+
24+
class MyRepository2Test {
25+
@Test
26+
public void test() throws Exception {
27+
MyRepository2Instance myInstance = new MyRepository2Instance();
28+
Assertions.assertEquals(123, myInstance.value("abc"));
29+
}
30+
31+
static class MyRepository2Instance implements MyRepository2 {
32+
@Override
33+
public Integer value(String number) {
34+
return 123;
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)