PageRenderTime 32ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/spice-inject/guice-patches/vanilla.src/com/google/inject/internal/Errors.java

https://github.com/peterlynch/spice
Java | 698 lines | 510 code | 121 blank | 67 comment | 77 complexity | dd54a893c8a610db928f76b98647eea1 MD5 | raw file
  1. /**
  2. * Copyright (C) 2006 Google Inc.
  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. * http://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 com.google.inject.internal;
  17. import com.google.inject.ConfigurationException;
  18. import com.google.inject.CreationException;
  19. import com.google.inject.Key;
  20. import com.google.inject.MembersInjector;
  21. import com.google.inject.Provider;
  22. import com.google.inject.ProvisionException;
  23. import com.google.inject.Scope;
  24. import com.google.inject.TypeLiteral;
  25. import com.google.inject.internal.util.ImmutableList;
  26. import com.google.inject.internal.util.ImmutableSet;
  27. import com.google.inject.internal.util.Lists;
  28. import com.google.inject.internal.util.SourceProvider;
  29. import com.google.inject.internal.util.StackTraceElements;
  30. import com.google.inject.spi.Dependency;
  31. import com.google.inject.spi.InjectionListener;
  32. import com.google.inject.spi.InjectionPoint;
  33. import com.google.inject.spi.Message;
  34. import com.google.inject.spi.TypeListenerBinding;
  35. import java.io.PrintWriter;
  36. import java.io.Serializable;
  37. import java.io.StringWriter;
  38. import java.lang.annotation.Annotation;
  39. import java.lang.reflect.Constructor;
  40. import java.lang.reflect.Field;
  41. import java.lang.reflect.Member;
  42. import java.lang.reflect.Method;
  43. import java.lang.reflect.Type;
  44. import java.util.Collection;
  45. import java.util.Collections;
  46. import java.util.Comparator;
  47. import java.util.Formatter;
  48. import java.util.List;
  49. /**
  50. * A collection of error messages. If this type is passed as a method parameter, the method is
  51. * considered to have executed succesfully only if new errors were not added to this collection.
  52. *
  53. * <p>Errors can be chained to provide additional context. To add context, call {@link #withSource}
  54. * to create a new Errors instance that contains additional context. All messages added to the
  55. * returned instance will contain full context.
  56. *
  57. * <p>To avoid messages with redundant context, {@link #withSource} should be added sparingly. A
  58. * good rule of thumb is to assume a ethod's caller has already specified enough context to
  59. * identify that method. When calling a method that's defined in a different context, call that
  60. * method with an errors object that includes its context.
  61. *
  62. * @author jessewilson@google.com (Jesse Wilson)
  63. */
  64. public final class Errors implements Serializable {
  65. /**
  66. * The root errors object. Used to access the list of error messages.
  67. */
  68. private final Errors root;
  69. /**
  70. * The parent errors object. Used to obtain the chain of source objects.
  71. */
  72. private final Errors parent;
  73. /**
  74. * The leaf source for errors added here.
  75. */
  76. private final Object source;
  77. /**
  78. * null unless (root == this) and error messages exist. Never an empty list.
  79. */
  80. private List<Message> errors; // lazy, use getErrorsForAdd()
  81. public Errors() {
  82. this.root = this;
  83. this.parent = null;
  84. this.source = SourceProvider.UNKNOWN_SOURCE;
  85. }
  86. public Errors(Object source) {
  87. this.root = this;
  88. this.parent = null;
  89. this.source = source;
  90. }
  91. private Errors(Errors parent, Object source) {
  92. this.root = parent.root;
  93. this.parent = parent;
  94. this.source = source;
  95. }
  96. /**
  97. * Returns an instance that uses {@code source} as a reference point for newly added errors.
  98. */
  99. public Errors withSource(Object source) {
  100. return source == SourceProvider.UNKNOWN_SOURCE
  101. ? this
  102. : new Errors(this, source);
  103. }
  104. /**
  105. * We use a fairly generic error message here. The motivation is to share the
  106. * same message for both bind time errors:
  107. * <pre><code>Guice.createInjector(new AbstractModule() {
  108. * public void configure() {
  109. * bind(Runnable.class);
  110. * }
  111. * }</code></pre>
  112. * ...and at provide-time errors:
  113. * <pre><code>Guice.createInjector().getInstance(Runnable.class);</code></pre>
  114. * Otherwise we need to know who's calling when resolving a just-in-time
  115. * binding, which makes things unnecessarily complex.
  116. */
  117. public Errors missingImplementation(Key key) {
  118. return addMessage("No implementation for %s was bound.", key);
  119. }
  120. public Errors jitDisabled(Key key) {
  121. return addMessage("Explicit bindings are required and %s is not explicitly bound.", key);
  122. }
  123. public Errors converterReturnedNull(String stringValue, Object source,
  124. TypeLiteral<?> type, MatcherAndConverter matchingConverter) {
  125. return addMessage("Received null converting '%s' (bound at %s) to %s%n"
  126. + " using %s.",
  127. stringValue, convert(source), type, matchingConverter);
  128. }
  129. public Errors conversionTypeError(String stringValue, Object source, TypeLiteral<?> type,
  130. MatcherAndConverter matchingConverter, Object converted) {
  131. return addMessage("Type mismatch converting '%s' (bound at %s) to %s%n"
  132. + " using %s.%n"
  133. + " Converter returned %s.",
  134. stringValue, convert(source), type, matchingConverter, converted);
  135. }
  136. public Errors conversionError(String stringValue, Object source,
  137. TypeLiteral<?> type, MatcherAndConverter matchingConverter, RuntimeException cause) {
  138. return errorInUserCode(cause, "Error converting '%s' (bound at %s) to %s%n"
  139. + " using %s.%n"
  140. + " Reason: %s",
  141. stringValue, convert(source), type, matchingConverter, cause);
  142. }
  143. public Errors ambiguousTypeConversion(String stringValue, Object source, TypeLiteral<?> type,
  144. MatcherAndConverter a, MatcherAndConverter b) {
  145. return addMessage("Multiple converters can convert '%s' (bound at %s) to %s:%n"
  146. + " %s and%n"
  147. + " %s.%n"
  148. + " Please adjust your type converter configuration to avoid overlapping matches.",
  149. stringValue, convert(source), type, a, b);
  150. }
  151. public Errors bindingToProvider() {
  152. return addMessage("Binding to Provider is not allowed.");
  153. }
  154. public Errors subtypeNotProvided(Class<? extends Provider<?>> providerType,
  155. Class<?> type) {
  156. return addMessage("%s doesn't provide instances of %s.", providerType, type);
  157. }
  158. public Errors notASubtype(Class<?> implementationType, Class<?> type) {
  159. return addMessage("%s doesn't extend %s.", implementationType, type);
  160. }
  161. public Errors recursiveImplementationType() {
  162. return addMessage("@ImplementedBy points to the same class it annotates.");
  163. }
  164. public Errors recursiveProviderType() {
  165. return addMessage("@ProvidedBy points to the same class it annotates.");
  166. }
  167. public Errors missingRuntimeRetention(Object source) {
  168. return addMessage("Please annotate with @Retention(RUNTIME).%n"
  169. + " Bound at %s.", convert(source));
  170. }
  171. public Errors missingScopeAnnotation() {
  172. return addMessage("Please annotate with @ScopeAnnotation.");
  173. }
  174. public Errors optionalConstructor(Constructor constructor) {
  175. return addMessage("%s is annotated @Inject(optional=true), "
  176. + "but constructors cannot be optional.", constructor);
  177. }
  178. public Errors cannotBindToGuiceType(String simpleName) {
  179. return addMessage("Binding to core guice framework type is not allowed: %s.", simpleName);
  180. }
  181. public Errors scopeNotFound(Class<? extends Annotation> scopeAnnotation) {
  182. return addMessage("No scope is bound to %s.", scopeAnnotation);
  183. }
  184. public Errors scopeAnnotationOnAbstractType(
  185. Class<? extends Annotation> scopeAnnotation, Class<?> type, Object source) {
  186. return addMessage("%s is annotated with %s, but scope annotations are not supported "
  187. + "for abstract types.%n Bound at %s.", type, scopeAnnotation, convert(source));
  188. }
  189. public Errors misplacedBindingAnnotation(Member member, Annotation bindingAnnotation) {
  190. return addMessage("%s is annotated with %s, but binding annotations should be applied "
  191. + "to its parameters instead.", member, bindingAnnotation);
  192. }
  193. private static final String CONSTRUCTOR_RULES =
  194. "Classes must have either one (and only one) constructor "
  195. + "annotated with @Inject or a zero-argument constructor that is not private.";
  196. public Errors missingConstructor(Class<?> implementation) {
  197. return addMessage("Could not find a suitable constructor in %s. " + CONSTRUCTOR_RULES,
  198. implementation);
  199. }
  200. public Errors tooManyConstructors(Class<?> implementation) {
  201. return addMessage("%s has more than one constructor annotated with @Inject. "
  202. + CONSTRUCTOR_RULES, implementation);
  203. }
  204. public Errors constructorNotDefinedByType(Constructor<?> constructor, TypeLiteral<?> type) {
  205. return addMessage("%s does not define %s", type, constructor);
  206. }
  207. public Errors duplicateScopes(Scope existing,
  208. Class<? extends Annotation> annotationType, Scope scope) {
  209. return addMessage("Scope %s is already bound to %s. Cannot bind %s.", existing,
  210. annotationType, scope);
  211. }
  212. public Errors voidProviderMethod() {
  213. return addMessage("Provider methods must return a value. Do not return void.");
  214. }
  215. public Errors missingConstantValues() {
  216. return addMessage("Missing constant value. Please call to(...).");
  217. }
  218. public Errors cannotInjectInnerClass(Class<?> type) {
  219. return addMessage("Injecting into inner classes is not supported. "
  220. + "Please use a 'static' class (top-level or nested) instead of %s.", type);
  221. }
  222. public Errors duplicateBindingAnnotations(Member member,
  223. Class<? extends Annotation> a, Class<? extends Annotation> b) {
  224. return addMessage("%s has more than one annotation annotated with @BindingAnnotation: "
  225. + "%s and %s", member, a, b);
  226. }
  227. public Errors cannotInjectFinalField(Field field) {
  228. return addMessage("Injected field %s cannot be final.", field);
  229. }
  230. public Errors cannotInjectAbstractMethod(Method method) {
  231. return addMessage("Injected method %s cannot be abstract.", method);
  232. }
  233. public Errors cannotInjectNonVoidMethod(Method method) {
  234. return addMessage("Injected method %s must return void.", method);
  235. }
  236. public Errors cannotInjectMethodWithTypeParameters(Method method) {
  237. return addMessage("Injected method %s cannot declare type parameters of its own.", method);
  238. }
  239. public Errors duplicateScopeAnnotations(
  240. Class<? extends Annotation> a, Class<? extends Annotation> b) {
  241. return addMessage("More than one scope annotation was found: %s and %s.", a, b);
  242. }
  243. public Errors recursiveBinding() {
  244. return addMessage("Binding points to itself.");
  245. }
  246. public Errors bindingAlreadySet(Key<?> key, Object source) {
  247. return addMessage("A binding to %s was already configured at %s.", key, convert(source));
  248. }
  249. public Errors childBindingAlreadySet(Key<?> key) {
  250. return addMessage("A binding to %s already exists on a child injector.", key);
  251. }
  252. public Errors errorCheckingDuplicateBinding(Key<?> key, Object source, Throwable t) {
  253. return addMessage(
  254. "A binding to %s was already configured at %s and an error was thrown "
  255. + "while checking duplicate bindings. Error: %s",
  256. key, source, t);
  257. }
  258. public Errors errorInjectingMethod(Throwable cause) {
  259. return errorInUserCode(cause, "Error injecting method, %s", cause);
  260. }
  261. public Errors errorNotifyingTypeListener(TypeListenerBinding listener,
  262. TypeLiteral<?> type, Throwable cause) {
  263. return errorInUserCode(cause,
  264. "Error notifying TypeListener %s (bound at %s) of %s.%n"
  265. + " Reason: %s",
  266. listener.getListener(), convert(listener.getSource()), type, cause);
  267. }
  268. public Errors errorInjectingConstructor(Throwable cause) {
  269. return errorInUserCode(cause, "Error injecting constructor, %s", cause);
  270. }
  271. public Errors errorInProvider(RuntimeException runtimeException) {
  272. Throwable unwrapped = unwrap(runtimeException);
  273. return errorInUserCode(unwrapped, "Error in custom provider, %s", unwrapped);
  274. }
  275. public Errors errorInUserInjector(
  276. MembersInjector<?> listener, TypeLiteral<?> type, RuntimeException cause) {
  277. return errorInUserCode(cause, "Error injecting %s using %s.%n"
  278. + " Reason: %s", type, listener, cause);
  279. }
  280. public Errors errorNotifyingInjectionListener(
  281. InjectionListener<?> listener, TypeLiteral<?> type, RuntimeException cause) {
  282. return errorInUserCode(cause, "Error notifying InjectionListener %s of %s.%n"
  283. + " Reason: %s", listener, type, cause);
  284. }
  285. public Errors exposedButNotBound(Key<?> key) {
  286. return addMessage("Could not expose() %s, it must be explicitly bound.", key);
  287. }
  288. public Errors keyNotFullySpecified(TypeLiteral<?> typeLiteral) {
  289. return addMessage("%s cannot be used as a key; It is not fully specified.", typeLiteral);
  290. }
  291. public static Collection<Message> getMessagesFromThrowable(Throwable throwable) {
  292. if (throwable instanceof ProvisionException) {
  293. return ((ProvisionException) throwable).getErrorMessages();
  294. } else if (throwable instanceof ConfigurationException) {
  295. return ((ConfigurationException) throwable).getErrorMessages();
  296. } else if (throwable instanceof CreationException) {
  297. return ((CreationException) throwable).getErrorMessages();
  298. } else {
  299. return ImmutableSet.of();
  300. }
  301. }
  302. public Errors errorInUserCode(Throwable cause, String messageFormat, Object... arguments) {
  303. Collection<Message> messages = getMessagesFromThrowable(cause);
  304. if (!messages.isEmpty()) {
  305. return merge(messages);
  306. } else {
  307. return addMessage(cause, messageFormat, arguments);
  308. }
  309. }
  310. private Throwable unwrap(RuntimeException runtimeException) {
  311. if(runtimeException instanceof Exceptions.UnhandledCheckedUserException) {
  312. return runtimeException.getCause();
  313. } else {
  314. return runtimeException;
  315. }
  316. }
  317. public Errors cannotInjectRawProvider() {
  318. return addMessage("Cannot inject a Provider that has no type parameter");
  319. }
  320. public Errors cannotInjectRawMembersInjector() {
  321. return addMessage("Cannot inject a MembersInjector that has no type parameter");
  322. }
  323. public Errors cannotInjectTypeLiteralOf(Type unsupportedType) {
  324. return addMessage("Cannot inject a TypeLiteral of %s", unsupportedType);
  325. }
  326. public Errors cannotInjectRawTypeLiteral() {
  327. return addMessage("Cannot inject a TypeLiteral that has no type parameter");
  328. }
  329. public Errors cannotSatisfyCircularDependency(Class<?> expectedType) {
  330. return addMessage(
  331. "Tried proxying %s to support a circular dependency, but it is not an interface.",
  332. expectedType);
  333. }
  334. public Errors circularProxiesDisabled(Class<?> expectedType) {
  335. return addMessage(
  336. "Tried proxying %s to support a circular dependency, but circular proxies are disabled.",
  337. expectedType);
  338. }
  339. public void throwCreationExceptionIfErrorsExist() {
  340. if (!hasErrors()) {
  341. return;
  342. }
  343. throw new CreationException(getMessages());
  344. }
  345. public void throwConfigurationExceptionIfErrorsExist() {
  346. if (!hasErrors()) {
  347. return;
  348. }
  349. throw new ConfigurationException(getMessages());
  350. }
  351. public void throwProvisionExceptionIfErrorsExist() {
  352. if (!hasErrors()) {
  353. return;
  354. }
  355. throw new ProvisionException(getMessages());
  356. }
  357. private Message merge(Message message) {
  358. List<Object> sources = Lists.newArrayList();
  359. sources.addAll(getSources());
  360. sources.addAll(message.getSources());
  361. return new Message(sources, message.getMessage(), message.getCause());
  362. }
  363. public Errors merge(Collection<Message> messages) {
  364. for (Message message : messages) {
  365. addMessage(merge(message));
  366. }
  367. return this;
  368. }
  369. public Errors merge(Errors moreErrors) {
  370. if (moreErrors.root == root || moreErrors.root.errors == null) {
  371. return this;
  372. }
  373. merge(moreErrors.root.errors);
  374. return this;
  375. }
  376. public List<Object> getSources() {
  377. List<Object> sources = Lists.newArrayList();
  378. for (Errors e = this; e != null; e = e.parent) {
  379. if (e.source != SourceProvider.UNKNOWN_SOURCE) {
  380. sources.add(0, e.source);
  381. }
  382. }
  383. return sources;
  384. }
  385. public void throwIfNewErrors(int expectedSize) throws ErrorsException {
  386. if (size() == expectedSize) {
  387. return;
  388. }
  389. throw toException();
  390. }
  391. public ErrorsException toException() {
  392. return new ErrorsException(this);
  393. }
  394. public boolean hasErrors() {
  395. return root.errors != null;
  396. }
  397. public Errors addMessage(String messageFormat, Object... arguments) {
  398. return addMessage(null, messageFormat, arguments);
  399. }
  400. private Errors addMessage(Throwable cause, String messageFormat, Object... arguments) {
  401. String message = format(messageFormat, arguments);
  402. addMessage(new Message(getSources(), message, cause));
  403. return this;
  404. }
  405. public Errors addMessage(Message message) {
  406. if (root.errors == null) {
  407. root.errors = Lists.newArrayList();
  408. }
  409. root.errors.add(message);
  410. return this;
  411. }
  412. public static String format(String messageFormat, Object... arguments) {
  413. for (int i = 0; i < arguments.length; i++) {
  414. arguments[i] = Errors.convert(arguments[i]);
  415. }
  416. return String.format(messageFormat, arguments);
  417. }
  418. public List<Message> getMessages() {
  419. if (root.errors == null) {
  420. return ImmutableList.of();
  421. }
  422. List<Message> result = Lists.newArrayList(root.errors);
  423. Collections.sort(result, new Comparator<Message>() {
  424. public int compare(Message a, Message b) {
  425. return a.getSource().compareTo(b.getSource());
  426. }
  427. });
  428. return result;
  429. }
  430. /** Returns the formatted message for an exception with the specified messages. */
  431. public static String format(String heading, Collection<Message> errorMessages) {
  432. Formatter fmt = new Formatter().format(heading).format(":%n%n");
  433. int index = 1;
  434. boolean displayCauses = getOnlyCause(errorMessages) == null;
  435. for (Message errorMessage : errorMessages) {
  436. fmt.format("%s) %s%n", index++, errorMessage.getMessage());
  437. List<Object> dependencies = errorMessage.getSources();
  438. for (int i = dependencies.size() - 1; i >= 0; i--) {
  439. Object source = dependencies.get(i);
  440. formatSource(fmt, source);
  441. }
  442. Throwable cause = errorMessage.getCause();
  443. if (displayCauses && cause != null) {
  444. StringWriter writer = new StringWriter();
  445. cause.printStackTrace(new PrintWriter(writer));
  446. fmt.format("Caused by: %s", writer.getBuffer());
  447. }
  448. fmt.format("%n");
  449. }
  450. if (errorMessages.size() == 1) {
  451. fmt.format("1 error");
  452. } else {
  453. fmt.format("%s errors", errorMessages.size());
  454. }
  455. return fmt.toString();
  456. }
  457. /**
  458. * Returns {@code value} if it is non-null allowed to be null. Otherwise a message is added and
  459. * an {@code ErrorsException} is thrown.
  460. */
  461. public <T> T checkForNull(T value, Object source, Dependency<?> dependency)
  462. throws ErrorsException {
  463. if (value != null || dependency.isNullable()) {
  464. return value;
  465. }
  466. int parameterIndex = dependency.getParameterIndex();
  467. String parameterName = (parameterIndex != -1)
  468. ? "parameter " + parameterIndex + " of "
  469. : "";
  470. addMessage("null returned by binding at %s%n but %s%s is not @Nullable",
  471. source, parameterName, dependency.getInjectionPoint().getMember());
  472. throw toException();
  473. }
  474. /**
  475. * Returns the cause throwable if there is exactly one cause in {@code messages}. If there are
  476. * zero or multiple messages with causes, null is returned.
  477. */
  478. public static Throwable getOnlyCause(Collection<Message> messages) {
  479. Throwable onlyCause = null;
  480. for (Message message : messages) {
  481. Throwable messageCause = message.getCause();
  482. if (messageCause == null) {
  483. continue;
  484. }
  485. if (onlyCause != null) {
  486. return null;
  487. }
  488. onlyCause = messageCause;
  489. }
  490. return onlyCause;
  491. }
  492. public int size() {
  493. return root.errors == null ? 0 : root.errors.size();
  494. }
  495. private static abstract class Converter<T> {
  496. final Class<T> type;
  497. Converter(Class<T> type) {
  498. this.type = type;
  499. }
  500. boolean appliesTo(Object o) {
  501. return type.isAssignableFrom(o.getClass());
  502. }
  503. String convert(Object o) {
  504. return toString(type.cast(o));
  505. }
  506. abstract String toString(T t);
  507. }
  508. private static final Collection<Converter<?>> converters = ImmutableList.of(
  509. new Converter<Class>(Class.class) {
  510. public String toString(Class c) {
  511. return c.getName();
  512. }
  513. },
  514. new Converter<Member>(Member.class) {
  515. public String toString(Member member) {
  516. return MoreTypes.toString(member);
  517. }
  518. },
  519. new Converter<Key>(Key.class) {
  520. public String toString(Key key) {
  521. if (key.getAnnotationType() != null) {
  522. return key.getTypeLiteral() + " annotated with "
  523. + (key.getAnnotation() != null ? key.getAnnotation() : key.getAnnotationType());
  524. } else {
  525. return key.getTypeLiteral().toString();
  526. }
  527. }
  528. });
  529. public static Object convert(Object o) {
  530. for (Converter<?> converter : converters) {
  531. if (converter.appliesTo(o)) {
  532. return converter.convert(o);
  533. }
  534. }
  535. return o;
  536. }
  537. public static void formatSource(Formatter formatter, Object source) {
  538. if (source instanceof Dependency) {
  539. Dependency<?> dependency = (Dependency<?>) source;
  540. InjectionPoint injectionPoint = dependency.getInjectionPoint();
  541. if (injectionPoint != null) {
  542. formatInjectionPoint(formatter, dependency, injectionPoint);
  543. } else {
  544. formatSource(formatter, dependency.getKey());
  545. }
  546. } else if (source instanceof InjectionPoint) {
  547. formatInjectionPoint(formatter, null, (InjectionPoint) source);
  548. } else if (source instanceof Class) {
  549. formatter.format(" at %s%n", StackTraceElements.forType((Class<?>) source));
  550. } else if (source instanceof Member) {
  551. formatter.format(" at %s%n", StackTraceElements.forMember((Member) source));
  552. } else if (source instanceof TypeLiteral) {
  553. formatter.format(" while locating %s%n", source);
  554. } else if (source instanceof Key) {
  555. Key<?> key = (Key<?>) source;
  556. formatter.format(" while locating %s%n", convert(key));
  557. } else {
  558. formatter.format(" at %s%n", source);
  559. }
  560. }
  561. public static void formatInjectionPoint(Formatter formatter, Dependency<?> dependency,
  562. InjectionPoint injectionPoint) {
  563. Member member = injectionPoint.getMember();
  564. Class<? extends Member> memberType = MoreTypes.memberType(member);
  565. if (memberType == Field.class) {
  566. dependency = injectionPoint.getDependencies().get(0);
  567. formatter.format(" while locating %s%n", convert(dependency.getKey()));
  568. formatter.format(" for field at %s%n", StackTraceElements.forMember(member));
  569. } else if (dependency != null) {
  570. formatter.format(" while locating %s%n", convert(dependency.getKey()));
  571. formatter.format(" for parameter %s at %s%n",
  572. dependency.getParameterIndex(), StackTraceElements.forMember(member));
  573. } else {
  574. formatSource(formatter, injectionPoint.getMember());
  575. }
  576. }
  577. }