summaryrefslogtreecommitdiff
path: root/bin/flycheck-android-java.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/flycheck-android-java.py')
-rw-r--r--bin/flycheck-android-java.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/bin/flycheck-android-java.py b/bin/flycheck-android-java.py
new file mode 100644
index 0000000..3f0f4bf
--- /dev/null
+++ b/bin/flycheck-android-java.py
@@ -0,0 +1,112 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import os
+import subprocess
+import sys
+import tempfile
+import time
+
+def find_dominating_file(dir, file):
+ """Find directory containing file."""
+ if os.path.exists(os.path.join(dir, file)):
+ return dir
+ return find_dominating_file(os.path.dirname(dir), file)
+
+def get_gradle_command(dir):
+ """Find top-project gradlew or fallback to using gradle on sub-project dir."""
+ topdir = find_dominating_file(dir, 'gradlew')
+ if topdir:
+ return [os.path.join(topdir, 'gradlew'), '-p', topdir]
+ topdir = find_dominating_file(dir, 'build.gradle')
+ if topdir:
+ return ['gradle', '-p', topdir]
+ return ['gradle']
+
+def filter_source_files(files):
+ """Remove any item not looking like a Java source file."""
+ return [f for f in files if f.endswith('.java')]
+
+def run_javac(encoding, source, target, bootcp, cp, files, output, args,
+ sourcefile):
+ """Execute javac with the given options."""
+ command = ['javac']
+ if encoding:
+ command.extend(['-encoding', encoding])
+ if source:
+ command.extend(['-source', source])
+ if target:
+ command.extend(['-target', target])
+ if bootcp:
+ command.extend(['-bootclasspath', bootcp])
+ if cp:
+ command.extend(['-cp', ':'.join(cp)])
+ if output:
+ command.extend(['-d', output])
+ command.extend(args)
+ command.append(sourcefile)
+ with tempfile.NamedTemporaryFile(mode='w') as f:
+ command.append('@' + f.name)
+ for source in filter_source_files(files):
+ f.write(source)
+ f.write('\n')
+ f.flush()
+ return subprocess.call(command)
+
+def file_in_list(needle, files):
+ """Find needle in files and if so, return the list without needle.
+Otherwise return None."""
+ for i in range(0, len(files) - 1):
+ if os.path.samefile(needle, files[i]):
+ return files[0:i] + files[i + 1:]
+ return None
+
+def figure_out_java_compilation(sourcefile, tempfile):
+ """Get options for Java compilation from gradle project and run javac."""
+ cmd = get_gradle_command(os.path.dirname(sourcefile))
+ cmd.extend(['-q', 'flycheckAndroidJava'])
+ output = subprocess.check_output(cmd, universal_newlines=True).split('\n')
+ data = None
+ for line in output:
+ if line == '***':
+ if data:
+ files = file_in_list(sourcefile, data['files'])
+ if files:
+ return run_javac(data['encoding'], data['source'],
+ data['target'], data['bootcp'],
+ data['cp'], files, data['output'],
+ data['args'], tempfile)
+ data = {}
+ elif data != None:
+ if line.startswith('args='):
+ data['args'] = line[6:-1].split(', ')
+ elif line.startswith('encoding='):
+ data['encoding'] = line[9:]
+ elif line.startswith('bootcp='):
+ data['bootcp'] = line[7:]
+ elif line.startswith('cp='):
+ data['cp'] = line[3:].split(':')
+ elif line.startswith('source='):
+ data['source'] = line[7:]
+ elif line.startswith('target='):
+ data['target'] = line[7:]
+ elif line.startswith('files='):
+ data['files'] = line[6:].split(':')
+ elif line.startswith('output='):
+ data['output'] = line[7:]
+ if data:
+ files = file_in_list(sourcefile, data['files'])
+ if files:
+ return run_javac(data['encoding'], data['source'], data['target'],
+ data['bootcp'], data['cp'], files, data['output'],
+ data['args'], tempfile)
+ return 0
+
+if len(sys.argv) == 3:
+ sys.exit(figure_out_java_compilation(os.path.abspath(sys.argv[1]),
+ sys.argv[2]))
+elif len(sys.argv) == 2:
+ sys.exit(figure_out_java_compilation(os.path.abspath(sys.argv[1]),
+ sys.argv[1]))
+else:
+ sys.exit(-1)