diff --git a/platforms/core-configuration/model-core/src/main/java/org/gradle/internal/instantiation/generator/AbstractClassGenerator.java b/platforms/core-configuration/model-core/src/main/java/org/gradle/internal/instantiation/generator/AbstractClassGenerator.java index bd0556c1906c..2ec62bf95993 100644 --- a/platforms/core-configuration/model-core/src/main/java/org/gradle/internal/instantiation/generator/AbstractClassGenerator.java +++ b/platforms/core-configuration/model-core/src/main/java/org/gradle/internal/instantiation/generator/AbstractClassGenerator.java @@ -1291,9 +1291,9 @@ private void validateMethod(Method method, PropertyAccessorType accessorType, Cl TreeFormatter formatter = new TreeFormatter(); formatter.node("Cannot use "); formatter.appendAnnotation(annotationType); - formatter.append(" annotation on property "); - formatter.appendMethod(method); - formatter.append(" of type "); + formatter.append(" annotation on property '"); + formatter.append(accessorType.propertyNameFor(method)); + formatter.append("' of type "); formatter.append(TypeToken.of(returnType).toString()); formatter.append(". Allowed property types: "); formatter.append(allowedTypes.stream() diff --git a/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorInjectDecoratedTest.groovy b/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorInjectDecoratedTest.groovy index 84441433da68..7b31fb512c08 100644 --- a/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorInjectDecoratedTest.groovy +++ b/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorInjectDecoratedTest.groovy @@ -268,7 +268,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @Inject and @CustomInject annotations together on method MultipleInjectAnnotations.getBoth()." + e.cause.message == "Cannot use @Inject and @CustomInject annotations together on method MultipleInjectAnnotations.getBoth(): Number." } def "object can provide its own service registry to provide services for injection"() { @@ -290,7 +290,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @Inject annotation on method ExtensibleBeanWithInject.getExtensions()." + e.cause.message == "Cannot use @Inject annotation on method ExtensibleBeanWithInject.getExtensions(): ExtensionContainer." } def "cannot attach @Inject annotation to final method"() { @@ -299,7 +299,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @Inject annotation on method FinalInjectBean.getThing() as it is final." + e.cause.message == "Cannot use @Inject annotation on method FinalInjectBean.getThing(): Number as it is final." } def "cannot attach @Inject annotation to static method"() { @@ -308,7 +308,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @Inject annotation on method StaticInjectBean.getThing() as it is static." + e.cause.message == "Cannot use @Inject annotation on method StaticInjectBean.getThing(): Number as it is static." } def "cannot attach @Inject annotation to private method"() { @@ -317,7 +317,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @Inject annotation on method PrivateInjectBean.getThing() as it is not public or protected." + e.cause.message == "Cannot use @Inject annotation on method PrivateInjectBean.getThing(): Number as it is not public or protected." } def "cannot attach @Inject annotation to non getter method"() { @@ -326,7 +326,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @Inject annotation on method NonGetterInjectBean.thing() as it is not a property getter." + e.cause.message == "Cannot use @Inject annotation on method NonGetterInjectBean.thing(): Number as it is not a property getter." } def "cannot attach custom annotation that is known but not enabled to getter method"() { @@ -337,7 +337,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @CustomInject annotation on method BeanWithCustomServices.getThing()." + e.cause.message == "Cannot use @CustomInject annotation on method BeanWithCustomServices.getThing(): Number." } def "cannot attach custom annotation that is known but not enabled to static method"() { @@ -348,7 +348,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @CustomInject annotation on method StaticCustomInjectBean.getThing()." + e.cause.message == "Cannot use @CustomInject annotation on method StaticCustomInjectBean.getThing(): Number." } def "cannot attach custom inject annotation to methods of ExtensionAware"() { @@ -359,7 +359,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @CustomInject annotation on method ExtensibleBeanWithCustomInject.getExtensions()." + e.cause.message == "Cannot use @CustomInject annotation on method ExtensibleBeanWithCustomInject.getExtensions(): ExtensionContainer." } def "cannot attach custom inject annotation to static method"() { @@ -371,7 +371,7 @@ class AsmBackedClassGeneratorInjectDecoratedTest extends AbstractClassGeneratorS then: def e = thrown(ClassGenerationException) - e.cause.message == "Cannot use @CustomInject annotation on method StaticCustomInjectBean.getThing() as it is static." + e.cause.message == "Cannot use @CustomInject annotation on method StaticCustomInjectBean.getThing(): Number as it is static." } } diff --git a/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorTest.java b/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorTest.java index 5cab8061adca..8ec8bf31bdcf 100644 --- a/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorTest.java +++ b/platforms/core-configuration/model-core/src/test/groovy/org/gradle/internal/instantiation/generator/AsmBackedClassGeneratorTest.java @@ -504,7 +504,7 @@ public void cannotCreateInstanceOfClassWithAbstractGetter() throws Exception { fail(); } catch (ClassGenerationException e) { assertThat(e.getMessage(), equalTo("Could not generate a decorated class for type AsmBackedClassGeneratorTest.AbstractGetterBean.")); - assertThat(e.getCause().getMessage(), equalTo("Cannot have abstract method AbstractGetterBean.getThing().")); + assertThat(e.getCause().getMessage(), equalTo("Cannot have abstract method AbstractGetterBean.getThing(): String.")); } } @@ -538,7 +538,18 @@ public void cannotCreateInstanceOfInterfaceWithAbstractGetterAndNoSetter() throw fail(); } catch (ClassGenerationException e) { assertThat(e.getMessage(), equalTo("Could not generate a decorated class for type AsmBackedClassGeneratorTest.GetterBeanInterface.")); - assertThat(e.getCause().getMessage(), equalTo("Cannot have abstract method GetterBeanInterface.getThing().")); + assertThat(e.getCause().getMessage(), equalTo("Cannot have abstract method GetterBeanInterface.getThing(): String.")); + } + } + + @Test + public void cannotCreateInstanceOfInterfaceWithAbstractGetterAndNoSetterWithGenericParam() throws Exception { + try { + newInstance(GetterBeanGenericInterface.class); + fail(); + } catch (ClassGenerationException e) { + assertThat(e.getMessage(), equalTo("Could not generate a decorated class for type AsmBackedClassGeneratorTest.GetterBeanGenericInterface.")); + assertThat(e.getCause().getMessage(), equalTo("Cannot have abstract method GetterBeanGenericInterface.getThing(): Provider.")); } } @@ -1742,6 +1753,10 @@ public interface GetterBeanInterface { String getThing(); } + public interface GetterBeanGenericInterface { + Provider getThing(); + } + public interface SetterBeanInterface { void setThing(String value); } diff --git a/platforms/core-runtime/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java b/platforms/core-runtime/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java index 72709d51a96b..9fe8cbff006e 100644 --- a/platforms/core-runtime/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java +++ b/platforms/core-runtime/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java @@ -184,6 +184,10 @@ public TreeFormatter appendMethod(Method method) { } } append(")"); + if (!method.getReturnType().equals(Void.TYPE)) { + append(": "); + appendType(method.getGenericReturnType()); + } return this; } diff --git a/platforms/core-runtime/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy b/platforms/core-runtime/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy index 0e2aeded8029..39ddc7cf7191 100644 --- a/platforms/core-runtime/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy +++ b/platforms/core-runtime/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy @@ -358,9 +358,11 @@ Some thing.''') formatter.appendMethod(String.getMethod("charAt", int.class)) formatter.append(" ") formatter.appendMethod(String.getMethod("getBytes", String.class)) + formatter.append(" ") + formatter.appendMethod(String.getMethod("getClass")) then: - formatter.toString() == toPlatformLineSeparators("thing String.length() String.charAt(int) String.getBytes(String)") + formatter.toString() == toPlatformLineSeparators("thing String.length(): int String.charAt(int): char String.getBytes(String): byte[] Object.getClass(): Class") } def "can append annoation name"() { diff --git a/platforms/software/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/transform/ArtifactTransformValuesInjectionIntegrationTest.groovy b/platforms/software/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/transform/ArtifactTransformValuesInjectionIntegrationTest.groovy index 59534493897d..9d8f9624d3f4 100644 --- a/platforms/software/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/transform/ArtifactTransformValuesInjectionIntegrationTest.groovy +++ b/platforms/software/dependency-management/src/integTest/groovy/org/gradle/integtests/resolve/transform/ArtifactTransformValuesInjectionIntegrationTest.groovy @@ -620,7 +620,7 @@ class ArtifactTransformValuesInjectionIntegrationTest extends AbstractDependency failure.assertHasDescription('A problem occurred evaluating root project') failure.assertHasCause('Could not create an instance of type MakeGreen$Parameters.') failure.assertHasCause('Could not generate a decorated class for type MakeGreen.Parameters.') - failure.assertHasCause("Cannot use @${annotation.simpleName} annotation on method Parameters.getBad().") + failure.assertHasCause("Cannot use @${annotation.simpleName} annotation on method Parameters.getBad(): String.") where: annotation << [InputArtifact, InputArtifactDependencies] @@ -894,7 +894,7 @@ class ArtifactTransformValuesInjectionIntegrationTest extends AbstractDependency then: failure.assertHasDescription("A problem occurred evaluating root project") failure.assertHasCause("Could not register artifact transform MakeGreen (from {color=blue} to {color=green})") - failure.assertHasCause("Cannot use @InputArtifact annotation on property MakeGreen.getInput() of type ${typeName}. Allowed property types: org.gradle.api.provider.Provider.") + failure.assertHasCause("Cannot use @InputArtifact annotation on property 'input' of type ${typeName}. Allowed property types: org.gradle.api.provider.Provider.") where: propertyType << [ @@ -935,7 +935,7 @@ class ArtifactTransformValuesInjectionIntegrationTest extends AbstractDependency then: failure.assertHasDescription("A problem occurred evaluating root project") failure.assertHasCause("Could not register artifact transform MakeGreen (from {color=blue} to {color=green})") - failure.assertHasCause("Cannot use @InputArtifactDependencies annotation on property MakeGreen.getDependencies() of type ${propertyType.name}. Allowed property types: org.gradle.api.file.FileCollection.") + failure.assertHasCause("Cannot use @InputArtifactDependencies annotation on property 'dependencies' of type ${propertyType.name}. Allowed property types: org.gradle.api.file.FileCollection.") where: annotation | propertyType @@ -1041,7 +1041,7 @@ class ArtifactTransformValuesInjectionIntegrationTest extends AbstractDependency failure.assertHasDescription("A problem occurred evaluating root project") failure.assertHasCause("Could not create task of type 'MyTask'.") failure.assertHasCause("Could not generate a decorated class for type MyTask.") - failure.assertHasCause("Cannot use @${annotation.simpleName} annotation on method MyTask.getThing().") + failure.assertHasCause("Cannot use @${annotation.simpleName} annotation on method MyTask.getThing(): File.") where: annotation << [InputArtifact, InputArtifactDependencies] diff --git a/subprojects/core/src/integTest/groovy/org/gradle/api/internal/model/ObjectFactoryIntegrationTest.groovy b/subprojects/core/src/integTest/groovy/org/gradle/api/internal/model/ObjectFactoryIntegrationTest.groovy index e95ec0a061f7..0dea49ac09ad 100644 --- a/subprojects/core/src/integTest/groovy/org/gradle/api/internal/model/ObjectFactoryIntegrationTest.groovy +++ b/subprojects/core/src/integTest/groovy/org/gradle/api/internal/model/ObjectFactoryIntegrationTest.groovy @@ -229,7 +229,7 @@ class ObjectFactoryIntegrationTest extends AbstractIntegrationSpec { fails() failure.assertHasCause("Could not create an instance of type Thing.") failure.assertHasCause("Could not generate a decorated class for type Thing.") - failure.assertHasCause("Cannot have abstract method Thing.getProp().") + failure.assertHasCause("Cannot have abstract method Thing.getProp(): String.") } def "services are injected into instances using constructor or getter"() { diff --git a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskServiceInjectionIntegrationTest.groovy b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskServiceInjectionIntegrationTest.groovy index e822e307acaa..75bea2cc6122 100644 --- a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskServiceInjectionIntegrationTest.groovy +++ b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskServiceInjectionIntegrationTest.groovy @@ -189,7 +189,7 @@ class TaskServiceInjectionIntegrationTest extends AbstractIntegrationSpec { then: failure.assertHasCause("Could not create task ':myTask'.") failure.assertHasCause("Could not create task of type 'CustomTask'.") - failure.assertHasCause("Cannot use @Inject annotation on method CustomTask.getExecutor() as it is not public or protected.") + failure.assertHasCause("Cannot use @Inject annotation on method CustomTask.getExecutor(): WorkerExecutor as it is not public or protected.") } def "can construct a task in Kotlin with @Inject services constructor arg"() {