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
+    }
 }