40596
|
1 |
/*
|
43646
|
2 |
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
40596
|
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. Oracle designates this
|
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
|
9 |
* by Oracle in the LICENSE file that accompanied this code.
|
|
10 |
*
|
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
15 |
* accompanied this code).
|
|
16 |
*
|
|
17 |
* You should have received a copy of the GNU General Public License version
|
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
20 |
*
|
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
22 |
* or visit www.oracle.com if you need additional information or have any
|
|
23 |
* questions.
|
|
24 |
*/
|
|
25 |
|
|
26 |
package com.sun.tools.jdeprscan;
|
|
27 |
|
|
28 |
import java.lang.annotation.IncompleteAnnotationException;
|
|
29 |
import java.util.ArrayList;
|
|
30 |
import java.util.List;
|
|
31 |
import java.util.Set;
|
|
32 |
import java.util.stream.Collectors;
|
|
33 |
|
|
34 |
import javax.annotation.processing.AbstractProcessor;
|
|
35 |
import javax.annotation.processing.Messager;
|
|
36 |
import javax.annotation.processing.ProcessingEnvironment;
|
|
37 |
import javax.annotation.processing.RoundEnvironment;
|
|
38 |
import javax.annotation.processing.SupportedAnnotationTypes;
|
|
39 |
import javax.annotation.processing.SupportedSourceVersion;
|
|
40 |
|
|
41 |
import javax.lang.model.element.Element;
|
|
42 |
import javax.lang.model.element.ElementKind;
|
|
43 |
import javax.lang.model.element.ExecutableElement;
|
|
44 |
import javax.lang.model.element.TypeElement;
|
|
45 |
import javax.lang.model.type.ArrayType;
|
|
46 |
import javax.lang.model.type.DeclaredType;
|
|
47 |
import javax.lang.model.type.ExecutableType;
|
|
48 |
import javax.lang.model.type.TypeMirror;
|
|
49 |
import javax.lang.model.util.Elements;
|
|
50 |
|
|
51 |
import javax.tools.Diagnostic;
|
|
52 |
|
48343
|
53 |
import static javax.lang.model.SourceVersion.RELEASE_11;
|
40596
|
54 |
|
|
55 |
/**
|
|
56 |
* Annotation processor for the Deprecation Scanner tool.
|
|
57 |
* Examines APIs for deprecated elements and records information
|
|
58 |
*
|
|
59 |
*/
|
|
60 |
@SupportedAnnotationTypes("java.lang.Deprecated")
|
48343
|
61 |
@SupportedSourceVersion(RELEASE_11)
|
40596
|
62 |
public class LoadProc extends AbstractProcessor {
|
|
63 |
Elements elements;
|
|
64 |
Messager messager;
|
|
65 |
final List<DeprData> deprList = new ArrayList<>();
|
|
66 |
|
|
67 |
public LoadProc() {
|
|
68 |
}
|
|
69 |
|
|
70 |
@Override
|
|
71 |
public void init(ProcessingEnvironment pe) {
|
|
72 |
super.init(pe);
|
|
73 |
elements = pe.getElementUtils();
|
|
74 |
messager = pe.getMessager();
|
|
75 |
}
|
|
76 |
|
|
77 |
@Override
|
|
78 |
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
|
79 |
if (roundEnv.processingOver()) {
|
|
80 |
return false;
|
|
81 |
}
|
|
82 |
|
|
83 |
// Assume annotations contains only @Deprecated.
|
|
84 |
// Note: no way to get deprecated packages, since
|
|
85 |
// @Deprecated is ignored in package-info.java files.
|
|
86 |
|
|
87 |
Set<? extends Element> set = roundEnv.getElementsAnnotatedWith(Deprecated.class);
|
|
88 |
for (Element e : set) {
|
|
89 |
ElementKind kind = e.getKind();
|
|
90 |
Deprecated depr = e.getAnnotation(Deprecated.class);
|
|
91 |
switch (kind) {
|
|
92 |
case CLASS:
|
|
93 |
case INTERFACE:
|
|
94 |
case ENUM:
|
|
95 |
case ANNOTATION_TYPE:
|
|
96 |
addType(kind, (TypeElement)e, depr);
|
|
97 |
break;
|
|
98 |
case CONSTRUCTOR:
|
|
99 |
case ENUM_CONSTANT:
|
|
100 |
case FIELD:
|
|
101 |
case METHOD:
|
|
102 |
Element encl = e.getEnclosingElement();
|
|
103 |
ElementKind enclKind = encl.getKind();
|
|
104 |
switch (enclKind) {
|
|
105 |
case CLASS:
|
|
106 |
case INTERFACE:
|
|
107 |
case ENUM:
|
|
108 |
case ANNOTATION_TYPE:
|
|
109 |
String detail = getDetail(e);
|
|
110 |
addMember(kind, (TypeElement)encl, detail, depr);
|
|
111 |
break;
|
|
112 |
default:
|
|
113 |
messager.printMessage(Diagnostic.Kind.WARNING,
|
|
114 |
"element " + e +
|
|
115 |
" within unknown enclosing element " + encl +
|
|
116 |
" of kind " + enclKind, e);
|
|
117 |
break;
|
|
118 |
}
|
|
119 |
break;
|
|
120 |
default:
|
|
121 |
messager.printMessage(Diagnostic.Kind.WARNING,
|
|
122 |
"unknown element " + e +
|
|
123 |
" of kind " + kind +
|
|
124 |
" within " + e.getEnclosingElement(), e);
|
|
125 |
break;
|
|
126 |
}
|
|
127 |
}
|
|
128 |
return true;
|
|
129 |
}
|
|
130 |
|
|
131 |
public List<DeprData> getDeprecations() {
|
|
132 |
return deprList;
|
|
133 |
}
|
|
134 |
|
|
135 |
String getDetail(Element e) {
|
|
136 |
if (e.getKind().isField()) {
|
|
137 |
return e.getSimpleName().toString();
|
|
138 |
} else {
|
|
139 |
// method or constructor
|
|
140 |
ExecutableElement ee = (ExecutableElement) e;
|
|
141 |
String ret;
|
|
142 |
ret = desc(ee.getReturnType());
|
|
143 |
List<? extends TypeMirror> parameterTypes = ((ExecutableType)ee.asType()).getParameterTypes();
|
|
144 |
String parms = parameterTypes.stream()
|
|
145 |
.map(this::desc)
|
|
146 |
.collect(Collectors.joining());
|
|
147 |
return ee.getSimpleName().toString() + "(" + parms + ")" + ret;
|
|
148 |
}
|
|
149 |
}
|
|
150 |
|
|
151 |
String desc(TypeMirror tm) {
|
|
152 |
switch (tm.getKind()) {
|
|
153 |
case BOOLEAN:
|
|
154 |
return "Z";
|
|
155 |
case BYTE:
|
|
156 |
return "B";
|
|
157 |
case SHORT:
|
|
158 |
return "S";
|
|
159 |
case CHAR:
|
|
160 |
return "C";
|
|
161 |
case INT:
|
|
162 |
return "I";
|
|
163 |
case LONG:
|
|
164 |
return "J";
|
|
165 |
case FLOAT:
|
|
166 |
return "F";
|
|
167 |
case DOUBLE:
|
|
168 |
return "D";
|
|
169 |
case VOID:
|
|
170 |
return "V";
|
|
171 |
case DECLARED:
|
|
172 |
String s =
|
|
173 |
((TypeElement)((DeclaredType)tm).asElement()).getQualifiedName().toString();
|
|
174 |
s = s.replace('.', '/');
|
|
175 |
return "L" + s + ";";
|
|
176 |
case ARRAY:
|
|
177 |
return "[" + desc(((ArrayType)tm).getComponentType());
|
|
178 |
default:
|
|
179 |
return tm.getKind().toString();
|
|
180 |
}
|
|
181 |
}
|
|
182 |
|
|
183 |
void addType(ElementKind kind, TypeElement type, Deprecated dep) {
|
|
184 |
addData(kind, type, "", dep);
|
|
185 |
}
|
|
186 |
|
|
187 |
void addMember(ElementKind kind, TypeElement type, String nameSig, Deprecated dep) {
|
|
188 |
addData(kind, type, nameSig, dep);
|
|
189 |
}
|
|
190 |
|
|
191 |
void addData(ElementKind kind, TypeElement type, String nameSig, Deprecated dep) {
|
|
192 |
String typeName = elements.getBinaryName(type).toString().replace('.', '/');
|
|
193 |
|
|
194 |
String since = "";
|
|
195 |
try {
|
|
196 |
since = dep.since();
|
|
197 |
} catch (IncompleteAnnotationException ignore) { }
|
|
198 |
|
|
199 |
boolean forRemoval = false;
|
|
200 |
try {
|
|
201 |
forRemoval = dep.forRemoval();
|
|
202 |
} catch (IncompleteAnnotationException ignore) { }
|
|
203 |
|
|
204 |
deprList.add(new DeprData(kind, type, typeName, nameSig, since, forRemoval));
|
|
205 |
}
|
|
206 |
}
|