You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2017/12/19 10:25:19 UTC
[1/2] groovy git commit: update checkstyle for latest build
Repository: groovy
Updated Branches:
refs/heads/GROOVY_2_5_X dafabb2eb -> 13522f887
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr617.patch
----------------------------------------------------------------------
diff --git a/pr617.patch b/pr617.patch
new file mode 100644
index 0000000..23f72a7
--- /dev/null
+++ b/pr617.patch
@@ -0,0 +1,293 @@
+From 2e36707b9446f8b48a85bee26f6ec746d56e8b95 Mon Sep 17 00:00:00 2001
+From: aalmiray <aa...@gmail.com>
+Date: Wed, 11 Oct 2017 16:34:27 +0200
+Subject: [PATCH 1/2] GROOVY-8352: add a @Generated annotation
+
+---
+ src/main/groovy/transform/Generated.java | 36 ++++++++++
+ .../org/codehaus/groovy/classgen/Verifier.java | 22 +++---
+ .../groovy/tools/javac/JavaStubGenerator.java | 10 +--
+ .../groovy/transform/GeneratedTransformTest.groovy | 81 ++++++++++++++++++++++
+ 4 files changed, 136 insertions(+), 13 deletions(-)
+ create mode 100644 src/main/groovy/transform/Generated.java
+ create mode 100644 src/test/org/codehaus/groovy/transform/GeneratedTransformTest.groovy
+
+diff --git a/src/main/groovy/transform/Generated.java b/src/main/groovy/transform/Generated.java
+new file mode 100644
+index 0000000000..f7ea40af6d
+--- /dev/null
++++ b/src/main/groovy/transform/Generated.java
+@@ -0,0 +1,36 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package groovy.transform;
++
++import java.lang.annotation.ElementType;
++import java.lang.annotation.Retention;
++import java.lang.annotation.RetentionPolicy;
++import java.lang.annotation.Target;
++
++/**
++ * The Generated annotation is used to mark members that have been generated.
++ *
++ * @author Andres Almiray
++ * @author Jochen Theodorou
++ * @author Mark Hoffmann
++ */
++@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.FIELD})
++@Retention(RetentionPolicy.RUNTIME)
++public @interface Generated {
++}
+diff --git a/src/main/org/codehaus/groovy/classgen/Verifier.java b/src/main/org/codehaus/groovy/classgen/Verifier.java
+index b98e784577..f1251d7e7a 100644
+--- a/src/main/org/codehaus/groovy/classgen/Verifier.java
++++ b/src/main/org/codehaus/groovy/classgen/Verifier.java
+@@ -21,6 +21,7 @@
+ import groovy.lang.GroovyClassLoader;
+ import groovy.lang.GroovyObject;
+ import groovy.lang.MetaClass;
++import groovy.transform.Generated;
+ import org.codehaus.groovy.GroovyBugError;
+ import org.codehaus.groovy.ast.*;
+ import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+@@ -124,6 +125,8 @@
+ new Parameter(ClassHelper.METACLASS_TYPE, "mc")
+ };
+
++ private static final Class GENERATED_ANNOTATION = Generated.class;
++
+ private ClassNode classNode;
+ private MethodNode methodNode;
+
+@@ -384,6 +387,7 @@ public void visit(MethodVisitor mv) {
+ protected void addGroovyObjectInterfaceAndMethods(ClassNode node, final String classInternalName) {
+ if (!node.isDerivedFromGroovyObject()) node.addInterface(ClassHelper.make(GroovyObject.class));
+ FieldNode metaClassField = getMetaClassField(node);
++ AnnotationNode generatedAnnotation = new AnnotationNode(ClassHelper.make(GENERATED_ANNOTATION));
+
+ if (!node.hasMethod("getMetaClass", Parameter.EMPTY_ARRAY)) {
+ metaClassField = setMetaClassFieldIfNotExists(node, metaClassField);
+@@ -425,7 +429,7 @@ public void visit(MethodVisitor mv) {
+ mv.visitInsn(ARETURN);
+ }
+ })
+- );
++ ).addAnnotation(generatedAnnotation);
+ }
+
+ Parameter[] parameters = new Parameter[]{new Parameter(ClassHelper.METACLASS_TYPE, "mc")};
+@@ -459,7 +463,7 @@ public void visit(MethodVisitor mv) {
+ ACC_PUBLIC, ClassHelper.VOID_TYPE,
+ SET_METACLASS_PARAMS, ClassNode.EMPTY_ARRAY,
+ setMetaClassCode
+- );
++ ).addAnnotation(generatedAnnotation);
+ }
+
+ if (!node.hasMethod("invokeMethod", INVOKE_METHOD_PARAMS)) {
+@@ -485,7 +489,7 @@ public void visit(MethodVisitor mv) {
+ mv.visitInsn(ARETURN);
+ }
+ })
+- );
++ ).addAnnotation(generatedAnnotation);
+ }
+
+ if (!node.hasMethod("getProperty", GET_PROPERTY_PARAMS)) {
+@@ -505,7 +509,7 @@ public void visit(MethodVisitor mv) {
+ mv.visitInsn(ARETURN);
+ }
+ })
+- );
++ ).addAnnotation(generatedAnnotation);
+ }
+
+ if (!node.hasMethod("setProperty", SET_PROPERTY_PARAMS)) {
+@@ -526,7 +530,7 @@ public void visit(MethodVisitor mv) {
+ mv.visitInsn(RETURN);
+ }
+ })
+- );
++ ).addAnnotation(generatedAnnotation);
+ }
+ }
+
+@@ -535,12 +539,12 @@ public void visit(MethodVisitor mv) {
+ * call will either be made to ClassNode.addSyntheticMethod() or ClassNode.addMethod(). If a non-synthetic method
+ * is to be added the ACC_SYNTHETIC modifier is removed if it has been accidentally supplied.
+ */
+- protected void addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters,
+- ClassNode[] exceptions, Statement code) {
++ protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters,
++ ClassNode[] exceptions, Statement code) {
+ if (shouldBeSynthetic) {
+- node.addSyntheticMethod(name, modifiers, returnType, parameters, exceptions, code);
++ return node.addSyntheticMethod(name, modifiers, returnType, parameters, exceptions, code);
+ } else {
+- node.addMethod(name, modifiers & ~ACC_SYNTHETIC, returnType, parameters, exceptions, code);
++ return node.addMethod(name, modifiers & ~ACC_SYNTHETIC, returnType, parameters, exceptions, code);
+ }
+ }
+
+diff --git a/src/main/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+index b672793c18..89d45aeba2 100644
+--- a/src/main/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
++++ b/src/main/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+@@ -155,8 +155,8 @@ protected void addPropertyMethod(MethodNode method) {
+ doAddMethod(method);
+ }
+ protected void addReturnIfNeeded(MethodNode node) {}
+- protected void addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
+- doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
++ protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
++ return doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
+ }
+
+ protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
+@@ -184,13 +184,15 @@ protected void addDefaultParameters(DefaultArgsAction action, MethodNode method)
+ }
+ }
+
+- private void doAddMethod(MethodNode method) {
++ private MethodNode doAddMethod(MethodNode method) {
+ String sig = method.getTypeDescriptor();
+
+- if (propertyMethodsWithSigs.containsKey(sig)) return;
++ if (propertyMethodsWithSigs.containsKey(sig)) return method;
+
+ propertyMethods.add(method);
+ propertyMethodsWithSigs.put(sig, method);
++
++ return method;
+ }
+
+ @Override
+diff --git a/src/test/org/codehaus/groovy/transform/GeneratedTransformTest.groovy b/src/test/org/codehaus/groovy/transform/GeneratedTransformTest.groovy
+new file mode 100644
+index 0000000000..34e9f0ea0c
+--- /dev/null
++++ b/src/test/org/codehaus/groovy/transform/GeneratedTransformTest.groovy
+@@ -0,0 +1,81 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package org.codehaus.groovy.transform
++
++import org.junit.After
++import org.junit.Before
++import org.junit.Rule
++import org.junit.Test
++import org.junit.rules.TestName
++import org.junit.runner.RunWith
++import org.junit.runners.JUnit4
++
++import static org.junit.Assume.assumeTrue
++
++/**
++ * Tests for the @Generated annotation.
++ */
++@RunWith(JUnit4)
++class GeneratedTransformTest extends GroovyShellTestCase {
++ @Rule public TestName nameRule = new TestName()
++
++ @Before
++ void setUp() {
++ super.setUp()
++ // check java version requirements
++ def v = System.getProperty("java.specification.version")
++ assert v
++ assumeTrue('Test requires jre8+', nameRule.methodName.endsWith('_vm8').implies(new BigDecimal(v) >= 1.8))
++ }
++
++ @After
++ void tearDown() {
++ super.tearDown()
++ }
++
++ @Test
++ void testDefaultGroovyMethodsAreAnnotatedWithGenerated() {
++ def person = evaluate('''
++ class Person {
++ String name
++ }
++ new Person()
++ ''')
++
++ GroovyObject.declaredMethods.each { m ->
++ def method = person.class.declaredMethods.find { it.name == m.name }
++ assert method.annotations*.annotationType().name == ['groovy.transform.Generated']
++ }
++ }
++
++ @Test
++ void testOverridenDefaultGroovyMethodsAreNotAnnotatedWithGenerated() {
++ def person = evaluate('''
++ class Person {
++ String name
++
++ def invokeMethod(String name, args) { }
++ }
++ new Person()
++ ''')
++
++ def method = person.class.declaredMethods.find { it.name == 'invokeMethod' }
++ assert !('groovy.transform.Generated' in method.annotations*.annotationType().name)
++ }
++}
+\ No newline at end of file
+
+From d2097c8cb1dc6080dc491d5fbae6b0732d697c23 Mon Sep 17 00:00:00 2001
+From: aalmiray <aa...@gmail.com>
+Date: Thu, 12 Oct 2017 10:07:07 +0200
+Subject: [PATCH 2/2] Remove author tags from javadoc
+
+---
+ src/main/groovy/transform/Generated.java | 4 ----
+ 1 file changed, 4 deletions(-)
+
+diff --git a/src/main/groovy/transform/Generated.java b/src/main/groovy/transform/Generated.java
+index f7ea40af6d..98eaf5b0df 100644
+--- a/src/main/groovy/transform/Generated.java
++++ b/src/main/groovy/transform/Generated.java
+@@ -25,10 +25,6 @@
+
+ /**
+ * The Generated annotation is used to mark members that have been generated.
+- *
+- * @author Andres Almiray
+- * @author Jochen Theodorou
+- * @author Mark Hoffmann
+ */
+ @Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, ElementType.FIELD})
+ @Retention(RetentionPolicy.RUNTIME)
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr622.patch
----------------------------------------------------------------------
diff --git a/pr622.patch b/pr622.patch
new file mode 100644
index 0000000..1d3df05
--- /dev/null
+++ b/pr622.patch
@@ -0,0 +1,237 @@
+From 3839297520e325b8520d856bd2d74fc5ee63cced Mon Sep 17 00:00:00 2001
+From: paulk <pa...@asert.com.au>
+Date: Mon, 30 Oct 2017 08:47:28 +1000
+Subject: [PATCH] GROOVY-8112: NPE in Groovy compiler when referencing @Field
+ in aic
+
+---
+ .../groovy/transform/FieldASTTransformation.java | 104 +++++++++++++++++----
+ .../groovy/transform/FieldTransformTest.groovy | 39 +++++++-
+ 2 files changed, 122 insertions(+), 21 deletions(-)
+
+diff --git a/src/main/org/codehaus/groovy/transform/FieldASTTransformation.java b/src/main/org/codehaus/groovy/transform/FieldASTTransformation.java
+index 52b4406b94..8e6b58e8b5 100644
+--- a/src/main/org/codehaus/groovy/transform/FieldASTTransformation.java
++++ b/src/main/org/codehaus/groovy/transform/FieldASTTransformation.java
+@@ -27,15 +27,19 @@
+ import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
+ import org.codehaus.groovy.ast.ClassHelper;
+ import org.codehaus.groovy.ast.ClassNode;
++import org.codehaus.groovy.ast.ConstructorNode;
+ import org.codehaus.groovy.ast.FieldNode;
+ import org.codehaus.groovy.ast.MethodNode;
++import org.codehaus.groovy.ast.Parameter;
+ import org.codehaus.groovy.ast.Variable;
+ import org.codehaus.groovy.ast.VariableScope;
+-import org.codehaus.groovy.ast.expr.BinaryExpression;
++import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+ import org.codehaus.groovy.ast.expr.ClosureExpression;
+ import org.codehaus.groovy.ast.expr.ConstantExpression;
++import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
+ import org.codehaus.groovy.ast.expr.DeclarationExpression;
+ import org.codehaus.groovy.ast.expr.Expression;
++import org.codehaus.groovy.ast.expr.TupleExpression;
+ import org.codehaus.groovy.ast.expr.VariableExpression;
+ import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+ import org.codehaus.groovy.classgen.VariableScopeVisitor;
+@@ -44,6 +48,7 @@
+ import org.codehaus.groovy.runtime.MetaClassHelper;
+ import org.objectweb.asm.Opcodes;
+
++import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Iterator;
+ import java.util.List;
+@@ -59,9 +64,6 @@
+
+ /**
+ * Handles transformation for the @Field annotation.
+- *
+- * @author Paul King
+- * @author Cedric Champeau
+ */
+ @GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
+ public class FieldASTTransformation extends ClassCodeExpressionTransformer implements ASTTransformation, Opcodes {
+@@ -77,6 +79,7 @@
+ private String variableName;
+ private FieldNode fieldNode;
+ private ClosureExpression currentClosure;
++ private ConstructorCallExpression currentAIC;
+
+ public void visit(ASTNode[] nodes, SourceUnit source) {
+ sourceUnit = source;
+@@ -166,23 +169,76 @@ public Expression transform(Expression expr) {
+ } else if (insideScriptBody && expr instanceof VariableExpression && currentClosure != null) {
+ VariableExpression ve = (VariableExpression) expr;
+ if (ve.getName().equals(variableName)) {
+- // we may only check the variable name because the Groovy compiler
+- // already fails if a variable with the same name already exists in the scope.
+- // this means that a closure cannot shadow a class variable
+- ve.setAccessedVariable(fieldNode);
+- final VariableScope variableScope = currentClosure.getVariableScope();
+- final Iterator<Variable> iterator = variableScope.getReferencedLocalVariablesIterator();
+- while (iterator.hasNext()) {
+- Variable next = iterator.next();
+- if (next.getName().equals(variableName)) iterator.remove();
+- }
+- variableScope.putReferencedClassVariable(fieldNode);
++ adjustToClassVar(ve);
+ return ve;
+ }
++ } else if (currentAIC != null && expr instanceof ArgumentListExpression) {
++ // if a match is found, the compiler will have already set up aic constructor to hav
++ // an argument which isn't needed since we'll be accessing the field; we must undo it
++ Expression skip = null;
++ List<Expression> origArgList = ((ArgumentListExpression) expr).getExpressions();
++ for (int i = 0; i < origArgList.size(); i++) {
++ Expression arg = origArgList.get(i);
++ if (matchesCandidate(arg)) {
++ skip = arg;
++ adjustConstructorAndFields(i, currentAIC.getType());
++ break;
++ }
++ }
++ if (skip != null) {
++ return adjustedArgList(skip, origArgList);
++ }
+ }
+ return expr.transformExpression(this);
+ }
+
++ private boolean matchesCandidate(Expression arg) {
++ return arg instanceof VariableExpression && ((VariableExpression) arg).getAccessedVariable() == candidate.getVariableExpression().getAccessedVariable();
++ }
++
++ private Expression adjustedArgList(Expression skip, List<Expression> origArgs) {
++ List<Expression> newArgs = new ArrayList<Expression>(origArgs.size() - 1);
++ for (Expression origArg : origArgs) {
++ if (skip != origArg) {
++ newArgs.add(origArg);
++ }
++ }
++ return new ArgumentListExpression(newArgs);
++ }
++
++ private void adjustConstructorAndFields(int skipIndex, ClassNode type) {
++ List<ConstructorNode> constructors = type.getDeclaredConstructors();
++ if (constructors.size() == 1) {
++ ConstructorNode constructor = constructors.get(0);
++ Parameter[] params = constructor.getParameters();
++ Parameter[] newParams = new Parameter[params.length - 1];
++ int to = 0;
++ for (int from = 0; from < params.length; from++) {
++ if (from != skipIndex) {
++ newParams[to++] = params[from];
++ }
++ }
++ type.removeConstructor(constructor);
++ // code doesn't mention the removed param at this point, okay to leave as is
++ type.addConstructor(constructor.getModifiers(), newParams, constructor.getExceptions(), constructor.getCode());
++ type.removeField(variableName);
++ }
++ }
++
++ private void adjustToClassVar(VariableExpression expr) {
++ // we only need to check the variable name because the Groovy compiler
++ // already fails if a variable with the same name already exists in the scope.
++ // this means that a closure cannot shadow a class variable
++ expr.setAccessedVariable(fieldNode);
++ final VariableScope variableScope = currentClosure.getVariableScope();
++ final Iterator<Variable> iterator = variableScope.getReferencedLocalVariablesIterator();
++ while (iterator.hasNext()) {
++ Variable next = iterator.next();
++ if (next.getName().equals(variableName)) iterator.remove();
++ }
++ variableScope.putReferencedClassVariable(fieldNode);
++ }
++
+ @Override
+ public void visitClosureExpression(final ClosureExpression expression) {
+ ClosureExpression old = currentClosure;
+@@ -192,6 +248,20 @@ public void visitClosureExpression(final ClosureExpression expression) {
+ }
+
+ @Override
++ public void visitConstructorCallExpression(final ConstructorCallExpression cce) {
++ if (!insideScriptBody || !cce.isUsingAnonymousInnerClass()) return;
++ ConstructorCallExpression old = currentAIC;
++ currentAIC = cce;
++ Expression newArgs = transform(cce.getArguments());
++ if (cce.getArguments() instanceof TupleExpression && newArgs instanceof TupleExpression) {
++ List<Expression> argList = ((TupleExpression) cce.getArguments()).getExpressions();
++ argList.clear();
++ argList.addAll(((TupleExpression) newArgs).getExpressions());
++ }
++ currentAIC = old;
++ }
++
++ @Override
+ public void visitMethod(MethodNode node) {
+ Boolean oldInsideScriptBody = insideScriptBody;
+ if (node.isScriptBody()) insideScriptBody = true;
+@@ -202,9 +272,7 @@ public void visitMethod(MethodNode node) {
+ @Override
+ public void visitExpressionStatement(ExpressionStatement es) {
+ Expression exp = es.getExpression();
+- if (exp instanceof BinaryExpression) {
+- exp.visit(this);
+- }
++ exp.visit(this);
+ super.visitExpressionStatement(es);
+ }
+
+diff --git a/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy b/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy
+index 2821f6e11c..6575720bfb 100644
+--- a/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy
++++ b/src/test/org/codehaus/groovy/transform/FieldTransformTest.groovy
+@@ -21,8 +21,7 @@ package org.codehaus.groovy.transform
+ import gls.CompilableTestSupport
+
+ /**
+- * @author Paul King
+- * @author C�dric Champeau
++ * Tests for the {@code @Field} transformation
+ */
+ class FieldTransformTest extends CompilableTestSupport {
+
+@@ -226,4 +225,38 @@ class FieldTransformTest extends CompilableTestSupport {
+ assert foo + bar + baz == 'foobarbaz'
+ '''
+ }
+-}
+\ No newline at end of file
++
++ void testAnonymousInnerClassReferencesToField() {
++ // GROOVY-8112
++ assertScript '''
++ @groovy.transform.Field
++ StringBuilder logger = new StringBuilder()
++ logger.append('a')
++ ['b'].each {
++ logger.append(it)
++ new Object() {
++ String toString() {
++ logger.append('c')
++ ['d'].each { logger.append(it) }
++ }
++ }.toString()
++ }
++ Closure c = { logger.append('e') }
++ c()
++ // control: worked previously, make sure we didn't break
++ def method() {
++ logger.append('f')
++ ['g'].each {
++ logger.append(it)
++ new Object() {
++ String toString() {
++ logger.append('h')
++ }
++ }.toString()
++ }
++ }
++ method()
++ assert logger.toString() == 'abcdefgh'
++ '''
++ }
++}
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr625.patch
----------------------------------------------------------------------
diff --git a/pr625.patch b/pr625.patch
new file mode 100644
index 0000000..4d0e8d2
--- /dev/null
+++ b/pr625.patch
@@ -0,0 +1,65 @@
+From 03fd268d814c491f1424f9fe8d8a0d30c5c333a5 Mon Sep 17 00:00:00 2001
+From: Shil Sinha <sh...@gmail.com>
+Date: Tue, 31 Oct 2017 13:29:19 -0400
+Subject: [PATCH] GROOVY-8369: Statically compiled property access on enum
+ class throws NoSuchFieldError
+
+---
+ .../classgen/asm/sc/StaticTypesCallSiteWriter.java | 10 +++++-----
+ .../asm/sc/FieldsAndPropertiesStaticCompileTest.groovy | 17 +++++++++++++++++
+ 2 files changed, 22 insertions(+), 5 deletions(-)
+
+diff --git a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+index 8d003ebc75..2eaa9348e6 100644
+--- a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
++++ b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+@@ -148,11 +148,6 @@ public void makeGetPropertySite(Expression receiver, final String methodName, fi
+ }
+ if (makeGetPropertyWithGetter(receiver, receiverType, methodName, safe, implicitThis)) return;
+ if (makeGetField(receiver, receiverType, methodName, safe, implicitThis, samePackages(receiverType.getPackageName(), classNode.getPackageName()))) return;
+- if (receiverType.isEnum()) {
+- mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(receiverType), methodName, BytecodeHelper.getTypeDescription(receiverType));
+- controller.getOperandStack().push(receiverType);
+- return;
+- }
+ if (receiver instanceof ClassExpression) {
+ if (makeGetField(receiver, receiver.getType(), methodName, safe, implicitThis, samePackages(receiver.getType().getPackageName(), classNode.getPackageName()))) return;
+ if (makeGetPropertyWithGetter(receiver, receiver.getType(), methodName, safe, implicitThis)) return;
+@@ -163,6 +158,11 @@ public void makeGetPropertySite(Expression receiver, final String methodName, fi
+ if (makeGetPropertyWithGetter(receiver, CLASS_Type, methodName, safe, implicitThis)) return;
+ if (makeGetField(receiver, CLASS_Type, methodName, safe, false, true)) return;
+ }
++ if (receiverType.isEnum()) {
++ mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(receiverType), methodName, BytecodeHelper.getTypeDescription(receiverType));
++ controller.getOperandStack().push(receiverType);
++ return;
++ }
+ if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, methodName, safe, implicitThis)) return;
+
+ // GROOVY-5580, it is still possible that we're calling a superinterface property
+diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+index 6af5f135f1..2bf0a867bd 100644
+--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
++++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+@@ -696,4 +696,21 @@ import org.codehaus.groovy.transform.sc.ListOfExpressionsExpression
+ assert astTrees['A$_closure1'][1].contains('INVOKESTATIC A.pfaccess$02 (LA;Ljava/lang/String;)Ljava/lang/String;')
+ }
+ }
++
++ //GROOVY-8369
++ void testPropertyAccessOnEnumClass() {
++ try {
++ assertScript '''
++ enum Foo {}
++
++ def test() {
++ println Foo.getModifiers() // => 16401 // ENUM | FINAL | PUBLIC (see GROOVY_8360 wrt STATIC)
++ println Foo.modifiers // java.lang.NoSuchFieldError: modifiers
++ }
++ test()
++ '''
++ } finally {
++ //println astTrees
++ }
++ }
+ }
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/src/main/groovy/transform/MapArguments.java.bak
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/MapArguments.java.bak b/src/main/groovy/transform/MapArguments.java.bak
new file mode 100644
index 0000000..c4d097d
--- /dev/null
+++ b/src/main/groovy/transform/MapArguments.java.bak
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.transform;
+
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+@GroovyASTTransformationClass("org.apache.groovy.transform.MapArgumentsASTTransformation")
+public @interface MapArguments {
+ Class typeHint() default Object.class;
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/src/main/org/apache/groovy/transform/MapArgumentsASTTransformation.java.bak
----------------------------------------------------------------------
diff --git a/src/main/org/apache/groovy/transform/MapArgumentsASTTransformation.java.bak b/src/main/org/apache/groovy/transform/MapArgumentsASTTransformation.java.bak
new file mode 100644
index 0000000..bd9b293
--- /dev/null
+++ b/src/main/org/apache/groovy/transform/MapArgumentsASTTransformation.java.bak
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *//*
+package org.apache.groovy.transform;
+
+import groovy.transform.MapArguments;
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.ConstructorNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.transform.AbstractASTTransformation;
+import org.codehaus.groovy.transform.GroovyASTTransformation;
+import org.objectweb.asm.Opcodes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.groovy.ast.tools.FactoryUtils.args;
+import static org.apache.groovy.ast.tools.FactoryUtils.callThisX;
+import static org.apache.groovy.ast.tools.FactoryUtils.castX;
+import static org.apache.groovy.ast.tools.FactoryUtils.classX;
+import static org.apache.groovy.ast.tools.FactoryUtils.constX;
+import static org.apache.groovy.ast.tools.FactoryUtils.ctorX;
+import static org.apache.groovy.ast.tools.FactoryUtils.stmt;
+import static org.apache.groovy.ast.tools.FactoryUtils.varX;
+
+@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
+public class MapArgumentsASTTransformation extends AbstractASTTransformation {
+
+ @Override
+ public void visit(ASTNode[] nodes, SourceUnit source) {
+ init(nodes, source);
+
+ MethodNode methodNode = (MethodNode) nodes[1];
+
+ Parameter[] parameters = methodNode.getParameters();
+ Parameter closureParameter = null;
+
+ switch (parameters.length) {
+ case 0:
+ addError("MapArguments parameters should not be empty", methodNode);
+ return;
+ case 1:
+ //TODO more object checks
+ break;
+ case 2:
+ closureParameter = parameters[1];
+ if (!(closureParameter.getType().isDerivedFrom(ClassHelper.CLOSURE_TYPE)) && !ClassHelper.isSAMType(closureParameter.getType())) {
+ addError("MapArguments second parameter can be a closure only", closureParameter);
+ return;
+ }
+ break;
+ default:
+ addError("MapArguments parameters length should not be greater than 2", methodNode);
+ return;
+ }
+
+ Parameter mapParameter = new Parameter(nonGeneric(ClassHelper.MAP_TYPE), "__namedArgs");
+
+ Parameter[] mapBasedMethodParameters = closureParameter != null ? new Parameter[]{mapParameter, closureParameter} : new Parameter[]{mapParameter};
+
+ ClassNode declaringClass = methodNode.getDeclaringClass();
+
+ if (declaringClass.hasMethod(methodNode.getName(), mapBasedMethodParameters)) {
+ addError("This class already has a Map-based method", methodNode);
+ return;
+ }
+
+ Expression convertedValueExpression;
+
+ ClassNode parameterType = parameters[0].getType();
+ if (checkForMapConstructor(parameterType)) {
+ ArgumentListExpression convertedArguments = args(varX(mapParameter));
+ if ((parameterType.getModifiers() & Opcodes.ACC_STATIC) == 0) {
+ if(methodNode.isStatic()) {
+ addError("You can't use inner class as map argument since it's impossible to instantiate it", methodNode);
+ return;
+ }
+ convertedArguments.getExpressions().add(0, VariableExpression.THIS_EXPRESSION);
+ }
+ convertedValueExpression = ctorX(parameterType, convertedArguments);
+ } else {
+ convertedValueExpression = castX(parameterType, varX(mapParameter));
+ }
+
+ ArgumentListExpression oldMethodArguments = FactoryUtils.args(convertedValueExpression);
+
+ List<MethodNode> generatedMethods = new ArrayList<MethodNode>();
+ generatedMethods.add(declaringClass.addMethod(
+ methodNode.getName(),
+ methodNode.getModifiers(),
+ methodNode.getReturnType(),
+ mapBasedMethodParameters,
+ methodNode.getExceptions(),
+ stmt(callThisX(methodNode.getName(), oldMethodArguments))
+ ));
+
+ if (closureParameter != null) {
+ oldMethodArguments.addExpression(varX(closureParameter));
+ generatedMethods.add(declaringClass.addMethod(
+ methodNode.getName(),
+ methodNode.getModifiers(),
+ methodNode.getReturnType(),
+ new Parameter[]{mapBasedMethodParameters[0]},
+ methodNode.getExceptions(),
+ stmt(callThisX(
+ methodNode.getName(),
+ args(oldMethodArguments.getExpression(0), castX(closureParameter.getType(), constX(null)))
+ ))
+ ));
+ }
+
+ for (MethodNode generatedMethod : generatedMethods) {
+ AnnotationNode mapArgumentsAnnotationNode = new AnnotationNode(ClassHelper.makeWithoutCaching(MapArguments.class));
+ mapArgumentsAnnotationNode.setMember("typeHint", classX(parameterType));
+ generatedMethod.addAnnotation(mapArgumentsAnnotationNode);
+ }
+ }
+
+ protected boolean checkForMapConstructor(ClassNode parameterType) {
+ List<ConstructorNode> declaredConstructors = parameterType.getDeclaredConstructors();
+
+ for (ConstructorNode declaredConstructor : declaredConstructors) {
+ Parameter[] declaredConstructorParameters = declaredConstructor.getParameters();
+ if (declaredConstructorParameters.length != 1) {
+ continue;
+ }
+
+ ClassNode declaredConstructorParameterType = declaredConstructorParameters[0].getType();
+
+ if (declaredConstructorParameterType == null) {
+ continue;
+ }
+
+ if (declaredConstructorParameterType.equals(ClassHelper.MAP_TYPE)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy8224Bug.groovy.bak
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy8224Bug.groovy.bak b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy8224Bug.groovy.bak
new file mode 100644
index 0000000..8fe711b
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy8224Bug.groovy.bak
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+/**
+ * Test that traits include getters/setters.
+ */
+class Groovy8224Bug extends StringSourcesStubTestCase {
+
+ Map<String, String> provideSources() {
+ [
+ 'Foo.groovy': '''
+ trait GroovyXTrait {
+ int foo
+ }
+ ''',
+ 'Main.java': '''
+ class Main {
+ public static void main(String[] args) {
+ new GroovyXImpl().getFoo();
+ }
+ }
+ ''',
+ 'GroovyXImpl.groovy': '''
+ class GroovyXImpl implements GroovyXTrait { }
+ ''',
+ ]
+ }
+
+ void verifyStubs() {
+ def stubSource = stubJavaSourceFor('GroovyXImpl')
+ assert stubSource.contains('interface Foo')
+ assert stubSource.contains('int foo()')
+ assert stubSource.contains('void baz(int y)')
+ assert stubSource.contains('void bar(int x)')
+ }
+}
[2/2] groovy git commit: update checkstyle for latest build
Posted by pa...@apache.org.
update checkstyle for latest build
one of the rules we previously used is no longer included
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/13522f88
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/13522f88
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/13522f88
Branch: refs/heads/GROOVY_2_5_X
Commit: 13522f8871d768e1d65c522325bbc47a88d77a2e
Parents: dafabb2
Author: paulk <pa...@asert.com.au>
Authored: Tue Dec 19 20:25:08 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Tue Dec 19 20:25:08 2017 +1000
----------------------------------------------------------------------
Groovy7037.patch | 71 ++++
Groovy8295.patch | 61 +++
config/checkstyle/checkstyle.xml | 3 +-
groovy8260Extras.patch | 388 +++++++++++++++++++
groovy8260c.patch | 188 +++++++++
ivy_snapshot.patch | 24 ++
pr502.patch | 118 ++++++
pr507.patch | 25 ++
pr555.patch | 312 +++++++++++++++
pr555a.patch | 94 +++++
pr565.patch | 168 ++++++++
pr584.patch | 57 +++
pr597.patch | 26 ++
pr603.patch | 102 +++++
pr607.patch | 60 +++
pr617.patch | 293 ++++++++++++++
pr622.patch | 237 +++++++++++
pr625.patch | 65 ++++
src/main/groovy/transform/MapArguments.java.bak | 33 ++
.../MapArgumentsASTTransformation.java.bak | 165 ++++++++
.../stubgenerator/Groovy8224Bug.groovy.bak | 53 +++
21 files changed, 2542 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/Groovy7037.patch
----------------------------------------------------------------------
diff --git a/Groovy7037.patch b/Groovy7037.patch
new file mode 100644
index 0000000..2417534
--- /dev/null
+++ b/Groovy7037.patch
@@ -0,0 +1,71 @@
+Index: src/test/groovy/bugs/Groovy7037Bug.groovy
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/test/groovy/bugs/Groovy7037Bug.groovy (revision )
++++ src/test/groovy/bugs/Groovy7037Bug.groovy (revision )
+@@ -0,0 +1,40 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package groovy.bugs
++
++class Groovy7037Bug extends GroovyTestCase {
++ void testGetAtShouldWorkWithVarArgs() {
++ assertScript '''
++ class Test {
++ def getAt(Integer x, Long y) { "A: $x $y" }
++ def getAt(Integer x, Long... y) { "B: $x ${y.join(' ')}" }
++ }
++
++ def t = new Test()
++ assert t[2, 4L] == 'A: 2 4'
++ def items = [2, 4L]
++ assert t[*items] == 'A: 2 4'
++ assert t.getAt(2, 4L) == 'A: 2 4'
++ assert t[2] == 'B: 2 '
++ assert t.getAt(2) == 'B: 2 '
++ assert t.getAt(2, 4L, 5L) == 'B: 2 4 5'
++ assert t[2, 4L, 5L] == 'B: 2 4 5'
++ '''
++ }
++}
+Index: src/main/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java (date 1472272655000)
++++ src/main/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java (revision )
+@@ -242,6 +242,15 @@
+ if (controller.getCompileStack().isLHS()) {
+ evaluateEqual(expression, false);
+ } else {
++ Expression arguments = expression.getRightExpression();
++ if (arguments instanceof ListExpression) {
++ Expression newArgs = new ArgumentListExpression(((ListExpression) arguments).getExpressions());
++ newArgs.setSourcePosition(arguments);
++ controller.getInvocationWriter().makeCall(
++ expression, expression.getLeftExpression(), new ConstantExpression("getAt"),
++ newArgs, InvocationWriter.invokeMethod, false, false, false);
++ break;
++ }
+ evaluateBinaryExpression("getAt", expression);
+ }
+ break;
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/Groovy8295.patch
----------------------------------------------------------------------
diff --git a/Groovy8295.patch b/Groovy8295.patch
new file mode 100644
index 0000000..4545691
--- /dev/null
+++ b/Groovy8295.patch
@@ -0,0 +1,61 @@
+--- C:\Users\U0076777\Groovyc-2.4.12.txt 2017-08-29 17:54:18.050000000 -0500
++++ C:\Users\U0076777\Groovyc-edited.txt 2017-08-29 17:55:43.727000000 -0500
+@@ -1006,7 +1006,7 @@
+ commandLineList.add(javaHome + separator + "bin" + separator + "java");
+ }
+ commandLineList.add("-classpath");
+- commandLineList.add(classpath.toString());
++ commandLineList.add(classpath.toString().replace(getProject().getBaseDir().getAbsolutePath(), "."));
+
+ final String fileEncodingProp = System.getProperty("file.encoding");
+ if ((fileEncodingProp != null) && !fileEncodingProp.equals("")) {
+@@ -1036,7 +1036,7 @@
+
+ private void doNormalCommandLineList(List<String> commandLineList, List<String> jointOptions, Path classpath) {
+ commandLineList.add("--classpath");
+- commandLineList.add(classpath.toString());
++ commandLineList.add(classpath.toString().replace(getProject().getBaseDir().getAbsolutePath(), "."));
+ if (jointCompilation) {
+ commandLineList.add("-j");
+ commandLineList.addAll(jointOptions);
+@@ -1100,18 +1100,12 @@
+ }
+
+ private String[] makeCommandLine(List<String> commandLineList) {
+- final String[] commandLine = new String[commandLineList.size()];
+- for (int i = 0; i < commandLine.length; ++i) {
+- commandLine[i] = commandLineList.get(i);
+- }
+- log.verbose("Compilation arguments:");
+- log.verbose(DefaultGroovyMethods.join(commandLine, "\n"));
+- return commandLine;
++ log.verbose("Compilation arguments:\n" + DefaultGroovyMethods.join(commandLineList, "\n"));
++ return commandLineList.toArray(new String[commandLineList.size()]);
+ }
+
+ private void runForked(String[] commandLine) {
+- // use the main method in FileSystemCompiler
+- final Execute executor = new Execute(); // new LogStreamHandler ( attributes , Project.MSG_INFO , Project.MSG_WARN ) ) ;
++ final Execute executor = new Execute();
+ executor.setAntRun(getProject());
+ executor.setWorkingDirectory(getProject().getBaseDir());
+ executor.setCommandline(commandLine);
+@@ -1280,12 +1274,12 @@
+ * may not exist in the classpath yet
+ */
+ if (!found && new File(cpEntry).exists()) {
+- try {
+- antLoader.addPathElement(cpEntry);
+- }
+- catch(BuildException e) {
+- log.warn("The classpath entry " + cpEntry + " is not a valid Java resource");
+- }
++ try {
++ antLoader.addPathElement(cpEntry);
++ }
++ catch(BuildException e) {
++ log.warn("The classpath entry " + cpEntry + " is not a valid Java resource");
++ }
+ }
+ }
+ }
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/config/checkstyle/checkstyle.xml
----------------------------------------------------------------------
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 34aebe1..339228e 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -154,7 +154,8 @@
<module name="UpperEll"/>
<!-- off for now - to allow parentheses which add clarity -->
<!--<module name="UnnecessaryParentheses"/>-->
- <module name="JUnitTestCase"/>
+ <!-- removed in recent versions of checkstyle -->
+ <!--<module name="JUnitTestCase"/>-->
<module name="FinalClass"/>
<!-- good to have but pollutes coverage -->
<!--<module name="HideUtilityClassConstructor"/>-->
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/groovy8260Extras.patch
----------------------------------------------------------------------
diff --git a/groovy8260Extras.patch b/groovy8260Extras.patch
new file mode 100644
index 0000000..24f20e6
--- /dev/null
+++ b/groovy8260Extras.patch
@@ -0,0 +1,388 @@
+Index: src/test/groovy/transform/stc/MiscSTCTest.groovy
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/test/groovy/transform/stc/MiscSTCTest.groovy (revision 456aa4dd37dbcebcfb263db2914b2d84246bc30f)
++++ src/test/groovy/transform/stc/MiscSTCTest.groovy (revision )
+@@ -275,5 +275,64 @@
+ public static class MiscSTCTestSupport {
+ static def foo() { '123' }
+ }
++
++ void testTernaryParam() {
++ assertScript '''
++ Date ternaryParam(Object input) {
++ input instanceof Date ? input : null
++ }
++ def d = new Date()
++ assert ternaryParam(42) == null
++ assert ternaryParam('foo') == null
++ assert ternaryParam(d) == d
++ '''
++ }
++
++ void testTernaryLocalVar() {
++ assertScript '''
++ Date ternaryLocalVar(Object input) {
++ Object copy = input
++ copy instanceof Date ? copy : null
++ }
++ def d = new Date()
++ assert ternaryLocalVar(42) == null
++ assert ternaryLocalVar('foo') == null
++ assert ternaryLocalVar(d) == d
++ '''
++ }
++
++ void testIfThenElseParam() {
++ assertScript '''
++ Date ifThenElseParam(Object input) {
++ if (input instanceof Date) {
++ input
++ } else {
++ null
++ }
++ }
++ def d = new Date()
++ assert ifThenElseParam(42) == null
++ assert ifThenElseParam('foo') == null
++ assert ifThenElseParam(d) == d
++ '''
++ }
++
++ void testIfThenElseLocalVar() {
++ assertScript '''
++ Date ifThenElseLocalVar(Object input) {
++ Date result
++ if (input instanceof Date) {
++ result = input
++ } else {
++ result = null
++ }
++ result
++ }
++ def d = new Date()
++ assert ifThenElseLocalVar(42) == null
++ assert ifThenElseLocalVar('foo') == null
++ assert ifThenElseLocalVar(d) == d
++ '''
++ }
+ }
+
+Index: src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java (revision 456aa4dd37dbcebcfb263db2914b2d84246bc30f)
++++ src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java (revision )
+@@ -112,7 +112,6 @@
+ import static org.codehaus.groovy.syntax.Types.COMPARE_EQUAL;
+ import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_EQUAL;
+ import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_IN;
+-import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_INSTANCEOF;
+ import static org.codehaus.groovy.syntax.Types.COMPARE_TO;
+ import static org.codehaus.groovy.syntax.Types.DIVIDE;
+ import static org.codehaus.groovy.syntax.Types.DIVIDE_EQUAL;
+@@ -483,7 +482,20 @@
+ }
+ }
+
+- if (! (vexp.getAccessedVariable() instanceof DynamicVariable)) return;
++ if (! (vexp.getAccessedVariable() instanceof DynamicVariable)) {
++ //if (vexp.getAccessedVariable() instanceof Parameter) {
++ ClassNode inferredTypeFromTempInfo = getInferredTypeFromTempInfo(vexp, null);
++ if (inferredTypeFromTempInfo != null) {
++ storeType(vexp, inferredTypeFromTempInfo);
++ }
++// } else if (vexp.getAccessedVariable() instanceof VariableExpression) {
++// ClassNode inferredTypeFromTempInfo = getInferredTypeFromTempInfo((Expression) vexp.getAccessedVariable(), null);
++// if (inferredTypeFromTempInfo != null) {
++// storeType((Expression) vexp.getAccessedVariable(), inferredTypeFromTempInfo);
++// }
++// }
++ return;
++ }
+
+ // a dynamic variable is either an undeclared variable
+ // or a member of a class used in a 'with'
+@@ -668,6 +680,9 @@
+ if (typeCheckingContext.ifElseForWhileAssignmentTracker != null && leftExpression instanceof VariableExpression
+ && !isNullConstant(rightExpression)) {
+ Variable accessedVariable = ((VariableExpression) leftExpression).getAccessedVariable();
++ if (accessedVariable instanceof Parameter) {
++ accessedVariable = new ParameterVariableExpression((Parameter) accessedVariable);
++ }
+ if (accessedVariable instanceof VariableExpression) {
+ VariableExpression var = (VariableExpression) accessedVariable;
+ List<ClassNode> types = typeCheckingContext.ifElseForWhileAssignmentTracker.get(var);
+@@ -1947,40 +1962,48 @@
+ protected ClassNode[] getArgumentTypes(ArgumentListExpression args) {
+ List<Expression> arglist = args.getExpressions();
+ ClassNode[] ret = new ClassNode[arglist.size()];
+- int i = 0;
+- Map<Object, List<ClassNode>> info = typeCheckingContext.temporaryIfBranchTypeInformation.empty() ? null : typeCheckingContext.temporaryIfBranchTypeInformation.peek();
+- for (Expression exp : arglist) {
+- if (isNullConstant(exp)) {
++ for (int i = 0; i < arglist.size(); i++) {
++ if (isNullConstant(arglist.get(i))) {
+ ret[i] = UNKNOWN_PARAMETER_TYPE;
+ } else {
+- ret[i] = getType(exp);
+- if (exp instanceof VariableExpression && info != null) {
+- List<ClassNode> classNodes = getTemporaryTypesForExpression(exp);
+- if (classNodes != null && !classNodes.isEmpty()) {
+- ArrayList<ClassNode> arr = new ArrayList<ClassNode>(classNodes.size() + 1);
+- arr.add(ret[i]);
+- arr.addAll(classNodes);
+- // GROOVY-7333: filter out Object
+- Iterator<ClassNode> iterator = arr.iterator();
+- while (iterator.hasNext()) {
+- ClassNode next = iterator.next();
+- if (ClassHelper.OBJECT_TYPE.equals(next)) {
+- iterator.remove();
+- }
+- }
+- if (arr.isEmpty()) {
+- ret[i] = ClassHelper.OBJECT_TYPE.getPlainNodeReference();
+- } else if (arr.size()==1) {
+- ret[i] = arr.get(0);
+- } else {
+- ret[i] = new UnionTypeClassNode(arr.toArray(new ClassNode[arr.size()]));
+- }
+- }
++ ret[i] = getInferredType(arglist.get(i));
++ }
++ }
++ return ret;
++ }
++
++ private ClassNode getInferredType(Expression exp) {
++ ClassNode result = getType(exp);
++ result = getInferredTypeFromTempInfo(exp, result);
++ return result;
++ }
++
++ private ClassNode getInferredTypeFromTempInfo(Expression exp, ClassNode result) {
++ Map<Object, List<ClassNode>> info = typeCheckingContext.temporaryIfBranchTypeInformation.empty() ? null : typeCheckingContext.temporaryIfBranchTypeInformation.peek();
++ if (exp instanceof VariableExpression && info != null) {
++ List<ClassNode> classNodes = getTemporaryTypesForExpression(exp);
++ if (classNodes != null && !classNodes.isEmpty()) {
++ ArrayList<ClassNode> arr = new ArrayList<ClassNode>(classNodes.size() + 1);
++ if (result != null) arr.add(result);
++ arr.addAll(classNodes);
++ // GROOVY-7333: filter out Object
++ Iterator<ClassNode> iterator = arr.iterator();
++ while (iterator.hasNext()) {
++ ClassNode next = iterator.next();
++ if (ClassHelper.OBJECT_TYPE.equals(next)) {
++ iterator.remove();
++ }
++ }
++ if (arr.isEmpty()) {
++ result = ClassHelper.OBJECT_TYPE.getPlainNodeReference();
++ } else if (arr.size()==1) {
++ result = arr.get(0);
++ } else {
++ result = new UnionTypeClassNode(arr.toArray(new ClassNode[arr.size()]));
+ }
+ }
+- i++;
+ }
+- return ret;
++ return result;
+ }
+
+ @Override
+@@ -4026,6 +4049,9 @@
+ List<ClassNode> temporaryTypesForExpression = getTemporaryTypesForExpression(vexp);
+ if (temporaryTypesForExpression == null || temporaryTypesForExpression.isEmpty()) {
+ type = typeCheckingContext.controlStructureVariables.get(parameter);
++// } else {
++// ClassNode temp = getInferredTypeFromTempInfo((Expression) exp, null);
++// type = temp;
+ }
+ // now check for closure override
+ TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
+@@ -4849,4 +4875,65 @@
+ }
+ }
+
++ /**
++ * Wrapper for a Parameter so it can be treated like a VariableExpression
++ * and tracked in the ifElseForWhileAssignmentTracker.
++ *
++ * This class purposely does not adhere to the normal equals and hashCode
++ * contract on the Object class and delegates those calls to the wrapped
++ * variable.
++ */
++ private static class ParameterVariableExpression extends VariableExpression {
++
++ private final Parameter parameter;
++
++ ParameterVariableExpression(Parameter parameter) {
++ super(parameter);
++ this.parameter = parameter;
++ ClassNode inferred = parameter.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
++ if (inferred == null) {
++ parameter.setNodeMetaData(StaticTypesMarker.INFERRED_TYPE, parameter.getOriginType());
++ }
++ }
++
++ @Override
++ public void copyNodeMetaData(ASTNode other) {
++ parameter.copyNodeMetaData(other);
++ }
++
++ @Override
++ public Object putNodeMetaData(Object key, Object value) {
++ return parameter.putNodeMetaData(key, value);
++ }
++
++ @Override
++ public void removeNodeMetaData(Object key) {
++ parameter.removeNodeMetaData(key);
++ }
++
++ @Override
++ public Map<?, ?> getNodeMetaData() {
++ return parameter.getNodeMetaData();
++ }
++
++ @Override
++ public <T> T getNodeMetaData(Object key) {
++ return parameter.getNodeMetaData(key);
++ }
++
++ @Override
++ public void setNodeMetaData(Object key, Object value) {
++ parameter.setNodeMetaData(key, value);
++ }
++
++ @Override
++ public int hashCode() {
++ return parameter.hashCode();
++ }
++
++ @Override
++ public boolean equals(Object other) {
++ return parameter.equals(other);
++ }
++ }
+ }
+Index: src/test/groovy/transform/stc/STCAssignmentTest.groovy
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- src/test/groovy/transform/stc/STCAssignmentTest.groovy (revision 456aa4dd37dbcebcfb263db2914b2d84246bc30f)
++++ src/test/groovy/transform/stc/STCAssignmentTest.groovy (revision )
+@@ -446,6 +446,21 @@
+ ''', 'Cannot find matching method java.io.Serializable#toInteger()'
+ }
+
++ void testIfElseBranchParameter() {
++ shouldFailWithMessages '''
++ def foo(x) {
++ def y = 'foo'
++ if (y) {
++ x = new HashSet()
++ } else {
++ x = '123'
++ }
++ x.toInteger()
++ }
++ foo('bar')
++ ''', 'Cannot find matching method java.lang.Object#toInteger()'
++ }
++
+ void testIfOnly() {
+ shouldFailWithMessages '''
+ def x = '123'
+@@ -457,6 +472,20 @@
+ ''', 'Cannot find matching method java.io.Serializable#toInteger()'
+ }
+
++ void testIfOnlyParameter() {
++ shouldFailWithMessages '''
++ def foo(x) {
++ def y = 'foo'
++ if (y) {
++ x = new HashSet()
++ assert x.isEmpty()
++ }
++ x.toInteger()
++ }
++ foo('123')
++ ''', 'Cannot find matching method java.lang.Object#toInteger()'
++ }
++
+ void testIfWithCommonInterface() {
+ assertScript '''
+ interface Foo { void foo() }
+@@ -872,5 +901,63 @@
+ }
+ '''
+ }
+-}
++
++ // GROOVY-8220
++ void testFlowTypingParameterTempTypeAssignmentTracking() {
++ assertScript '''
++ class Foo {
++ CharSequence makeEnv( env, StringBuilder result = new StringBuilder() ) {
++ if (env instanceof File) {
++ env = env.toPath()
++ }
++ if (env instanceof String && env.contains('=')) {
++ result << 'export ' << env << ';'
++ }
++ return result.toString()
++ }
++ }
++ assert new Foo().makeEnv('X=1') == 'export X=1;'
++ '''
++ // GROOVY-8237
++ assertScript '''
++ class Foo {
++ String parse(Reader reader) {
++ if (reader == null)
++ reader = new BufferedReader(reader)
++ int i = reader.read()
++ return (i != -1) ? 'bar' : 'baz'
++ }
++ }
++ assert new Foo().parse(new StringReader('foo')) == 'bar'
++ '''
++ }
+
++ void testFlowTypingParameterTempTypeAssignmentTrackingWithGenerics() {
++ assertScript '''
++ class M {
++ Map<String, List<Object>> mvm = new HashMap<String, List<Object>>()
++ void setProperty(String name, value) {
++ if (value instanceof File) {
++ value = new File(value, 'bar.txt')
++ }
++ else if (value instanceof URL) {
++ value = value.toURI()
++ }
++ else if (value instanceof InputStream) {
++ value = new BufferedInputStream(value)
++ }
++ else if (value instanceof GString) {
++ value = value.toString()
++ }
++ if (mvm[name]) {
++ mvm[name].add value
++ } else {
++ mvm.put(name, [value])
++ }
++ }
++ }
++ new M().setProperty('foo', 'bar')
++ '''
++ }
++
++}
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/groovy8260c.patch
----------------------------------------------------------------------
diff --git a/groovy8260c.patch b/groovy8260c.patch
new file mode 100644
index 0000000..f7598cd
--- /dev/null
+++ b/groovy8260c.patch
@@ -0,0 +1,188 @@
+commit 26d11337cfa4d66eed6eca1f99f5a5309427ebd9
+Author: paulk <pa...@asert.com.au>
+Date: Fri Sep 29 22:35:54 2017 +1000
+
+ GROOVY-8260: Static compilation requires casting inside instanceof check (handle additional cases)
+
+diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+index 807449a1a..bda414bb8 100644
+--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
++++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+@@ -480,7 +480,30 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
+ }
+ }
+
+- if (! (vexp.getAccessedVariable() instanceof DynamicVariable)) return;
++ if (!(vexp.getAccessedVariable() instanceof DynamicVariable)) {
++ VariableExpression variable = null;
++ if (vexp.getAccessedVariable() instanceof Parameter) {
++ variable = new ParameterVariableExpression((Parameter) vexp.getAccessedVariable());
++ } else if (vexp.getAccessedVariable() instanceof VariableExpression) {
++ variable = (VariableExpression) vexp.getAccessedVariable();
++ }
++ if (variable != null) {
++ ClassNode inferredType = getInferredTypeFromTempInfo(variable, variable.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE));
++ if (inferredType != null && !inferredType.getName().equals("java.lang.Object")) {
++ if (typeCheckingContext.getEnclosingBinaryExpression() != null) {
++ // TODO narrow this down to assignment
++ if (typeCheckingContext.getEnclosingBinaryExpression().getRightExpression() == vexp) {
++ vexp.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, inferredType);
++ }
++ } else {
++ // stash away type info that will be lost later to handle case
++ // where this expression has return added later - piggy back on existing key
++ vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType);
++ }
++ }
++ }
++ return;
++ }
+
+ // a dynamic variable is either an undeclared variable
+ // or a member of a class used in a 'with'
+@@ -1833,6 +1856,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
+ if (typeCheckingContext.getEnclosingClosure()!=null) {
+ return type;
+ }
++ if ((expression instanceof VariableExpression) && hasInferredReturnType(expression)) {
++ type = expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
++ }
+ MethodNode enclosingMethod = typeCheckingContext.getEnclosingMethod();
+ if (enclosingMethod != null && typeCheckingContext.getEnclosingClosure()==null) {
+ if (!enclosingMethod.isVoidMethod()
+@@ -3205,7 +3231,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
+ int depth = typeCheckingContext.temporaryIfBranchTypeInformation.size();
+ while (classNodes == null && depth > 0) {
+ final Map<Object, List<ClassNode>> tempo = typeCheckingContext.temporaryIfBranchTypeInformation.get(--depth);
+- Object key = extractTemporaryTypeInfoKey(objectExpression);
++ Object key = objectExpression instanceof ParameterVariableExpression
++ ? ((ParameterVariableExpression) objectExpression).parameter
++ : extractTemporaryTypeInfoKey(objectExpression);
+ classNodes = tempo.get(key);
+ }
+ return classNodes;
+@@ -3393,6 +3421,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
+ typeCheckingContext.popTemporaryTypeInfo();
+ falseExpression.visit(this);
+ ClassNode resultType;
++ ClassNode typeOfFalse = getType(falseExpression);
++ ClassNode typeOfTrue = getType(trueExpression);
++ if (hasInferredReturnType(falseExpression)) {
++ typeOfFalse = falseExpression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
++ }
++ if (hasInferredReturnType(trueExpression)) {
++ typeOfTrue = trueExpression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
++ }
+ if (isNullConstant(trueExpression) || isNullConstant(falseExpression)) {
+ BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
+ if (enclosingBinaryExpression != null && enclosingBinaryExpression.getRightExpression()==expression) {
+@@ -3400,20 +3436,23 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
+ } else if (isNullConstant(trueExpression) && isNullConstant(falseExpression)) {
+ resultType = OBJECT_TYPE;
+ } else if (isNullConstant(trueExpression)) {
+- resultType = wrapTypeIfNecessary(getType(falseExpression));
++ resultType = wrapTypeIfNecessary(typeOfFalse);
+ } else {
+- resultType = wrapTypeIfNecessary(getType(trueExpression));
++ resultType = wrapTypeIfNecessary(typeOfTrue);
+ }
+ } else {
+ // store type information
+- final ClassNode typeOfTrue = getType(trueExpression);
+- final ClassNode typeOfFalse = getType(falseExpression);
+ resultType = lowestUpperBound(typeOfTrue, typeOfFalse);
+ }
+ storeType(expression, resultType);
+ popAssignmentTracking(oldTracker);
+ }
+
++ private boolean hasInferredReturnType(Expression expression) {
++ ClassNode type = expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
++ return type != null && !type.getName().equals("java.lang.Object");
++ }
++
+ @Override
+ public void visitTryCatchFinally(final TryCatchStatement statement) {
+ final List<CatchStatement> catchStatements = statement.getCatchStatements();
+diff --git a/src/test/groovy/transform/stc/MiscSTCTest.groovy b/src/test/groovy/transform/stc/MiscSTCTest.groovy
+index 13bdb40c6..fadac0afa 100644
+--- a/src/test/groovy/transform/stc/MiscSTCTest.groovy
++++ b/src/test/groovy/transform/stc/MiscSTCTest.groovy
+@@ -22,8 +22,6 @@ import org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor
+
+ /**
+ * Unit tests for static type checking : miscellaneous tests.
+- *
+- * @author Cedric Champeau
+ */
+ class MiscSTCTest extends StaticTypeCheckingTestCase {
+
+@@ -272,8 +270,67 @@ class MiscSTCTest extends StaticTypeCheckingTestCase {
+ }
+ }
+
+- public static class MiscSTCTestSupport {
++ static class MiscSTCTestSupport {
+ static def foo() { '123' }
+ }
++
++ void testTernaryParam() {
++ assertScript '''
++ Date ternaryParam(Object input) {
++ input instanceof Date ? input : null
++ }
++ def d = new Date()
++ assert ternaryParam(42) == null
++ assert ternaryParam('foo') == null
++ assert ternaryParam(d) == d
++ '''
++ }
++
++ void testTernaryLocalVar() {
++ assertScript '''
++ Date ternaryLocalVar(Object input) {
++ Object copy = input
++ copy instanceof Date ? copy : null
++ }
++ def d = new Date()
++ assert ternaryLocalVar(42) == null
++ assert ternaryLocalVar('foo') == null
++ assert ternaryLocalVar(d) == d
++ '''
++ }
++
++ void testIfThenElseParam() {
++ assertScript '''
++ Date ifThenElseParam(Object input) {
++ if (input instanceof Date) {
++ input
++ } else {
++ null
++ }
++ }
++ def d = new Date()
++ assert ifThenElseParam(42) == null
++ assert ifThenElseParam('foo') == null
++ assert ifThenElseParam(d) == d
++ '''
++ }
++
++ void testIfThenElseLocalVar() {
++ assertScript '''
++ Date ifThenElseLocalVar(Object input) {
++ Date result
++ if (input instanceof Date) {
++ result = input
++ } else {
++ result = null
++ }
++ result
++ }
++ def d = new Date()
++ assert ifThenElseLocalVar(42) == null
++ assert ifThenElseLocalVar('foo') == null
++ assert ifThenElseLocalVar(d) == d
++ '''
++ }
+ }
+
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/ivy_snapshot.patch
----------------------------------------------------------------------
diff --git a/ivy_snapshot.patch b/ivy_snapshot.patch
new file mode 100644
index 0000000..3ce0c68
--- /dev/null
+++ b/ivy_snapshot.patch
@@ -0,0 +1,24 @@
+Index: build.gradle
+IDEA additional info:
+Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
+<+>UTF-8
+===================================================================
+--- build.gradle (revision 8301ba03d2a38b36b9f718db54f46b935e1aba5d)
++++ build.gradle (revision )
+@@ -94,6 +94,7 @@
+ }
+ jcenter()
+ maven { url 'http://dl.bintray.com/melix/thirdparty-apache' } // openbeans
++ maven { url 'https://repository.apache.org/snapshots/' }
+ }
+
+ apply plugin: 'groovy'
+@@ -168,7 +169,7 @@
+ eclipseOsgiVersion = '3.9.1-v20140110-1610'
+ gparsVersion = '1.2.1'
+ gradleVersion = '3.5.1'
+- ivyVersion = '2.4.0'
++ ivyVersion = '2.5.0-SNAPSHOT'
+ jansiVersion = '1.13'
+ jarjarVersion = '1.4.1'
+ jlineVersion = '2.14.5'
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr502.patch
----------------------------------------------------------------------
diff --git a/pr502.patch b/pr502.patch
new file mode 100644
index 0000000..b63c727
--- /dev/null
+++ b/pr502.patch
@@ -0,0 +1,118 @@
+From 764388a34b9f6fbf1c605fbbf02700b8ebed82d8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christoffer=20Hammarstr=C3=B6m?=
+ <ch...@linuxgods.com>
+Date: Wed, 22 Feb 2017 02:18:52 +0100
+Subject: [PATCH] Add tests to prove that calling
+ CompilerConfiguration.setScriptBaseClass with a Java class causes ModuleNode
+ to generate a constructor that prevents Field initialization from Binding
+ context.
+
+---
+ src/test/groovy/lang/BindingScript.java | 32 +++++++++++++++++
+ src/test/groovy/lang/GroovyShellTest2.groovy | 54 ++++++++++++++++++++++++++++
+ 2 files changed, 86 insertions(+)
+ create mode 100644 src/test/groovy/lang/BindingScript.java
+
+diff --git a/src/test/groovy/lang/BindingScript.java b/src/test/groovy/lang/BindingScript.java
+new file mode 100644
+index 0000000..81cda00
+--- /dev/null
++++ b/src/test/groovy/lang/BindingScript.java
+@@ -0,0 +1,32 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package groovy.lang;
++
++/**
++ * A Script which requires a Binding passed in the constructor and disallows calling the default constructor.
++ */
++public abstract class BindingScript extends Script {
++ protected BindingScript() {
++ throw new UnsupportedOperationException("\n\t*******\n\tBindingScript() should not be called! Should be calling BindingScript(Binding)!\n\t*******");
++ }
++
++ protected BindingScript(Binding binding) {
++ super(binding);
++ }
++}
+diff --git a/src/test/groovy/lang/GroovyShellTest2.groovy b/src/test/groovy/lang/GroovyShellTest2.groovy
+index 27259bf..c883553 100644
+--- a/src/test/groovy/lang/GroovyShellTest2.groovy
++++ b/src/test/groovy/lang/GroovyShellTest2.groovy
+@@ -43,6 +43,60 @@ class GroovyShellTest2 extends GroovyTestCase {
+ assert result == arg0
+ }
+
++ void testBindingsInFieldInitializersWithAnnotatedJavaBaseScript() {
++ def shell = new GroovyShell();
++ def scriptText = '''
++ @groovy.transform.BaseScript groovy.lang.BindingScript baseScript
++ @groovy.transform.Field def script_args = getProperty('args')
++
++ assert script_args[0] == 'Hello Groovy'
++ script_args[0]
++'''
++
++ def arg0 = 'Hello Groovy'
++ def result = shell.run scriptText, 'TestBindingsInFieldInitializersWithAnnotatedJavaBaseScript.groovy', [arg0]
++ assert result == arg0
++ }
++
++ /**
++ This test fails because {@link org.codehaus.groovy.ast.ModuleNode#setScriptBaseClassFromConfig(org.codehaus.groovy.ast.ClassNode)}
++ calls .setSuperClass(ClassHelper.make(baseClassName)) on the Scripts ClassNode.
++
++ The ClassNode created for this scriptBaseClass has lazyInitDone = true and constructors = null so when
++ .getSuperClass().getDeclaredConstructor(SCRIPT_CONTEXT_CTOR) is called by {@link org.codehaus.groovy.ast.ModuleNode#createStatementsClass()}
++ then ClassNode.constructors is set to an empty ArrayList in {@link org.codehaus.groovy.ast.ClassNode#getDeclaredConstructors()}
++
++ The script constructor is then generated as
++ Constructor(Binding context) {
++ super(); // Fields are initialized after the call to super()
++ setBinding(context); // Fields are initalized before the call to setBinding(context)
++ }
++
++ instead of
++ Constructor(Binding context) {
++ super(context); // Fields are initialized after the call to super(context)
++ }
++
++ Fields are initialized between the call to super() and the setBinding(context)
++ which means Field initializers don't have access to the Binding context.
++ */
++ void testBindingsInFieldInitializersWithConfigJavaBaseScript() {
++ def config = new org.codehaus.groovy.control.CompilerConfiguration()
++ config.scriptBaseClass = BindingScript.class.name
++
++ def shell = new GroovyShell(config);
++ def scriptText = '''
++ @groovy.transform.Field def script_args = getProperty('args')
++
++ assert script_args[0] == 'Hello Groovy'
++ script_args[0]
++'''
++
++ def arg0 = 'Hello Groovy'
++ def result = shell.run scriptText, 'TestBindingsInFieldInitializersWithConfigJavaBaseScript.groovy', [arg0]
++ assert result == arg0
++ }
++
+ void testBindingsInScriptFieldInitializers() {
+ def shell = new GroovyShell();
+ def scriptText = '''
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr507.patch
----------------------------------------------------------------------
diff --git a/pr507.patch b/pr507.patch
new file mode 100644
index 0000000..72d74a1
--- /dev/null
+++ b/pr507.patch
@@ -0,0 +1,25 @@
+From: AarjavP <Aa...@users.noreply.github.com>
+Date: Wed, 30 Aug 2017 17:39:44 +0200
+Subject: [PATCH] Fix wildcard arg handling in startGroovy.bat (closes #507)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Aarjav Patel
+---
+ src/bin/startGroovy.bat | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/bin/startGroovy.bat b/src/bin/startGroovy.bat
+index 1b7988218..f869ff7938b5a4262be297007178ef6f68aafaff 100644
+--- a/src/bin/startGroovy.bat
++++ b/src/bin/startGroovy.bat
+@@ -177,7 +177,7 @@
+ goto process_arg
+
+ :get_arg
+-rem remove quotes around first arg
++rem remove quotes around first arg and don't expand wildcards
+ for /f %%i in (%1) do set _ARG=%_ARG% %%~i
+ rem set the remaining args
+ set _ARGS=%2
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr555.patch
----------------------------------------------------------------------
diff --git a/pr555.patch b/pr555.patch
new file mode 100644
index 0000000..67423c6
--- /dev/null
+++ b/pr555.patch
@@ -0,0 +1,312 @@
+From 11a0b159d8d04f3c1e518613566a1b459ecda44d Mon Sep 17 00:00:00 2001
+From: noamt <no...@10ne.org>
+Date: Wed, 31 May 2017 20:57:04 +0200
+Subject: [PATCH 1/5] GROOVY-8200 - Shorthand |= results in NPE: Fixing the NPE
+ with an explicit test and assignment of the right-hand boolean operator.
+ Assigning a primitive boolean variable with null, like `boolean x = null`,
+ will end up as `false`. I think it only makes sense to apply the same
+ behavior to the right hand operator.
+
+---
+ .../groovy/runtime/DefaultGroovyMethods.java | 12 ++++++++
+ .../groovy/runtime/DefaultGroovyMethodsTest.groovy | 36 ++++++++++++++++++++++
+ 2 files changed, 48 insertions(+)
+
+diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+index 76b9fa6378..da50255833 100644
+--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
++++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+@@ -15760,6 +15760,9 @@ public static BigInteger toBigInteger(Number self) {
+ * @since 1.0
+ */
+ public static Boolean and(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return left && right;
+ }
+
+@@ -15772,6 +15775,9 @@ public static Boolean and(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean or(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return left || right;
+ }
+
+@@ -15784,6 +15790,9 @@ public static Boolean or(Boolean left, Boolean right) {
+ * @since 1.8.3
+ */
+ public static Boolean implies(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return !left || right;
+ }
+
+@@ -15796,6 +15805,9 @@ public static Boolean implies(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean xor(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return left ^ right;
+ }
+
+diff --git a/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
+index 087b301bc3..c0e4e1a990 100644
+--- a/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
++++ b/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
+@@ -239,4 +239,40 @@ public class DefaultGroovyMethodsTest extends GroovyTestCase {
+ private static class MyList extends ArrayList {
+ public MyList() {}
+ }
++
++ public void testBooleanOr() {
++ assertTrue(DefaultGroovyMethods.or(true, true))
++ assertTrue(DefaultGroovyMethods.or(true, false))
++ assertTrue(DefaultGroovyMethods.or(false, true))
++ assertFalse(DefaultGroovyMethods.or(false, false))
++ assertFalse(DefaultGroovyMethods.or(false, null))
++ assertTrue(DefaultGroovyMethods.or(true, null))
++ }
++
++ public void testBooleanAnd() {
++ assertTrue(DefaultGroovyMethods.and(true, true))
++ assertFalse(DefaultGroovyMethods.and(true, false))
++ assertFalse(DefaultGroovyMethods.and(false, true))
++ assertFalse(DefaultGroovyMethods.and(false, false))
++ assertFalse(DefaultGroovyMethods.and(false, null))
++ assertFalse(DefaultGroovyMethods.and(true, null))
++ }
++
++ public void testBooleanXor() {
++ assertFalse(DefaultGroovyMethods.xor(true, true))
++ assertTrue(DefaultGroovyMethods.xor(true, false))
++ assertTrue(DefaultGroovyMethods.xor(false, true))
++ assertFalse(DefaultGroovyMethods.xor(false, false))
++ assertFalse(DefaultGroovyMethods.xor(false, null))
++ assertTrue(DefaultGroovyMethods.xor(true, null))
++ }
++
++ public void testBooleanImplication() {
++ assertTrue(DefaultGroovyMethods.implies(true, true))
++ assertTrue(DefaultGroovyMethods.xor(true, false))
++ assertTrue(DefaultGroovyMethods.xor(false, true))
++ assertFalse(DefaultGroovyMethods.xor(false, false))
++ assertFalse(DefaultGroovyMethods.xor(false, null))
++ assertTrue(DefaultGroovyMethods.xor(true, null))
++ }
+ }
+
+From 2d8fc8957a82658ec000e77cb1cab66565ef2a6a Mon Sep 17 00:00:00 2001
+From: noamt <no...@10ne.org>
+Date: Thu, 1 Jun 2017 15:02:40 +0200
+Subject: [PATCH 2/5] GROOVY-8200 - Shorthand |= results in NPE: Using a
+ cleaner, safe assignment of the right hand operator
+
+---
+ .../codehaus/groovy/runtime/DefaultGroovyMethods.java | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+index da50255833..f359f44dfd 100644
+--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
++++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+@@ -15760,9 +15760,7 @@ public static BigInteger toBigInteger(Number self) {
+ * @since 1.0
+ */
+ public static Boolean and(Boolean left, Boolean right) {
+- if (right == null) {
+- right = Boolean.FALSE;
+- }
++ right = Boolean.TRUE.equals(right);
+ return left && right;
+ }
+
+@@ -15775,9 +15773,7 @@ public static Boolean and(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean or(Boolean left, Boolean right) {
+- if (right == null) {
+- right = Boolean.FALSE;
+- }
++ right = Boolean.TRUE.equals(right);
+ return left || right;
+ }
+
+@@ -15790,9 +15786,7 @@ public static Boolean or(Boolean left, Boolean right) {
+ * @since 1.8.3
+ */
+ public static Boolean implies(Boolean left, Boolean right) {
+- if (right == null) {
+- right = Boolean.FALSE;
+- }
++ right = Boolean.TRUE.equals(right);
+ return !left || right;
+ }
+
+@@ -15805,9 +15799,7 @@ public static Boolean implies(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean xor(Boolean left, Boolean right) {
+- if (right == null) {
+- right = Boolean.FALSE;
+- }
++ right = Boolean.TRUE.equals(right);
+ return left ^ right;
+ }
+
+
+From 9d9f2d49db0cd149349b74549f5556a650bc5c7f Mon Sep 17 00:00:00 2001
+From: noamt <no...@10ne.org>
+Date: Wed, 7 Jun 2017 12:33:13 +0300
+Subject: [PATCH 3/5] GROOVY-8200 - Shorthand |= results in NPE: Reducing the
+ expression to a one liner
+
+---
+ .../org/codehaus/groovy/runtime/DefaultGroovyMethods.java | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+index f359f44dfd..193a7bf655 100644
+--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
++++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+@@ -15760,8 +15760,7 @@ public static BigInteger toBigInteger(Number self) {
+ * @since 1.0
+ */
+ public static Boolean and(Boolean left, Boolean right) {
+- right = Boolean.TRUE.equals(right);
+- return left && right;
++ return left && Boolean.TRUE.equals(right);
+ }
+
+ /**
+@@ -15773,8 +15772,7 @@ public static Boolean and(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean or(Boolean left, Boolean right) {
+- right = Boolean.TRUE.equals(right);
+- return left || right;
++ return left || Boolean.TRUE.equals(right);
+ }
+
+ /**
+@@ -15786,8 +15784,7 @@ public static Boolean or(Boolean left, Boolean right) {
+ * @since 1.8.3
+ */
+ public static Boolean implies(Boolean left, Boolean right) {
+- right = Boolean.TRUE.equals(right);
+- return !left || right;
++ return !left || Boolean.TRUE.equals(right);
+ }
+
+ /**
+@@ -15799,8 +15796,7 @@ public static Boolean implies(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean xor(Boolean left, Boolean right) {
+- right = Boolean.TRUE.equals(right);
+- return left ^ right;
++ return left ^ Boolean.TRUE.equals(right);
+ }
+
+ // public static Boolean negate(Boolean left) {
+
+From aa715bcc38fa2cfb13de7cbccbda5c6aaba2cf14 Mon Sep 17 00:00:00 2001
+From: noamt <no...@10ne.org>
+Date: Thu, 8 Jun 2017 14:03:19 +0300
+Subject: [PATCH 4/5] GROOVY-8200 - Shorthand |= results in NPE: Fix copy-pasta
+ mistake in DefaultGroovyMethodsTest
+
+---
+ .../codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
+index c0e4e1a990..713e29b431 100644
+--- a/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
++++ b/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
+@@ -269,10 +269,10 @@ public class DefaultGroovyMethodsTest extends GroovyTestCase {
+
+ public void testBooleanImplication() {
+ assertTrue(DefaultGroovyMethods.implies(true, true))
+- assertTrue(DefaultGroovyMethods.xor(true, false))
+- assertTrue(DefaultGroovyMethods.xor(false, true))
+- assertFalse(DefaultGroovyMethods.xor(false, false))
+- assertFalse(DefaultGroovyMethods.xor(false, null))
+- assertTrue(DefaultGroovyMethods.xor(true, null))
++ assertFalse(DefaultGroovyMethods.implies(true, false))
++ assertTrue(DefaultGroovyMethods.implies(false, true))
++ assertTrue(DefaultGroovyMethods.implies(false, false))
++ assertTrue(DefaultGroovyMethods.implies(false, null))
++ assertFalse(DefaultGroovyMethods.implies(true, null))
+ }
+ }
+
+From 0e95399596b828c1ad14f571290e79ad03eef2b2 Mon Sep 17 00:00:00 2001
+From: noamt <no...@10ne.org>
+Date: Thu, 8 Jun 2017 14:04:06 +0300
+Subject: [PATCH 5/5] GROOVY-8200 - Shorthand |= results in NPE: Adding tests
+ for the shorthand logical operators
+
+---
+ src/spec/test/OperatorsTest.groovy | 44 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 43 insertions(+), 1 deletion(-)
+
+diff --git a/src/spec/test/OperatorsTest.groovy b/src/spec/test/OperatorsTest.groovy
+index a0eddf38d8..46b87f7e7b 100644
+--- a/src/spec/test/OperatorsTest.groovy
++++ b/src/spec/test/OperatorsTest.groovy
+@@ -607,4 +607,46 @@ assert (b1 + 11).size == 15
+ assert str1 == str2
+ '''
+ }
+-}
++
++ void testBooleanOr() {
++ assertScript '''
++boolean trueValue1 = true, trueValue2 = true, trueValue3 = true
++boolean falseValue1 = false, falseValue2 = false, falseValue3 = false
++
++assert (trueValue1 |= true)
++assert (trueValue2 |= false)
++assert (trueValue3 |= null)
++assert (falseValue1 |= true)
++assert !(falseValue2 |= false)
++assert !(falseValue3 |= null)
++'''
++ }
++
++ void testBooleanAnd() {
++ assertScript '''
++boolean trueValue1 = true, trueValue2 = true, trueValue3 = true
++boolean falseValue1 = false, falseValue2 = false, falseValue3 = false
++
++assert (trueValue1 &= true)
++assert !(trueValue2 &= false)
++assert !(trueValue3 &= null)
++assert !(falseValue1 &= true)
++assert !(falseValue2 &= false)
++assert !(falseValue3 &= null)
++'''
++ }
++
++ void testBooleanXor() {
++ assertScript '''
++boolean trueValue1 = true, trueValue2 = true, trueValue3 = true
++boolean falseValue1 = false, falseValue2 = false, falseValue3 = false
++
++assert !(trueValue1 ^= true)
++assert (trueValue2 ^= false)
++assert (trueValue3 ^= null)
++assert (falseValue1 ^= true)
++assert !(falseValue2 ^= false)
++assert !(falseValue3 ^= null)
++'''
++ }
++}
+\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr555a.patch
----------------------------------------------------------------------
diff --git a/pr555a.patch b/pr555a.patch
new file mode 100644
index 0000000..9e54187
--- /dev/null
+++ b/pr555a.patch
@@ -0,0 +1,94 @@
+ .../groovy/runtime/DefaultGroovyMethods.java | 12 ++++++++
+ .../groovy/runtime/DefaultGroovyMethodsTest.groovy | 36 ++++++++++++++++++++++
+ 2 files changed, 48 insertions(+)
+
+diff --git a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+index 76b9fa6378..da50255833 100644
+--- a/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
++++ b/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+@@ -15760,6 +15760,9 @@ public static BigInteger toBigInteger(Number self) {
+ * @since 1.0
+ */
+ public static Boolean and(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return left && right;
+ }
+
+@@ -15772,6 +15775,9 @@ public static Boolean and(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean or(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return left || right;
+ }
+
+@@ -15784,6 +15790,9 @@ public static Boolean or(Boolean left, Boolean right) {
+ * @since 1.8.3
+ */
+ public static Boolean implies(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return !left || right;
+ }
+
+@@ -15796,6 +15805,9 @@ public static Boolean implies(Boolean left, Boolean right) {
+ * @since 1.0
+ */
+ public static Boolean xor(Boolean left, Boolean right) {
++ if (right == null) {
++ right = Boolean.FALSE;
++ }
+ return left ^ right;
+ }
+
+diff --git a/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
+index 087b301bc3..c0e4e1a990 100644
+--- a/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
++++ b/src/test/org/codehaus/groovy/runtime/DefaultGroovyMethodsTest.groovy
+@@ -239,4 +239,40 @@ public class DefaultGroovyMethodsTest extends GroovyTestCase {
+ private static class MyList extends ArrayList {
+ public MyList() {}
+ }
++
++ public void testBooleanOr() {
++ assertTrue(DefaultGroovyMethods.or(true, true))
++ assertTrue(DefaultGroovyMethods.or(true, false))
++ assertTrue(DefaultGroovyMethods.or(false, true))
++ assertFalse(DefaultGroovyMethods.or(false, false))
++ assertFalse(DefaultGroovyMethods.or(false, null))
++ assertTrue(DefaultGroovyMethods.or(true, null))
++ }
++
++ public void testBooleanAnd() {
++ assertTrue(DefaultGroovyMethods.and(true, true))
++ assertFalse(DefaultGroovyMethods.and(true, false))
++ assertFalse(DefaultGroovyMethods.and(false, true))
++ assertFalse(DefaultGroovyMethods.and(false, false))
++ assertFalse(DefaultGroovyMethods.and(false, null))
++ assertFalse(DefaultGroovyMethods.and(true, null))
++ }
++
++ public void testBooleanXor() {
++ assertFalse(DefaultGroovyMethods.xor(true, true))
++ assertTrue(DefaultGroovyMethods.xor(true, false))
++ assertTrue(DefaultGroovyMethods.xor(false, true))
++ assertFalse(DefaultGroovyMethods.xor(false, false))
++ assertFalse(DefaultGroovyMethods.xor(false, null))
++ assertTrue(DefaultGroovyMethods.xor(true, null))
++ }
++
++ public void testBooleanImplication() {
++ assertTrue(DefaultGroovyMethods.implies(true, true))
++ assertTrue(DefaultGroovyMethods.xor(true, false))
++ assertTrue(DefaultGroovyMethods.xor(false, true))
++ assertFalse(DefaultGroovyMethods.xor(false, false))
++ assertFalse(DefaultGroovyMethods.xor(false, null))
++ assertTrue(DefaultGroovyMethods.xor(true, null))
++ }
+ }
+
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr565.patch
----------------------------------------------------------------------
diff --git a/pr565.patch b/pr565.patch
new file mode 100644
index 0000000..31c7ce7
--- /dev/null
+++ b/pr565.patch
@@ -0,0 +1,168 @@
+From b3a0e1634749dbd703f705795a767b71c11a7bec Mon Sep 17 00:00:00 2001
+From: paulk <pa...@asert.com.au>
+Date: Sun, 25 Jun 2017 21:57:36 +1000
+Subject: [PATCH] GROOVY-8236: Report more meaningful error for versions of
+ Groovy not supporting @Repeatable
+
+---
+ .../codehaus/groovy/classgen/ExtendedVerifier.java | 58 +++++++++++++++++++---
+ src/test/gls/annotations/AnnotationTest.groovy | 38 ++++++++++++++
+ 2 files changed, 89 insertions(+), 7 deletions(-)
+
+diff --git a/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java b/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
+index bad5acc649..e1cb4182a1 100644
+--- a/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
++++ b/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
+@@ -19,7 +19,9 @@
+ package org.codehaus.groovy.classgen;
+
+ import org.codehaus.groovy.ast.*;
++import org.codehaus.groovy.ast.expr.ClassExpression;
+ import org.codehaus.groovy.ast.expr.DeclarationExpression;
++import org.codehaus.groovy.ast.expr.Expression;
+ import org.codehaus.groovy.ast.stmt.ReturnStatement;
+ import org.codehaus.groovy.ast.stmt.Statement;
+ import org.codehaus.groovy.ast.tools.ParameterUtils;
+@@ -34,6 +36,7 @@
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.HashMap;
++import java.util.LinkedHashMap;
+ import java.util.List;
+ import java.util.Map;
+
+@@ -135,21 +138,62 @@ protected void visitAnnotations(AnnotatedNode node, int target) {
+ addError("Annotations are not supported in the current runtime. " + JVM_ERROR_MESSAGE, node);
+ return;
+ }
++ Map<String, List<AnnotationNode>> runtimeAnnotations = new LinkedHashMap<String, List<AnnotationNode>>();
+ for (AnnotationNode unvisited : node.getAnnotations()) {
+ AnnotationNode visited = visitAnnotation(unvisited);
+- boolean isTargetAnnotation = visited.getClassNode().isResolved() &&
+- visited.getClassNode().getName().equals("java.lang.annotation.Target");
++ String name = visited.getClassNode().getName();
++ if (visited.hasRuntimeRetention()) {
++ List<AnnotationNode> seen = runtimeAnnotations.get(name);
++ if (seen == null) {
++ seen = new ArrayList<AnnotationNode>();
++ }
++ seen.add(visited);
++ runtimeAnnotations.put(name, seen);
++ }
++ boolean isTargetAnnotation = name.equals("java.lang.annotation.Target");
+
+ // Check if the annotation target is correct, unless it's the target annotating an annotation definition
+ // defining on which target elements the annotation applies
+ if (!isTargetAnnotation && !visited.isTargetAllowed(target)) {
+- addError("Annotation @" + visited.getClassNode().getName()
+- + " is not allowed on element " + AnnotationNode.targetToName(target),
+- visited);
++ addError("Annotation @" + name + " is not allowed on element "
++ + AnnotationNode.targetToName(target), visited);
+ }
+ visitDeprecation(node, visited);
+ visitOverride(node, visited);
+ }
++ checkForDuplicateAnnotations(runtimeAnnotations);
++ }
++
++ private void checkForDuplicateAnnotations(Map<String, List<AnnotationNode>> runtimeAnnotations) {
++ for (Map.Entry<String, List<AnnotationNode>> next : runtimeAnnotations.entrySet()) {
++ if (next.getValue().size() > 1) {
++ String repeatableName = null;
++ AnnotationNode repeatee = next.getValue().get(0);
++ List<AnnotationNode> repeateeAnnotations = repeatee.getClassNode().getAnnotations();
++ for (AnnotationNode anno : repeateeAnnotations) {
++ ClassNode annoClassNode = anno.getClassNode();
++ if (annoClassNode.getName().equals("java.lang.annotation.Repeatable")) {
++ Expression value = anno.getMember("value");
++ if (value instanceof ClassExpression) {
++ ClassExpression ce = (ClassExpression) value;
++ if (ce.getType() != null && ce.getType().isAnnotationDefinition()) {
++ repeatableName = ce.getType().getName();
++ }
++ }
++ break;
++ }
++ }
++ // TODO: further checks: that repeatableName is valid and has RUNTIME retention?
++ if (repeatableName != null) {
++ addError("Annotation @" + next.getKey() + " has RUNTIME retention and " + next.getValue().size()
++ + " occurrences. Automatic repeated annotations are not supported in this version of Groovy. " +
++ "Consider using the explicit @" + repeatableName + " collector annotation instead.", next.getValue().get(1));
++ } else {
++ addError("Annotation @" + next.getKey() + " has RUNTIME retention and " + next.getValue().size()
++ + " occurrences. Duplicate annotations not allowed.", next.getValue().get(1));
++ }
++ }
++ }
+ }
+
+ private static void visitDeprecation(AnnotatedNode node, AnnotationNode visited) {
+@@ -222,7 +266,7 @@ private static boolean isOverrideMethod(MethodNode method) {
+ }
+ ClassNode superClass = next.getUnresolvedSuperClass();
+ if (superClass != null) {
+- next = correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
++ next = correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
+ } else {
+ next = null;
+ }
+@@ -231,7 +275,7 @@ private static boolean isOverrideMethod(MethodNode method) {
+ }
+
+ private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
+- for (MethodNode orig : correctedNext.getDeclaredMethods(mn.getName())) {
++ for (MethodNode orig : correctedNext.getDeclaredMethods(mn.getName())) {
+ MethodNode method = correctToGenericsSpec(genericsSpec, orig);
+ if (ParameterUtils.parametersEqual(method.getParameters(), mn.getParameters())) {
+ return method;
+diff --git a/src/test/gls/annotations/AnnotationTest.groovy b/src/test/gls/annotations/AnnotationTest.groovy
+index 80e42427ac..9f306ff1e4 100644
+--- a/src/test/gls/annotations/AnnotationTest.groovy
++++ b/src/test/gls/annotations/AnnotationTest.groovy
+@@ -704,6 +704,44 @@ class AnnotationTest extends CompilableTestSupport {
+ '''
+ }
+
++ // GROOVY-8236
++ void testAnnotationWithRepeated() {
++ def errorMessage = shouldNotCompile '''
++ import java.lang.annotation.*
++
++ class MyClass {
++ @MyAnnotation(value = "val1")
++ @MyAnnotation(value = "val2")
++ //change annotation to next line and the code will work
++ //@MyAnnotationArray( [@MyAnnotation("val1"), @MyAnnotation("val2")] )
++ String annotatedMethod() {
++ 'foo'
++ }
++ static void main(String... args) {
++ MyClass myc = new MyClass()
++ assert 'foo' == myc.annotatedMethod()
++ def m = myc.getClass().getMethod("annotatedMethod")
++ List annos = m.getAnnotations()
++ assert annos.size() == 1
++ }
++ }
++
++ @Target(ElementType.METHOD)
++ @Retention(RetentionPolicy.RUNTIME)
++ @Repeatable(MyAnnotationArray)
++ @interface MyAnnotation {
++ String value() default "val0"
++ }
++
++ @Retention(RetentionPolicy.RUNTIME)
++ @interface MyAnnotationArray {
++ MyAnnotation[] value()
++ }
++ '''
++ assert errorMessage.contains('Automatic repeated annotations are not supported')
++ assert errorMessage.contains('Consider using the explicit @MyAnnotationArray collector annotation')
++ }
++
+ //Parametrized tests in Spock would allow to make it much more readable
+ private static String codeWithMetaAnnotationWithTarget(String targetElementTypeName) {
+ """
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr584.patch
----------------------------------------------------------------------
diff --git a/pr584.patch b/pr584.patch
new file mode 100644
index 0000000..ec5c5fe
--- /dev/null
+++ b/pr584.patch
@@ -0,0 +1,57 @@
+From 2c11c1b72ff47e6c5ccb2134a7ea86da8cabc028 Mon Sep 17 00:00:00 2001
+From: John Wagenleitner <jw...@apache.org>
+Date: Sun, 13 Aug 2017 17:15:00 -0700
+Subject: [PATCH] GROOVY-8249: Newify local variable declaration fails to
+ resolve class expression
+
+---
+ .../groovy/classgen/VariableScopeVisitor.java | 1 +
+ .../groovy/transform/NewifyTransformTest.groovy | 24 ++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+index 7a99014fed..f920211e32 100644
+--- a/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
++++ b/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+@@ -330,6 +330,7 @@ public void visitIfElse(IfStatement ifElse) {
+ }
+
+ public void visitDeclarationExpression(DeclarationExpression expression) {
++ visitAnnotations(expression);
+ // visit right side first to avoid the usage of a
+ // variable before its declaration
+ expression.getRightExpression().visit(this);
+diff --git a/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy b/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
+index d585c8a32c..c2cce48ef0 100644
+--- a/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
++++ b/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
+@@ -211,4 +211,28 @@ class NewifyTransformTest extends GroovyShellTestCase {
+ assert Foo.answer == 42
+ '''
+ }
++
++ // GROOVY-8249
++ void testLocalVariableDeclResolvesClass() {
++ assertScript '''
++ class A {
++ final int id
++ A(int id) { this.id = id + 10 }
++ }
++ class Foo {
++ static String test() {
++ @Newify(String)
++ String answer = String('bar')
++ answer
++ }
++ static int test2() {
++ @Newify(A)
++ int answer = A(32).id
++ answer
++ }
++ }
++ assert Foo.test() == 'bar'
++ assert Foo.test2() == 42
++ '''
++ }
+ }
+\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr597.patch
----------------------------------------------------------------------
diff --git a/pr597.patch b/pr597.patch
new file mode 100644
index 0000000..3678787
--- /dev/null
+++ b/pr597.patch
@@ -0,0 +1,26 @@
+From 9740919cee991a573a45e288f8aa7d4490dfcc4f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Aur=C3=A9lien=20Pupier?= <ap...@redhat.com>
+Date: Wed, 30 Aug 2017 17:39:44 +0200
+Subject: [PATCH] GROOVY-8305: Fix default Ivy settings file for local m2 path
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Aurélien Pupier <ap...@redhat.com>
+---
+ src/resources/groovy/grape/defaultGrapeConfig.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/resources/groovy/grape/defaultGrapeConfig.xml b/src/resources/groovy/grape/defaultGrapeConfig.xml
+index 11161d37f4..a9f03062af 100644
+--- a/src/resources/groovy/grape/defaultGrapeConfig.xml
++++ b/src/resources/groovy/grape/defaultGrapeConfig.xml
+@@ -26,7 +26,7 @@
+ <ivy pattern="${user.home}/.groovy/grapes/[organisation]/[module]/ivy-[revision].xml"/>
+ <artifact pattern="${user.home}/.groovy/grapes/[organisation]/[module]/[type]s/[artifact]-[revision](-[classifier]).[ext]"/>
+ </filesystem>
+- <ibiblio name="localm2" root="file:${user.home}/.m2/repository/" checkmodified="true" changingPattern=".*" changingMatcher="regexp" m2compatible="true"/>
++ <ibiblio name="localm2" root="file:/${user.home}/.m2/repository/" checkmodified="true" changingPattern=".*" changingMatcher="regexp" m2compatible="true"/>
+ <!-- todo add 'endorsed groovy extensions' resolver here -->
+ <ibiblio name="jcenter" root="https://jcenter.bintray.com/" m2compatible="true"/>
+ <ibiblio name="ibiblio" m2compatible="true"/>
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr603.patch
----------------------------------------------------------------------
diff --git a/pr603.patch b/pr603.patch
new file mode 100644
index 0000000..db060a1
--- /dev/null
+++ b/pr603.patch
@@ -0,0 +1,102 @@
+From e8fd90ae974fa97817682c1c4f8936feef2d2a66 Mon Sep 17 00:00:00 2001
+From: paulk <pa...@asert.com.au>
+Date: Mon, 18 Sep 2017 13:37:59 +1000
+Subject: [PATCH] GROOVY-8260: Static compilation requires casting inside
+ instanceof check
+
+---
+ .../transform/stc/StaticTypeCheckingVisitor.java | 14 ++++--
+ src/test/groovy/bugs/Groovy8260Bug.groovy | 57 ++++++++++++++++++++++
+ 2 files changed, 67 insertions(+), 4 deletions(-)
+ create mode 100644 src/test/groovy/bugs/Groovy8260Bug.groovy
+
+diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+index 12ea2b50f2..8c66eb7b9d 100644
+--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
++++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+@@ -4018,12 +4018,18 @@ protected ClassNode getType(ASTNode exp) {
+ }
+ if (variable instanceof Parameter) {
+ Parameter parameter = (Parameter) variable;
+- ClassNode type = typeCheckingContext.controlStructureVariables.get(parameter);
++ ClassNode type = null;
++ // check if param part of control structure - but not if inside instanceof
++ List<ClassNode> temporaryTypesForExpression = getTemporaryTypesForExpression(vexp);
++ if (temporaryTypesForExpression == null || temporaryTypesForExpression.isEmpty()) {
++ type = typeCheckingContext.controlStructureVariables.get(parameter);
++ }
++ // now check for closure override
+ TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
+- ClassNode[] closureParamTypes = (ClassNode[])(enclosingClosure!=null?enclosingClosure.getClosureExpression().getNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS):null);
+- if (type==null && enclosingClosure !=null && "it".equals(variable.getName()) && closureParamTypes!=null) {
++ ClassNode[] closureParamTypes = (ClassNode[]) (enclosingClosure != null ? enclosingClosure.getClosureExpression().getNodeMetaData(StaticTypesMarker.CLOSURE_ARGUMENTS) : null);
++ if (type == null && enclosingClosure != null && "it".equals(variable.getName()) && closureParamTypes != null) {
+ final Parameter[] parameters = enclosingClosure.getClosureExpression().getParameters();
+- if (parameters.length==0 && getTemporaryTypesForExpression(vexp)==null && closureParamTypes.length!=0) {
++ if (parameters.length == 0 && temporaryTypesForExpression == null && closureParamTypes.length != 0) {
+ type = closureParamTypes[0];
+ }
+ }
+diff --git a/src/test/groovy/bugs/Groovy8260Bug.groovy b/src/test/groovy/bugs/Groovy8260Bug.groovy
+new file mode 100644
+index 0000000000..e69d68bdd3
+--- /dev/null
++++ b/src/test/groovy/bugs/Groovy8260Bug.groovy
+@@ -0,0 +1,57 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements. See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership. The ASF licenses this file
++ * to you under the Apache License, Version 2.0 (the
++ * "License"); you may not use this file except in compliance
++ * with the License. You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing,
++ * software distributed under the License is distributed on an
++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++ * KIND, either express or implied. See the License for the
++ * specific language governing permissions and limitations
++ * under the License.
++ */
++package groovy.bugs
++
++class Groovy8260Bug extends GroovyTestCase {
++
++ void testNoCastForInstanceofInsideLoop() {
++ assertScript '''
++ import groovy.transform.CompileStatic
++
++ interface FooI {
++ def intfMethod()
++ }
++
++ class Foo implements FooI {
++ def intfMethod() { 'Foo Interface method' }
++ def implMethod() { 'Foo Implementation method' }
++ }
++
++ @CompileStatic
++ def method(FooI propIn, List result) {
++ if (propIn instanceof Foo) {
++ result << propIn.implMethod()
++ } else {
++ result << propIn?.intfMethod()
++ }
++ for (FooI propLoop : [null, new Foo()]) {
++ result << propLoop?.intfMethod()
++ if (propLoop instanceof Foo) {
++ result << propLoop.implMethod()
++ }
++ }
++ }
++
++ def result = []
++ method(null, result)
++ assert result == [null, null, 'Foo Interface method', 'Foo Implementation method']
++ '''
++ }
++
++}
http://git-wip-us.apache.org/repos/asf/groovy/blob/13522f88/pr607.patch
----------------------------------------------------------------------
diff --git a/pr607.patch b/pr607.patch
new file mode 100644
index 0000000..8a5206b
--- /dev/null
+++ b/pr607.patch
@@ -0,0 +1,60 @@
+From f30d2e5dd6ce8045eb6656d1993f0dd9b07edfc5 Mon Sep 17 00:00:00 2001
+From: "alexey.afanasiev" <Al...@jetbrains.com>
+Date: Tue, 26 Sep 2017 17:43:15 +0300
+Subject: [PATCH] GROOVY-8330: Wrong 'Inconvertible types' error on casting
+ interface
+
+---
+ .../transform/stc/StaticTypeCheckingVisitor.java | 2 ++
+ .../groovy/transform/stc/STCAssignmentTest.groovy | 26 ++++++++++++++++++++++
+ 2 files changed, 28 insertions(+)
+
+diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+index cbb2798470..4c55eeafb8 100644
+--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
++++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+@@ -3369,6 +3369,8 @@ protected boolean checkCast(final ClassNode targetType, final Expression source)
+ return false;
+ } else if ((expressionType.getModifiers()& Opcodes.ACC_FINAL)==0 && targetType.isInterface()) {
+ return true;
++ } else if ((targetType.getModifiers()& Opcodes.ACC_FINAL)==0 && expressionType.isInterface()) {
++ return true;
+ } else if (!isAssignableTo(targetType, expressionType) && !implementsInterfaceOrIsSubclassOf(expressionType, targetType)) {
+ return false;
+ }
+diff --git a/src/test/groovy/transform/stc/STCAssignmentTest.groovy b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
+index 3c00185b90..acb1c7532b 100644
+--- a/src/test/groovy/transform/stc/STCAssignmentTest.groovy
++++ b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
+@@ -872,5 +872,31 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
+ }
+ '''
+ }
++
++ void testNarrowingConversion() {
++ assertScript '''
++ interface A1{}
++ interface A2 extends A1{}
++
++ class C1 implements A1{}
++
++ def m(A2 a2) {
++ C1 c1 = (C1) a2
++ }
++ '''
++ }
++
++ void testFinalNarrowingConversion() {
++ shouldFailWithMessages '''
++ interface A1{}
++ interface A2 extends A1{}
++
++ final class C1 implements A1{}
++
++ def m(A2 a2) {
++ C1 c1 = (C1) a2
++ }
++ ''', "Inconvertible types: cannot cast A2 to C1"
++ }
+ }
+