From 720dced06b1ec447d77b00550b8b299dfe3e18d9 Mon Sep 17 00:00:00 2001 From: John Wagenleitner Date: Sun, 21 May 2017 10:16:06 -0700 Subject: [PATCH 1/5] GROOVY-7611: java.util.Optional should evaluate to false if empty --- build.gradle | 9 ++++ .../groovy/vmplugin/VMPluginFactory.java | 25 ++++----- .../codehaus/groovy/vmplugin/vm8/Java8.java | 54 +++++++++++++++++++ .../vm8/Java8DefaultGroovyMethods.java | 45 ++++++++++++++++ .../vm8/Java8DefaultGroovyMethodsTest.groovy | 30 +++++++++++ 5 files changed, 147 insertions(+), 16 deletions(-) create mode 100644 src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java create mode 100644 src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java create mode 100644 src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy diff --git a/build.gradle b/build.gradle index 47e0d1927e8..e59b82e7363 100644 --- a/build.gradle +++ b/build.gradle @@ -268,12 +268,18 @@ sourceSets { 'src/main', "$generatedDirectory/src/main" ] + if (!JavaVersion.current().isJava8Compatible()) { + exclude '**/vm8/*' + } } groovy { srcDirs = [ 'src/main', "$generatedDirectory/src/main" ] + if (!JavaVersion.current().isJava8Compatible()) { + exclude '**/vm8/*' + } } resources { srcDirs = ['src/main', 'src/tools', 'src/resources'] @@ -292,6 +298,9 @@ sourceSets { test { groovy { srcDirs = ['src/test'] + if (!JavaVersion.current().isJava8Compatible()) { + exclude '**/vm8/*' + } } resources { srcDirs = ['src/test-resources'] diff --git a/src/main/org/codehaus/groovy/vmplugin/VMPluginFactory.java b/src/main/org/codehaus/groovy/vmplugin/VMPluginFactory.java index 127f65e093d..fe625fbb04c 100644 --- a/src/main/org/codehaus/groovy/vmplugin/VMPluginFactory.java +++ b/src/main/org/codehaus/groovy/vmplugin/VMPluginFactory.java @@ -18,6 +18,8 @@ */ package org.codehaus.groovy.vmplugin; +import org.codehaus.groovy.vmplugin.v7.Java7; + /** * Factory class to get functionality based on the VM version. * The usage of this class is not for public use, only for the @@ -26,26 +28,17 @@ */ public class VMPluginFactory { - private static final String JDK5_CLASSNAME_CHECK = "java.lang.annotation.Annotation"; - private static final String JDK6_CLASSNAME_CHECK = "javax.script.ScriptEngine"; - private static final String JDK7_CLASSNAME_CHECK = "java.util.Objects"; - - private static final String JDK5_PLUGIN_NAME = "org.codehaus.groovy.vmplugin.v5.Java5"; - private static final String JDK6_PLUGIN_NAME = "org.codehaus.groovy.vmplugin.v6.Java6"; - private static final String JDK7_PLUGIN_NAME = "org.codehaus.groovy.vmplugin.v7.Java7"; + private static final String JDK8_CLASSNAME_CHECK = "java.util.Optional"; + private static final String JDK8_PLUGIN_NAME = "org.codehaus.groovy.vmplugin.vm8.Java8"; - private static VMPlugin plugin; + private static final VMPlugin plugin; static { - plugin = createPlugin(JDK7_CLASSNAME_CHECK, JDK7_PLUGIN_NAME); - if (plugin == null) { - // v6 plugin is the same as v5 but with some scripting stuff - // so check below is good enough for now (can be true for JVM 5) - plugin = createPlugin(JDK6_CLASSNAME_CHECK, JDK6_PLUGIN_NAME); - } - if (plugin == null) { - plugin = createPlugin(JDK5_CLASSNAME_CHECK, JDK5_PLUGIN_NAME); + VMPlugin target = createPlugin(JDK8_CLASSNAME_CHECK, JDK8_PLUGIN_NAME); + if (target == null) { + target = new Java7(); } + plugin = target; } public static VMPlugin getPlugin() { diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java new file mode 100644 index 00000000000..6c8a6b41e4c --- /dev/null +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java @@ -0,0 +1,54 @@ +/* + * 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.vmplugin.vm8; + +import org.codehaus.groovy.vmplugin.v7.Java7; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Java 8 based functions. + * + * @since 2.5 + */ +public class Java8 extends Java7 { + + private final Class[] PLUGIN_DGM; + + public Java8() { + super(); + List> dgmClasses = new ArrayList<>(); + Collections.addAll(dgmClasses, (Class[]) super.getPluginDefaultGroovyMethods()); + dgmClasses.add(Java8DefaultGroovyMethods.class); + PLUGIN_DGM = dgmClasses.toArray(new Class[0]); + } + + @Override + public Class[] getPluginDefaultGroovyMethods() { + return PLUGIN_DGM; + } + + @Override + public int getVersion() { + return 8; + } + +} diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java new file mode 100644 index 00000000000..71d0521fec4 --- /dev/null +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java @@ -0,0 +1,45 @@ +/* + * 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.vmplugin.vm8; + +import java.util.Optional; + +/** + * Defines new Groovy methods which appear on normal JDK 8 + * classes inside the Groovy environment. + * + * @since 2.5 + */ +public class Java8DefaultGroovyMethods { + + // No instances, static methods only + private Java8DefaultGroovyMethods() { + } + + /** + * Coerce an Optional instance to a boolean value. + * + * @param optional the Optional + * @return {@code true} if a value is present, otherwise {@code false} + */ + public static boolean asBoolean(Optional optional) { + return optional.isPresent(); + } + +} diff --git a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy new file mode 100644 index 00000000000..df98dc0328f --- /dev/null +++ b/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy @@ -0,0 +1,30 @@ +/* + * 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.vmplugin.vm8 + +class Java8DefaultGroovyMethodsTest extends GroovyTestCase { + + // GROOVY-7611 + void testOptionalAsBoolean() { + assert Optional.of('foo') + assert !Optional.empty() + assert !Optional.ofNullable(null) + } + +} From d41a92cccb3ef4187987f2d05b06a225587e54d3 Mon Sep 17 00:00:00 2001 From: John Wagenleitner Date: Mon, 22 May 2017 18:09:07 -0700 Subject: [PATCH 2/5] generate GDK docs --- gradle/docs.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gradle/docs.gradle b/gradle/docs.gradle index d7843abb02d..3be8f3c9f72 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -143,7 +143,7 @@ task docGDK { arg(value: '-link') arg(value: 'groovy,org.codehaus.groovy=http://docs.groovy-lang.org/latest/html/gapi/') arg(value: '-link') - arg(value: 'java,org.xml,javax,org.w3c=http://docs.oracle.com/javase/7/docs/api/') + arg(value: 'java,org.xml,javax,org.w3c=http://docs.oracle.com/javase/8/docs/api/') // either package name if in core or fully qualified path otherwise arg(value: 'org.codehaus.groovy.runtime.DefaultGroovyMethods') arg(value: 'org.codehaus.groovy.runtime.DefaultGroovyStaticMethods') @@ -155,8 +155,7 @@ task docGDK { arg(value: 'org.codehaus.groovy.runtime.SocketGroovyMethods') arg(value: 'org.codehaus.groovy.runtime.StringGroovyMethods') arg(value: 'org.codehaus.groovy.vmplugin.v5.PluginDefaultGroovyMethods') - arg(value: 'org.codehaus.groovy.vmplugin.v6.PluginDefaultGroovyMethods') - arg(value: 'org.codehaus.groovy.vmplugin.v6.PluginStaticGroovyMethods') + arg(value: 'org.codehaus.groovy.vmplugin.vm8.Java8DefaultGroovyMethods') // TODO don't hard-code these arg(value: 'subprojects/groovy-sql/src/main/java/org/codehaus/groovy/runtime/SqlGroovyMethods.java') arg(value: 'subprojects/groovy-swing/src/main/java/org/codehaus/groovy/runtime/SwingGroovyMethods.java') From ca05cb9fd506f073225f5c297c962e022bea3e47 Mon Sep 17 00:00:00 2001 From: John Wagenleitner Date: Mon, 22 May 2017 18:51:18 -0700 Subject: [PATCH 3/5] add VMPlugin default methods to Static Compiler method resolution --- .../stc/StaticTypeCheckingSupport.java | 4 +++ .../Java8DefaultGroovyMethodsSCTest.groovy | 26 +++++++++++++++++++ .../vm8/Java8DefaultGroovyMethodsTest.groovy | 23 +++++++++++++--- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index d9a477ded5e..1aebf932d9f 100644 --- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -37,6 +37,7 @@ import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl; import org.codehaus.groovy.tools.GroovyClass; import org.codehaus.groovy.transform.trait.Traits; +import org.codehaus.groovy.vmplugin.VMPluginFactory; import org.objectweb.asm.Opcodes; import java.lang.ref.WeakReference; @@ -2124,6 +2125,9 @@ private static Map> getDGMMethods(List instanceExtClasses.add(FloatArrayStaticTypesHelper.class); instanceExtClasses.add(DoubleArrayStaticTypesHelper.class); + Collections.addAll(instanceExtClasses, VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods()); + Collections.addAll(staticExtClasses, VMPluginFactory.getPlugin().getPluginStaticGroovyMethods()); + scanClassesForDGMMethods(methods, staticExtClasses, true); scanClassesForDGMMethods(methods, instanceExtClasses, false); diff --git a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy b/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy new file mode 100644 index 00000000000..5f901e157ae --- /dev/null +++ b/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy @@ -0,0 +1,26 @@ +/* + * 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.vmplugin.vm8 + +import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport + +class Java8DefaultGroovyMethodsSCTest + extends Java8DefaultGroovyMethodsTest + implements StaticCompilationTestSupport { +} diff --git a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy index df98dc0328f..b21ea204570 100644 --- a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy +++ b/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy @@ -18,13 +18,28 @@ */ package org.codehaus.groovy.vmplugin.vm8 -class Java8DefaultGroovyMethodsTest extends GroovyTestCase { +import groovy.transform.stc.StaticTypeCheckingTestCase + +class Java8DefaultGroovyMethodsTest extends StaticTypeCheckingTestCase { // GROOVY-7611 void testOptionalAsBoolean() { - assert Optional.of('foo') - assert !Optional.empty() - assert !Optional.ofNullable(null) + assertScript ''' + boolean m() { + assert Optional.of('foo') + assert !Optional.empty() + assert !Optional.ofNullable(null) + + def x = Optional.empty() ? 1 : -1 + assert x == -1 + + x = Optional.ofNullable(null) ? 1 : -1 + assert x == -1 + + Optional.empty() + } + assert !m() + ''' } } From c750bfd489f57da362f8fba9ef114d30f280cfa8 Mon Sep 17 00:00:00 2001 From: John Wagenleitner Date: Mon, 22 May 2017 20:46:47 -0700 Subject: [PATCH 4/5] use standard name for plugin default methods class --- gradle/docs.gradle | 2 +- src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java | 2 +- ...aultGroovyMethods.java => PluginDefaultGroovyMethods.java} | 4 ++-- ...sSCTest.groovy => PluginDefaultGroovyMethodsSCTest.groovy} | 4 ++-- ...thodsTest.groovy => PluginDefaultGroovyMethodsTest.groovy} | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename src/main/org/codehaus/groovy/vmplugin/vm8/{Java8DefaultGroovyMethods.java => PluginDefaultGroovyMethods.java} (94%) rename src/test/org/codehaus/groovy/vmplugin/vm8/{Java8DefaultGroovyMethodsSCTest.groovy => PluginDefaultGroovyMethodsSCTest.groovy} (92%) rename src/test/org/codehaus/groovy/vmplugin/vm8/{Java8DefaultGroovyMethodsTest.groovy => PluginDefaultGroovyMethodsTest.groovy} (95%) diff --git a/gradle/docs.gradle b/gradle/docs.gradle index 3be8f3c9f72..936da4725d6 100644 --- a/gradle/docs.gradle +++ b/gradle/docs.gradle @@ -155,7 +155,7 @@ task docGDK { arg(value: 'org.codehaus.groovy.runtime.SocketGroovyMethods') arg(value: 'org.codehaus.groovy.runtime.StringGroovyMethods') arg(value: 'org.codehaus.groovy.vmplugin.v5.PluginDefaultGroovyMethods') - arg(value: 'org.codehaus.groovy.vmplugin.vm8.Java8DefaultGroovyMethods') + arg(value: 'org.codehaus.groovy.vmplugin.vm8.PluginDefaultGroovyMethods') // TODO don't hard-code these arg(value: 'subprojects/groovy-sql/src/main/java/org/codehaus/groovy/runtime/SqlGroovyMethods.java') arg(value: 'subprojects/groovy-swing/src/main/java/org/codehaus/groovy/runtime/SwingGroovyMethods.java') diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java index 6c8a6b41e4c..400557713df 100644 --- a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java @@ -37,7 +37,7 @@ public Java8() { super(); List> dgmClasses = new ArrayList<>(); Collections.addAll(dgmClasses, (Class[]) super.getPluginDefaultGroovyMethods()); - dgmClasses.add(Java8DefaultGroovyMethods.class); + dgmClasses.add(PluginDefaultGroovyMethods.class); PLUGIN_DGM = dgmClasses.toArray(new Class[0]); } diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java b/src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java similarity index 94% rename from src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java rename to src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java index 71d0521fec4..6a589165e01 100644 --- a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethods.java +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java @@ -26,10 +26,10 @@ * * @since 2.5 */ -public class Java8DefaultGroovyMethods { +public class PluginDefaultGroovyMethods { // No instances, static methods only - private Java8DefaultGroovyMethods() { + private PluginDefaultGroovyMethods() { } /** diff --git a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy b/src/test/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethodsSCTest.groovy similarity index 92% rename from src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy rename to src/test/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethodsSCTest.groovy index 5f901e157ae..373403cdf17 100644 --- a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsSCTest.groovy +++ b/src/test/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethodsSCTest.groovy @@ -20,7 +20,7 @@ package org.codehaus.groovy.vmplugin.vm8 import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport -class Java8DefaultGroovyMethodsSCTest - extends Java8DefaultGroovyMethodsTest +class PluginDefaultGroovyMethodsSCTest + extends PluginDefaultGroovyMethodsTest implements StaticCompilationTestSupport { } diff --git a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy b/src/test/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethodsTest.groovy similarity index 95% rename from src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy rename to src/test/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethodsTest.groovy index b21ea204570..5afe05e6f40 100644 --- a/src/test/org/codehaus/groovy/vmplugin/vm8/Java8DefaultGroovyMethodsTest.groovy +++ b/src/test/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethodsTest.groovy @@ -20,7 +20,7 @@ package org.codehaus.groovy.vmplugin.vm8 import groovy.transform.stc.StaticTypeCheckingTestCase -class Java8DefaultGroovyMethodsTest extends StaticTypeCheckingTestCase { +class PluginDefaultGroovyMethodsTest extends StaticTypeCheckingTestCase { // GROOVY-7611 void testOptionalAsBoolean() { From a13066c195ff305e8f572f4559b1c3a5fb6aa66d Mon Sep 17 00:00:00 2001 From: John Wagenleitner Date: Tue, 23 May 2017 07:09:01 -0700 Subject: [PATCH 5/5] fix @since --- src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java | 2 +- .../groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java index 400557713df..905af38e453 100644 --- a/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/Java8.java @@ -27,7 +27,7 @@ /** * Java 8 based functions. * - * @since 2.5 + * @since 2.5.0 */ public class Java8 extends Java7 { diff --git a/src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java b/src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java index 6a589165e01..7ae53214a66 100644 --- a/src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java +++ b/src/main/org/codehaus/groovy/vmplugin/vm8/PluginDefaultGroovyMethods.java @@ -24,7 +24,7 @@ * Defines new Groovy methods which appear on normal JDK 8 * classes inside the Groovy environment. * - * @since 2.5 + * @since 2.5.0 */ public class PluginDefaultGroovyMethods {