diff --git a/inject-kotlin/src/main/kotlin/io/micronaut/kotlin/processing/visitor/TypeElementSymbolProcessor.kt b/inject-kotlin/src/main/kotlin/io/micronaut/kotlin/processing/visitor/TypeElementSymbolProcessor.kt index c3f2b6beaa7..fcfaf016357 100644 --- a/inject-kotlin/src/main/kotlin/io/micronaut/kotlin/processing/visitor/TypeElementSymbolProcessor.kt +++ b/inject-kotlin/src/main/kotlin/io/micronaut/kotlin/processing/visitor/TypeElementSymbolProcessor.kt @@ -99,6 +99,15 @@ internal open class TypeElementSymbolProcessor(private val environment: SymbolPr .filterIsInstance() .filter { declaration: KSClassDeclaration -> acceptClass(declaration) + && declaration.classKind != ClassKind.ANNOTATION_CLASS + } + .filter { + val className = it.qualifiedName?.asString() + return@filter if (className == null) { + false + } else { + processed.add(className) + } } .toList() @@ -111,31 +120,25 @@ internal open class TypeElementSymbolProcessor(private val environment: SymbolPr // Micronaut Data use-case: EntityMapper with a higher priority needs to process entities first // before RepositoryMapper is going to process repositories and read entities - for (typeElement in elements) { - if (typeElement.classKind != ClassKind.ANNOTATION_CLASS) { - val className = typeElement.qualifiedName?.asString() - if (className != null && !processed.contains(className)) { - processed.add(className) - - for (loadedVisitor in loadedVisitors) { - if (!loadedVisitor.matches(typeElement)) { - continue - } - try { - typeElement.accept( - ElementVisitor( - loadedVisitor, - typeElement, - classElementsCache - ), className - ) - } catch (e: ProcessingException) { - BeanDefinitionProcessor.handleProcessingException(environment, e) - } catch (e: Exception) { - environment.logger.error("Error processing type visitor [${loadedVisitor.visitor}]: ${e.message}", typeElement) - environment.logger.exception(e) - } - } + for (loadedVisitor in loadedVisitors) { + for (typeElement in elements) { + if (!loadedVisitor.matches(typeElement)) { + continue + } + try { + typeElement.accept( + ElementVisitor( + loadedVisitor, + typeElement, + classElementsCache + ), + "ignore" + ) + } catch (e: ProcessingException) { + BeanDefinitionProcessor.handleProcessingException(environment, e) + } catch (e: Exception) { + environment.logger.error("Error processing type visitor [${loadedVisitor.visitor}]: ${e.message}", typeElement) + environment.logger.exception(e) } } } diff --git a/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor1.java b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor1.java new file mode 100644 index 00000000000..c30448dcf3d --- /dev/null +++ b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor1.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017-2020 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.kotlin.processing.visitor.order; + +import io.micronaut.inject.ast.ClassElement; +import io.micronaut.inject.visitor.TypeElementVisitor; +import io.micronaut.inject.visitor.VisitorContext; + +import java.util.ArrayList; +import java.util.List; + +public class MyVisitor1 implements TypeElementVisitor { + + static List ORDER = new ArrayList<>(); + + @Override + public void start(VisitorContext visitorContext) { + ORDER.clear(); + } + + @Override + public void visitClass(ClassElement element, VisitorContext context) { + ORDER.add(getClass().getSimpleName() + " " + element.getName()); + } + + @Override + public int getOrder() { + return 1; + } +} diff --git a/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor2.java b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor2.java new file mode 100644 index 00000000000..91c251eef26 --- /dev/null +++ b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor2.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017-2020 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.kotlin.processing.visitor.order; + +import io.micronaut.inject.ast.ClassElement; +import io.micronaut.inject.visitor.TypeElementVisitor; +import io.micronaut.inject.visitor.VisitorContext; + +public class MyVisitor2 implements TypeElementVisitor { + + @Override + public void visitClass(ClassElement element, VisitorContext context) { + MyVisitor1.ORDER.add(getClass().getSimpleName() + " " + element.getName()); + } + + @Override + public int getOrder() { + return 2; + } +} diff --git a/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor3.java b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor3.java new file mode 100644 index 00000000000..448d2c049b6 --- /dev/null +++ b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/MyVisitor3.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017-2020 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.kotlin.processing.visitor.order; + +import io.micronaut.inject.ast.ClassElement; +import io.micronaut.inject.visitor.TypeElementVisitor; +import io.micronaut.inject.visitor.VisitorContext; + +public class MyVisitor3 implements TypeElementVisitor { + + @Override + public void visitClass(ClassElement element, VisitorContext context) { + MyVisitor1.ORDER.add(getClass().getSimpleName() + " " + element.getName()); + } + + @Override + public int getOrder() { + return 3; + } +} diff --git a/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/VisitMyAnnotation.java b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/VisitMyAnnotation.java new file mode 100644 index 00000000000..a5d7708b581 --- /dev/null +++ b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/VisitMyAnnotation.java @@ -0,0 +1,28 @@ +/* + * Copyright 2017-2020 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.kotlin.processing.visitor.order; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD}) +public @interface VisitMyAnnotation { +} diff --git a/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/VisitorOrderSpec.groovy b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/VisitorOrderSpec.groovy new file mode 100644 index 00000000000..d7d35794aca --- /dev/null +++ b/inject-kotlin/src/test/groovy/io/micronaut/kotlin/processing/visitor/order/VisitorOrderSpec.groovy @@ -0,0 +1,30 @@ +package io.micronaut.kotlin.processing.visitor.order + +import io.micronaut.annotation.processing.test.AbstractKotlinCompilerSpec + +class VisitorOrderSpec extends AbstractKotlinCompilerSpec { + + void 'test annotating'() { + when: + buildBeanDefinition('vis.MyBean1', ''' +package vis + +import io.micronaut.kotlin.processing.visitor.order.VisitMyAnnotation + +@VisitMyAnnotation +class MyBean1 + +@VisitMyAnnotation +class MyBean2 + +@VisitMyAnnotation +class MyBean3 + +''') + then: + MyVisitor1.ORDER == ["MyVisitor3 vis.MyBean1", "MyVisitor3 vis.MyBean2", "MyVisitor3 vis.MyBean3", + "MyVisitor2 vis.MyBean1", "MyVisitor2 vis.MyBean2", "MyVisitor2 vis.MyBean3", + "MyVisitor1 vis.MyBean1", "MyVisitor1 vis.MyBean2", "MyVisitor1 vis.MyBean3"] + } + +} diff --git a/inject-kotlin/src/test/resources/META-INF/services/io.micronaut.inject.visitor.TypeElementVisitor b/inject-kotlin/src/test/resources/META-INF/services/io.micronaut.inject.visitor.TypeElementVisitor index 46102e6a19c..2f9805ec01c 100644 --- a/inject-kotlin/src/test/resources/META-INF/services/io.micronaut.inject.visitor.TypeElementVisitor +++ b/inject-kotlin/src/test/resources/META-INF/services/io.micronaut.inject.visitor.TypeElementVisitor @@ -5,3 +5,6 @@ io.micronaut.kotlin.processing.annotations.AnnotateMethodParameterSpec$AnnotateM io.micronaut.kotlin.processing.annotations.AnnotateMethodReturnSpec$AnnotateMethodReturnVisitor io.micronaut.kotlin.processing.annotations.AnnotateMethodSpec$AnnotationMethodVisitor io.micronaut.kotlin.processing.annotations.AnnotatePropertySpec$AnnotatePropertyVisitor +io.micronaut.kotlin.processing.visitor.order.MyVisitor1 +io.micronaut.kotlin.processing.visitor.order.MyVisitor2 +io.micronaut.kotlin.processing.visitor.order.MyVisitor3