summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@yahoo.com>2017-01-10 08:43:23 +0100
committerJoel Klinghed <the_jk@yahoo.com>2017-01-10 08:43:23 +0100
commit01401d210feebece12d804fcab311063a1ea4c54 (patch)
treeca02e19d4233f79adb1d8bee6ffea3eefd46a0cd
Initial commit
-rw-r--r--bin/flycheck-android-java.py112
-rw-r--r--flycheck-android-experimental.el44
2 files changed, 156 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)
diff --git a/flycheck-android-experimental.el b/flycheck-android-experimental.el
new file mode 100644
index 0000000..96374c7
--- /dev/null
+++ b/flycheck-android-experimental.el
@@ -0,0 +1,44 @@
+;;; flycheck-android-experimental.el --- Flycheck for Android using experimental
+;;; gradle plugin
+
+;; Copyright (C) 2017 by Joel Klinghed
+
+;; Author: Joel Klinghed <the_jk@yahoo.com>
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'flycheck)
+
+(flycheck-define-checker android-java
+ "Java syntax checker using javac."
+ :command ("python"
+ (eval (flycheck-android-find-tool "java"))
+ (eval buffer-file-name)
+ source)
+ :error-patterns
+ ((warning line-start (file-name) ":" line ": warning:"
+ (message (one-or-more (not (any "^")))
+ (any "^"))
+ line-end)
+ (error line-start (file-name) ":" line ": error:"
+ (message (one-or-more (not (any "^")))
+ (any "^"))
+ line-end))
+ :modes java-mode)
+
+(defun flycheck-android-find-tool (tool)
+ "Find flycheck-android-TOOL.py.
+TOOL=name of tool"
+ (let ((filename (concat "flycheck-android-" tool ".py")))
+ (expand-file-name
+ filename
+ (concat (file-name-as-directory "bin")
+ (file-name-directory (symbol-file 'flycheck-android-find-tool))))))
+
+(add-to-list 'flycheck-checkers 'android-java)
+
+(provide 'flycheck-android-experimental)
+
+;;; flycheck-android-experimental.el ends here