Skip to content

Commit

Permalink
* fix databinding annotation dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
lomanyong committed Nov 5, 2016
1 parent 72fb9a8 commit 3d81728
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 37 deletions.
2 changes: 1 addition & 1 deletion freeline_core/gradle_clean_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def generate_sorted_build_tasks(self):
install_task = InstallApkTask(self._adb, self._config)
clean_all_cache_task = CleanAllCacheTask(self._config['build_cache_dir'], ignore=[
'stat_cache.json', 'apktime', 'jar_dependencies.json', 'resources_dependencies.json', 'public_keeper.xml',
'assets_dependencies.json'])
'assets_dependencies.json', 'freeline_annotation_info.json'])
build_base_resource_task = BuildBaseResourceTask(self._config, self._project_info)
generate_stat_task = GenerateFileStatTask(self._config)
append_stat_task = GenerateFileStatTask(self._config, is_append=True)
Expand Down
44 changes: 41 additions & 3 deletions freeline_core/gradle_inc_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
GradleCleanCacheTask, GradleMergeDexTask, get_sync_native_file_path, fix_package_name, DataBindingProcessor, \
DatabindingDirectoryLookUp
from task import find_root_tasks, find_last_tasks, Task
from utils import get_file_content, write_file_content, is_windows_system, cexec, load_json_cache, get_md5
from utils import get_file_content, write_file_content, is_windows_system, cexec, load_json_cache, get_md5, \
write_json_cache
from tracing import Tracing
from exceptions import FreelineException

Expand Down Expand Up @@ -536,8 +537,6 @@ def fill_classpaths(self):
if os.path.exists(os.path.join(src_dir, java_src)):
existence = True
break
# if not os.path.exists(os.path.join(src_dir, java_src)):
# android_tools.delete_class(dirpath, fn.replace('.class', ''))
if not existence:
android_tools.delete_class(dirpath, fn.replace('.class', ''))

Expand Down Expand Up @@ -649,12 +648,51 @@ def _generate_java_compile_args(self, extra_javac_args_enabled=False):
if 'apt' in self._changed_files:
for fpath in self._changed_files['apt']:
javacargs.append(fpath)
files = self._get_apt_related_files()
for fpath in files:
if fpath and os.path.exists(fpath) and fpath not in self._changed_files['src'] and fpath not in \
self._changed_files['apt']:
self.debug('add apt related file: {}'.format(fpath))
javacargs.append(fpath)
javacargs.extend(self._extra_javac_args)

javacargs.append('-d')
javacargs.append(self._finder.get_patch_classes_cache_dir())
return javacargs

def _get_apt_related_files(self):
path = self._get_apt_related_files_cache_path()
if os.path.exists(path):
return load_json_cache(path)
else:
info_path = os.path.join(self._cache_dir, 'freeline_annotation_info.json')
if os.path.exists(info_path):
info_cache = load_json_cache(info_path)
related_files = []
for anno, files in info_cache.iteritems():
for info in files:
if 'java_path' in info and info['java_path']:
related_files.append(info['java_path'])
write_json_cache(self._get_apt_related_files_cache_path(), related_files)
return related_files
return []

def _append_new_related_files(self):
related_files = self._get_apt_related_files()

def append_files(file_list):
for fpath in file_list:
if fpath and fpath not in related_files:
self.debug('add new related file: {}'.format(fpath))
related_files.append(fpath)

append_files(self._changed_files['src'])
append_files(self._changed_files['apt'])
write_json_cache(self._get_apt_related_files_cache_path(), related_files)

def _get_apt_related_files_cache_path(self):
return os.path.join(self._cache_dir, 'apt_related_files_cache.json')

def run_retrolambda(self):
if self._is_need_javac and self._is_retrolambda_enabled:
lambda_config = self._config['retrolambda'][self._name]
Expand Down
30 changes: 19 additions & 11 deletions freeline_core/gradle_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,19 +831,27 @@ def process_layout_info(self, fpath):
classpaths = []

for import_node in imports:
imports_dict[import_node.attrib['name']] = import_node.attrib
if 'name' in import_node.attrib:
imports_dict[import_node.attrib['name']] = import_node.attrib
if 'type' in import_node.attrib:
classpath = import_node.attrib['type']
if classpath and classpath not in classpaths and not classpath.startswith(
'android.') and not classpath.startswith('java.'):
classpaths.append(classpath)

for variable_node in variables:
variable_type = variable_node.attrib['type']
if '.' in variable_type:
classpath = variable_type
elif variable_type in imports_dict:
classpath = imports_dict[variable_type]['type']
else:
classpath = None

if classpath and not classpath.startswith('android.') and not classpath.startswith('java.'):
classpaths.append(classpath)
if 'type' in variable_node.attrib:
variable_type = variable_node.attrib['type']
if '.' in variable_type:
classpath = variable_type
elif variable_type in imports_dict:
classpath = imports_dict[variable_type]['type']
else:
classpath = None

if classpath and classpath not in classpaths and not classpath.startswith(
'android.') and not classpath.startswith('java.'):
classpaths.append(classpath)

return classpaths
return []
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.antfortune.freeline

import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Label
Expand All @@ -14,14 +15,28 @@ class FreelineClassVisitor extends ClassVisitor implements Opcodes {

private static final String SUFFIX_ANDROIDANNOTATION = "_"

public boolean isHack = true;
public boolean isHack = true

public FreelineClassVisitor(int api, ClassWriter cw) {
public String className = null

public String filePath = null

public String entry = null

public boolean isJar = false

public def foundAnnos = []

public FreelineClassVisitor(String path, String entry, boolean isJar, int api, ClassWriter cw) {
super(api, cw)
this.filePath = path
this.entry = entry
this.isJar = isJar
}

@Override
void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
className = name;
if ("android/app/Application".equals(superName)) {
isHack = false;
}
Expand Down Expand Up @@ -68,6 +83,19 @@ class FreelineClassVisitor extends ClassVisitor implements Opcodes {
}
super.visitMaxs(i, i1)
}

@Override
AnnotationVisitor visitAnnotation(String annoDesc, boolean visible) {
if (annoDesc != null) {
FreelineAnnotationCollector.ANNOTATION_CLASSES.each { anno ->
if (!foundAnnos.contains(anno) && annoDesc.contains(anno)) {
foundAnnos.add(anno)
FreelineAnnotationCollector.addNewAnno(anno, filePath, className, entry, isJar)
}
}
}
return super.visitAnnotation(annoDesc, visible)
}
}
return mv;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import java.util.zip.ZipEntry
*/
class FreelineInjector {

public static void inject(List<String> excludeClasses, File file, List<String> modules) {
public static void inject(List<String> excludeClasses, File file, Collection<String> modules) {
if (file.path.endsWith(".class")
&& !isExcluded(file.path, excludeClasses)) {
realInject(file)
Expand Down Expand Up @@ -44,7 +44,7 @@ class FreelineInjector {
return false
}

private static boolean isProjectModuleJar(String path, List<String> modules) {
private static boolean isProjectModuleJar(String path, Collection<String> modules) {
for (String module : modules) {
if (path.contains(module)) {
return true
Expand All @@ -61,7 +61,7 @@ class FreelineInjector {
FileInputStream fis = new FileInputStream(file)
FileOutputStream fos = new FileOutputStream(pending)
println "inject: ${file.path}"
byte[] bytes = hackClass(fis);
byte[] bytes = hackClass(file.path, null, false, fis);
fos.write(bytes)
fis.close()
fos.close()
Expand All @@ -81,7 +81,7 @@ class FreelineInjector {

if (entryName.endsWith(".class")) {
println "inject jar class: ${entryName}"
jos.write(hackClass(is))
jos.write(hackClass(file.path, entryName, true, is))
} else {
println "skip jar entry: ${entryName}"
jos.write(readBytes(is))
Expand All @@ -108,10 +108,10 @@ class FreelineInjector {
}
}

private static byte[] hackClass(InputStream inputStream) {
private static byte[] hackClass(String path, String entry, boolean isJar, InputStream inputStream) {
ClassReader cr = new ClassReader(inputStream)
ClassWriter cw = new ClassWriter(cr, 0)
ClassVisitor cv = new FreelineClassVisitor(Opcodes.ASM4, cw)
ClassVisitor cv = new FreelineClassVisitor(path, entry, isJar, Opcodes.ASM4, cw)
cr.accept(cv, 0)
return cw.toByteArray()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,20 +290,21 @@ class FreelinePlugin implements Plugin<Project> {

classesProcessTask.outputs.upToDateWhen { false }
String backUpDirPath = FreelineUtils.getBuildBackupDir(project.buildDir.absolutePath)
def modules = [:]
project.rootProject.allprojects.each { pro ->
//modules.add("exploded-aar" + File.separator + pro.group + File.separator + pro.name + File.separator)
modules[pro.name] = "exploded-aar" + File.separator + pro.group + File.separator + pro.name + File.separator
}

if (preDexTask) {
preDexTask.outputs.upToDateWhen { false }
def hackClassesBeforePreDex = "hackClassesBeforePreDex${variant.name.capitalize()}"
project.task(hackClassesBeforePreDex) << {
def jarDependencies = []
def modules = []
project.rootProject.allprojects.each { pro ->
modules.add("exploded-aar" + File.separator + pro.group + File.separator + pro.name + File.separator)
}

preDexTask.inputs.files.files.each { f ->
if (f.path.endsWith(".jar")) {
FreelineInjector.inject(excludeHackClasses, f as File, modules)
FreelineInjector.inject(excludeHackClasses, f as File, modules.values())
jarDependencies.add(f.path)
}
}
Expand All @@ -321,23 +322,18 @@ class FreelinePlugin implements Plugin<Project> {
def backupMap = [:]
project.task(hackClassesBeforeDex) << {
def jarDependencies = []
def modules = []
project.rootProject.allprojects.each { pro ->
modules.add("exploded-aar" + File.separator + pro.group + File.separator + pro.name + File.separator)
}

classesProcessTask.inputs.files.files.each { f ->
if (f.isDirectory()) {
f.eachFileRecurse(FileType.FILES) { file ->
backUpClass(backupMap, file as File, backUpDirPath as String)
FreelineInjector.inject(excludeHackClasses, file as File, modules)
FreelineInjector.inject(excludeHackClasses, file as File, modules.values())
if (file.path.endsWith(".jar")) {
jarDependencies.add(file.path)
}
}
} else {
backUpClass(backupMap, f as File, backUpDirPath as String)
FreelineInjector.inject(excludeHackClasses, f as File, modules)
FreelineInjector.inject(excludeHackClasses, f as File, modules.values())
if (f.path.endsWith(".jar")) {
jarDependencies.add(f.path)
}
Expand Down Expand Up @@ -373,6 +369,7 @@ class FreelinePlugin implements Plugin<Project> {
def assembleTask = project.tasks.findByName("assemble${variant.name.capitalize()}")
if (assembleTask) {
assembleTask.doLast {
FreelineAnnotationCollector.saveCollections(project, FreelineUtils.getBuildCacheDir(project.buildDir.absolutePath), modules)
FreelineUtils.addNewAttribute(project, 'apt', projectAptConfig)
FreelineUtils.addNewAttribute(project, 'retrolambda', projectRetrolambdaConfig)
FreelineUtils.addNewAttribute(project, 'databinding_compiler_jar', databindingCompilerJarPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,20 @@ class FreelineUtils {
}

public static void addNewAttribute(Project project, String key, def value) {
def description = readProjectDescription(project)
if (description != null) {
description[key] = value
saveJson(new JsonBuilder(description).toPrettyString(), joinPath(getFreelineCacheDir(project.rootDir.absolutePath), 'project_description.json'), true)
}
}

public static def readProjectDescription(Project project) {
def descriptionFile = new File(joinPath(getFreelineCacheDir(project.rootDir.absolutePath), 'project_description.json'))
if (descriptionFile.exists()) {
def description = new JsonSlurper().parseText(descriptionFile.text)
description[key] = value
saveJson(new JsonBuilder(description).toPrettyString(), descriptionFile.absolutePath, true)
return description
}
return null
}

public static String joinPath(String... sep) {
Expand Down

0 comments on commit 3d81728

Please sign in to comment.