1/*
2 * Copyright (c) 2012, 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
24import com.sun.source.tree.CompilationUnitTree;
25import com.sun.source.tree.IdentifierTree;
26import com.sun.source.tree.MemberSelectTree;
27import com.sun.source.tree.Tree;
28import com.sun.source.util.JavacTask;
29import com.sun.source.util.Plugin;
30import com.sun.source.util.TaskEvent;
31import com.sun.source.util.TaskListener;
32import com.sun.source.util.TreePathScanner;
33import com.sun.source.util.Trees;
34import java.util.regex.Pattern;
35import javax.lang.model.type.TypeMirror;
36import javax.tools.Diagnostic.Kind;
37
38public class ShowTypePlugin implements Plugin {
39
40    public String getName() {
41        return "showtype";
42    }
43
44    public void init(JavacTask task, String... args) {
45        Pattern pattern = null;
46        if (args.length == 1)
47            pattern = Pattern.compile(args[0]);
48        task.addTaskListener(new PostAnalyzeTaskListener(task, pattern));
49    }
50
51    private static class PostAnalyzeTaskListener implements TaskListener {
52        private final ShowTypeTreeVisitor visitor;
53
54        PostAnalyzeTaskListener(JavacTask task, Pattern pattern) {
55            visitor = new ShowTypeTreeVisitor(task, pattern);
56        }
57
58        @Override
59        public void started(TaskEvent taskEvent) { }
60
61        @Override
62        public void finished(TaskEvent taskEvent) {
63            if (taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) {
64                CompilationUnitTree compilationUnit = taskEvent.getCompilationUnit();
65                visitor.scan(compilationUnit, null);
66            }
67        }
68    }
69
70    private static class ShowTypeTreeVisitor extends TreePathScanner<Void, Void> {
71        private final Trees trees;
72        private final Pattern pattern;
73        private CompilationUnitTree currCompUnit;
74
75        ShowTypeTreeVisitor(JavacTask task, Pattern pattern) {
76            trees = Trees.instance(task);
77            this.pattern = pattern;
78        }
79
80        @Override
81        public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) {
82            currCompUnit = tree;
83            return super.visitCompilationUnit(tree, ignore);
84        }
85
86        @Override
87        public Void visitIdentifier(IdentifierTree tree, Void ignore) {
88            show(tree, tree.getName());
89            return super.visitIdentifier(tree, ignore);
90        }
91
92        @Override
93        public Void visitMemberSelect(MemberSelectTree tree, Void ignore) {
94            show(tree, tree.getIdentifier());
95            return super.visitMemberSelect(tree, ignore);
96        }
97
98        void show(Tree tree, CharSequence name) {
99            if (pattern == null || pattern.matcher(name).matches()) {
100                TypeMirror type = trees.getTypeMirror(getCurrentPath());
101                trees.printMessage(Kind.NOTE, "type is " + type, tree, currCompUnit);
102            }
103        }
104    }
105
106}
107