Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

review fix: issue related with ReferenceBuilder and generics #1373

Merged
merged 2 commits into from
Jun 7, 2017
Merged
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
17 changes: 10 additions & 7 deletions src/main/java/spoon/support/compiler/jdt/ReferenceBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,8 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -102,7 +100,7 @@ public class ReferenceBuilder {

// Allow to detect circular references and to avoid endless recursivity
// when resolving parameterizedTypes (e.g. Enum<E extends Enum<E>>)
private Set<TypeBinding> exploringParameterizedBindings = new HashSet<>();
private Map<TypeBinding, CtTypeReference> exploringParameterizedBindings = new HashMap<>();
private Map<String, CtTypeReference<?>> basestypes = new TreeMap<>();

private boolean bounds = false;
Expand Down Expand Up @@ -654,11 +652,16 @@ <T> CtTypeReference<T> getTypeReference(TypeBinding binding) {
if (bindingCache.containsKey(b)) {
ref.addActualTypeArgument(getCtCircularTypeReference(b));
} else {
if (!this.exploringParameterizedBindings.contains(b)) {
this.exploringParameterizedBindings.add(b);
ref.addActualTypeArgument(getTypeReference(b));
if (!this.exploringParameterizedBindings.containsKey(b)) {
this.exploringParameterizedBindings.put(b, null);
CtTypeReference typeRefB = getTypeReference(b);
this.exploringParameterizedBindings.put(b, typeRefB);
ref.addActualTypeArgument(typeRefB);
} else {
this.exploringParameterizedBindings.remove(b);
CtTypeReference typeRefB = this.exploringParameterizedBindings.get(b);
if (typeRefB != null) {
ref.addActualTypeArgument(typeRefB.clone());
}
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/spoon/test/generics/GenericsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,34 @@ public void testWildCardonShadowClass() throws Exception {
factory = launcher.getFactory();
CtInterface<?> fakeTplItf2 = factory.Interface().get(FakeTpl.class);
checkFakeTpl(fakeTplItf2);
}

@Test
public void testDiamondComplexGenericsRxJava() {
Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/generics/testclasses/rxjava/");
launcher.setSourceOutputDirectory("./target/spooned-rxjava");
launcher.run();

Factory factory = launcher.getFactory();

List<CtConstructorCall> invocations = factory.getModel().getElements(new TypeFilter<>(CtConstructorCall.class));

boolean invocationDetected = false;
for (CtConstructorCall call : invocations) {
if (call.getType().getSimpleName().equals("ToNotificationSubscriber")) {
assertEquals(1, call.getType().getActualTypeArguments().size());

CtTypeReference actualTA = call.getType().getActualTypeArguments().get(0);
assertTrue(actualTA instanceof CtWildcardReference);
assertEquals("?", actualTA.getSimpleName());
assertTrue( ((CtWildcardReference)actualTA).getBoundingType() == null );
invocationDetected = true;
}
}

canBeBuilt("./target/spooned-rxjava",8);

assertTrue(invocationDetected);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package spoon.test.generics.testclasses.rxjava;

/**
* Created by urli on 07/06/2017.
*/
public final class BehaviorSubject<T> extends Subject<T, T> {
public static <T> BehaviorSubject<T> create() {
return new BehaviorSubject<>();
}

@Override
public void onNext(T var1) {

}

@Override
public void onError(Throwable var1) {

}

@Override
public void onComplete() {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package spoon.test.generics.testclasses.rxjava;

import java.util.Objects;

/**
* Created by urli on 07/06/2017.
*/
public class Observable<T> implements Publisher<T> {

public final void subscribe(Subscriber<? super T> s) {
Objects.requireNonNull(s);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package spoon.test.generics.testclasses.rxjava;

/**
* Created by urli on 07/06/2017.
*/
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package spoon.test.generics.testclasses.rxjava;

/**
* Created by urli on 07/06/2017.
*/
public interface Publisher<T> {
void subscribe(Subscriber<? super T> var1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package spoon.test.generics.testclasses.rxjava;

import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;

/**
* Created by urli on 07/06/2017.
*/
public final class PublisherRedo<T> implements Publisher<T> {
final Function<? super Observable<Try<Optional<Object>>>, ? extends Publisher<?>> manager;

public PublisherRedo(Function<? super Observable<Try<Optional<Object>>>, ? extends Publisher<?>> manager) {
this.manager = manager;
}

public void subscribe(Subscriber<? super T> s) {

BehaviorSubject<Try<Optional<Object>>> subject = BehaviorSubject.create();
RedoSubscriber<T> parent = new RedoSubscriber<>();
Publisher<?> action = manager.apply(subject);

action.subscribe(new ToNotificationSubscriber<>(parent::handle));
}

private void subscribe(ToNotificationSubscriber truc) {

}

static final class RedoSubscriber<T> extends AtomicBoolean implements Subscriber<T> {
void handle(Try<Optional<Object>> notification) {

}

@Override
public void onNext(T var1) {

}

@Override
public void onError(Throwable var1) {

}

@Override
public void onComplete() {

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package spoon.test.generics.testclasses.rxjava;

/**
* Created by urli on 07/06/2017.
*/
public abstract class Subject<T, R> extends Observable<R> implements Processor<T, R> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package spoon.test.generics.testclasses.rxjava;

/**
* Created by urli on 07/06/2017.
*/
public interface Subscriber<T> {
void onNext(T var1);

void onError(Throwable var1);

void onComplete();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package spoon.test.generics.testclasses.rxjava;

import java.util.Optional;
import java.util.function.Consumer;

/**
* Created by urli on 07/06/2017.
*/
public final class ToNotificationSubscriber<T> implements Subscriber<T> {
final Consumer<? super Try<Optional<Object>>> consumer;

public ToNotificationSubscriber(Consumer<? super Try<Optional<Object>>> consumer) {
this.consumer = consumer;
}

@Override
public void onNext(T var1) {

}

@Override
public void onError(Throwable var1) {

}

@Override
public void onComplete() {

}
}
8 changes: 8 additions & 0 deletions src/test/java/spoon/test/generics/testclasses/rxjava/Try.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package spoon.test.generics.testclasses.rxjava;


/**
* Created by urli on 07/06/2017.
*/
public final class Try<T> {
}