1a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar/* 2a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * Copyright (C) 2015 The Android Open Source Project 3a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * 4a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * you may not use this file except in compliance with the License. 6a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * You may obtain a copy of the License at 7a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * 8a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * 10a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * Unless required by applicable law or agreed to in writing, software 11a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * See the License for the specific language governing permissions and 14a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar * limitations under the License. 15a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar */ 16a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.annotationprocessor; 18b617e5da04aa910be70204afb886b1ebebb80618George Mount 19fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.Bindable; 20fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.BindingBuildInfo; 2161630faa88ee4817834d47294a0e17f19d8e1c51George Mountimport android.databinding.tool.CompilerChef.BindableHolder; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.GenerationalClassUtil; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L; 242611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyarimport android.databinding.tool.util.Preconditions; 254df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyarimport android.databinding.tool.writer.BRWriter; 264df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyarimport android.databinding.tool.writer.JavaFileWriter; 27b617e5da04aa910be70204afb886b1ebebb80618George Mount 28846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.io.Serializable; 29846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mountimport java.util.HashMap; 30b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.util.HashSet; 31a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyarimport java.util.List; 32b617e5da04aa910be70204afb886b1ebebb80618George Mountimport java.util.Set; 33b617e5da04aa910be70204afb886b1ebebb80618George Mount 341b9940e612fc73202837fbe9db2f9035f307b5d1George Mountimport javax.annotation.processing.ProcessingEnvironment; 35b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.annotation.processing.RoundEnvironment; 36b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.Element; 378e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mountimport javax.lang.model.element.ElementKind; 38b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.ExecutableElement; 39b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.Name; 40b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.TypeElement; 41b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.element.VariableElement; 42b617e5da04aa910be70204afb886b1ebebb80618George Mountimport javax.lang.model.type.TypeKind; 4386558cbd9a58387d6b88a8d032eb2d1e33353030George Mountimport javax.lang.model.util.Types; 44b617e5da04aa910be70204afb886b1ebebb80618George Mount 45a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar// binding app info and library info are necessary to trigger this. 4661630faa88ee4817834d47294a0e17f19d8e1c51George Mountpublic class ProcessBindable extends ProcessDataBinding.ProcessingStep implements BindableHolder { 47a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar Intermediate mProperties; 48b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar HashMap<String, HashSet<String>> mLayoutVariables = new HashMap<String, HashSet<String>>(); 491b9940e612fc73202837fbe9db2f9035f307b5d1George Mount 501b9940e612fc73202837fbe9db2f9035f307b5d1George Mount @Override 51a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public boolean onHandleStep(RoundEnvironment roundEnv, ProcessingEnvironment processingEnv, 52a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar BindingBuildInfo buildInfo) { 53a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (mProperties == null) { 54a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mProperties = new IntermediateV1(buildInfo.modulePackage()); 5561630faa88ee4817834d47294a0e17f19d8e1c51George Mount mergeLayoutVariables(); 5661630faa88ee4817834d47294a0e17f19d8e1c51George Mount mLayoutVariables.clear(); 5786558cbd9a58387d6b88a8d032eb2d1e33353030George Mount TypeElement observableType = processingEnv.getElementUtils(). 5886558cbd9a58387d6b88a8d032eb2d1e33353030George Mount getTypeElement("android.databinding.Observable"); 5986558cbd9a58387d6b88a8d032eb2d1e33353030George Mount Types typeUtils = processingEnv.getTypeUtils(); 6061630faa88ee4817834d47294a0e17f19d8e1c51George Mount for (Element element : AnnotationUtil 6161630faa88ee4817834d47294a0e17f19d8e1c51George Mount .getElementsAnnotatedWith(roundEnv, Bindable.class)) { 6261630faa88ee4817834d47294a0e17f19d8e1c51George Mount Element enclosingElement = element.getEnclosingElement(); 6361630faa88ee4817834d47294a0e17f19d8e1c51George Mount ElementKind kind = enclosingElement.getKind(); 6461630faa88ee4817834d47294a0e17f19d8e1c51George Mount if (kind != ElementKind.CLASS && kind != ElementKind.INTERFACE) { 6561630faa88ee4817834d47294a0e17f19d8e1c51George Mount L.e("Bindable must be on a member field or method. The enclosing type is %s", 6661630faa88ee4817834d47294a0e17f19d8e1c51George Mount enclosingElement.getKind()); 6761630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 6861630faa88ee4817834d47294a0e17f19d8e1c51George Mount TypeElement enclosing = (TypeElement) enclosingElement; 6986558cbd9a58387d6b88a8d032eb2d1e33353030George Mount if (!typeUtils.isAssignable(enclosing.asType(), observableType.asType())) { 7086558cbd9a58387d6b88a8d032eb2d1e33353030George Mount L.e("Bindable must be on a member in an Observable class. %s is not Observable", 7186558cbd9a58387d6b88a8d032eb2d1e33353030George Mount enclosingElement.getSimpleName()); 7286558cbd9a58387d6b88a8d032eb2d1e33353030George Mount } 7361630faa88ee4817834d47294a0e17f19d8e1c51George Mount String name = getPropertyName(element); 7461630faa88ee4817834d47294a0e17f19d8e1c51George Mount if (name != null) { 7561630faa88ee4817834d47294a0e17f19d8e1c51George Mount Preconditions 7661630faa88ee4817834d47294a0e17f19d8e1c51George Mount .checkNotNull(mProperties, "Must receive app / library info before " 7761630faa88ee4817834d47294a0e17f19d8e1c51George Mount + "Bindable fields."); 7861630faa88ee4817834d47294a0e17f19d8e1c51George Mount mProperties.addProperty(enclosing.getQualifiedName().toString(), name); 7961630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 808e5d3b4aa4e47fc0150b4a26b58ec6e5c17b9d16George Mount } 814a0f06e92a846a9bfd8986443e8dae7459157f8fGeorge Mount GenerationalClassUtil.writeIntermediateFile(processingEnv, 824a0f06e92a846a9bfd8986443e8dae7459157f8fGeorge Mount mProperties.getPackage(), 834a0f06e92a846a9bfd8986443e8dae7459157f8fGeorge Mount createIntermediateFileName(mProperties.getPackage()), mProperties); 844a0f06e92a846a9bfd8986443e8dae7459157f8fGeorge Mount generateBRClasses(!buildInfo.isLibrary(), mProperties.getPackage()); 85b617e5da04aa910be70204afb886b1ebebb80618George Mount } 86a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return false; 87a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 88a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 89a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 9061630faa88ee4817834d47294a0e17f19d8e1c51George Mount public void addVariable(String variableName, String containingClassName) { 9161630faa88ee4817834d47294a0e17f19d8e1c51George Mount HashSet<String> variableNames = mLayoutVariables.get(containingClassName); 9261630faa88ee4817834d47294a0e17f19d8e1c51George Mount if (variableNames == null) { 93b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar variableNames = new HashSet<String>(); 9461630faa88ee4817834d47294a0e17f19d8e1c51George Mount mLayoutVariables.put(containingClassName, variableNames); 9561630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 9661630faa88ee4817834d47294a0e17f19d8e1c51George Mount variableNames.add(variableName); 9761630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 9861630faa88ee4817834d47294a0e17f19d8e1c51George Mount 9961630faa88ee4817834d47294a0e17f19d8e1c51George Mount @Override 100a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public void onProcessingOver(RoundEnvironment roundEnvironment, 101a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar ProcessingEnvironment processingEnvironment, BindingBuildInfo buildInfo) { 102b617e5da04aa910be70204afb886b1ebebb80618George Mount } 103b617e5da04aa910be70204afb886b1ebebb80618George Mount 104a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private String createIntermediateFileName(String appPkg) { 105e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar return appPkg + GenerationalClassUtil.ExtensionFilter.BR.getExtension(); 106a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 107a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 108a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private void generateBRClasses(boolean useFinalFields, String pkg) { 109a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.d("************* Generating BR file %s. use final: %s", pkg, useFinalFields); 110b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar HashSet<String> properties = new HashSet<String>(); 111a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mProperties.captureProperties(properties); 112a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar List<Intermediate> previousIntermediates = loadPreviousBRFiles(); 113a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (Intermediate intermediate : previousIntermediates) { 114a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar intermediate.captureProperties(properties); 115a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 1164df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar final JavaFileWriter writer = getWriter(); 1174df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar BRWriter brWriter = new BRWriter(properties, useFinalFields); 1184df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar writer.writeToFile(pkg + ".BR", brWriter.write(pkg)); 1194df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar //writeBRClass(useFinalFields, pkg, properties); 120a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar if (useFinalFields) { 121a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar // generate BR for all previous packages 122a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar for (Intermediate intermediate : previousIntermediates) { 1234df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar writer.writeToFile(intermediate.getPackage() + ".BR", 1244df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar brWriter.write(intermediate.getPackage())); 12543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar } 126b617e5da04aa910be70204afb886b1ebebb80618George Mount } 1274df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar mCallback.onBrWriterReady(brWriter); 128a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 129a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 130b617e5da04aa910be70204afb886b1ebebb80618George Mount private String getPropertyName(Element element) { 131b617e5da04aa910be70204afb886b1ebebb80618George Mount switch (element.getKind()) { 132b617e5da04aa910be70204afb886b1ebebb80618George Mount case FIELD: 133b617e5da04aa910be70204afb886b1ebebb80618George Mount return stripPrefixFromField((VariableElement) element); 134b617e5da04aa910be70204afb886b1ebebb80618George Mount case METHOD: 135b617e5da04aa910be70204afb886b1ebebb80618George Mount return stripPrefixFromMethod((ExecutableElement) element); 136b617e5da04aa910be70204afb886b1ebebb80618George Mount default: 137a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.e("@Bindable is not allowed on %s", element.getKind()); 138b617e5da04aa910be70204afb886b1ebebb80618George Mount return null; 139b617e5da04aa910be70204afb886b1ebebb80618George Mount } 140b617e5da04aa910be70204afb886b1ebebb80618George Mount } 141b617e5da04aa910be70204afb886b1ebebb80618George Mount 142b617e5da04aa910be70204afb886b1ebebb80618George Mount private static String stripPrefixFromField(VariableElement element) { 143b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 144b617e5da04aa910be70204afb886b1ebebb80618George Mount if (name.length() >= 2) { 145b617e5da04aa910be70204afb886b1ebebb80618George Mount char firstChar = name.charAt(0); 146b617e5da04aa910be70204afb886b1ebebb80618George Mount char secondChar = name.charAt(1); 1477201118b5554426cea3fcd07e4fd96e999d3eea9George Mount if (name.length() > 2 && firstChar == 'm' && secondChar == '_') { 1487201118b5554426cea3fcd07e4fd96e999d3eea9George Mount char thirdChar = name.charAt(2); 1497201118b5554426cea3fcd07e4fd96e999d3eea9George Mount if (Character.isJavaIdentifierStart(thirdChar)) { 1507201118b5554426cea3fcd07e4fd96e999d3eea9George Mount return "" + Character.toLowerCase(thirdChar) + 1517201118b5554426cea3fcd07e4fd96e999d3eea9George Mount name.subSequence(3, name.length()); 1527201118b5554426cea3fcd07e4fd96e999d3eea9George Mount } 1537201118b5554426cea3fcd07e4fd96e999d3eea9George Mount } else if ((firstChar == 'm' && Character.isUpperCase(secondChar)) || 154b617e5da04aa910be70204afb886b1ebebb80618George Mount (firstChar == '_' && Character.isJavaIdentifierStart(secondChar))) { 155b617e5da04aa910be70204afb886b1ebebb80618George Mount return "" + Character.toLowerCase(secondChar) + name.subSequence(2, name.length()); 156b617e5da04aa910be70204afb886b1ebebb80618George Mount } 157b617e5da04aa910be70204afb886b1ebebb80618George Mount } 158b617e5da04aa910be70204afb886b1ebebb80618George Mount return name.toString(); 159b617e5da04aa910be70204afb886b1ebebb80618George Mount } 160b617e5da04aa910be70204afb886b1ebebb80618George Mount 161b617e5da04aa910be70204afb886b1ebebb80618George Mount private String stripPrefixFromMethod(ExecutableElement element) { 162b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 163b617e5da04aa910be70204afb886b1ebebb80618George Mount CharSequence propertyName; 164b617e5da04aa910be70204afb886b1ebebb80618George Mount if (isGetter(element) || isSetter(element)) { 165b617e5da04aa910be70204afb886b1ebebb80618George Mount propertyName = name.subSequence(3, name.length()); 166b617e5da04aa910be70204afb886b1ebebb80618George Mount } else if (isBooleanGetter(element)) { 167b617e5da04aa910be70204afb886b1ebebb80618George Mount propertyName = name.subSequence(2, name.length()); 168b617e5da04aa910be70204afb886b1ebebb80618George Mount } else { 169a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar L.e("@Bindable associated with method must follow JavaBeans convention %s", element); 170b617e5da04aa910be70204afb886b1ebebb80618George Mount return null; 171b617e5da04aa910be70204afb886b1ebebb80618George Mount } 172b617e5da04aa910be70204afb886b1ebebb80618George Mount char firstChar = propertyName.charAt(0); 173b617e5da04aa910be70204afb886b1ebebb80618George Mount return "" + Character.toLowerCase(firstChar) + 174b617e5da04aa910be70204afb886b1ebebb80618George Mount propertyName.subSequence(1, propertyName.length()); 175b617e5da04aa910be70204afb886b1ebebb80618George Mount } 176b617e5da04aa910be70204afb886b1ebebb80618George Mount 17761630faa88ee4817834d47294a0e17f19d8e1c51George Mount private void mergeLayoutVariables() { 17861630faa88ee4817834d47294a0e17f19d8e1c51George Mount for (String containingClass : mLayoutVariables.keySet()) { 17961630faa88ee4817834d47294a0e17f19d8e1c51George Mount for (String variable : mLayoutVariables.get(containingClass)) { 18061630faa88ee4817834d47294a0e17f19d8e1c51George Mount mProperties.addProperty(containingClass, variable); 18161630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 18261630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 18361630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 18461630faa88ee4817834d47294a0e17f19d8e1c51George Mount 185b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean prefixes(CharSequence sequence, String prefix) { 186b617e5da04aa910be70204afb886b1ebebb80618George Mount boolean prefixes = false; 187b617e5da04aa910be70204afb886b1ebebb80618George Mount if (sequence.length() > prefix.length()) { 188b617e5da04aa910be70204afb886b1ebebb80618George Mount int count = prefix.length(); 189b617e5da04aa910be70204afb886b1ebebb80618George Mount prefixes = true; 190b617e5da04aa910be70204afb886b1ebebb80618George Mount for (int i = 0; i < count; i++) { 191b617e5da04aa910be70204afb886b1ebebb80618George Mount if (sequence.charAt(i) != prefix.charAt(i)) { 192b617e5da04aa910be70204afb886b1ebebb80618George Mount prefixes = false; 193b617e5da04aa910be70204afb886b1ebebb80618George Mount break; 194b617e5da04aa910be70204afb886b1ebebb80618George Mount } 195b617e5da04aa910be70204afb886b1ebebb80618George Mount } 196b617e5da04aa910be70204afb886b1ebebb80618George Mount } 197b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes; 198b617e5da04aa910be70204afb886b1ebebb80618George Mount } 199b617e5da04aa910be70204afb886b1ebebb80618George Mount 200b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean isGetter(ExecutableElement element) { 201b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 202b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes(name, "get") && 203b617e5da04aa910be70204afb886b1ebebb80618George Mount Character.isJavaIdentifierStart(name.charAt(3)) && 204b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getParameters().isEmpty() && 205b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getReturnType().getKind() != TypeKind.VOID; 206b617e5da04aa910be70204afb886b1ebebb80618George Mount } 207b617e5da04aa910be70204afb886b1ebebb80618George Mount 208b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean isSetter(ExecutableElement element) { 209b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 210b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes(name, "set") && 211b617e5da04aa910be70204afb886b1ebebb80618George Mount Character.isJavaIdentifierStart(name.charAt(3)) && 212b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getParameters().size() == 1 && 213b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getReturnType().getKind() == TypeKind.VOID; 214b617e5da04aa910be70204afb886b1ebebb80618George Mount } 215b617e5da04aa910be70204afb886b1ebebb80618George Mount 216b617e5da04aa910be70204afb886b1ebebb80618George Mount private static boolean isBooleanGetter(ExecutableElement element) { 217b617e5da04aa910be70204afb886b1ebebb80618George Mount Name name = element.getSimpleName(); 218b617e5da04aa910be70204afb886b1ebebb80618George Mount return prefixes(name, "is") && 219b617e5da04aa910be70204afb886b1ebebb80618George Mount Character.isJavaIdentifierStart(name.charAt(2)) && 220b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getParameters().isEmpty() && 221b617e5da04aa910be70204afb886b1ebebb80618George Mount element.getReturnType().getKind() == TypeKind.BOOLEAN; 222b617e5da04aa910be70204afb886b1ebebb80618George Mount } 223612997fe2e41366573855f56898b27d4c8787244George Mount 224a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private List<Intermediate> loadPreviousBRFiles() { 225a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return GenerationalClassUtil 226e8609ca3a9e95cb730d74f8a6114bc2ae11b6a10Yigit Boyar .loadObjects(GenerationalClassUtil.ExtensionFilter.BR); 227612997fe2e41366573855f56898b27d4c8787244George Mount } 228612997fe2e41366573855f56898b27d4c8787244George Mount 229a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private interface Intermediate extends Serializable { 230846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 231846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount void captureProperties(Set<String> properties); 232846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 233846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount void addProperty(String className, String propertyName); 234a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 23561630faa88ee4817834d47294a0e17f19d8e1c51George Mount boolean hasValues(); 23661630faa88ee4817834d47294a0e17f19d8e1c51George Mount 237a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar String getPackage(); 238846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 239846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 240846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount private static class IntermediateV1 implements Serializable, Intermediate { 241846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 242a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private static final long serialVersionUID = 2L; 243a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 244a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar private String mPackage; 245b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar private final HashMap<String, HashSet<String>> mProperties = new HashMap<String, HashSet<String>>(); 246846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 247a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public IntermediateV1(String aPackage) { 248a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar mPackage = aPackage; 249a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 250a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 251846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount @Override 252846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount public void captureProperties(Set<String> properties) { 253846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount for (HashSet<String> propertySet : mProperties.values()) { 254846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.addAll(propertySet); 255846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 256846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 257846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount 258846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount @Override 259846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount public void addProperty(String className, String propertyName) { 260846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount HashSet<String> properties = mProperties.get(className); 261846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount if (properties == null) { 262b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar properties = new HashSet<String>(); 263846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount mProperties.put(className, properties); 264846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 265846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount properties.add(propertyName); 266846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 267a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar 268a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar @Override 26961630faa88ee4817834d47294a0e17f19d8e1c51George Mount public boolean hasValues() { 27061630faa88ee4817834d47294a0e17f19d8e1c51George Mount return !mProperties.isEmpty(); 27161630faa88ee4817834d47294a0e17f19d8e1c51George Mount } 27261630faa88ee4817834d47294a0e17f19d8e1c51George Mount 27361630faa88ee4817834d47294a0e17f19d8e1c51George Mount @Override 274a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar public String getPackage() { 275a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar return mPackage; 276a6e4583962e19e8e93b4ca3f9fe3d34560b6d96cYigit Boyar } 277846795ea3e69eb482968cfea3312df04787c9bcfGeorge Mount } 278b617e5da04aa910be70204afb886b1ebebb80618George Mount} 279