1 /*
   2  * Copyright (c) 2012, 2013, 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 8005046 8011052
  27  * @summary Test basic properties of javax.lang.element.Element
  28  * @author  Joseph D. Darcy
  29  * @library /tools/javac/lib
  30  * @build   JavacTestingAbstractProcessor TestExecutableElement
  31  * @compile -processor TestExecutableElement -proc:only TestExecutableElement.java
  32  */
  33 
  34 import java.lang.annotation.*;
  35 import java.util.Formatter;
  36 import java.util.Set;
  37 import java.util.Objects;
  38 import java.util.regex.*;
  39 import javax.annotation.processing.*;
  40 import javax.lang.model.SourceVersion;
  41 import static javax.lang.model.SourceVersion.*;
  42 import javax.lang.model.element.*;
  43 import javax.lang.model.util.*;
  44 import static javax.lang.model.util.ElementFilter.*;
  45 import static javax.tools.Diagnostic.Kind.*;
  46 import static javax.tools.StandardLocation.*;
  47 
  48 /**
  49  * Test some basic workings of javax.lang.element.ExecutableElement
  50  */
  51 public class TestExecutableElement extends JavacTestingAbstractProcessor implements ProviderOfDefault {
  52     @IsDefault(false)
  53     public boolean process(Set<? extends TypeElement> annotations,
  54                            RoundEnvironment roundEnv) {
  55         int errors = 0;
  56         if (!roundEnv.processingOver()) {
  57             boolean hasRun = false;
  58             for (Element element : roundEnv.getRootElements()) {
  59                 for (ExecutableElement method : methodsIn(element.getEnclosedElements())) {
  60                     hasRun = true;
  61                     errors += checkIsDefault(method);
  62                 }
  63             }
  64 
  65             if (!hasRun) {
  66                 messager.printMessage(ERROR, "No test cases run; test fails.");
  67             }
  68         }
  69         return true;
  70     }
  71 
  72     @IsDefault(false)
  73     int checkIsDefault(ExecutableElement method) {
  74         System.out.println("Testing " + method);
  75         IsDefault expectedIsDefault = method.getAnnotation(IsDefault.class);
  76 
  77         boolean expectedDefault = (expectedIsDefault != null) ?
  78             expectedIsDefault.value() :
  79             false;
  80 
  81         boolean methodIsDefault = method.isDefault();
  82 
  83         if (expectedDefault) {
  84             if (!method.getModifiers().contains(Modifier.DEFAULT)) {
  85                 messager.printMessage(ERROR,
  86                                       "Modifier \"default\" not present as expected.",
  87                                       method);
  88             }
  89 
  90             // Check printing output
  91             java.io.Writer stringWriter = new java.io.StringWriter();
  92             eltUtils.printElements(stringWriter, method);
  93             Pattern p = Pattern.compile(expectedIsDefault.expectedTextRegex(), Pattern.DOTALL);
  94 
  95             if (! p.matcher(stringWriter.toString()).matches()) {
  96                 messager.printMessage(ERROR,
  97                                       new Formatter().format("Unexpected printing ouptput:%n\tgot %s,%n\texpected pattern %s.",
  98                                                              stringWriter.toString(),
  99                                                              expectedIsDefault.expectedTextRegex()).toString(),
 100                                       method);
 101             }
 102 
 103             System.out.println("\t" + stringWriter.toString());
 104 
 105         } else {
 106             if (method.getModifiers().contains(Modifier.DEFAULT)) {
 107                 messager.printMessage(ERROR,
 108                                       "Modifier \"default\" present when not expected.",
 109                                       method);
 110             }
 111         }
 112 
 113         if (methodIsDefault != expectedDefault) {
 114             messager.printMessage(ERROR,
 115                                   new Formatter().format("Unexpected Executable.isDefault result: got ``%s'', expected ``%s''.",
 116                                                          expectedDefault,
 117                                                          methodIsDefault).toString(),
 118                                   method);
 119             return 1;
 120         }
 121         return 0;
 122     }
 123 }
 124 
 125 /**
 126  * Expected value of the ExecutableElement.isDefault method.
 127  */
 128 @Retention(RetentionPolicy.RUNTIME)
 129 @Target(ElementType.METHOD)
 130 @interface IsDefault {
 131     boolean value();
 132     String expectedTextRegex() default "";
 133 }
 134 
 135 /**
 136  * Test interface to provide a default method.
 137  */
 138 interface ProviderOfDefault {
 139     @IsDefault(false)
 140     boolean process(Set<? extends TypeElement> annotations,
 141                     RoundEnvironment roundEnv);
 142 
 143     @IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$")
 144     default strictfp void quux() {};
 145 }