From 76c9fb28bd5a0e5744c854d0c026f4b94844962b Mon Sep 17 00:00:00 2001 From: Alex Semin Date: Thu, 25 Apr 2024 17:25:34 +0200 Subject: [PATCH 1/3] Fix formatting --- .../problems/ConfigurationCacheProblems.kt | 2 ++ .../gradle/configurationcache/problems/PropertyProblem.kt | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt index 88a8724bd003..42168537d0df 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt @@ -55,6 +55,7 @@ class ConfigurationCacheProblems( val listenerManager: ListenerManager ) : ProblemsListener, ProblemReporter, AutoCloseable { + private val summarizer = ConfigurationCacheProblemsSummary() @@ -192,6 +193,7 @@ class ConfigurationCacheProblems( val log: (String) -> Unit = if (logReportAsInfo) logger::info else logger::warn log(summary.textForConsole(cacheActionText, htmlReportFile)) } + else -> validationFailures.accept(failure) } } diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt index dd926e4f6a7b..155dd5c9f7a7 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt @@ -175,27 +175,32 @@ sealed class PropertyTrace { is Gradle -> { append("Gradle runtime") } + is Property -> { append(trace.kind) append(" ") quoted(trace.name) append(" of ") } + is SystemProperty -> { append("system property ") quoted(trace.name) append(" set at ") } + is Bean -> { quoted(trace.type.name) append(" bean found in ") } + is Task -> { append("task ") quoted(trace.path) append(" of type ") quoted(trace.type.name) } + is BuildLogic -> { append(trace.source.displayName) trace.lineNumber?.let { @@ -203,13 +208,16 @@ sealed class PropertyTrace { append(it) } } + is BuildLogicClass -> { append("class ") quoted(trace.name) } + is Unknown -> { append("unknown location") } + is Project -> { append("project ") quoted(trace.path) From 6d44ee28c6e9d7f5cd2e3bc5b3a88cc72d88df1b Mon Sep 17 00:00:00 2001 From: Alex Semin Date: Thu, 25 Apr 2024 17:47:18 +0200 Subject: [PATCH 2/3] Expose Failure on ProblemDiagnostics --- .../problems/DefaultProblemDiagnosticsFactory.java | 14 ++++++++++++-- .../problems/NoOpProblemDiagnosticsFactory.java | 7 +++++++ .../org/gradle/problems/ProblemDiagnostics.java | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/DefaultProblemDiagnosticsFactory.java b/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/DefaultProblemDiagnosticsFactory.java index 46cf746d24eb..ad31f9dec05b 100644 --- a/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/DefaultProblemDiagnosticsFactory.java +++ b/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/DefaultProblemDiagnosticsFactory.java @@ -106,15 +106,16 @@ private ProblemDiagnostics locationFromStackTrace(@Nullable Throwable throwable, } List stackTrace = Collections.emptyList(); + Failure stackTracingFailure = null; Location location = null; if (throwable != null) { stackTrace = transformer.transform(throwable.getStackTrace()); - Failure stackTracingFailure = failureFactory.create(throwable); + stackTracingFailure = failureFactory.create(throwable); location = locationAnalyzer.locationForUsage(stackTracingFailure, fromException); } UserCodeSource source = applicationContext != null ? applicationContext.getSource() : null; - return new DefaultProblemDiagnostics(keepException ? throwable : null, stackTrace, location, source); + return new DefaultProblemDiagnostics(stackTracingFailure, keepException ? throwable : null, stackTrace, location, source); } @NonNullApi @@ -160,23 +161,32 @@ private Throwable getImplicitThrowable(Supplier factory) { } private static class DefaultProblemDiagnostics implements ProblemDiagnostics { + private final Failure failure; private final Throwable exception; private final List stackTrace; private final Location location; private final UserCodeSource source; public DefaultProblemDiagnostics( + @Nullable Failure stackTracingFailure, @Nullable Throwable exception, List stackTrace, @Nullable Location location, @Nullable UserCodeSource source ) { + this.failure = stackTracingFailure; this.exception = exception; this.stackTrace = stackTrace; this.location = location; this.source = source; } + @Nullable + @Override + public Failure getFailure() { + return failure; + } + @Nullable @Override public Throwable getException() { diff --git a/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/NoOpProblemDiagnosticsFactory.java b/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/NoOpProblemDiagnosticsFactory.java index 429cc7aa4e28..ddeb13c28df3 100644 --- a/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/NoOpProblemDiagnosticsFactory.java +++ b/platforms/ide/problems-api/src/main/java/org/gradle/internal/problems/NoOpProblemDiagnosticsFactory.java @@ -18,6 +18,7 @@ import com.google.common.base.Supplier; import org.gradle.internal.code.UserCodeSource; +import org.gradle.internal.problems.failure.Failure; import org.gradle.problems.Location; import org.gradle.problems.ProblemDiagnostics; import org.gradle.problems.buildtree.ProblemDiagnosticsFactory; @@ -29,6 +30,12 @@ public class NoOpProblemDiagnosticsFactory implements ProblemDiagnosticsFactory { public static final ProblemDiagnostics EMPTY_DIAGNOSTICS = new ProblemDiagnostics() { + @Nullable + @Override + public Failure getFailure() { + return null; + } + @Nullable @Override public Throwable getException() { diff --git a/platforms/ide/problems-api/src/main/java/org/gradle/problems/ProblemDiagnostics.java b/platforms/ide/problems-api/src/main/java/org/gradle/problems/ProblemDiagnostics.java index 09ee6cf26d98..633bd5d2b73a 100644 --- a/platforms/ide/problems-api/src/main/java/org/gradle/problems/ProblemDiagnostics.java +++ b/platforms/ide/problems-api/src/main/java/org/gradle/problems/ProblemDiagnostics.java @@ -17,6 +17,7 @@ package org.gradle.problems; import org.gradle.internal.code.UserCodeSource; +import org.gradle.internal.problems.failure.Failure; import javax.annotation.Nullable; import java.util.List; @@ -25,6 +26,19 @@ * An immutable set of diagnostic information for a problem. */ public interface ProblemDiagnostics { + + /** + * A stack tracing failure associated with the problem. + *

+ * Usually, if the problem was caused by an exception, the failure would correspond to that exception. + * However, problems that are registered explicitly (e.g. deprecation warnings) will not have an associated exception. + * In this case, the failure can be synthetic to provide the stack trace for the problem origin. + *

+ * The failure can also be omitted due to limits. Its absence does not mean there was no exception causing the problem. + */ + @Nullable + Failure getFailure(); + /** * Returns an exception that can be thrown when this problem should result in an error. * From 70f2748062fea00495b92c0d339794cab23e1896 Mon Sep 17 00:00:00 2001 From: Alex Semin Date: Thu, 25 Apr 2024 17:47:48 +0200 Subject: [PATCH 3/3] Include stack tracing failure for PropertyProblem --- .../ConfigurationCacheFingerprintWriter.kt | 1 - ...cheInjectedClasspathInstrumentationStrategy.kt | 3 +-- .../problems/ConfigurationCacheProblems.kt | 9 +++++++-- .../problems/ConfigurationCacheReport.kt | 9 ++------- .../problems/DecoratedPropertyProblem.kt | 15 ++++++++++----- .../problems/DefaultProblemFactory.kt | 10 ++++++---- .../problems/PropertyProblem.kt | 6 ++++++ .../configurationcache/serialization/Logging.kt | 7 +++---- 8 files changed, 35 insertions(+), 25 deletions(-) diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/fingerprint/ConfigurationCacheFingerprintWriter.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/fingerprint/ConfigurationCacheFingerprintWriter.kt index ea8a2c20fa0b..6f34dc484e4e 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/fingerprint/ConfigurationCacheFingerprintWriter.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/fingerprint/ConfigurationCacheFingerprintWriter.kt @@ -773,7 +773,6 @@ class ConfigurationCacheFingerprintWriter( PropertyProblem( trace, StructuredMessage.build(messageBuilder), - null, documentationSection = documentationSection ) ) diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/initialization/ConfigurationCacheInjectedClasspathInstrumentationStrategy.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/initialization/ConfigurationCacheInjectedClasspathInstrumentationStrategy.kt index 3f8c25a88e32..1abe4ee690ac 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/initialization/ConfigurationCacheInjectedClasspathInstrumentationStrategy.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/initialization/ConfigurationCacheInjectedClasspathInstrumentationStrategy.kt @@ -33,8 +33,7 @@ class ConfigurationCacheInjectedClasspathInstrumentationStrategy( PropertyProblem( PropertyTrace.Gradle, StructuredMessage.build { text("support for using a Java agent with TestKit builds is not yet implemented with the configuration cache.") }, - null, - DocumentationSection.NotYetImplementedTestKitJavaAgent + documentationSection = DocumentationSection.NotYetImplementedTestKitJavaAgent ) ) return CachedClasspathTransformer.StandardTransform.BuildLogic diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt index 42168537d0df..a6f8c4a0863f 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheProblems.kt @@ -31,6 +31,7 @@ import org.gradle.configurationcache.initialization.ConfigurationCacheStartParam import org.gradle.initialization.RootBuildLifecycleListener import org.gradle.internal.InternalBuildAdapter import org.gradle.internal.event.ListenerManager +import org.gradle.internal.problems.failure.FailureFactory import org.gradle.internal.service.scopes.Scope import org.gradle.internal.service.scopes.ServiceScope import org.gradle.problems.buildtree.ProblemReporter @@ -52,7 +53,10 @@ class ConfigurationCacheProblems( val cacheKey: ConfigurationCacheKey, private - val listenerManager: ListenerManager + val listenerManager: ListenerManager, + + private + val failureFactory: FailureFactory ) : ProblemsListener, ProblemReporter, AutoCloseable { @@ -130,7 +134,8 @@ class ConfigurationCacheProblems( } override fun onError(trace: PropertyTrace, error: Exception, message: StructuredMessageBuilder) { - onProblem(PropertyProblem(trace, StructuredMessage.build(message), error)) + val failure = failureFactory.create(error) + onProblem(PropertyProblem(trace, StructuredMessage.build(message), error, failure)) } } } diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheReport.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheReport.kt index 3f443cef416c..c7680977ca29 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheReport.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/ConfigurationCacheReport.kt @@ -27,7 +27,6 @@ import org.gradle.internal.hash.HashCode import org.gradle.internal.hash.Hashing import org.gradle.internal.hash.HashingOutputStream import org.gradle.internal.problems.failure.Failure -import org.gradle.internal.problems.failure.FailureFactory import org.gradle.internal.service.scopes.Scope import org.gradle.internal.service.scopes.ServiceScope import java.io.Closeable @@ -42,8 +41,7 @@ import kotlin.contracts.contract class ConfigurationCacheReport( executorFactory: ExecutorFactory, temporaryFileProvider: TemporaryFileProvider, - internalOptions: InternalOptions, - private val failureFactory: FailureFactory + internalOptions: InternalOptions ) : Closeable { companion object { @@ -229,7 +227,7 @@ class ConfigurationCacheReport( private fun decorateProblem(problem: PropertyProblem, severity: ProblemSeverity): DecoratedPropertyProblem { - val failure = problem.exception?.toFailure() + val failure = problem.stackTracingFailure return DecoratedPropertyProblem( problem.trace, decorateMessage(problem, failure), @@ -238,9 +236,6 @@ class ConfigurationCacheReport( ) } - private - fun Throwable.toFailure() = failureFactory.create(this) - private fun decoratedFailureFor(failure: Failure?, severity: ProblemSeverity): DecoratedFailure? { return when { diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DecoratedPropertyProblem.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DecoratedPropertyProblem.kt index 85f60a62b6ec..cc830a7260f3 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DecoratedPropertyProblem.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DecoratedPropertyProblem.kt @@ -75,9 +75,14 @@ class FailureDecorator { private fun exceptionSummaryFor(failure: Failure): StructuredMessage? { - failure.stackTrace.forEachIndexed { index, element -> - if (failure.getStackTraceRelevance(index).isUserCode()) { - return exceptionSummaryFrom(element) + return failure.findFirstUserCode()?.let(::exceptionSummaryFrom) + } + + private + fun Failure.findFirstUserCode(): StackTraceElement? { + stackTrace.forEachIndexed { index, element -> + if (getStackTraceRelevance(index).isUserCode()) { + return element } } @@ -85,9 +90,9 @@ class FailureDecorator { } private - fun exceptionSummaryFrom(elem: StackTraceElement) = StructuredMessage.build { + fun exceptionSummaryFrom(frame: StackTraceElement) = StructuredMessage.build { text("at ") - reference(elem.toString()) + reference(frame.toString()) } private diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DefaultProblemFactory.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DefaultProblemFactory.kt index 6675da4e5336..6d08d8ff7b59 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DefaultProblemFactory.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/DefaultProblemFactory.kt @@ -36,8 +36,9 @@ class DefaultProblemFactory( locationForCaller(consumer, userCodeContext.current()?.source) override fun problem(message: StructuredMessage, exception: Throwable?, documentationSection: DocumentationSection?): PropertyProblem { - val trace = locationForCaller(null, problemStream.forCurrentCaller(exception)) - return PropertyProblem(trace, message, exception, documentationSection) + val diagnostics = problemStream.forCurrentCaller(exception) + val trace = locationForCaller(null, diagnostics) + return PropertyProblem(trace, message, exception, diagnostics.failure, documentationSection) } override fun problem(consumer: String?, messageBuilder: StructuredMessage.Builder.() -> Unit): ProblemFactory.Builder { @@ -73,13 +74,14 @@ class DefaultProblemFactory( } override fun build(): PropertyProblem { + val exceptionMessage = exceptionMessage val diagnostics = if (exceptionMessage == null) { problemStream.forCurrentCaller() } else { - problemStream.forCurrentCaller(Supplier { InvalidUserCodeException(exceptionMessage!!) }) + problemStream.forCurrentCaller(Supplier { InvalidUserCodeException(exceptionMessage) }) } val location = locationMapper(locationForCaller(consumer, diagnostics)) - return PropertyProblem(location, message, diagnostics.exception, documentationSection) + return PropertyProblem(location, message, diagnostics.exception, diagnostics.failure, documentationSection) } } } diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt index 155dd5c9f7a7..7dee54d65fab 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/problems/PropertyProblem.kt @@ -17,6 +17,7 @@ package org.gradle.configurationcache.problems import org.gradle.internal.DisplayName +import org.gradle.internal.problems.failure.Failure import kotlin.reflect.KClass @@ -27,6 +28,11 @@ data class PropertyProblem internal constructor( val trace: PropertyTrace, val message: StructuredMessage, val exception: Throwable? = null, + /** + * A failure containing stack tracing information. + * The failure may be synthetic when the cause of the problem was not an exception. + */ + val stackTracingFailure: Failure? = null, val documentationSection: DocumentationSection? = null ) diff --git a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/serialization/Logging.kt b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/serialization/Logging.kt index f4498e39456a..e1230372d3fc 100644 --- a/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/serialization/Logging.kt +++ b/platforms/core-configuration/configuration-cache/src/main/kotlin/org/gradle/configurationcache/serialization/Logging.kt @@ -31,11 +31,10 @@ import kotlin.reflect.KClass fun IsolateContext.logPropertyProblem( action: String, - exception: Throwable? = null, documentationSection: DocumentationSection? = null, message: StructuredMessageBuilder ) { - logPropertyProblem(action, PropertyProblem(trace, build(message), exception, documentationSection)) + logPropertyProblem(action, PropertyProblem(trace, build(message), documentationSection = documentationSection)) } @@ -108,7 +107,7 @@ fun IsolateContext.logNotImplemented(feature: String, documentationSection: Docu build { text("support for $feature is not yet implemented with the configuration cache.") }, - null, documentationSection + documentationSection = documentationSection ) ) } @@ -116,7 +115,7 @@ fun IsolateContext.logNotImplemented(feature: String, documentationSection: Docu private fun IsolateContext.logPropertyProblem(documentationSection: DocumentationSection? = null, message: StructuredMessageBuilder) { - val problem = PropertyProblem(trace, build(message), null, documentationSection) + val problem = PropertyProblem(trace, build(message), documentationSection = documentationSection) logPropertyProblem("serialize", problem) }