|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2023 the original author or authors. |
|
|
|
* Copyright 2002-2024 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -23,7 +23,6 @@ import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.Objects; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.StringJoiner; |
|
|
|
|
|
|
|
import java.util.function.Consumer; |
|
|
|
import java.util.function.Consumer; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
import java.util.stream.Stream; |
|
|
|
import java.util.stream.Stream; |
|
|
|
@ -75,6 +74,7 @@ public final class TypeHint implements ConditionalHint { |
|
|
|
return new Builder(type); |
|
|
|
return new Builder(type); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Return the type that this hint handles. |
|
|
|
* Return the type that this hint handles. |
|
|
|
* @return the type |
|
|
|
* @return the type |
|
|
|
@ -123,9 +123,7 @@ public final class TypeHint implements ConditionalHint { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public String toString() { |
|
|
|
public String toString() { |
|
|
|
return new StringJoiner(", ", TypeHint.class.getSimpleName() + "[", "]") |
|
|
|
return TypeHint.class.getSimpleName() + "[type=" + this.type + "]"; |
|
|
|
.add("type=" + this.type) |
|
|
|
|
|
|
|
.toString(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -157,16 +155,14 @@ public final class TypeHint implements ConditionalHint { |
|
|
|
|
|
|
|
|
|
|
|
private final Set<MemberCategory> memberCategories = new HashSet<>(); |
|
|
|
private final Set<MemberCategory> memberCategories = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Builder(TypeReference type) { |
|
|
|
Builder(TypeReference type) { |
|
|
|
this.type = type; |
|
|
|
this.type = type; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Make this hint conditional on the fact that the specified type |
|
|
|
* Make this hint conditional on the fact that the specified type is in a |
|
|
|
* is in a reachable code path from a static analysis point of view. |
|
|
|
* reachable code path from a static analysis point of view. |
|
|
|
* @param reachableType the type that should be reachable for this |
|
|
|
* @param reachableType the type that should be reachable for this hint to apply |
|
|
|
* hint to apply |
|
|
|
|
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Builder onReachableType(TypeReference reachableType) { |
|
|
|
public Builder onReachableType(TypeReference reachableType) { |
|
|
|
@ -175,10 +171,9 @@ public final class TypeHint implements ConditionalHint { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Make this hint conditional on the fact that the specified type |
|
|
|
* Make this hint conditional on the fact that the specified type is in a |
|
|
|
* is in a reachable code path from a static analysis point of view. |
|
|
|
* reachable code path from a static analysis point of view. |
|
|
|
* @param reachableType the type that should be reachable for this |
|
|
|
* @param reachableType the type that should be reachable for this hint to apply |
|
|
|
* hint to apply |
|
|
|
|
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Builder onReachableType(Class<?> reachableType) { |
|
|
|
public Builder onReachableType(Class<?> reachableType) { |
|
|
|
@ -215,8 +210,9 @@ public final class TypeHint implements ConditionalHint { |
|
|
|
* constructor |
|
|
|
* constructor |
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
* @return {@code this}, to facilitate method chaining |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private Builder withConstructor(List<TypeReference> parameterTypes, |
|
|
|
private Builder withConstructor( |
|
|
|
Consumer<ExecutableHint.Builder> constructorHint) { |
|
|
|
List<TypeReference> parameterTypes, Consumer<ExecutableHint.Builder> constructorHint) { |
|
|
|
|
|
|
|
|
|
|
|
ExecutableKey key = new ExecutableKey("<init>", parameterTypes); |
|
|
|
ExecutableKey key = new ExecutableKey("<init>", parameterTypes); |
|
|
|
ExecutableHint.Builder builder = this.constructors.computeIfAbsent(key, |
|
|
|
ExecutableHint.Builder builder = this.constructors.computeIfAbsent(key, |
|
|
|
k -> ExecutableHint.ofConstructor(parameterTypes)); |
|
|
|
k -> ExecutableHint.ofConstructor(parameterTypes)); |
|
|
|
@ -271,38 +267,30 @@ public final class TypeHint implements ConditionalHint { |
|
|
|
TypeHint build() { |
|
|
|
TypeHint build() { |
|
|
|
return new TypeHint(this); |
|
|
|
return new TypeHint(this); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final class ExecutableKey { |
|
|
|
private static final class ExecutableKey { |
|
|
|
|
|
|
|
|
|
|
|
private final String name; |
|
|
|
private final String name; |
|
|
|
|
|
|
|
|
|
|
|
private final List<String> parameterTypes; |
|
|
|
private final List<String> parameterTypes; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ExecutableKey(String name, List<TypeReference> parameterTypes) { |
|
|
|
private ExecutableKey(String name, List<TypeReference> parameterTypes) { |
|
|
|
this.name = name; |
|
|
|
this.name = name; |
|
|
|
this.parameterTypes = parameterTypes.stream().map(TypeReference::getCanonicalName).toList(); |
|
|
|
this.parameterTypes = parameterTypes.stream().map(TypeReference::getCanonicalName).toList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public boolean equals(@Nullable Object o) { |
|
|
|
public boolean equals(@Nullable Object other) { |
|
|
|
if (this == o) { |
|
|
|
return (this == other || (other instanceof ExecutableKey that && |
|
|
|
return true; |
|
|
|
this.name.equals(that.name) && this.parameterTypes.equals(that.parameterTypes))); |
|
|
|
} |
|
|
|
|
|
|
|
if (o == null || getClass() != o.getClass()) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ExecutableKey that = (ExecutableKey) o; |
|
|
|
|
|
|
|
return this.name.equals(that.name) && this.parameterTypes.equals(that.parameterTypes); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public int hashCode() { |
|
|
|
public int hashCode() { |
|
|
|
return Objects.hash(this.name, this.parameterTypes); |
|
|
|
return Objects.hash(this.name, this.parameterTypes); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|