1/*
2 * Copyright (c) 2010, 2015, 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 java.util.*;
25import javax.annotation.processing.*;
26import javax.lang.model.SourceVersion;
27import javax.lang.model.util.*;
28import static javax.lang.model.SourceVersion.*;
29
30/**
31 * An abstract annotation processor tailored to {@code javac} regression testing.
32 */
33public abstract class JavacTestingAbstractProcessor extends AbstractProcessor {
34    private static final Set<String> allAnnotations;
35
36    static {
37        Set<String> tmp = new HashSet<>();
38        tmp.add("*");
39        allAnnotations = Collections.unmodifiableSet(tmp);
40    }
41
42    protected Elements eltUtils;
43    protected Elements elements;
44    protected Types    typeUtils;
45    protected Types    types;
46    protected Filer    filer;
47    protected Messager messager;
48    protected Map<String, String> options;
49
50    /**
51     * Constructor for subclasses to call.
52     */
53    protected JavacTestingAbstractProcessor() {
54        super();
55    }
56
57    /**
58     * Return the latest source version. Unless this method is
59     * overridden, an {@code IllegalStateException} will be thrown if a
60     * subclass has a {@code SupportedSourceVersion} annotation.
61     */
62    @Override
63    public SourceVersion getSupportedSourceVersion() {
64        SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
65        if (ssv != null)
66            throw new IllegalStateException("SupportedSourceVersion annotation not supported here.");
67
68        return SourceVersion.latest();
69    }
70
71    /**
72     * If the processor class is annotated with {@link
73     * SupportedAnnotationTypes}, return an unmodifiable set with the
74     * same set of strings as the annotation.  If the class is not so
75     * annotated, a one-element set containing {@code "*"} is returned
76     * to indicate all annotations are processed.
77     *
78     * @return the names of the annotation types supported by this
79     * processor, or an empty set if none
80     */
81    @Override
82    public Set<String> getSupportedAnnotationTypes() {
83        SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
84        if (sat != null)
85            return super.getSupportedAnnotationTypes();
86        else
87            return allAnnotations;
88    }
89
90    @Override
91    public void init(ProcessingEnvironment processingEnv) {
92        super.init(processingEnv);
93        elements = eltUtils  = processingEnv.getElementUtils();
94        types = typeUtils = processingEnv.getTypeUtils();
95        filer     = processingEnv.getFiler();
96        messager  = processingEnv.getMessager();
97        options   = processingEnv.getOptions();
98    }
99
100    protected void addExports(String moduleName, String... packageNames) {
101        for (String packageName : packageNames) {
102            try {
103                ModuleLayer layer = ModuleLayer.boot();
104                Optional<Module> m = layer.findModule(moduleName);
105                if (!m.isPresent())
106                    throw new Error("module not found: " + moduleName);
107                m.get().addExports(packageName, getClass().getModule());
108            } catch (Exception e) {
109                throw new Error("failed to add exports for " + moduleName + "/" + packageName);
110            }
111        }
112    }
113
114    /*
115     * The set of visitors below will directly extend the most recent
116     * corresponding platform visitor type.
117     */
118
119    @SupportedSourceVersion(RELEASE_9)
120    public static abstract class AbstractAnnotationValueVisitor<R, P> extends AbstractAnnotationValueVisitor9<R, P> {
121
122        /**
123         * Constructor for concrete subclasses to call.
124         */
125        protected AbstractAnnotationValueVisitor() {
126            super();
127        }
128    }
129
130    @SupportedSourceVersion(RELEASE_9)
131    public static abstract class AbstractElementVisitor<R, P> extends AbstractElementVisitor9<R, P> {
132        /**
133         * Constructor for concrete subclasses to call.
134         */
135        protected AbstractElementVisitor(){
136            super();
137        }
138    }
139
140    @SupportedSourceVersion(RELEASE_9)
141    public static abstract class AbstractTypeVisitor<R, P> extends AbstractTypeVisitor9<R, P> {
142        /**
143         * Constructor for concrete subclasses to call.
144         */
145        protected AbstractTypeVisitor() {
146            super();
147        }
148    }
149
150    @SupportedSourceVersion(RELEASE_9)
151    public static class ElementKindVisitor<R, P> extends ElementKindVisitor9<R, P> {
152        /**
153         * Constructor for concrete subclasses; uses {@code null} for the
154         * default value.
155         */
156        protected ElementKindVisitor() {
157            super(null);
158        }
159
160        /**
161         * Constructor for concrete subclasses; uses the argument for the
162         * default value.
163         *
164         * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
165         */
166        protected ElementKindVisitor(R defaultValue) {
167            super(defaultValue);
168        }
169    }
170
171    @SupportedSourceVersion(RELEASE_9)
172    public static class ElementScanner<R, P> extends ElementScanner9<R, P> {
173        /**
174         * Constructor for concrete subclasses; uses {@code null} for the
175         * default value.
176         */
177        protected ElementScanner(){
178            super(null);
179        }
180
181        /**
182         * Constructor for concrete subclasses; uses the argument for the
183         * default value.
184         */
185        protected ElementScanner(R defaultValue){
186            super(defaultValue);
187        }
188    }
189
190    @SupportedSourceVersion(RELEASE_9)
191    public static class SimpleAnnotationValueVisitor<R, P> extends SimpleAnnotationValueVisitor9<R, P> {
192        /**
193         * Constructor for concrete subclasses; uses {@code null} for the
194         * default value.
195         */
196        protected SimpleAnnotationValueVisitor() {
197            super(null);
198        }
199
200        /**
201         * Constructor for concrete subclasses; uses the argument for the
202         * default value.
203         *
204         * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
205         */
206        protected SimpleAnnotationValueVisitor(R defaultValue) {
207            super(defaultValue);
208        }
209    }
210
211    @SupportedSourceVersion(RELEASE_9)
212    public static class SimpleElementVisitor<R, P> extends SimpleElementVisitor9<R, P> {
213        /**
214         * Constructor for concrete subclasses; uses {@code null} for the
215         * default value.
216         */
217        protected SimpleElementVisitor(){
218            super(null);
219        }
220
221        /**
222         * Constructor for concrete subclasses; uses the argument for the
223         * default value.
224         *
225         * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
226         */
227        protected SimpleElementVisitor(R defaultValue){
228            super(defaultValue);
229        }
230    }
231
232    @SupportedSourceVersion(RELEASE_9)
233    public static class SimpleTypeVisitor<R, P> extends SimpleTypeVisitor9<R, P> {
234        /**
235         * Constructor for concrete subclasses; uses {@code null} for the
236         * default value.
237         */
238        protected SimpleTypeVisitor(){
239            super(null);
240        }
241
242        /**
243         * Constructor for concrete subclasses; uses the argument for the
244         * default value.
245         *
246         * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
247         */
248        protected SimpleTypeVisitor(R defaultValue){
249            super(defaultValue);
250        }
251    }
252
253    @SupportedSourceVersion(RELEASE_9)
254    public static class TypeKindVisitor<R, P> extends TypeKindVisitor9<R, P> {
255        /**
256         * Constructor for concrete subclasses to call; uses {@code null}
257         * for the default value.
258         */
259        protected TypeKindVisitor() {
260            super(null);
261        }
262
263        /**
264         * Constructor for concrete subclasses to call; uses the argument
265         * for the default value.
266         *
267         * @param defaultValue the value to assign to {@link #DEFAULT_VALUE}
268         */
269        protected TypeKindVisitor(R defaultValue) {
270            super(defaultValue);
271        }
272    }
273}
274