GROOVY-10936: `~string` is a `java.util.regex.Pattern`
4_0_X backport
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/BitwiseNegationExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/BitwiseNegationExpression.java
index 2f54b7d..c9f5fb3 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/BitwiseNegationExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/BitwiseNegationExpression.java
@@ -18,6 +18,7 @@
*/
package org.codehaus.groovy.ast.expr;
+import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.GroovyCodeVisitor;
@@ -25,7 +26,7 @@
private final Expression expression;
- public BitwiseNegationExpression(Expression expression) {
+ public BitwiseNegationExpression(final Expression expression) {
this.expression = expression;
}
@@ -34,26 +35,32 @@
}
@Override
- public void visit(GroovyCodeVisitor visitor) {
- visitor.visitBitwiseNegationExpression(this);
+ public String getText() {
+ return "~(" + getExpression().getText() + ")";
+ }
+
+ /**
+ * @see org.codehaus.groovy.runtime.InvokerHelper#bitwiseNegate(Object)
+ */
+ @Override
+ public ClassNode getType() {
+ ClassNode type = getExpression().getType();
+ if (ClassHelper.isStringType(type) || ClassHelper.isGStringType(type)) {
+ type = ClassHelper.PATTERN_TYPE; // GROOVY-10936
+ }
+ return type;
}
@Override
- public Expression transformExpression(ExpressionTransformer transformer) {
- Expression ret = new BitwiseNegationExpression(transformer.transform(expression));
+ public Expression transformExpression(final ExpressionTransformer transformer) {
+ Expression ret = new BitwiseNegationExpression(transformer.transform(getExpression()));
ret.setSourcePosition(this);
ret.copyNodeMetaData(this);
return ret;
}
@Override
- public String getText() {
- return expression.getText();
+ public void visit(final GroovyCodeVisitor visitor) {
+ visitor.visitBitwiseNegationExpression(this);
}
-
- @Override
- public ClassNode getType() {
- return expression.getType();
- }
-
}
diff --git a/src/test/groovy/bugs/TernaryOperatorTest.groovy b/src/test/groovy/bugs/TernaryOperatorTest.groovy
deleted file mode 100644
index fd740d6..0000000
--- a/src/test/groovy/bugs/TernaryOperatorTest.groovy
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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
-
-import groovy.test.GroovyTestCase
-
-class TernaryOperatorBugTest extends GroovyTestCase {
- void testTernaryOperator() {
- assertScript '''
- Class dsClass = true ? LinkedHashSet : HashSet
- '''
- }
-}
diff --git a/src/test/groovy/operator/TernaryOperatorsTest.groovy b/src/test/groovy/operator/TernaryOperatorsTest.groovy
index 59e24d9..edb90b5 100644
--- a/src/test/groovy/operator/TernaryOperatorsTest.groovy
+++ b/src/test/groovy/operator/TernaryOperatorsTest.groovy
@@ -18,33 +18,37 @@
*/
package groovy.operator
-import groovy.test.GroovyTestCase
+import org.junit.Test
-class TernaryOperatorsTest extends GroovyTestCase {
+import java.util.regex.Pattern
+final class TernaryOperatorsTest {
+
+ @Test
void testSimpleUse() {
def y = 5
def x = (y > 1) ? "worked" : "failed"
assert x == "worked"
-
- x = (y < 4) ? "failed" : "worked"
+ x = (y < 4) ? "failed" : "worked"
assert x == "worked"
}
+ @Test
void testUseInParameterCalling() {
def z = 123
assertCalledWithFoo(z > 100 ? "foo" : "bar")
assertCalledWithFoo(z < 100 ? "bar" : "foo")
- }
+ }
- def assertCalledWithFoo(param) {
+ void assertCalledWithFoo(param) {
println "called with param ${param}"
assert param == "foo"
}
- void testWithBoolean(){
+ @Test
+ void testWithBoolean() {
def a = 1
def x = a!=null ? a!=2 : a!=1
assert x == true
@@ -52,6 +56,7 @@
assert y == false
}
+ @Test
void testElvisOperator() {
def a = 1
def x = a?:2
@@ -74,12 +79,14 @@
assert ret2 == 'b'
}
+ @Test
void testForType() {
boolean b = false
int anInt = b ? 100 : 100 / 3
assert anInt.class == Integer
}
+ @Test
void testBytecodeRegisters() {
// this code will blow up if the true and false parts
// are not handled correctly in regards to the registers.
@@ -88,6 +95,7 @@
assert true
}
+ @Test
void testLineBreaks() {
def bar = 0 ? "moo" : "cow"
assert bar == 'cow'
@@ -119,4 +127,25 @@
: "cow"
assert bar == 'cow'
}
+
+ // GROOVY-10936
+ @Test
+ void testCommonType() {
+ def random = new Random()
+
+ def staticPatternSlashy = ~/some static pattern \w+/
+ def staticPatternString = ~"some static pattern \\w+"
+ def dynamicPatternSlashy = (random.nextInt() % 2 == 0) ? ~/pattern one \w+/ : ~/pattern two \w+/
+ def dynamicPatternString = (random.nextInt() % 2 == 0) ? ~"pattern one \\w+" : ~"pattern two \\w+"
+
+ assert staticPatternSlashy instanceof Pattern
+ assert staticPatternString instanceof Pattern
+ assert dynamicPatternSlashy instanceof Pattern
+ assert dynamicPatternString instanceof Pattern
+ }
+
+ @Test // see StatementMetaTypeChooser#resolveType
+ void testClassExpressionIsJavaLangClassNotLiteralType() {
+ Class dsClass = true ? LinkedHashSet : HashSet
+ }
}