Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions toothpick-runtime/src/main/java/toothpick/ScopeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ public <T> T getInstance(Class<T> clazz) {
@Override
public <T> T getInstance(Class<T> clazz, String name) {
crashIfClosed();
ConfigurationHolder.configuration.checkCyclesStart(clazz, name);
ConfigurationHolder.configuration.checkCyclesStart(this, clazz, name);
T t;
try {
t = lookupProvider(clazz, name).get(this);
} finally {
ConfigurationHolder.configuration.checkCyclesEnd(clazz, name);
ConfigurationHolder.configuration.checkCyclesEnd(this, clazz, name);
}
return t;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ public void checkIllegalBinding(Binding binding, Scope scope) {
}

@Override
public void checkCyclesStart(Class clazz, String name) {
runtimeCheckConfiguration.checkCyclesStart(clazz, name);
public void checkCyclesStart(Scope scope, Class clazz, String name) {
runtimeCheckConfiguration.checkCyclesStart(scope, clazz, name);
}

@Override
public void checkCyclesEnd(Class clazz, String name) {
runtimeCheckConfiguration.checkCyclesEnd(clazz, name);
public void checkCyclesEnd(Scope scope, Class clazz, String name) {
runtimeCheckConfiguration.checkCyclesEnd(scope, clazz, name);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface RuntimeCheckConfiguration {
* @param clazz the class to be injected.
* @param name the name of the required injection.
*/
void checkCyclesStart(Class clazz, String name);
void checkCyclesStart(Scope scope, Class clazz, String name);

/**
* Called when the class {@code class} ends being injected using the qualifier {@code name}. Will
Expand All @@ -47,5 +47,5 @@ interface RuntimeCheckConfiguration {
* @param clazz the class to be injected.
* @param name the name of the required injection.
*/
void checkCyclesEnd(Class clazz, String name);
void checkCyclesEnd(Scope scope, Class clazz, String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class RuntimeCheckOffConfiguration implements RuntimeCheckConfiguration {
public void checkIllegalBinding(Binding binding, Scope scope) {}

@Override
public void checkCyclesStart(Class clazz, String name) {}
public void checkCyclesStart(Scope scope, Class clazz, String name) {}

@Override
public void checkCyclesEnd(Class clazz, String name) {}
public void checkCyclesEnd(Scope scope, Class clazz, String name) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
class RuntimeCheckOnConfiguration implements RuntimeCheckConfiguration {
// We need a LIFO structure here, but stack is thread safe and we use thread local,
// so this property is overkill and LinkedHashSet is faster on retrieval.
private ThreadLocal<LinkedHashSet<Pair>> cycleDetectionStack =
new ThreadLocal<LinkedHashSet<Pair>>() {
private ThreadLocal<LinkedHashSet<Entry>> cycleDetectionStack =
new ThreadLocal<LinkedHashSet<Entry>>() {
@Override
protected LinkedHashSet<Pair> initialValue() {
protected LinkedHashSet<Entry> initialValue() {
return new LinkedHashSet<>();
}
};
Expand Down Expand Up @@ -76,52 +76,54 @@ public void checkIllegalBinding(Binding binding, Scope scope) {
}

@Override
public void checkCyclesStart(Class clazz, String name) {
final Pair pair = new Pair(clazz, name);
final LinkedHashSet<Pair> linkedHashSet = cycleDetectionStack.get();
if (linkedHashSet.contains(pair)) {
throw new CyclicDependencyException(Pair.getClassList(linkedHashSet), clazz);
public void checkCyclesStart(Scope scope, Class clazz, String name) {
final Entry entry = new Entry(scope, clazz, name);
final LinkedHashSet<Entry> linkedHashSet = cycleDetectionStack.get();
if (linkedHashSet.contains(entry)) {
throw new CyclicDependencyException(Entry.getClassList(linkedHashSet), clazz);
}

linkedHashSet.add(pair);
linkedHashSet.add(entry);
}

@Override
public void checkCyclesEnd(Class clazz, String name) {
cycleDetectionStack.get().remove(new Pair(clazz, name));
public void checkCyclesEnd(Scope scope, Class clazz, String name) {
cycleDetectionStack.get().remove(new Entry(scope, clazz, name));
}

private static class Pair {
private static class Entry {
public final Scope scope;
public final Class clazz;
public final String name;

Pair(Class clazz, String name) {
Entry(Scope scope, Class clazz, String name) {
this.scope = scope;
this.clazz = clazz;
this.name = name;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof Pair)) {
if (!(o instanceof Entry)) {
return false;
}
Pair p = (Pair) o;
return equal(p.clazz, clazz) && equal(p.name, name);
Entry p = (Entry) o;
return equal(p.scope, scope) && equal(p.clazz, clazz) && equal(p.name, name);
}

@Override
public int hashCode() {
return (clazz == null ? 0 : clazz.hashCode()) ^ (name == null ? 0 : name.hashCode());
return (scope == null ? 0 : scope.hashCode()) ^ (clazz == null ? 0 : clazz.hashCode()) ^ (name == null ? 0 : name.hashCode());
}

private boolean equal(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}

private static List<Class<?>> getClassList(Collection<Pair> pairCollection) {
private static List<Class<?>> getClassList(Collection<Entry> entryCollection) {
List<Class<?>> classList = new ArrayList<>();
for (Pair pair : pairCollection) {
classList.add(pair.clazz);
for (Entry entry : entryCollection) {
classList.add(entry.clazz);
}
return classList;
}
Expand Down