1 /*
   2  * @test  /nodynamiccopyright/
   3  * @bug 6406771
   4  * @summary CompilationUnitTree needs access to a line map
   5  */
   6 
   7 // WARNING: White-space and layout is important in this file, especially tab characters.
   8 
   9 import java.io.*;
  10 import java.util.*;
  11 import javax.annotation.processing.*;
  12 import javax.lang.model.*;
  13 import javax.lang.model.element.*;
  14 import javax.tools.*;
  15 import com.sun.tools.javac.api.*;
  16 import com.sun.source.tree.*;
  17 import com.sun.source.util.*;
  18 import com.sun.tools.javac.tree.JCTree;
  19 
  20 
  21 @SupportedAnnotationTypes("*")
  22 public class T6406771 extends AbstractProcessor {
  23     String[] tests = {
  24         "line:24",
  25         "line:25",
  26         "line:26", "line:26",
  27 //       1         2         3         4         5         6
  28 //3456789012345678901234567890123456789012345678901234567890
  29       "col:7", "col:16", "col:26",                 // this line uses spaces
  30         "col:9",        "col:25",       "col:41",  // this line uses tabs
  31                    "col:20",              "col:43" // this line uses a mixture
  32     };
  33 
  34     // White-space after this point does not matter
  35 
  36     public static void main(String[] args) {
  37         String self = T6406771.class.getName();
  38         String testSrc = System.getProperty("test.src");
  39         String testClasses = System.getProperty("test.classes");
  40 
  41         JavacTool tool = JavacTool.create();
  42         StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
  43         JavaFileObject f = fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, self+".java"))).iterator().next();
  44 
  45         List<String> opts = Arrays.asList("-d", ".", "-processorpath", testClasses, "-processor", self, "-proc:only");
  46 
  47         JavacTask task = tool.getTask(null, fm, null, opts, null, Arrays.asList(f));
  48 
  49         if (!task.call())
  50             throw new AssertionError("failed");
  51     }
  52 
  53     public boolean process(Set<? extends TypeElement> elems, RoundEnvironment rEnv) {
  54         final String LINE = "line" + ':';   // avoid matching this string
  55         final String COLUMN  = "col" + ':';
  56         final Messager messager = processingEnv.getMessager();
  57         final Trees trees = Trees.instance(processingEnv);
  58 
  59         TreeScanner<Void,LineMap> s = new  TreeScanner<Void,LineMap>() {
  60             public Void visitLiteral(LiteralTree tree, LineMap lineMap) {
  61                 if (tree.getKind() == Tree.Kind.STRING_LITERAL) {
  62                     String s = (String) tree.getValue();
  63                     int pos = ((JCTree) tree).pos; // can't get through public api, bug 6412669 filed
  64                     String prefix;
  65                     long found;
  66                     if (s.startsWith(LINE)) {
  67                         prefix = LINE;
  68                         found = lineMap.getLineNumber(pos);
  69                     }
  70                     else if (s.startsWith(COLUMN)) {
  71                         prefix = COLUMN;
  72                         found = lineMap.getColumnNumber(pos);
  73                     }
  74                     else
  75                         return null;
  76                     int expect = Integer.parseInt(s.substring(prefix.length()));
  77                     if (expect != found) {
  78                         messager.printMessage(Diagnostic.Kind.ERROR,
  79                                               "Error: " + prefix + " pos=" + pos
  80                                               + " expect=" + expect + " found=" + found);
  81                     }
  82                 }
  83                 return null;
  84             }
  85         };
  86 
  87         for (Element e: rEnv.getRootElements()) {
  88             System.err.println(e);
  89             Tree t = trees.getTree(e);
  90             TreePath p = trees.getPath(e);
  91             s.scan(p.getLeaf(), p.getCompilationUnit().getLineMap());
  92 
  93         }
  94 
  95         return true;
  96     }
  97 
  98     @Override
  99     public SourceVersion getSupportedSourceVersion() {
 100         return SourceVersion.latest();
 101     }
 102 }