diff --git a/core/src/com/google/inject/spi/Elements.java b/core/src/com/google/inject/spi/Elements.java index a7fe1358d1..2497664bcb 100644 --- a/core/src/com/google/inject/spi/Elements.java +++ b/core/src/com/google/inject/spi/Elements.java @@ -669,7 +669,17 @@ private ElementSource getElementSource() { if (stackTraceOption == IncludeStackTraceOption.COMPLETE || stackTraceOption == IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE) { // With the above conditions and assignments 'callStack' is non-null - declaringSource = sourceProvider.get(callStack); + StackTraceElement callingSource = sourceProvider.get(callStack); + // If we've traversed past all reasonable sources and into our internal code, then we + // don't know the source. + if (callingSource + .getClassName() + .equals("com.google.inject.internal.InjectorShell$Builder") + && callingSource.getMethodName().equals("build")) { + declaringSource = SourceProvider.UNKNOWN_SOURCE; + } else { + declaringSource = callingSource; + } } else { // or if (stackTraceOption == IncludeStackTraceOptions.OFF) // As neither 'declaring source' nor 'call stack' is available use 'module source' declaringSource = sourceProvider.getFromClassNames(moduleSource.getModuleClassNames()); diff --git a/core/test/com/google/inject/spi/SourcesTest.java b/core/test/com/google/inject/spi/SourcesTest.java new file mode 100644 index 0000000000..42ffc6ff12 --- /dev/null +++ b/core/test/com/google/inject/spi/SourcesTest.java @@ -0,0 +1,47 @@ +package com.google.inject.spi; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Module; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests sources are set correctly in elements. */ +@RunWith(JUnit4.class) +public final class SourcesTest { + + @Test + public void entirelyFilteredSourceShowsAsUnknown() { + ElementSource source = + (ElementSource) + Guice.createInjector( + new AbstractModule() { + @Override + protected void configure() { + binder().skipSources(getClass()).bind(String.class).toInstance("Foo"); + } + }) + .getBinding(String.class) + .getSource(); + assertThat(source.getDeclaringSource()).isEqualTo("[unknown source]"); + } + + @Test + public void unfilteredShowsCorrectly() { + Module m = + new AbstractModule() { + @Override + protected void configure() { + binder().bind(String.class).toInstance("Foo"); + } + }; + ElementSource source = + (ElementSource) Guice.createInjector(m).getBinding(String.class).getSource(); + StackTraceElement ste = (StackTraceElement) source.getDeclaringSource(); + assertThat(ste.getClassName()).isEqualTo(m.getClass().getName()); + assertThat(ste.getMethodName()).isEqualTo("configure"); + } +}