
auto.parse.processor..AutoParseProcessor.swp Maven / Gradle / Ivy
b0VIM 7.4 ?&?T+?~tY andrew and ~andrew/workspace/8tory-gitlab/gitlab/android/auto-parse/auto-parse-processor/src/main/java/auto/parse/processor/AutoParseProcessor.java utf-8
3210 #"! U tp
j m k 4 ? ; t D g ? H R g
[ ? d ad ? j ? ? ? ? P % " ? ? ? e ?
?
?
?
?
a
E
(
? ? ? ? y _ D - ? ? ? N ?
?
?
j
7
? ? y Q * ? ? ? k H G * ) % ? ? ? ? { ] . ? ? ? ? ? ? ` # ? ? ? ? ? w , & " ! ? ? ? ? ? - ? s K E ? ? ? ? Z 4 . ? ? private void abortWithError(String msg, Element e) throws CompileException { */ * the processing of other classes. * Issue a compilation error and abandon the processing of this class. This does not prevent /** } processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, e); private void reportError(String msg, Element e) { */ * continue correctly after an error. * test case in CompilationErrorsTest for any new call to reportError(...) to ensure that we * continue processing and perhaps report other errors. It is a good idea to introduce a * Issue a compilation error. This method does not throw an exception, since we want to /** // CHECKSTYLE:ON private static class CompileException extends Exception {} // CHECKSTYLE:OFF:WhitespaceAround @SuppressWarnings("serial") } } processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, msg); if (!SILENT) { private void note(String msg) { } return SourceVersion.latestSupported(); public SourceVersion getSupportedSourceVersion() { @Override } return Collections.singleton(AutoParse.class.getName()); public Set getSupportedAnnotationTypes() { @Override public AutoParseProcessor() {} private static final boolean SILENT = true; public class AutoParseProcessor extends AbstractProcessor { @SupportedOptions(EclipseHack.ENABLING_OPTION) @AutoService(Processor.class) */ * @author Éamonn McManus * @see auto.parse.AutoParse * * class. * Javac annotation processor (compiler plugin) for value types; user code never references this /** import auto.parse.AutoParse; import javax.tools.JavaFileObject; import javax.tools.Diagnostic; import javax.lang.model.util.Types; import javax.lang.model.util.Elements; import javax.lang.model.util.ElementFilter; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeKind; import javax.lang.model.type.ArrayType; import javax.lang.model.element.VariableElement; import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ElementKind; import javax.lang.model.element.Element; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.SourceVersion; import javax.annotation.processing.SupportedOptions; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.AbstractProcessor; import java.util.TreeMap; import java.util.Set; import java.util.Map; import java.util.List; import java.util.Iterator; import java.util.HashSet; import java.util.Collections; import java.util.Collection; import java.util.Arrays; import java.util.ArrayList; import java.lang.annotation.Annotation; import java.io.Writer; import java.io.Serializable; import java.io.IOException; import com.google.auto.service.AutoService; package auto.parse.processor; */ * limitations under the License. * See the License for the specific language governing permissions and * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * distributed under the License is distributed on an "AS IS" BASIS, * Unless required by applicable law or agreed to in writing, software * * http://www.apache.org/licenses/LICENSE-2.0 * * You may obtain a copy of the License at * you may not use this file except in compliance with the License. * Licensed under the Apache License, Version 2.0 (the "License"); * * Copyright (C) 2012 Google, Inc. /* ad ? ? d ? ? L ? ? ? ?
?
5
? ? ? ? ? . ? ? ? ? ? ? ? ? ? O ?
?
?
m
=
? ? ? ? ? s Y D < , & " ! ? ? l [ N 8 ! ? ? ? ? v p l k . ? ? ? ? ? k ) ? ? ? ? ? ? ? ? H ? ? ? ? ? ? M 5 ! ? ? ? ? ? ? ? ? } } return new EclipseHack(processingEnv); private EclipseHack eclipseHack() { } } return s + ">"; } sep = ", "; s += sep + "?"; for (int i = 0; i < typeParameters.size(); i++) { String sep = ""; String s = "<"; } else { return ""; if (typeParameters.isEmpty()) { List extends TypeParameterElement> typeParameters = type.getTypeParameters(); private static String wildcardTypeString(TypeElement type) { // The @AutoParse type, with a ? for every type. } } return s + ">"; } sep = ", "; s += sep + typeParameter.getSimpleName(); for (TypeParameterElement typeParameter : typeParameters) { String sep = ""; String s = "<"; } else { return ""; if (typeParameters.isEmpty()) { List extends TypeParameterElement> typeParameters = type.getTypeParameters(); private static String actualTypeString(TypeElement type) { } } return s + ">"; } sep = ", "; s += sep + typeParameterString(typeParameter); for (TypeParameterElement typeParameter : typeParameters) { String sep = ""; String s = "<"; } else { return ""; if (typeParameters.isEmpty()) { List extends TypeParameterElement> typeParameters = type.getTypeParameters(); private static String formalTypeString(TypeElement type) { } } return s; } sep = " & "; s += sep + bound; for (TypeMirror bound : bounds) { String sep = ""; s += " extends "; } else { return s; if (bounds.isEmpty()) { List extends TypeMirror> bounds = type.getBounds(); String s = type.getSimpleName().toString(); private static String typeParameterString(TypeParameterElement type) { // Why does TypeParameterElement.toString() not return this? Grrr. } return processingEnv.getElementUtils().getTypeElement(className).asType(); private TypeMirror getTypeMirror(String className) { } return getTypeMirror(c.getName()); private TypeMirror getTypeMirror(Class> c) { } return ""; } } } } break; "serialVersionUID must be a static final long compile-time constant", field); reportError( } else { return value + "L"; && value != null) { && field.asType().getKind() == TypeKind.LONG if (field.getModifiers().containsAll(Arrays.asList(Modifier.STATIC, Modifier.FINAL)) Object value = field.getConstantValue(); if (field.getSimpleName().toString().equals("serialVersionUID")) { for (VariableElement field : fields) { List fields = ElementFilter.fieldsIn(type.getEnclosedElements()); if (typeUtils.isAssignable(type.asType(), serializable)) { TypeMirror serializable = getTypeMirror(Serializable.class); Types typeUtils = processingEnv.getTypeUtils(); private String getSerialVersionUID(TypeElement type) { // serialVersionUID = 1234L, otherwise "". // Return a string like "1234L" if type instanceof Serializable and defines ad ? ? ; ? ? ? ? 8 ? ? ? ? R ?
?
?
?
?
?
C
? ? y x , ? ? ? ? d U T ?
?
?
?
[
N
M
3
? q c b N , ? ? R 8 * ) ? ? " public boolean equals(Object o) {", "$[equals?\n @Override", // equals(Object) " }]", " + \"}\";", "$[p]=\" + $[p.array?[$[Arrays].toString($[p])][$[p]]]]", "$[props:p|\n + \", |" + " return \"$[simpleclassname]{\"$[props?\n + \"]" + " public String toString() {", "$[toString?\n @Override", // toString() " }]", " return $[p.array?[$[p.nullable?$[p] == null ? null : ]$[p].clone()][_get(\"$[p]\", ($[p.type]) null)]];", " $[p.access]$[p.type] $[p]() {", "$[props:p|\n|\n @Override", // Property getters " }", " return parseObject.getString(key);", " private String _get(String key, String defValue) {", " }\n", " return parseObject.getParseUser(key);", " private ParseUser _get(String key, ParseUser defValue) {", " }\n", " return parseObject.getParseObject(key);", " private ParseObject _get(String key, ParseObject defValue) {", " }\n", " return parseObject.getParseGeoPoint(key);", " private ParseGeoPoint _get(String key, ParseGeoPoint defValue) {", " }\n", " return parseObject.getParseFile(key);", " private ParseFile _get(String key, ParseFile defValue) {", " }\n", " return parseObject.getNumber(key);", " private Number _get(String key, Number defValue) {", " }\n", " return parseObject.getLong(key);", " private long _get(String key, Long defValue) {", " }\n", " return (ParseRelation) parseObject.getRelation(key);", " private ParseRelation _get(String key, ParseRelation defValue) {", " @SuppressWarnings(\"unchecked\")", " }\n", " return (Map) parseObject.getMap(key);", " private Map _get(String key, Map defValue) {", " @SuppressWarnings(\"unchecked\")", " }\n", " return (List) parseObject.getList(key);", ad ? ? 4 ? ? ? ? { z - ? ? ? ? ? S
?
?
?
?
R
? ? ? ? V & ? ? ? ? Z + ?
?
?
?
L
? ? g f ? ? ? Z ? ? ? ? K
? ? ? ? 4 ? ? ? ? l ] \ ? ? ? ? c V U ; ? y k j V 4 ? ? Z @ 2 1 ? ? ? " public boolean equals(Object o) {", "$[equals?\n @Override", // equals(Object) " }]", " + \"}\";", "$[p]=\" + $[p.array?[$[Arrays].toString($[p])][$[p]]]]", "$[props:p|\n + \", |" + " return \"$[simpleclassname]{\"$[props?\n + \"]" + " public String toString() {", "$[toString?\n @Override", // toString() " }]", " return $[p.array?[$[p.nullable?$[p] == null ? null : ]$[p].clone()][_get(\"$[p]\", ($[p.type]) null)]];", " $[p.access]$[p.type] $[p]() {", "$[props:p|\n|\n @Override", // Property getters " }", " return parseObject.getString(key);", " private String _get(String key, String defValue) {", " }\n", " return parseObject.getParseUser(key);", " private ParseUser _get(String key, ParseUser defValue) {", " }\n", " return parseObject.getParseObject(key);", " private ParseObject _get(String key, ParseObject defValue) {", " }\n", " return parseObject.getParseGeoPoint(key);", " private ParseGeoPoint _get(String key, ParseGeoPoint defValue) {", " }\n", " return parseObject.getParseFile(key);", " private ParseFile _get(String key, ParseFile defValue) {", " }\n", " return parseObject.getNumber(key);", " private Number _get(String key, Number defValue) {", " }\n", " return parseObject.getLong(key);", " private long _get(String key, Long defValue) {", " }\n", " return (ParseRelation) parseObject.getRelation(key);", " private ParseRelation _get(String key, ParseRelation defValue) {", " }\n", " return (Map) parseObject.getMap(key);", " private Map _get(String key, Map d " @SuppressWarnings("private List _get(String " private List _get(String key, List defValue) {", " @SuppressWarnings(\"unchecked\")", " }\n", " return parseObject.getJSONObject(key);", " private JSONObject _get(String key, JSONObject defValue) {", " }\n", " return parseObject.getJSONArray(key);", " private JSONArray _get(String key, JSONArray defValue) {", " }\n", " return parseObject.getInt(key);", " private int _get(String key, Integer defValue) {", " }\n", " return parseObject.getDouble(key);", " private double _get(String key, Double defValue) {", " }\n", " return parseObject.getDate(key);", " private Date _get(String key, Date defValue) {", " }\n", " return parseObject.getBytes(key);", " private byte[] _get(String key, byte[] defValue) {", " }\n", " return parseObject.getBoolean(key);", " private boolean _get(String key, Boolean defValue) {", " }\n", " return parseObject.get(key);", " private Object _get(String key, Object defValue) {", " }\n", " return ($[origclass]$[actualtypes]) this;", " parseObject.put(\"$[p]\", $[p]);]", "$[props:p|\n|", " public $[origclass]$[actualtypes] commit() {", " }\n", " this.$[p] = $[p];]", "$[props:p|\n|", " this();", " public $[subclass](\n $[props:p|,\n |$[p.type] $[p]]) {", " }\n", " this.parseObject = parseObject;", " public $[subclass](ParseObject parseObject) {", " }\n", ad ? m ? ? ? ? ? V ' ? ? ? ? p c O I E D ?
?
F
!
? ? ? q ? ? ? ? ? u B ?
?
?
`
5
? ? ? ? f K ? ? ? ? ? a + ? ? ? ? ? { w v 1 ? ? ? ? ? j f e ? ^ ! ? ? ? ? ? ? ? d @ ? ? ? ? g > ? ? ? ? c b < ; & ? ? " this.parseObject = this;", " public $[subclass]() {", // Constructor " ParseObject parseObject;\n", //"$[props:p|| public $[p.type] $[p];\n]", // Fields "public class $[subclass]$[formaltypes] extends $[origclass]$[actualtypes] {", // Class declaration "import com.parse.ParseUser;\n", "import com.parse.ParseRelation;", "import com.parse.ParseObject;", "import com.parse.ParseGeoPoint;", "import com.parse.ParseFile;", "import java.util.Map;", "import java.util.List;", "import org.json.JSONObject;", "import org.json.JSONArray;", "import java.util.Date;", "$[imports:i||import $[i];\n]", // Imports "$[pkg?package $[pkg];\n]", // Package declaration // CHECKSTYLE:OFF:OperatorWrap private static final String TEMPLATE_STRING = concatLines( // See the Template class for an explanation of the various constructs. // so than sb.append(this).append(that) with ifs and fors scattered around everywhere. // The code below uses a small templating language. This is not hugely readable, but is much more } return sb.toString(); } sb.append(line).append("\n"); for (String line : lines) { StringBuilder sb = new StringBuilder(); private static String concatLines(String... lines) { // This is just because I hate typing "...\n" + all the time. } } return name; } else { return name.substring(pkgName.length() + 1); if (!pkgName.isEmpty()) { String pkgName = TypeSimplifier.packageNameOf(type); String name = type.getQualifiedName().toString(); private static String classNameOf(TypeElement type) { // Return the name of the class, including any enclosing classes but not the package. } } return s; } else { return s.substring(s.lastIndexOf('.') + 1); if (s.contains(".")) { private static String simpleNameOf(String s) { } return generatedClassName(type, "AutoParse_"); private String generatedSubclassName(TypeElement type) { } return pkg + dot + prefix + name; String dot = pkg.isEmpty() ? "" : "."; String pkg = TypeSimplifier.packageNameOf(type); } name = type.getSimpleName() + "_" + name; type = (TypeElement) type.getEnclosingElement(); while (type.getEnclosingElement() instanceof TypeElement) { String name = type.getSimpleName().toString(); private String generatedClassName(TypeElement type, String prefix) { } } } reportError("@AutoParse processor threw an exception: " + e, type); // Don't propagate this exception, which will confusingly crash the compiler. } catch (RuntimeException e) { // We abandoned this type, but continue with the next. } catch (CompileException e) { processType(type); try { for (TypeElement type : types) { Collection extends TypeElement> types = ElementFilter.typesIn(annotatedElements); roundEnv.getElementsAnnotatedWith(AutoParse.class); Collection extends Element> annotatedElements = private void process(RoundEnvironment roundEnv) { } } return false; } else { return true; process(roundEnv); if (claimed) { AutoParse.class.getName())); && annotations.iterator().next().getQualifiedName().toString().equals( boolean claimed = (annotations.size() == 1 public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) { @Override } throw new CompileException(); reportError(msg, e); ad ' ? g ? M & ? ? ? ? ? n 4 ?
?
U
? ` = ? ? ? l W V N ?
?
?
a
? ? ? q ] J 8 % ? ? ? ? } h ; * ? ? ? ? ? ? ; ? ? ? ? ? ? c 1
? ? ? ? | h 1 ? ? ? ^ J ? ? ? ~ U I A ; : ? ? ? o R C 0 ( " ? ? private static boolean isJavaLangObject(TypeElement type) { } } } return ""; } else { return "protected "; } else if (mods.contains(Modifier.PROTECTED)) { return "public "; if (mods.contains(Modifier.PUBLIC)) { Set mods = method.getModifiers(); public String access() { } } } return this + ".hashCode()"; } else { return "(" + this + " == null) ? 0 : " + this + ".hashCode()"; if (nullable()) { default: return vars.get("Arrays") + ".hashCode(" + this + ")"; case ARRAY: return this + " ? 1231 : 1237"; case BOOLEAN: + "Double.doubleToLongBits(" + this + ")"; return "(Double.doubleToLongBits(" + this + ") >>> 32) ^ " case DOUBLE: return "Float.floatToIntBits(" + this + ")"; case FLOAT: return "(" + this + " >>> 32) ^ " + this; case LONG: return this.toString(); case INT: case CHAR: case SHORT: case BYTE: switch (method.getReturnType().getKind()) { public String hashCodeExpression() { */ * A string representing an expression that is the hashCode of this property. /** } return template.rewrite(newVars); newVars.put("p", this); Map newVars = new TreeMap(vars); } break; template = OBJECT_EQUALS_TEMPLATE; default: break; template = ARRAY_EQUALS_TEMPLATE; case ARRAY: break; template = DOUBLE_EQUALS_TEMPLATE; case DOUBLE: break; template = FLOAT_EQUALS_TEMPLATE; case FLOAT: break; template = PRIMITIVE_EQUALS_TEMPLATE; case BOOLEAN: case LONG: case INT: case CHAR: case SHORT: case BYTE: switch (method.getReturnType().getKind()) { Template template; // language is unreadable enough as it is. // If the templating language had a case statement we wouldn't need this function, but the public String equalsThatExpression() { */ * in another variable called "that" whose type is the class marked {@code @AutoParse}. * A string representing an expression that compares this property with the same property /** // CHECKSTYLE:ON "this.$[p].equals(that.$[p]())"); "(this.$[p] == null) ? (that.$[p]() == null) : ]" + "$[p.nullable?" + private static final Template OBJECT_EQUALS_TEMPLATE = Template.compile( // CHECKSTYLE:OFF:OperatorWrap "Double.doubleToLongBits(this.$[p]) == Double.doubleToLongBits(that.$[p]())"); private static final Template DOUBLE_EQUALS_TEMPLATE = Template.compile( "Float.floatToIntBits(this.$[p]) == Float.floatToIntBits(that.$[p]())"); private static final Template FLOAT_EQUALS_TEMPLATE = Template.compile( + "(that instanceof $[subclass]) ? (($[subclass]) that).$[p] : that.$[p]())"); Template.compile("$[Arrays].equals(this.$[p], " private static final Template ARRAY_EQUALS_TEMPLATE = Template.compile("this.$[p] == that.$[p]()"); private static final Template PRIMITIVE_EQUALS_TEMPLATE = } return false; } } return true; if (name.equals("Nullable")) { String name = annotationMirror.getAnnotationType().asElement().getSimpleName().toString(); for (AnnotationMirror annotationMirror : method.getAnnotationMirrors()) { ad N H ? ? ? F ? ? U ?
?
?
?
d
0
? ? V P ? | X ?
E
? s ? ? x ; ? ? ? 8 ? ? ? ? ? h ^ V P L K ? ? \ ? i c 4 ? ? ? ] W ? ? p ; ? ? N M vars.put("cacheHashCode", autoParse.cacheHashCode()); vars.put("subclass", simpleNameOf(generatedSubclassName(type))); vars.put("wildcardtypes", wildcardTypeString(type)); vars.put("actualtypes", actualTypeString(type)); vars.put("formaltypes", formalTypeString(type)); vars.put("simpleclassname", simpleNameOf(classNameOf(type))); vars.put("origclass", classNameOf(type)); vars.put("pkg", TypeSimplifier.packageNameOf(type)); Map vars = new TreeMap(); } abortWithError("One @AutoParse class may not extend another", type); if (ancestorIsAndroidAutoParse(type)) { } abortWithError("@" + AutoParse.class.getName() + " only applies to classes", type); if (type.getKind() != ElementKind.CLASS) { } + "does not have that annotation; this is probably a compiler bug", type); abortWithError("annotation processor for @AutoParse was invoked with a type that " // but it has happened in the past and can crash the compiler. // This shouldn't happen unless the compilation environment is buggy, if (autoParse == null) { AutoParse autoParse = type.getAnnotation(AutoParse.class); private void processType(TypeElement type) throws CompileException { } } } } methods.add(method); if (!alreadySeen) { } } alreadySeen = true; // If we inherit this method on more than one path, we don't want to add it twice. && method.getParameters().equals(otherMethod.getParameters())) { } else if (method.getSimpleName().equals(otherMethod.getSimpleName()) methodIter.remove(); if (elementUtils.overrides(method, otherMethod, type)) { ExecutableElement otherMethod = methodIter.next(); for (Iterator methodIter = methods.iterator(); methodIter.hasNext();) { boolean alreadySeen = false; if (!method.getModifiers().contains(Modifier.PRIVATE)) { for (ExecutableElement method : theseMethods) { eclipseHack().sortMethodsIfSimulatingEclipse(theseMethods); List theseMethods = ElementFilter.methodsIn(type.getEnclosedElements()); // that while still using Elements.overrides. // This algorithm is quadratic in the number of methods but it's hard to see how to improve // Add each method of this class, and in so doing remove any inherited method it overrides. } (TypeElement) typeUtils.asElement(type.getSuperclass()), methods); findLocalAndInheritedMethods( // method after any interfaces that declared it. // Visit the superclass after superinterfaces so we will always see the implementation of a if (type.getSuperclass().getKind() != TypeKind.NONE) { } findLocalAndInheritedMethods((TypeElement) typeUtils.asElement(superInterface), methods); for (TypeMirror superInterface : type.getInterfaces()) { Elements elementUtils = processingEnv.getElementUtils(); Types typeUtils = processingEnv.getTypeUtils(); note("Looking at methods in " + type); private void findLocalAndInheritedMethods(TypeElement type, List methods) { } && method.getParameters().get(0).asType().toString().equals("java.lang.Object")); || (name.equals("equals") && method.getParameters().size() == 1 && method.getParameters().isEmpty()) return ((name.equals("toString") || name.equals("hashCode")) String name = method.getSimpleName().toString(); private static boolean isToStringOrEqualsOrHashCode(ExecutableElement method) { } return type.getSuperclass().getKind() == TypeKind.NONE && type.getKind() == ElementKind.CLASS; ad p R ? ? u q p # ? ? U ?
?
p
3
? u T N ? ~ = ?
?
O
8
2
? ? ? Q P ? ? ? Z ? ? ? ? ? ? T 0 ? ? ? ? ? ? h ? ? a ( ? ? ? ? ? ? ? ? ? ? 1 ? ? ? ^ ? p o // Compilation will fail in that case, but we don't want it to crash the compiler with // The defaults here only come into play when an ancestor class doesn't exist. Map vars = new TreeMap(); private static Map objectMethodsToGenerate(List methods) { */ * generated. * "toString", "equals", "hashCode" and corresponding value true if that method should be * Given a list of all methods defined in or inherited by a class, returns a map with keys /** } } } type); + "class would not obey the contract of " + bad + " in " + Annotation.class.getName(), reportError("The implementation of " + bad + " that would be generated for this @AutoParse " : "hashCode()"; ? (hashCode ? "equals(Object) and hashCode()" : "equals(Object)") String bad = equals if (equals || hashCode) { boolean hashCode = (Boolean) vars.get("hashCode"); boolean equals = (Boolean) vars.get("equals"); if (typeUtils.isAssignable(type.asType(), javaLangAnnotationAnnotation)) { Types typeUtils = processingEnv.getTypeUtils(); TypeMirror javaLangAnnotationAnnotation = getTypeMirror(Annotation.class); private void dontImplementAnnotationEqualsOrHashCode(TypeElement type, Map vars) { } return false; } } return true; if (type.getKind() == TypeKind.ARRAY) { for (TypeMirror type : types) { private static boolean containsArrayType(Set types) { } return returnTypes; } returnTypes.add(method.getReturnType()); for (ExecutableElement method : methods) { HashSet returnTypes = new HashSet(); private Set returnTypesOf(List methods) { } vars.put("parcelable", processingEnv.getTypeUtils().isAssignable(type.asType(), parcelable)); TypeMirror parcelable = getTypeMirror("android.os.Parcelable"); vars.put("serialVersionUID", getSerialVersionUID(type)); vars.put("props", props); eclipseHack().reorderProperties(props); // If we are running from Eclipse, undo the work of its compiler which sorts methods. } props.add(prop); Property prop = new Property(method, propType, vars); String propType = typeSimplifier.simplify(method.getReturnType()); for (ExecutableElement method : toImplement) { List props = new ArrayList(); vars.put("Arrays", typeSimplifier.simplify(javaUtilArrays)); vars.put("imports", typeSimplifier.typesToImport()); TypeSimplifier typeSimplifier = new TypeSimplifier(processingEnv.getTypeUtils(), pkg, types); String pkg = TypeSimplifier.packageNameOf(type); } types.add(javaUtilArrays); // Arrange to import it unless that would introduce ambiguity. // If there are array properties then we will be referencing java.util.Arrays. if (containsArrayType(types)) { TypeMirror javaUtilArrays = getTypeMirror(Arrays.class); types.addAll(returnTypesOf(toImplement)); Set types = new HashSet(); List toImplement = methodsToImplement(methods); dontImplementAnnotationEqualsOrHashCode(type, vars); vars.putAll(objectMethodsToGenerate(methods)); findLocalAndInheritedMethods(type, methods); List methods = new ArrayList(); throws CompileException { private void defineVarsForType(TypeElement type, Map vars) } writeSourceFile(generatedSubclassName(type), text, type); String text = template.rewrite(vars); defineVarsForType(type, vars); ad B ? [ ? B # ? ? ? 0 ?
?
?
?
v
e
a
`
? ? ? Q ? ] ?
?
q
e
B
1
? ? ? ? ? ? r N H 0 , + ? ? R ? y ? ? ? ? \ 0 ? ? ? ? y g E ? ? ? ? ? s k M ? ? ? ? u b , ? ? ? ? P ? ? ? ? ? ? ? } } type = parentElement; } return true; if (parentElement.getAnnotation(AutoParse.class) != null) { TypeElement parentElement = (TypeElement) typeUtils.asElement(parentMirror); Types typeUtils = processingEnv.getTypeUtils(); } return false; if (parentMirror.getKind() == TypeKind.NONE) { TypeMirror parentMirror = type.getSuperclass(); while (true) { private boolean ancestorIsAndroidAutoParse(TypeElement type) { } } "Could not write generated class " + className + ": " + e); processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, } catch (IOException e) { } writer.close(); } finally { writer.write(text); try { Writer writer = sourceFile.openWriter(); processingEnv.getFiler().createSourceFile(className, originatingType); JavaFileObject sourceFile = note(text); try { private void writeSourceFile(String className, String text, TypeElement originatingType) { } && !((ArrayType) type).getComponentType().getKind().isPrimitive(); return type.getKind() == TypeKind.ARRAY private static boolean isReferenceArrayType(TypeMirror type) { } return isDescribeContents || isWriteToParcel; && method.getParameters().get(1).asType().toString().equals("int"); && method.getParameters().get(0).asType().toString().equals("android.os.Parcel") && method.getReturnType().toString().equals("void") boolean isWriteToParcel = name.equals("writeToParcel") && method.getParameters().size() == 2 && method.getReturnType().toString().equals("int"); boolean isDescribeContents = name.equals("describeContents") && method.getParameters().isEmpty() String name = method.getSimpleName().toString(); private boolean isFromParcelable(ExecutableElement method) { } return toImplement; } throw new CompileException(); if (errors) { } } } errors = true; method); reportError("@AutoParse classes cannot have abstract methods other than property getters", } else { toImplement.add(method); } errors = true; + "a primitive array", method); reportError("An @AutoParse class cannot define an array-valued property unless it is " if (isReferenceArrayType(method.getReturnType())) { if (method.getParameters().isEmpty() && method.getReturnType().getKind() != TypeKind.VOID) { && !isToStringOrEqualsOrHashCode(method) && !isFromParcelable(method)) { if (method.getModifiers().contains(Modifier.ABSTRACT) for (ExecutableElement method : methods) { boolean errors = false; List toImplement = new ArrayList(); throws CompileException { private List methodsToImplement(List methods) } return vars; assert vars.size() == 3; } } vars.put(method.getSimpleName().toString(), canGenerate); || isJavaLangObject((TypeElement) method.getEnclosingElement()); boolean canGenerate = method.getModifiers().contains(Modifier.ABSTRACT) if (isToStringOrEqualsOrHashCode(method)) { for (ExecutableElement method : methods) { vars.put("toString", false); vars.put("hashCode", false); vars.put("equals", false); // definitions of these three methods (perhaps the ones in Object) so we will overwrite these: // an exception before it does. If all ancestors do exist then we will definitely find ad ? t ? ? ? ? 4 ? ? ? ? ? t _ ?
?
?
?
h
R
7
? ? ? ? ? + * ? r ?
?
?
t
e
W
M
? ? ? [ N D ? ? ? ? r [ N C B 8 ! ? ? ? ? h < ; ? ? ? ? ? ? ? k ; 5 4 ? ? ? ? ? ? ? a B ? ? ? ? ? ? i E ! ? ? ? ? . ? ? ? ? ? ? ? ? e $ ? ? public boolean nullable() { } return method.getReturnType().getKind() == TypeKind.ARRAY; public boolean array() { } return method.getReturnType().getKind().isPrimitive(); public boolean primitive() { } } + "Go ahead and claim " + kind + " yours"); default: throw new RuntimeException("Found a new Primitive type on the Java platform. " case DOUBLE: return "Double"; case FLOAT: return "Float"; case CHAR: return "Character"; case LONG: return "Long"; case INT: return "Integer"; case SHORT: return "Short"; case BYTE: return "Byte"; case BOOLEAN: return "Boolean"; switch(kind) { private String box(TypeKind kind) { } return primitive() ? box(method.getReturnType().getKind()) : type(); public String castType() { // That wouldn't be necessary if we supported Java 7+. Oh well. } return type; public String type() { } return (TypeElement) method.getEnclosingElement(); TypeElement owner() { } return method.getSimpleName().toString(); public String toString() { @Override } this.vars = vars; this.type = type; this.method = method; Property(ExecutableElement method, String type, Map vars) { private final Map vars; private final String type; private final ExecutableElement method; static class Property { private static final Template template = Template.compile(TEMPLATE_STRING); ); // CHECKSTYLE:ON "}" "]", " }", " return 0;", " @Override public int describeContents() {", "", " }", "$[props:p|| dest.writeValue($[p]);\n]", " @Override public void writeToParcel(android.os.Parcel dest, int flags) {", "", " }", " this(\n $[props:p|,\n |($[p.castType]) in.readValue(CL)]);", " private $[subclass](android.os.Parcel in) {", "", " private final static java.lang.ClassLoader CL = $[subclass].class.getClassLoader();", "", " };", " }", " return new $[origclass][size];", " @Override public $[origclass][] newArray(int size) {", " }", " return new $[subclass](in);", " @Override public $[origclass] createFromParcel(android.os.Parcel in) {", " public static final android.os.Parcelable.Creator<$[origclass]> CREATOR = new android.os.Parcelable.Creator<$[origclass]>() {", "$[parcelable?\n\n", // parcelable "$[serialVersionUID?\n\n private static final long serialVersionUID = $[serialVersionUID];]", // serialVersionUID " }]" + " return h;", "$[cacheHashCode? hashCode = h;\n]" + "]" + " h ^= $[p.hashCodeExpression];", " h *= 1000003;", "$[props:p||" + " int h = 1;", " }\n]" + " return hashCode;", "$[cacheHashCode? if (hashCode != 0) {", " public int hashCode() {", " @Override", "$[cacheHashCode? private transient int hashCode;\n\n]" + "$[hashCode?", // hashCode() " }]", " return false;", " }", "$[props:p|\n && |($[p.equalsThatExpression])];", " return $[props!true]" + " $[origclass]$[wildcardtypes] that = ($[origclass]$[wildcardtypes]) o;", " if (o instanceof $[origclass]) {", " }", " return true;", " if (o == this) {",
© 2015 - 2025 Weber Informatics LLC | Privacy Policy