Skip to content

Commit

Permalink
better coverage parsing for adapter to prevent previous issue
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Aug 6, 2024
1 parent 3eb32bd commit 9980354
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 238 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.reflect.Member;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
Expand Down Expand Up @@ -91,11 +92,20 @@ public static void main(String[] args) throws IOException, URISyntaxException {
}
System.out.println("Checking version " + stubVersion);

Map<Type, Type> stubClassTypes = versionProvider.classStubs.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getFirst()));
Set<FullyQualifiedMemberNameAndDesc> stubClassMethods = versionProvider.classStubs.entrySet().stream().flatMap (e ->
Stream.<Member>concat(
Arrays.stream(e.getValue().getSecond().getFirst().getDeclaredMethods()),
Arrays.stream(e.getValue().getSecond().getFirst().getConstructors())
).filter(m -> (m.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) != 0 && (m.getModifiers() & Opcodes.ACC_SYNTHETIC) == 0)
.map(MemberNameAndDesc::fromMember)
.map(m -> m.toFullyQualified(e.getValue().getFirst()))
).collect(Collectors.toSet());
var unmatchedStubs = versionProvider.stubMappings.values().stream().flatMap(value -> Stream.of(value.getMethodStubMap().values().stream(), value.getMethodModifyMap().values().stream()).flatMap(e -> e)).map(Pair::getFirst).collect(Collectors.toList());

try {
var requiredStubs = new ArrayList<MemberInfo>();
compare(versions.get(v), classes, requiredStubs);
Map<Type, Pair<Type, Pair<Class<?>, Adapter>>> stubClasses = versionProvider.classStubs;

outer:
for (var staticAndStub : requiredStubs) {
Expand All @@ -118,65 +128,43 @@ public static void main(String[] args) throws IOException, URISyntaxException {
for (int i = 0; i < descArgs.length; i++) {
var arg = descArgs[i];
if (arg.getSort() == Type.OBJECT) {
var stubCls = stubClasses.get(arg);
var stubCls = stubClassTypes.get(arg);
if (stubCls != null) {
descArgs[i] = stubCls.getFirst();
descArgs[i] = stubCls;
}
} else if (arg.getSort() == Type.ARRAY) {
var dims = arg.getDimensions();
var elem = arg.getElementType();
if (elem.getSort() == Type.OBJECT) {
var stubCls = stubClasses.get(elem);
var stubCls = stubClassTypes.get(elem);
if (stubCls != null) {
descArgs[i] = Type.getType("[".repeat(dims) + stubCls.getFirst().getDescriptor());
descArgs[i] = Type.getType("[".repeat(dims) + stubCls.getDescriptor());
}
}
}
}
var ret = desc.getReturnType();
if (ret.getSort() == Type.OBJECT) {
var stubCls = stubClasses.get(ret);
var stubCls = stubClassTypes.get(ret);
if (stubCls != null) {
ret = stubCls.getFirst();
ret = stubCls;
}
} else if (ret.getSort() == Type.ARRAY) {
var dims = ret.getDimensions();
var elem = ret.getElementType();
if (elem.getSort() == Type.OBJECT) {
var stubCls = stubClasses.get(elem);
var stubCls = stubClassTypes.get(elem);
if (stubCls != null) {
ret = Type.getType("[".repeat(dims) + stubCls.getFirst().getDescriptor());
ret = Type.getType("[".repeat(dims) + stubCls.getDescriptor());
}
}
}
var member = new MemberNameAndDesc(stub.getName(), Type.getMethodType(ret, descArgs));

if (versionProvider.classStubs.containsKey(stub.getOwner())) {
var clsStub = versionProvider.classStubs.get(stub.getOwner());
try {
Class<?> cls = Class.forName(clsStub.getFirst().getInternalName().replace('/', '.'), true, ClassDowngrader.getCurrentVersionDowngrader().getClassLoader());
// check if has matching method
if (member.getName().equals("<init>")) {
for (var m : cls.getConstructors()) {
if ((m.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0 || (m.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0)
continue;
if (Type.getType(m).equals(member.getDesc())) {
availableStubCount++;
continue outer;
}
}
} else {
for (var m : cls.getDeclaredMethods()) {
if ((m.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0 || (m.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0)
continue;
if (m.getName().equals(member.getName()) && Type.getType(m).equals(member.getDesc())) {
availableStubCount++;
continue outer;
}
}
}
} catch (ClassNotFoundException e) {
System.err.println("Failed to load class " + clsStub.getFirst().getInternalName());
if (stubClassTypes.containsKey(stub.getOwner())) {
if (stubClassMethods.remove(member.toFullyQualified(stubClassTypes.get(stub.getOwner())))) {
availableStubCount++;
continue;
}
}

Expand Down Expand Up @@ -234,9 +222,16 @@ public static void main(String[] args) throws IOException, URISyntaxException {
var parentOnly = Path.of("./coverage/" + stubVersion + "/parentOnly.txt");
writeList(parentOnlyStubs, parentOnly);
}
if (!unmatchedStubs.isEmpty()) {
if (!unmatchedStubs.isEmpty() || !stubClassMethods.isEmpty()) {
var unmatched = Path.of("./coverage/" + stubVersion + "/unmatched.txt");
writeList(unmatchedStubs.stream().map(methodStubPair -> new MemberInfo("unknown", FullyQualifiedMemberNameAndDesc.of(methodStubPair), false, false)).collect(Collectors.toList()), unmatched);
writeList(
Stream.concat(
unmatchedStubs.stream().map(FullyQualifiedMemberNameAndDesc::of),
stubClassMethods.stream()
).map(e -> new MemberInfo("unknown", e, false, false))
.collect(Collectors.toList()),
unmatched
);
}

} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import xyz.wagyourtail.jvmdg.version.Adapter;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.BiPredicate;

@Adapter("Ljava/net/http/HttpHeaders;")
public class J_N_H_HttpHeaders {
Expand All @@ -15,10 +21,39 @@ public J_N_H_HttpHeaders(Map<String, List<String>> headers) {
this.headers = headers;
}

public static J_N_H_HttpHeaders of(Map<String, List<String>> map, BiPredicate<String, String> filter) {
Map<String, List<String>> filtered = new TreeMap<>();
for (Map.Entry<String, List<String>> e : map.entrySet()) {
String key = e.getKey().trim();
if (key.isEmpty()) {
throw new IllegalArgumentException("empty key");
}
List<String> adding = new ArrayList<>();
for (String value : e.getValue()) {
if (value == null) {
throw new IllegalArgumentException("null value for key " + key);
}
if (filter.test(key, value)) {
adding.add(value);
}
}
if (!adding.isEmpty()) {
if (filtered.put(key.toLowerCase(Locale.ROOT), adding) != null) {
throw new IllegalArgumentException("duplicate key: " + key);
}
}
}
return new J_N_H_HttpHeaders(Map.copyOf(filtered));
}

public Optional<String> firstValue(String name) {
return headers.containsKey(name) ? Optional.of(headers.get(name).get(0)) : Optional.empty();
}

public OptionalLong firstValueAsLong(String name) {
return headers.containsKey(name) ? OptionalLong.of(Long.parseLong(headers.get(name).get(0))) : OptionalLong.empty();
}

public List<String> allValues(String name) {
return headers.get(name);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,106 +285,5 @@ public void cancel() {
}
};
}

public static BodyPublisher concat(BodyPublisher... publishers) {
return new BodyPublisher() {
@Override
public long contentLength() {
long sum = 0;
for (BodyPublisher publisher : publishers) {
sum += publisher.contentLength();
}
return sum;
}

@Override
public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
subscriber.onSubscribe(new Flow.Subscription() {
private final Iterator<BodyPublisher> iterator = List.of(publishers).iterator();
private boolean completed;

@Override
public void request(long n) {
if (n <= 0) {
subscriber.onError(new IllegalArgumentException("n <= 0"));
return;
}
if (completed) {
return;
}
try {
while (n > 0) {
if (!iterator.hasNext()) {
completed = true;
subscriber.onComplete();
return;
}
BodyPublisher publisher = iterator.next();
long contentLength = publisher.contentLength();
if (contentLength > 0) {
publisher.subscribe(new Flow.Subscriber<>() {
private long remaining = contentLength;

@Override
public void onSubscribe(Flow.Subscription subscription) {
subscription.request(Long.MAX_VALUE);
}

@Override
public void onNext(ByteBuffer item) {
subscriber.onNext(item);
remaining -= item.remaining();
if (remaining == 0) {
subscriber.onComplete();
}
}

@Override
public void onError(Throwable throwable) {
subscriber.onError(throwable);
}

@Override
public void onComplete() {
}
});
} else {
publisher.subscribe(new Flow.Subscriber<>() {
@Override
public void onSubscribe(Flow.Subscription subscription) {
subscription.request(Long.MAX_VALUE);
}

@Override
public void onNext(ByteBuffer item) {
subscriber.onNext(item);
}

@Override
public void onError(Throwable throwable) {
subscriber.onError(throwable);
}

@Override
public void onComplete() {
subscriber.onComplete();
}
});
}
n--;
}
} catch (Throwable t) {
subscriber.onError(t);
}
}

@Override
public void cancel() {
completed = true;
}
});
}
};
}
}
}

This file was deleted.

Loading

0 comments on commit 9980354

Please sign in to comment.