You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/07/01 17:13:20 UTC
[groovy] branch GROOVY_4_0_X updated: sync with `master`
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
new c3b5eaf0f3 sync with `master`
c3b5eaf0f3 is described below
commit c3b5eaf0f397ccae6e1391c9d14d6ddab62bcb94
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jul 1 11:59:16 2022 -0500
sync with `master`
---
.../ast/decompiled/AsmReferenceResolver.java | 17 +-
.../ast/decompiled/ClassSignatureParser.java | 75 +++++----
.../groovy/ast/decompiled/DecompiledClassNode.java | 184 ++++++++++-----------
.../ast/decompiled/FormalParameterParser.java | 38 +++--
.../stc/ClosureParamTypeInferenceSTCTest.groovy | 172 +++++++++++--------
.../classgen/asm/BinaryOperationsTest.groovy | 41 +++--
6 files changed, 292 insertions(+), 235 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java
index 64cf500630..70c35b30b7 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/AsmReferenceResolver.java
@@ -35,12 +35,12 @@ public class AsmReferenceResolver {
private final ClassNodeResolver resolver;
private final CompilationUnit unit;
- public AsmReferenceResolver(ClassNodeResolver resolver, CompilationUnit unit) {
+ public AsmReferenceResolver(final ClassNodeResolver resolver, final CompilationUnit unit) {
this.resolver = resolver;
this.unit = unit;
}
- public ClassNode resolveClass(String className) {
+ public ClassNode resolveClass(final String className) {
ClassNode classNode = resolveClassNullable(className);
if (classNode == null) {
throw new NoClassDefFoundError(className);
@@ -48,20 +48,20 @@ public class AsmReferenceResolver {
return classNode;
}
- public ClassNode resolveClassNullable(String className) {
+ public ClassNode resolveClassNullable(final String className) {
ClassNode beingCompiled = unit.getAST().getClass(className);
if (beingCompiled != null) {
return beingCompiled;
}
ClassNodeResolver.LookupResult lookupResult = resolver.resolveName(className, unit);
- return lookupResult == null ? null :lookupResult.getClassNode();
+ return lookupResult != null ? lookupResult.getClassNode() : null;
}
- public ClassNode resolveType(Type type) {
+ public ClassNode resolveType(final Type type) {
if (type.getSort() == Type.ARRAY) {
ClassNode result = resolveNonArrayType(type.getElementType());
- for (int i = 0; i < type.getDimensions(); i++) {
+ for (int n = type.getDimensions(); n > 0; n -= 1) {
result = result.makeArray();
}
return result;
@@ -70,7 +70,7 @@ public class AsmReferenceResolver {
return resolveNonArrayType(type);
}
- private ClassNode resolveNonArrayType(Type type) {
+ private ClassNode resolveNonArrayType(final Type type) {
String className = type.getClassName();
if (type.getSort() != Type.OBJECT) {
return ClassHelper.make(className);
@@ -79,12 +79,11 @@ public class AsmReferenceResolver {
return resolveClass(className);
}
- public Class resolveJvmClass(String name) {
+ public Class resolveJvmClass(final String name) {
try {
return unit.getClassLoader().loadClass(name, false, true);
} catch (ClassNotFoundException e) {
throw new GroovyBugError("JVM class can't be loaded for " + name, e);
}
}
-
}
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java
index ca7e090218..443a810dad 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/ClassSignatureParser.java
@@ -18,7 +18,6 @@
*/
package org.codehaus.groovy.ast.decompiled;
-import org.apache.groovy.util.ObjectHolder;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.GenericsType;
import org.codehaus.groovy.ast.RecordComponentNode;
@@ -31,81 +30,87 @@ import java.util.List;
import java.util.stream.Collectors;
class ClassSignatureParser {
- static void configureClass(ClassNode classNode, ClassStub stub, AsmReferenceResolver resolver) {
+
+ static void configureClass(final ClassNode classNode, final ClassStub stub, final AsmReferenceResolver resolver) {
if (stub.signature != null) {
parseClassSignature(classNode, stub.signature, resolver);
return;
}
if (stub.superName != null) {
- classNode.setSuperClass(resolver.resolveClass(AsmDecompiler.fromInternalName(stub.superName)));
+ ClassNode sc = resolver.resolveClass(AsmDecompiler.fromInternalName(stub.superName));
+ classNode.setSuperClass(sc);
}
- ClassNode[] interfaces = new ClassNode[stub.interfaceNames.length];
- for (int i = 0; i < stub.interfaceNames.length; i++) {
- interfaces[i] = resolver.resolveClass(AsmDecompiler.fromInternalName(stub.interfaceNames[i]));
+ {
+ final int nInterfaces = stub.interfaceNames.length;
+ ClassNode[] interfaces = new ClassNode[nInterfaces];
+ for (int i = 0; i < nInterfaces; i += 1) { String name = stub.interfaceNames[i];
+ interfaces[i] = resolver.resolveClass(AsmDecompiler.fromInternalName(name));
+ }
+ classNode.setInterfaces(interfaces);
}
- classNode.setInterfaces(interfaces);
+
if (!stub.permittedSubclasses.isEmpty()) {
- List<ClassNode> permittedSubclasses = classNode.getPermittedSubclasses();
+ List<ClassNode> permitted = classNode.getPermittedSubclasses(); // collector
for (String name : stub.permittedSubclasses) {
- permittedSubclasses.add(resolver.resolveClass(AsmDecompiler.fromInternalName(name)));
+ ClassNode ps = resolver.resolveClass(AsmDecompiler.fromInternalName(name));
+ permitted.add(ps);
}
}
if (!stub.recordComponents.isEmpty()) {
- classNode.setRecordComponents(stub.recordComponents.stream().map(r -> {
- ClassNode type = resolver.resolveType(Type.getType(r.descriptor));
- ObjectHolder<ClassNode> typeHolder = new ObjectHolder<>(type);
- if (null != r.signature) {
- new SignatureReader(r.signature).accept(new TypeSignatureParser(resolver) {
+ classNode.setRecordComponents(stub.recordComponents.stream().map(rc -> {
+ ClassNode[] type = {resolver.resolveType(Type.getType(rc.descriptor))};
+ if (rc.signature != null) {
+ new SignatureReader(rc.signature).accept(new TypeSignatureParser(resolver) {
@Override
void finished(final ClassNode result) {
- typeHolder.setObject(applyErasure(result, typeHolder.getObject()));
+ type[0] = applyErasure(result, type[0]);
}
});
}
- ClassNode cn = typeHolder.getObject();
- Annotations.addTypeAnnotations(r, cn, resolver);
- RecordComponentNode recordComponentNode = new RecordComponentNode(classNode, r.name, cn);
- Annotations.addAnnotations(r, recordComponentNode, resolver);
- return recordComponentNode;
+ ClassNode rcType = type[0];
+ Annotations.addTypeAnnotations(rc, rcType, resolver);
+
+ RecordComponentNode recordComponent = new RecordComponentNode(classNode, rc.name, rcType);
+ Annotations.addAnnotations(rc, recordComponent, resolver);
+ return recordComponent;
}).collect(Collectors.toList()));
}
}
- private static void parseClassSignature(final ClassNode classNode, String signature, final AsmReferenceResolver resolver) {
- final List<ClassNode> interfaces = new ArrayList<ClassNode>();
- FormalParameterParser v = new FormalParameterParser(resolver) {
+ private static void parseClassSignature(final ClassNode classNode, final String signature, final AsmReferenceResolver resolver) {
+ List<ClassNode> interfaces = new ArrayList<>();
+ FormalParameterParser parser = new FormalParameterParser(resolver) {
@Override
public SignatureVisitor visitSuperclass() {
flushTypeParameter();
return new TypeSignatureParser(resolver) {
@Override
- void finished(ClassNode result) {
- classNode.setSuperClass(result);
+ void finished(final ClassNode superClass) {
+ classNode.setSuperClass(superClass);
}
};
}
-
@Override
public SignatureVisitor visitInterface() {
flushTypeParameter();
return new TypeSignatureParser(resolver) {
@Override
- void finished(ClassNode result) {
- interfaces.add(result);
+ void finished(final ClassNode superInterface) {
+ interfaces.add(superInterface);
}
};
}
-
};
- new SignatureReader(signature).accept(v);
- GenericsType[] typeParameters = v.getTypeParameters();
- if (typeParameters.length > 0) {
- classNode.setGenericsTypes(typeParameters);
- }
- classNode.setInterfaces(interfaces.toArray(ClassNode.EMPTY_ARRAY));
+ new SignatureReader(signature).accept(parser);
+
+ classNode.setInterfaces(interfaces.isEmpty() ? ClassNode.EMPTY_ARRAY :
+ interfaces.toArray(ClassNode.EMPTY_ARRAY));
+
+ GenericsType[] typeParameters = parser.getTypeParameters();
+ if (typeParameters.length > 0) classNode.setGenericsTypes(typeParameters);
}
}
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java b/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java
index a803be6915..52d32dc677 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/DecompiledClassNode.java
@@ -40,13 +40,12 @@ import java.util.function.Supplier;
* @see AsmDecompiler
*/
public class DecompiledClassNode extends ClassNode {
+
private final ClassStub classData;
private final AsmReferenceResolver resolver;
- private volatile boolean supersInitialized;
- private volatile boolean membersInitialized;
public DecompiledClassNode(final ClassStub classData, final AsmReferenceResolver resolver) {
- super(classData.className, getFullModifiers(classData), null, null, MixinNode.EMPTY_ARRAY);
+ super(classData.className, getModifiers(classData), null, null, MixinNode.EMPTY_ARRAY);
this.classData = classData;
this.resolver = resolver;
isPrimaryNode = false;
@@ -57,11 +56,12 @@ public class DecompiledClassNode extends ClassNode {
* the INNERCLASS reference since the top-level modifiers for inner classes
* wont include static or private/protected.
*/
- private static int getFullModifiers(ClassStub data) {
- return (data.innerClassModifiers == -1)
- ? data.accessModifiers : data.innerClassModifiers;
+ private static int getModifiers(ClassStub classData) {
+ return (classData.innerClassModifiers != -1 ? classData.innerClassModifiers : classData.accessModifiers);
}
+ //
+
public long getCompilationTimeStamp() {
if (classData.fields != null) {
for (FieldStub field : classData.fields) {
@@ -77,64 +77,59 @@ public class DecompiledClassNode extends ClassNode {
}
@Override
- public GenericsType[] getGenericsTypes() {
- lazyInitSupers();
- return super.getGenericsTypes();
- }
-
- @Override
- public boolean isUsingGenerics() {
- lazyInitSupers();
- return super.isUsingGenerics();
+ public Class getTypeClass() {
+ return resolver.resolveJvmClass(getName());
}
- @Override
- public List<FieldNode> getFields() {
- lazyInitMembers();
- return super.getFields();
+ public boolean isParameterized() {
+ return (classData.signature != null && classData.signature.charAt(0) == '<');
}
@Override
- public ClassNode[] getInterfaces() {
- lazyInitSupers();
- return super.getInterfaces();
+ public boolean isResolved() {
+ return true;
}
@Override
- public List<MethodNode> getMethods() {
- lazyInitMembers();
- return super.getMethods();
+ public boolean isSealed() {
+ // check Groovy "sealed"
+ List<AnnotationStub> annotations = classData.annotations;
+ if (annotations != null) {
+ for (AnnotationStub stub : annotations) {
+ if (stub.className.equals("groovy.transform.Sealed")) {
+ return true;
+ }
+ }
+ }
+ // check Java "sealed"
+ try {
+ return ReflectionUtils.isSealed(getTypeClass());
+ } catch (NoClassDefFoundError ignored) {
+ }
+ return false;
}
@Override
- public List<ConstructorNode> getDeclaredConstructors() {
- lazyInitMembers();
- return super.getDeclaredConstructors();
+ public String setName(String name) {
+ throw new UnsupportedOperationException();
}
@Override
- public FieldNode getDeclaredField(String name) {
- lazyInitMembers();
- return super.getDeclaredField(name);
+ public void setRedirect(ClassNode cn) {
+ throw new UnsupportedOperationException();
}
@Override
- public List<MethodNode> getDeclaredMethods(String name) {
- lazyInitMembers();
- return super.getDeclaredMethods(name);
+ public void setUsingGenerics(boolean b) {
+ throw new UnsupportedOperationException();
}
@Override
- public ClassNode getUnresolvedSuperClass(boolean useRedirect) {
- lazyInitSupers();
- return super.getUnresolvedSuperClass(useRedirect);
+ public void setGenericsPlaceHolder(boolean b) {
+ throw new UnsupportedOperationException();
}
- @Override
- public ClassNode[] getUnresolvedInterfaces(boolean useRedirect) {
- lazyInitSupers();
- return super.getUnresolvedInterfaces(useRedirect);
- }
+ //--------------------------------------------------------------------------
@Override
public List<AnnotationNode> getAnnotations() {
@@ -149,70 +144,42 @@ public class DecompiledClassNode extends ClassNode {
}
@Override
- public void setRedirect(ClassNode cn) {
- throw new UnsupportedOperationException();
+ public GenericsType[] getGenericsTypes() {
+ lazyInitSupers();
+ return super.getGenericsTypes();
}
@Override
- public void setGenericsPlaceHolder(boolean b) {
- throw new UnsupportedOperationException();
+ public ClassNode[] getInterfaces() {
+ lazyInitSupers();
+ return super.getInterfaces();
}
@Override
- public void setUsingGenerics(boolean b) {
- throw new UnsupportedOperationException();
+ public List<RecordComponentNode> getRecordComponents() {
+ lazyInitSupers();
+ return super.getRecordComponents();
}
@Override
- public String setName(String name) {
- throw new UnsupportedOperationException();
- }
-
- public boolean isParameterized() {
- return (classData.signature != null && classData.signature.charAt(0) == '<');
+ public ClassNode[] getUnresolvedInterfaces(boolean useRedirect) {
+ lazyInitSupers();
+ return super.getUnresolvedInterfaces(useRedirect);
}
@Override
- public boolean isResolved() {
- return true;
+ public ClassNode getUnresolvedSuperClass(boolean useRedirect) {
+ lazyInitSupers();
+ return super.getUnresolvedSuperClass(useRedirect);
}
@Override
- public boolean isSealed() {
- List<AnnotationStub> annotations = classData.annotations;
- if (annotations != null) {
- for (AnnotationStub stub : annotations) {
- if (stub.className.equals("groovy.transform.Sealed")) {
- return true;
- }
- }
- }
- return isSealedSafe();
- }
-
- private boolean isSealedSafe() {
- try {
- return ReflectionUtils.isSealed(getTypeClass());
- } catch (NoClassDefFoundError ignored) {
- }
- return false;
- }
-
- /**
- * Get the record components of record types
- *
- * @return {@code RecordComponentNode} instances
- * @since 4.0.0
- */
- public List<RecordComponentNode> getRecordComponents() {
+ public boolean isUsingGenerics() {
lazyInitSupers();
- return super.getRecordComponents();
+ return super.isUsingGenerics();
}
- @Override
- public Class getTypeClass() {
- return resolver.resolveJvmClass(getName());
- }
+ private volatile boolean supersInitialized;
private void lazyInitSupers() {
if (supersInitialized) return;
@@ -226,6 +193,40 @@ public class DecompiledClassNode extends ClassNode {
}
}
+ //--------------------------------------------------------------------------
+
+ @Override
+ public List<ConstructorNode> getDeclaredConstructors() {
+ lazyInitMembers();
+ return super.getDeclaredConstructors();
+ }
+
+ @Override
+ public FieldNode getDeclaredField(final String name) {
+ lazyInitMembers();
+ return super.getDeclaredField(name);
+ }
+
+ @Override
+ public List<MethodNode> getDeclaredMethods(final String name) {
+ lazyInitMembers();
+ return super.getDeclaredMethods(name);
+ }
+
+ @Override
+ public List<FieldNode> getFields() {
+ lazyInitMembers();
+ return super.getFields();
+ }
+
+ @Override
+ public List<MethodNode> getMethods() {
+ lazyInitMembers();
+ return super.getMethods();
+ }
+
+ private volatile boolean membersInitialized;
+
private void lazyInitMembers() {
if (membersInitialized) return;
@@ -233,7 +234,7 @@ public class DecompiledClassNode extends ClassNode {
if (!membersInitialized) {
if (classData.methods != null) {
for (MethodStub method : classData.methods) {
- if (isConstructor(method)) {
+ if ("<init>".equals(method.methodName)) {
addConstructor(createConstructor(method));
} else {
addMethod(createMethodNode(method));
@@ -281,9 +282,4 @@ public class DecompiledClassNode extends ClassNode {
return constructorNodeSupplier.get();
}
-
- private boolean isConstructor(MethodStub method) {
- return "<init>".equals(method.methodName);
- }
-
}
diff --git a/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java b/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java
index 2e7b1ebf0b..55de8532cb 100644
--- a/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java
+++ b/src/main/java/org/codehaus/groovy/ast/decompiled/FormalParameterParser.java
@@ -29,33 +29,40 @@ import java.util.List;
import static org.codehaus.groovy.control.CompilerConfiguration.ASM_API_VERSION;
abstract class FormalParameterParser extends SignatureVisitor {
- private final AsmReferenceResolver resolver;
+
private String currentTypeParameter;
- private final List<ClassNode> parameterBounds = new ArrayList<ClassNode>();
- private final List<GenericsType> typeParameters = new ArrayList<GenericsType>();
+ private final List<ClassNode> parameterBounds = new ArrayList<>();
+ private final List<GenericsType> typeParameters = new ArrayList<>();
+
+ private final AsmReferenceResolver resolver;
- public FormalParameterParser(AsmReferenceResolver resolver) {
+ public FormalParameterParser(final AsmReferenceResolver resolver) {
super(ASM_API_VERSION);
this.resolver = resolver;
}
- @Override
- public void visitFormalTypeParameter(String name) {
- flushTypeParameter();
- currentTypeParameter = name;
- }
-
protected void flushTypeParameter() {
if (currentTypeParameter != null) {
ClassNode ref = Java8.configureTypeVariableReference(currentTypeParameter);
- ClassNode[] boundNodes = parameterBounds.toArray(ClassNode.EMPTY_ARRAY);
- typeParameters.add(Java8.configureTypeVariableDefinition(ref, boundNodes));
+ ClassNode[] theBoundTypes = parameterBounds.toArray(ClassNode.EMPTY_ARRAY);
+ typeParameters.add(Java8.configureTypeVariableDefinition(ref, theBoundTypes));
- currentTypeParameter = null;
parameterBounds.clear();
+ currentTypeParameter = null;
}
}
+ public GenericsType[] getTypeParameters() {
+ flushTypeParameter();
+ return typeParameters.toArray(GenericsType.EMPTY_ARRAY);
+ }
+
+ @Override
+ public void visitFormalTypeParameter(final String name) {
+ flushTypeParameter();
+ currentTypeParameter = name;
+ }
+
@Override
public SignatureVisitor visitClassBound() {
return new TypeSignatureParser(resolver) {
@@ -70,9 +77,4 @@ abstract class FormalParameterParser extends SignatureVisitor {
public SignatureVisitor visitInterfaceBound() {
return visitClassBound();
}
-
- public GenericsType[] getTypeParameters() {
- flushTypeParameter();
- return typeParameters.toArray(GenericsType.EMPTY_ARRAY);
- }
}
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index 88a1e27744..8a74e3d12a 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -582,30 +582,30 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
void testInferenceForDGM_dropWhileOnIterable() {
assertScript '''
- assert (0..10).dropWhile { it<5 } == (5..10)
- assert (0..10).dropWhile { int i -> i<5 } == (5..10)
+ assert (0..10).dropWhile { it<5 } == (5..10)
+ assert (0..10).dropWhile { int i -> i<5 } == (5..10)
'''
}
void testInferenceForDGM_dropWhileOnList() {
assertScript '''
- assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { it<5 } == [5,6,7,8,9,10]
- assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { int i -> i<5 } == [5,6,7,8,9,10]
+ assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { it<5 } == [5,6,7,8,9,10]
+ assert [0,1,2,3,4,5,6,7,8,9,10].dropWhile { int i -> i<5 } == [5,6,7,8,9,10]
'''
}
void testInferenceForDGM_dropWhileOnIterator() {
assertScript '''
- assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
- assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
+ assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
+ assert [0,1,2,3,4,5,6,7,8,9,10].iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
'''
}
void testInferenceForDGM_dropWhileOnArray() {
assertScript '''
- Integer[] array = [0,1,2,3,4,5,6,7,8,9,10]
- assert array.iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
- assert array.iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
+ Integer[] array = [0,1,2,3,4,5,6,7,8,9,10]
+ assert array.iterator().dropWhile { it<5 } as List == [5,6,7,8,9,10]
+ assert array.iterator().dropWhile { int i -> i<5 } as List == [5,6,7,8,9,10]
'''
}
@@ -640,13 +640,15 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
}
@NotYetImplemented
void testInferenceForDGM_eachWithIndexOnRecursiveIterable() { // GROOVY-10651
- assertScript '''
- void proc(groovy.transform.stc.TreeNode node) {
- node.eachWithIndex { child, index ->
- proc(child) // recurse
+ ['', '<?>'].each { args ->
+ assertScript """
+ void proc(groovy.transform.stc.TreeNode$args node) {
+ node.eachWithIndex { child, index ->
+ proc(child) // recurse
+ }
}
- }
- '''
+ """
+ }
}
void testInferenceForDGM_everyOnIterable() {
@@ -1052,18 +1054,16 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
void testDGM_sortOnMap() {
assertScript '''
- def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }
- assert map == [b:3, d:4, a:5, c:6]
+ def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }
+ assert map == [b:3, d:4, a:5, c:6]
'''
-
assertScript '''
- def map = [a:5, b:3, c:6, d:4].sort { a -> a.value }
- assert map == [b:3, d:4, a:5, c:6]
+ def map = [a:5, b:3, c:6, d:4].sort { a -> a.value }
+ assert map == [b:3, d:4, a:5, c:6]
'''
-
assertScript '''
- def map = [a:5, b:3, c:6, d:4].sort { it.value }
- assert map == [b:3, d:4, a:5, c:6]
+ def map = [a:5, b:3, c:6, d:4].sort { it.value }
+ assert map == [b:3, d:4, a:5, c:6]
'''
}
@@ -1075,42 +1075,45 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
void testDGM_takeWhileOnIterable() {
assertScript '''
- class AbcIterable implements Iterable<String> {
- Iterator<String> iterator() { "abc".iterator() }
- }
- def abc = new AbcIterable()
- assert abc.takeWhile{ it < 'b' } == ['a']
- assert abc.takeWhile{ it <= 'b' } == ['a', 'b']
-'''
+ class AbcIterable implements Iterable<String> {
+ Iterator<String> iterator() { "abc".iterator() }
+ }
+ def abc = new AbcIterable()
+ assert abc.takeWhile{ it < 'b' } == ['a']
+ assert abc.takeWhile{ it <= 'b' } == ['a', 'b']
+ '''
}
void testDGM_takeWhileOnIterator() {
assertScript '''
- class AbcIterable implements Iterable<String> {
- Iterator<String> iterator() { "abc".iterator() }
- }
- def abc = new AbcIterable()
- assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
- assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
-'''
+ class AbcIterable implements Iterable<String> {
+ Iterator<String> iterator() { "abc".iterator() }
+ }
+ def abc = new AbcIterable()
+ assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+ assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+ '''
}
void testDGM_takeWhileOnList() {
assertScript '''
- def abc = ['a','b','c']
- assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
- assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']'''
+ def abc = ['a','b','c']
+ assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
+ assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+ '''
}
void testDGM_takeWhileOnArray() {
assertScript '''
String[] abc = ['a','b','c']
assert abc.iterator().takeWhile{ it < 'b' }.collect() == ['a']
- assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']'''
+ assert abc.iterator().takeWhile{ it <= 'b' }.collect() == ['a', 'b']
+ '''
}
void testDGM_takeWhileOnMap() {
assertScript '''
def shopping = [milk:1, bread:2, chocolate:3]
assert shopping.takeWhile{ it.key.size() < 6 } == [milk:1, bread:2]
assert shopping.takeWhile{ it.value % 2 } == [milk:1]
- assert shopping.takeWhile{ k, v -> k.size() + v <= 7 } == [milk:1, bread:2]'''
+ assert shopping.takeWhile{ k, v -> k.size() + v <= 7 } == [milk:1, bread:2]
+ '''
}
void testDGM_times() {
@@ -1124,35 +1127,41 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
void testDGM_unique() {
assertScript '''
- def orig = [1, 3, 4, 5]
- def uniq = orig.unique(false) { it % 2 }
- assert orig == [1, 3, 4, 5]
- assert uniq == [1, 4]'''
-
- assertScript '''def orig = [2, 3, 3, 4]
- def uniq = orig.unique(false) { a, b -> a <=> b }
- assert orig == [2, 3, 3, 4]
- assert uniq == [2, 3, 4]'''
+ def orig = [1, 3, 4, 5]
+ def uniq = orig.unique(false) { it % 2 }
+ assert orig == [1, 3, 4, 5]
+ assert uniq == [1, 4]
+ '''
+ assertScript '''
+ def orig = [2, 3, 3, 4]
+ def uniq = orig.unique(false) { a, b -> a <=> b }
+ assert orig == [2, 3, 3, 4]
+ assert uniq == [2, 3, 4]
+ '''
}
void testDGM_uniqueOnCollection() {
assertScript '''
- def orig = [1, 3, 4, 5]
- def uniq = orig.unique { it % 2 }
- assert uniq == [1, 4]'''
-
- assertScript '''def orig = [2, 3, 3, 4]
- def uniq = orig.unique { a, b -> a <=> b }
- assert uniq == [2, 3, 4]'''
+ def orig = [1, 3, 4, 5]
+ def uniq = orig.unique { it % 2 }
+ assert uniq == [1, 4]
+ '''
+ assertScript '''
+ def orig = [2, 3, 3, 4]
+ def uniq = orig.unique { a, b -> a <=> b }
+ assert uniq == [2, 3, 4]
+ '''
}
void testDGM_uniqueOnIterator() {
assertScript '''
- def orig = [1, 3, 4, 5].iterator()
- def uniq = orig.unique { it % 2 }.collect()
- assert uniq == [1, 4]'''
-
- assertScript '''def orig = [2, 3, 3, 4].iterator()
- def uniq = orig.unique { a, b -> a <=> b }.collect()
- assert uniq == [2, 3, 4]'''
+ def orig = [1, 3, 4, 5].iterator()
+ def uniq = orig.unique { it % 2 }.collect()
+ assert uniq == [1, 4]
+ '''
+ assertScript '''
+ def orig = [2, 3, 3, 4].iterator()
+ def uniq = orig.unique { a, b -> a <=> b }.collect()
+ assert uniq == [2, 3, 4]
+ '''
}
void testDGM_anyOnMap() {
@@ -1232,6 +1241,21 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ @NotYetImplemented
+ void testGroovy6022() {
+ assertScript '''import groovy.transform.stc.SimpleType
+ class Item {
+ int x
+ }
+
+ void m(Item item, @ClosureParams(value=SimpleType, options="Item") Closure... closures) {
+ closures*.call(item)
+ }
+
+ m(new Item(), { item -> item.x }, { it.x })
+ '''
+ }
+
void testGroovy6602() {
shouldFailWithMessages '''import groovy.transform.stc.SimpleType
void foo(@ClosureParams(value=SimpleType, options="java.lang.Number") Closure c) {
@@ -1511,4 +1535,22 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
m((text, item) -> { })
'''
}
+
+ void testGroovy10673() {
+ assertScript '''import java.util.function.Consumer
+
+ void proc(Consumer<Number> action) {
+ action.accept(1.2345)
+ }
+
+ int i = 0
+ proc { n ->
+ def c = {
+ i = n.intValue()
+ }
+ c()
+ }
+ assert i == 1
+ '''
+ }
}
diff --git a/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy
index a7ce4820f7..6255532e6f 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/BinaryOperationsTest.groovy
@@ -104,32 +104,45 @@ class BinaryOperationsTest extends AbstractBytecodeTestCase {
void testCharXor() {
if (config.indyEnabled) return;
- assert compile("""
- int i = ('a' as char) ^ ('b' as char)
- """).hasStrictSequence ([
- "IXOR"
+ assert compile('''
+ int i = ('a' as char) ^ ('b' as char)
+ ''').hasStrictSequence ([
+ 'IXOR'
])
}
+ // GROOVY-10657
+ void testPutAtValue() {
+ def sequence = compile '''
+ class C {
+ void putAt(String key, Object value) {
+ }
+ }
+
+ def obj = new C()
+ obj['key'] = 'xx'
+ '''
+ }
+
void testPrimitiveOrAssign() {
['byte','int','short','long'].each { type ->
assertScript """
- $type[] b = new $type[1]
- b[0] = 16
- b[0] |= 2
- assert b[0] == 18:"Failure for type $type"
+ $type[] array = new $type[1]
+ array[0] = 16
+ array[0] |= 2
+ assert array[0] == 18 : "Failure for type $type"
"""
- }
+ }
}
void testPrimitiveAndAssign() {
['byte','int','short','long'].each { type ->
assertScript """
- $type[] b = new $type[1]
- b[0] = 18
- b[0] &= 2
- assert b[0] == 2:"Failure for type $type"
+ $type[] array = new $type[1]
+ array[0] = 18
+ array[0] &= 2
+ assert array[0] == 2 : "Failure for type $type"
"""
- }
+ }
}
}