Skip to content

Commit

Permalink
Implement custom error formatting for BINDING_ALREADY_SET errors.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=323883237
  • Loading branch information
xiaomingjia authored and nick-someone committed Jul 30, 2020
1 parent edfa686 commit bd10dea
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ protected void putBinding(BindingImpl<?> binding) {
if (injector.getBindingData().getExplicitBinding(key) != null) {
try {
if (!isOkayDuplicate(original, binding, injector.getBindingData())) {
if (InternalFlags.enableExperimentalErrorMessages()) {
errors.bindingAlreadySet(binding, original);
return;
}
errors.bindingAlreadySet(key, original.getSource());
return;
}
Expand Down
54 changes: 54 additions & 0 deletions core/src/com/google/inject/internal/BindingAlreadySetError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.google.inject.internal;

import com.google.common.collect.ImmutableList;
import com.google.inject.Binding;
import com.google.inject.spi.ErrorDetail;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.stream.Collectors;

/** Error reported by Guice when a key is bound at multiple places the injector. */
final class BindingAlreadySetError extends ErrorDetail<BindingAlreadySetError> {
private final Binding<?> binding;
private final Binding<?> original;

BindingAlreadySetError(Binding<?> binding, Binding<?> original, List<Object> sources) {
super(
String.format("%s was bound multiple times.", Messages.convert(binding.getKey())),
sources,
null);
this.binding = binding;
this.original = original;
}

@Override
public boolean isMergeable(ErrorDetail<?> otherError) {
return otherError instanceof BindingAlreadySetError
&& ((BindingAlreadySetError) otherError).binding.getKey().equals(binding.getKey());
}

@Override
public void format(int index, List<ErrorDetail<?>> mergeableErrors, Formatter formatter) {
List<List<Object>> sourcesList = new ArrayList<>();
sourcesList.add(ImmutableList.of(original.getSource()));
sourcesList.add(ImmutableList.of(binding.getSource()));
sourcesList.addAll(
mergeableErrors.stream()
.map(e -> ((BindingAlreadySetError) e).binding.getSource())
.map(ImmutableList::of)
.collect(Collectors.toList()));

formatter.format("%s) %s %s%n%n", index, "[Guice/BindingAlreadySet]", getMessage());
formatter.format("Bound at the following %s locations:%n", sourcesList.size());
for (int i = 0; i < sourcesList.size(); i++) {
ErrorFormatter.formatSources(i + 1, sourcesList.get(i), formatter);
}
formatter.format("%n");
}

@Override
public BindingAlreadySetError withSources(List<Object> newSources) {
return new BindingAlreadySetError(binding, original, newSources);
}
}
6 changes: 6 additions & 0 deletions core/src/com/google/inject/internal/Errors.java
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ public Errors recursiveBinding() {
return addMessage(ErrorId.RECURSIVE_BINDING, "Binding points to itself.");
}

Errors bindingAlreadySet(Binding<?> binding, Binding<?> original) {
BindingAlreadySetError error = new BindingAlreadySetError(binding, original, getSources());
return addMessage(
new Message(GuiceInternal.GUICE_INTERNAL, ErrorId.BINDING_ALREADY_SET, error));
}

public Errors bindingAlreadySet(Key<?> key, Object source) {
return addMessage(
ErrorId.BINDING_ALREADY_SET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ final class MissingImplementationError extends ErrorDetail<MissingImplementation
private final Key<?> key;

public MissingImplementationError(Key<?> key, List<Object> sources) {
super("", sources, null);
super(
String.format("No implementation for %s was bound.", Messages.convert(key)), sources, null);
this.key = key;
}

Expand All @@ -29,16 +30,13 @@ public void format(int index, List<ErrorDetail<?>> mergeableErrors, Formatter fo
sourcesList.add(getSources());
sourcesList.addAll(
mergeableErrors.stream().map(ErrorDetail::getSources).collect(Collectors.toList()));
formatter.format(
"%s) [Guice/MissingImplementation]: No implementation for %s was bound.%n",
index, Messages.convert(key));

List<List<Object>> filteredSourcesList =
sourcesList.stream()
.map(this::trimSource)
.filter(sources -> !sources.isEmpty())
.collect(Collectors.toList());

formatter.format("%s) %s: %s%n", index, "[Guice/MissingImplementation]", getMessage());
if (!filteredSourcesList.isEmpty()) {
formatter.format("%n%s%n", "Requested by:");
int sourceListIndex = 1;
Expand Down

0 comments on commit bd10dea

Please sign in to comment.