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