Skip to content

Commit 2d8798b

Browse files
committed
Merge branch 'develop' into post-java8-features
# Conflicts: # .idea/inspectionProfiles/Project_Default.xml
2 parents e004e96 + 09d23d8 commit 2d8798b

File tree

10 files changed

+99
-36
lines changed

10 files changed

+99
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: "Validate Gradle Wrapper"
2+
on: [push, pull_request]
3+
4+
jobs:
5+
validation:
6+
name: "Validation"
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
- uses: gradle/[email protected]
11+

.idea/inspectionProfiles/Project_Default.xml

+2-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Procyon.Expressions/src/main/java/com/strobel/expressions/ExpressionVisitor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ protected Expression visitNewArray(final NewArrayExpression node) {
183183
return node.update(visit(node.getExpressions()));
184184
}
185185

186-
protected <T> LambdaExpression<T> visitLambda(final LambdaExpression<T> node) {
186+
protected <T> Expression visitLambda(final LambdaExpression<T> node) {
187187
return node.update(visit(node.getBody()), visitAndConvertList(node.getParameters(), "visitLambda"));
188188
}
189189

Procyon.Expressions/src/main/java/com/strobel/expressions/Optimizer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ static Expression optimize(final Expression node) {
3333
}
3434

3535
static <T> LambdaExpression<T> optimize(final LambdaExpression<T> node) {
36-
return OPTIMIZER.visitLambda(node);
36+
final @SuppressWarnings("unchecked") LambdaExpression<T> lambda = (LambdaExpression<T>) OPTIMIZER.visitLambda(node);
37+
return lambda;
3738
}
3839

3940
@Override
@@ -52,7 +53,7 @@ protected Expression visitBinary(final BinaryExpression node) {
5253

5354
return super.visitBinary(node);
5455
}
55-
56+
5657
@Override
5758
protected Expression visitUnary(final UnaryExpression node) {
5859
Expression reduced = reduceNullConstantCheck(node);

Procyon.Reflection/src/main/java/com/strobel/reflection/MemberInfo.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,14 @@ public boolean equals(final Object o) {
122122

123123
@Override
124124
public int hashCode() {
125-
final int nameHash = HashUtilities.hashCode(getName());
125+
final int baseHash = HashUtilities.combineHashCodes(getName(), getErasedSignature());
126126
final Type t = getDeclaringType();
127127

128128
if (t != null) {
129-
return HashUtilities.combineHashCodes(t.hashCode(), nameHash);
129+
return HashUtilities.combineHashCodes(t.getInternalName(), baseHash);
130130
}
131131

132-
return nameHash;
132+
return baseHash;
133133
}
134134

135135
public boolean isEquivalentTo(final MemberInfo m) {

Procyon.Reflection/src/main/java/com/strobel/reflection/Resolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ public Type<?> visitField(final Field field, final Frame frame) {
772772
final ReflectedField reflectedField = new ReflectedField(
773773
declaringType,
774774
field,
775-
frame.resolveType(field.getType())
775+
frame.resolveType(field.getGenericType())
776776
);
777777

778778
declaringType.addField(reflectedField);

Procyon.Reflection/src/main/java/com/strobel/reflection/Type.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -331,13 +331,11 @@ public boolean containsGenericParameter(final Type<?> genericParameter) {
331331
return this.isEquivalentTo(genericParameter);
332332
}
333333

334-
if (isGenericTypeDefinition()) {
335-
final TypeBindings typeArguments = getTypeBindings();
334+
final TypeBindings typeArguments = getTypeBindings();
336335

337-
for (int i = 0, n = typeArguments.size(); i < n; i++) {
338-
if (typeArguments.getBoundType(i).containsGenericParameter(genericParameter)) {
339-
return true;
340-
}
336+
for (int i = 0, n = typeArguments.size(); i < n; i++) {
337+
if (typeArguments.getBoundType(i).containsGenericParameter(genericParameter)) {
338+
return true;
341339
}
342340
}
343341

Procyon.Reflection/src/main/java/com/strobel/reflection/TypeCache.java

+25-22
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.strobel.core.Comparer;
1717
import com.strobel.core.HashUtilities;
18+
import com.strobel.reflection.emit.TypeBuilder;
1819
import com.strobel.util.TypeUtils;
1920

2021
import java.util.LinkedHashMap;
@@ -36,20 +37,19 @@ public Key key(final Type<?> type, final TypeList typeArguments) {
3637
return new Key(type.isGenericType() ? type.getGenericTypeDefinition() : type, typeArguments);
3738
}
3839

39-
public Type find(final Key key) {
40+
public Type<?> find(final Key key) {
4041
return _map.get(key);
4142
}
4243

4344
public <T> Type<T[]> getArrayType(final Type<T> elementType) {
45+
add(elementType);
46+
4447
Type<T[]> arrayType = (Type<T[]>) _arrayMap.get(elementType);
4548

46-
if (arrayType != null) {
47-
return arrayType;
49+
if (arrayType == null) {
50+
_arrayMap.put(elementType, arrayType = elementType.createArrayType());
4851
}
4952

50-
arrayType = elementType.createArrayType();
51-
add(arrayType);
52-
5353
return arrayType;
5454
}
5555

@@ -59,15 +59,15 @@ public <T> Type<T> getGenericType(final Type<T> type, final TypeList typeArgumen
5959
typeArguments
6060
);
6161

62-
Type genericType = _map.get(key);
62+
Type<T> genericType = (Type<T>) _map.get(key);
6363

6464
if (genericType == null) {
65-
genericType = new GenericType(
65+
genericType = new GenericType<>(
6666
type.getGenericTypeDefinition(),
6767
typeArguments
6868
);
6969

70-
final Type existing = _map.put(key, genericType);
70+
final Type<T> existing = (Type<T>) _map.put(key, genericType);
7171

7272
if (existing != null) {
7373
return existing;
@@ -85,7 +85,7 @@ public int size() {
8585
return _map.size();
8686
}
8787

88-
public void put(final Key key, final Type type) {
88+
void put(final Key key, final Type<?> type) {
8989
final String descriptor = key.descriptor;
9090

9191
if (!_definitionMap.containsKey(descriptor)) {
@@ -102,26 +102,29 @@ public void put(final Key key, final Type type) {
102102
}
103103

104104
_map.put(key, type);
105+
}
105106

106-
if (type.isArray()) {
107-
final Type elementType = type.getElementType();
108-
if (!_arrayMap.containsKey(elementType)) {
109-
_arrayMap.put(elementType, type);
110-
}
107+
public void add(final Type<?> type) {
108+
Type<?> coreType = type;
109+
110+
while (coreType.isArray()) {
111+
coreType = coreType.getElementType();
112+
}
113+
114+
if (coreType.isWildcardType() || coreType.isGenericParameter() || coreType instanceof TypeBuilder<?>) {
115+
return;
111116
}
112-
}
113117

114-
public void add(final Type type) {
115118
final TypeList typeArguments;
116119

117-
if (type.isGenericType()) {
118-
typeArguments = type.getTypeBindings().getBoundTypes();
120+
if (coreType.isGenericType()) {
121+
typeArguments = coreType.getTypeBindings().getBoundTypes();
119122
}
120123
else {
121124
typeArguments = TypeList.empty();
122125
}
123126

124-
put(key(type, typeArguments), type);
127+
put(key(coreType, typeArguments), coreType);
125128
}
126129

127130
final static class Key {
@@ -181,8 +184,8 @@ public final boolean equals(final Object o) {
181184
}
182185

183186
for (int i = 0, n = typeArguments.size(); i < n; ++i) {
184-
final Type argument = typeArguments.get(i);
185-
final Type otherArgument = otherArguments.get(i);
187+
final Type<?> argument = typeArguments.get(i);
188+
final Type<?> otherArgument = otherArguments.get(i);
186189

187190
if (!Comparer.equals(argument, otherArgument)) {
188191
return false;

Procyon.Reflection/src/test/java/com/strobel/reflection/ReflectionTests.java

+44
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.junit.Test;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
1920
import java.util.HashMap;
2021
import java.util.List;
2122
import java.util.Map;
@@ -169,4 +170,47 @@ public void testGetUnderlyingType() throws Throwable {
169170
assertSame(gd, uea);
170171
assertSame(gd, uia);
171172
}
173+
174+
@Test
175+
public void testBoundGenericFields() {
176+
@SuppressWarnings("unused")
177+
class GenericTestObject<T> {
178+
public List<T> items;
179+
180+
public T sum(final List<T> values) {
181+
throw new UnsupportedOperationException();
182+
}
183+
}
184+
185+
final class TestObject extends GenericTestObject<Double> {
186+
}
187+
188+
final FieldInfo items = Type.of(TestObject.class).getField("items");
189+
190+
assertEquals(Types.List.makeGenericType(Types.Double),
191+
items.getFieldType());
192+
}
193+
194+
@Test
195+
public void genericParameterArrayTypesDoNotCollideInTypeCache() {
196+
class MyClass {
197+
public <T> Iterable<T> enumerate(final T[] items) {
198+
return Arrays.asList(items);
199+
}
200+
}
201+
202+
class MyOtherClass {
203+
public Object getFirstOrNull(final Object... values) {
204+
return values.length > 0 ? values[0] : null;
205+
}
206+
}
207+
208+
final Type<MyClass> c1 = Type.of(MyClass.class); // Load class with method having T[] parameter
209+
c1.getMethods(); // Load methods of class with method having T[] parameter
210+
final Type<MyOtherClass> c2 = Type.of(MyOtherClass.class); // Load class with method having Object[] parameter
211+
final Type<Object[]> objectArrayType = Types.Object.makeArrayType(); // Prepare Object[] type for comparison
212+
final MethodInfo method = c2.getMethod("getFirstOrNull", objectArrayType); // Load specific method having Object[] parameter
213+
final Type<?> methodParameterType = method.getParameters().getParameterTypes().get(0); // Retrieve method parameter type (expected to be Object[])
214+
assertEquals(objectArrayType, methodParameterType); // The method parameter type should match the expected Object[], but will be T[]
215+
}
172216
}

Procyon.Reflection/src/test/java/com/strobel/reflection/emit/TypeBuilderTests.java

+5
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ public void testTypeBuilderArrayTypes() throws Throwable {
363363
final Type<?> createdTypeVariable = createdType.getGenericTypeParameters().get(0);
364364
final Type<?> createdTypeVariableArray = createdTypeVariable.makeArrayType();
365365

366+
assertNotSame(createdType, type);
367+
assertNotSame(createdArrayType, arrayType);
368+
assertNotSame(createdTypeVariable, typeVariable);
369+
assertNotSame(createdTypeVariableArray, typeVariableArray);
370+
366371
assertTrue(type.isEquivalentTo(createdType));
367372
assertTrue(createdType.isEquivalentTo(type));
368373
assertTrue(arrayType.isEquivalentTo(createdArrayType));

0 commit comments

Comments
 (0)