1 /*
   2  * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug     6338064 6346249 6340951 6392177
  27  * @summary Tree API: can't determine kind of operator
  28  * @author  Peter von der Ah\u00e9
  29  * @library ../lib
  30  * @build JavacTestingAbstractProcessor TestOperators
  31  * @compile -processor TestOperators -proc:only TestOperators.java
  32  */
  33 
  34 import java.util.Set;
  35 import javax.annotation.processing.*;
  36 import javax.lang.model.element.*;
  37 import javax.lang.model.util.*;
  38 import static javax.tools.Diagnostic.Kind.*;
  39 
  40 import com.sun.source.tree.*;
  41 import com.sun.source.util.Trees;
  42 
  43 import static com.sun.source.tree.Tree.Kind.*;
  44 
  45 @interface TestMe {
  46     Tree.Kind value();
  47 }
  48 
  49 @SupportedAnnotationTypes("TestMe")
  50 public class TestOperators extends JavacTestingAbstractProcessor {
  51 
  52     @TestMe(POSTFIX_INCREMENT)
  53     public int test_POSTFIX_INCREMENT(int i) {
  54         return i++;
  55     }
  56 
  57     @TestMe(POSTFIX_DECREMENT)
  58     public int test_POSTFIX_DECREMENT(int i) {
  59         return i--;
  60     }
  61 
  62     @TestMe(PREFIX_INCREMENT)
  63     public int test_PREFIX_INCREMENT(int i) {
  64         return ++i;
  65     }
  66 
  67     @TestMe(PREFIX_DECREMENT)
  68     public int test_PREFIX_DECREMENT(int i) {
  69         return --i;
  70     }
  71 
  72     @TestMe(UNARY_PLUS)
  73     public int test_UNARY_PLUS(int i) {
  74         return +i;
  75     }
  76 
  77     @TestMe(UNARY_MINUS)
  78     public int test_UNARY_MINUS(int i) {
  79         return -i;
  80     }
  81 
  82     @TestMe(BITWISE_COMPLEMENT)
  83     public int test_BITWISE_COMPLEMENT(int i) {
  84         return ~i;
  85     }
  86 
  87     @TestMe(LOGICAL_COMPLEMENT)
  88     public boolean test_LOGICAL_COMPLEMENT(boolean b) {
  89         return !b;
  90     }
  91 
  92     @TestMe(MULTIPLY)
  93     public int test_MULTIPLY(int i, int j) {
  94         return i * j;
  95     }
  96 
  97     @TestMe(DIVIDE)
  98     public int test_DIVIDE(int i, int j) {
  99         return i / j;
 100     }
 101 
 102     @TestMe(REMAINDER)
 103     public int test_REMAINDER(int i, int j) {
 104         return i % j;
 105     }
 106 
 107     @TestMe(PLUS)
 108     public int test_PLUS(int i, int j) {
 109         return i + j;
 110     }
 111 
 112     @TestMe(MINUS)
 113     public int test_MINUS(int i, int j) {
 114         return i - j;
 115     }
 116 
 117     @TestMe(LEFT_SHIFT)
 118     public int test_LEFT_SHIFT(int i, int j) {
 119         return i << j;
 120     }
 121 
 122     @TestMe(RIGHT_SHIFT)
 123     public int test_RIGHT_SHIFT(int i, int j) {
 124         return i >> j;
 125     }
 126 
 127     @TestMe(UNSIGNED_RIGHT_SHIFT)
 128     public int test_UNSIGNED_RIGHT_SHIFT(int i, int j) {
 129         return i >>> j;
 130     }
 131 
 132     @TestMe(LESS_THAN)
 133     public boolean test_LESS_THAN(int i, int j) {
 134         return i < j;
 135     }
 136 
 137     @TestMe(GREATER_THAN)
 138     public boolean test_GREATER_THAN(int i, int j) {
 139         return i > j;
 140     }
 141 
 142     @TestMe(LESS_THAN_EQUAL)
 143     public boolean test_LESS_THAN_EQUAL(int i, int j) {
 144         return i <= j;
 145     }
 146 
 147     @TestMe(GREATER_THAN_EQUAL)
 148     public boolean test_GREATER_THAN_EQUAL(int i, int j) {
 149         return i >= j;
 150     }
 151 
 152     @TestMe(EQUAL_TO)
 153     public boolean test_EQUAL_TO(int i, int j) {
 154         return i == j;
 155     }
 156 
 157     @TestMe(NOT_EQUAL_TO)
 158     public boolean test_NOT_EQUAL_TO(int i, int j) {
 159         return i != j;
 160     }
 161 
 162     @TestMe(AND)
 163     public boolean test_AND(boolean a, boolean b) {
 164         return a & b;
 165     }
 166 
 167     @TestMe(XOR)
 168     public boolean test_XOR(boolean a, boolean b) {
 169         return a ^ b;
 170     }
 171 
 172     @TestMe(OR)
 173     public boolean test_OR(boolean a, boolean b) {
 174         return a | b;
 175     }
 176 
 177     @TestMe(CONDITIONAL_AND)
 178     public boolean test_CONDITIONAL_AND(boolean a, boolean b) {
 179         return a && b;
 180     }
 181 
 182     @TestMe(CONDITIONAL_OR)
 183     public boolean test_CONDITIONAL_OR(boolean a, boolean b) {
 184         return a || b;
 185     }
 186 
 187     @TestMe(MULTIPLY_ASSIGNMENT)
 188     public int test_MULTIPLY_ASSIGNMENT(int i, int j) {
 189         return i *= j;
 190     }
 191 
 192     @TestMe(DIVIDE_ASSIGNMENT)
 193     public int test_DIVIDE_ASSIGNMENT(int i, int j) {
 194         return i /= j;
 195     }
 196 
 197     @TestMe(REMAINDER_ASSIGNMENT)
 198     public int test_REMAINDER_ASSIGNMENT(int i, int j) {
 199         return i %= j;
 200     }
 201 
 202     @TestMe(PLUS_ASSIGNMENT)
 203     public int test_PLUS_ASSIGNMENT(int i, int j) {
 204         return i += j;
 205     }
 206 
 207     @TestMe(MINUS_ASSIGNMENT)
 208     public int test_MINUS_ASSIGNMENT(int i, int j) {
 209         return i -= j;
 210     }
 211 
 212     @TestMe(LEFT_SHIFT_ASSIGNMENT)
 213     public int test_LEFT_SHIFT_ASSIGNMENT(int i, int j) {
 214         return i <<= j;
 215     }
 216 
 217     @TestMe(RIGHT_SHIFT_ASSIGNMENT)
 218     public int test_RIGHT_SHIFT_ASSIGNMENT(int i, int j) {
 219         return i >>= j;
 220     }
 221 
 222     @TestMe(UNSIGNED_RIGHT_SHIFT_ASSIGNMENT)
 223     public int test_UNSIGNED_RIGHT_SHIFT_ASSIGNMENT(int i, int j) {
 224         return i >>>= j;
 225     }
 226 
 227     @TestMe(AND_ASSIGNMENT)
 228     public boolean test_AND_ASSIGNMENT(boolean a, boolean b) {
 229         return a &= b;
 230     }
 231 
 232     @TestMe(XOR_ASSIGNMENT)
 233     public boolean test_XOR_ASSIGNMENT(boolean a, boolean b) {
 234         return a ^= b;
 235     }
 236 
 237     @TestMe(OR_ASSIGNMENT)
 238     public boolean test_OR_ASSIGNMENT(boolean a, boolean b) {
 239         return a |= b;
 240     }
 241 
 242     @TestMe(INT_LITERAL)
 243     public Object test_INT_LITERAL() {
 244         return 0;
 245     }
 246 
 247     @TestMe(LONG_LITERAL)
 248     public Object test_LONG_LITERAL() {
 249         return 0L;
 250     }
 251 
 252     @TestMe(FLOAT_LITERAL)
 253     public Object test_FLOAT_LITERAL() {
 254         return 0.0F;
 255     }
 256 
 257     @TestMe(DOUBLE_LITERAL)
 258     public Object test_DOUBLE_LITERAL() {
 259         return 0.0;
 260     }
 261 
 262     @TestMe(BOOLEAN_LITERAL)
 263     public Object test_BOOLEAN_LITERAL() {
 264         return true;
 265     }
 266 
 267     @TestMe(CHAR_LITERAL)
 268     public Object test_CHAR_LITERAL() {
 269         return 'a';
 270     }
 271 
 272     @TestMe(STRING_LITERAL)
 273     public Object test_STRING_LITERAL() {
 274         return "a";
 275     }
 276 
 277     @TestMe(NULL_LITERAL)
 278     public Object test_NULL_LITERAL() {
 279         return null;
 280     }
 281 
 282     @TestMe(UNBOUNDED_WILDCARD)
 283     public Set<?> test_UNBOUNDED_WILDCARD() {
 284         return null;
 285     }
 286 
 287     @TestMe(EXTENDS_WILDCARD)
 288     public Set<? extends Number> test_EXTENDS_WILDCARD() {
 289         return null;
 290     }
 291 
 292     @TestMe(SUPER_WILDCARD)
 293     public Set<? super Number> test_SUPER_WILDCARD() {
 294         return null;
 295     }
 296 
 297     public boolean process(Set<? extends TypeElement> annotations,
 298                            RoundEnvironment roundEnvironment)
 299     {
 300         final Trees trees = Trees.instance(processingEnv);
 301         final Messager log = processingEnv.getMessager();
 302         final Elements elements = processingEnv.getElementUtils();
 303         class Scan extends ElementScanner<Void,Void> {
 304             @Override
 305             public Void visitExecutable(ExecutableElement e, Void p) {
 306                 Object debug = e; // info for exception handler
 307                 try {
 308                     TestMe info = e.getAnnotation(TestMe.class);
 309                     if (info == null)
 310                         return null;
 311 
 312                     Tree.Kind kind = info.value();
 313                     MethodTree node = trees.getTree(e);
 314                     debug = node;
 315                     Tree testNode;
 316                     switch (kind) {
 317                     case UNBOUNDED_WILDCARD:
 318                     case EXTENDS_WILDCARD:
 319                     case SUPER_WILDCARD:
 320                         ParameterizedTypeTree typeTree;
 321                         typeTree = (ParameterizedTypeTree) node.getReturnType();
 322                         testNode = typeTree.getTypeArguments().get(0);
 323                         break;
 324                     default:
 325                         ReturnTree returnNode;
 326                         returnNode = (ReturnTree) node.getBody().getStatements().get(0);
 327                         testNode = returnNode.getExpression();
 328                     }
 329                     if (testNode.getKind() != kind) {
 330                         log.printMessage(ERROR, testNode.getKind() + " != " + kind, e);
 331                         throw new AssertionError(testNode);
 332                     }
 333                     System.err.format("OK: %32s %s%n", kind, testNode);
 334                 } catch (Error ex) {
 335                     System.err.println("Error while looking at " + debug);
 336                     throw ex;
 337                 }
 338                 return null;
 339             }
 340         }
 341         Scan scan = new Scan();
 342         for (Element e : roundEnvironment.getRootElements()) {
 343             scan.scan(e);
 344         }
 345         return true;
 346     }
 347 }