Reviewed By: jberdine Differential Revision: D20438569 fbshipit-source-id: 7db527273master
parent
04543938ab
commit
36b8ee7198
@ -1,84 +0,0 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from . import util
|
||||
from inferlib import jwlib
|
||||
|
||||
MODULE_NAME = __name__
|
||||
MODULE_DESCRIPTION = '''Run analysis of code built with a command like:
|
||||
ant [options] [target]
|
||||
|
||||
Analysis examples:
|
||||
infer -- ant compile'''
|
||||
LANG = ['java']
|
||||
|
||||
|
||||
def gen_instance(*args):
|
||||
return AntCapture(*args)
|
||||
|
||||
|
||||
# This creates an empty argparser for the module, which provides only
|
||||
# description/usage information and no arguments.
|
||||
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)
|
||||
|
||||
|
||||
class AntCapture:
|
||||
|
||||
def __init__(self, args, cmd):
|
||||
self.args = args
|
||||
util.log_java_version()
|
||||
logging.info(util.run_cmd_ignore_fail([cmd[0], '-version']))
|
||||
# TODO: make the extraction of targets smarter
|
||||
self.build_cmd = [cmd[0], '-verbose'] + cmd[1:]
|
||||
|
||||
def is_interesting(self, content):
|
||||
return self.is_quoted(content) or content.endswith('.java')
|
||||
|
||||
def is_quoted(self, argument):
|
||||
quote = '\''
|
||||
return len(argument) > 2 and argument[0] == quote\
|
||||
and argument[-1] == quote
|
||||
|
||||
def remove_quotes(self, argument):
|
||||
if self.is_quoted(argument):
|
||||
return argument[1:-1]
|
||||
else:
|
||||
return argument
|
||||
|
||||
def get_infer_commands(self, verbose_output):
|
||||
javac_pattern = '[javac]'
|
||||
argument_start_pattern = 'Compilation arguments'
|
||||
calls = []
|
||||
javac_arguments = []
|
||||
collect = False
|
||||
for line in verbose_output.split('\n'):
|
||||
if javac_pattern in line:
|
||||
if argument_start_pattern in line:
|
||||
collect = True
|
||||
if javac_arguments != []:
|
||||
capture = jwlib.create_infer_command(javac_arguments)
|
||||
calls.append(capture)
|
||||
javac_arguments = []
|
||||
if collect:
|
||||
pos = line.index(javac_pattern) + len(javac_pattern)
|
||||
content = line[pos:].strip()
|
||||
if self.is_interesting(content):
|
||||
arg = self.remove_quotes(content)
|
||||
javac_arguments.append(arg)
|
||||
if javac_arguments != []:
|
||||
capture = jwlib.create_infer_command(javac_arguments)
|
||||
calls.append(capture)
|
||||
javac_arguments = []
|
||||
return calls
|
||||
|
||||
def capture(self):
|
||||
(code, (verbose_out, _)) = util.get_build_output(self.build_cmd)
|
||||
if code != os.EX_OK:
|
||||
return code
|
||||
cmds = self.get_infer_commands(verbose_out)
|
||||
return util.run_compilation_commands(cmds)
|
@ -0,0 +1,73 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
open! IStd
|
||||
module L = Logging
|
||||
|
||||
let javac_pattern = "[javac]"
|
||||
|
||||
let arg_start_pattern = "Compilation arguments"
|
||||
|
||||
let extract_javac_args line =
|
||||
let is_quoted s =
|
||||
String.length s > 2 && String.is_prefix s ~prefix:"'" && String.is_suffix s ~suffix:"'"
|
||||
in
|
||||
let remove_quotes s = if is_quoted s then String.sub s ~pos:1 ~len:(String.length s - 2) else s in
|
||||
let is_interesting s = String.is_suffix s ~suffix:".java" || is_quoted s in
|
||||
Option.map (String.substr_index line ~pattern:javac_pattern) ~f:(fun pos ->
|
||||
let content = String.drop_prefix line (pos + String.length javac_pattern) |> String.strip in
|
||||
if is_interesting content then Some (remove_quotes content) else None )
|
||||
|> Option.join
|
||||
|
||||
|
||||
let do_javac_capture rev_javac_args =
|
||||
let prog = Config.bin_dir ^/ "infer" in
|
||||
let args =
|
||||
"capture" :: "--continue" :: "--" :: "javac"
|
||||
:: List.rev_filter_map rev_javac_args ~f:(fun arg ->
|
||||
if String.equal "-Werror" arg then None
|
||||
else if String.is_substring arg ~substring:"-g:" then Some "-g"
|
||||
else Some arg )
|
||||
in
|
||||
L.debug Capture Verbose "%s %s@." prog (String.concat ~sep:" " args) ;
|
||||
Process.create_process_and_wait ~prog ~args
|
||||
|
||||
|
||||
type fold_state = {collecting: bool; rev_javac_args: string list}
|
||||
|
||||
let capture ~prog ~args =
|
||||
let _, java_version =
|
||||
Process.create_process_and_wait_with_output ~prog:"java" ~args:["-version"]
|
||||
in
|
||||
let _, javac_version =
|
||||
Process.create_process_and_wait_with_output ~prog:"javac" ~args:["-version"]
|
||||
in
|
||||
let ant_version, _ = Process.create_process_and_wait_with_output ~prog ~args:["-version"] in
|
||||
L.environment_info "%s %s %s@." java_version javac_version ant_version ;
|
||||
L.debug Capture Verbose "%s %s@." prog @@ String.concat ~sep:" " args ;
|
||||
let ant_out, _ = Process.create_process_and_wait_with_output ~prog ~args:("-verbose" :: args) in
|
||||
L.debug Capture Verbose "%s" ant_out ;
|
||||
let res =
|
||||
List.fold (String.split_lines ant_out) ~init:{collecting= false; rev_javac_args= []}
|
||||
~f:(fun {collecting; rev_javac_args} line ->
|
||||
let is_line_interesting = String.is_substring line ~substring:javac_pattern in
|
||||
if is_line_interesting then
|
||||
let start_collecting = String.is_substring line ~substring:arg_start_pattern in
|
||||
let collecting = collecting || start_collecting in
|
||||
let rev_javac_args =
|
||||
if start_collecting && not (List.is_empty rev_javac_args) then (
|
||||
do_javac_capture rev_javac_args ; [] )
|
||||
else rev_javac_args
|
||||
in
|
||||
let rev_javac_args =
|
||||
if collecting then
|
||||
Option.fold (extract_javac_args line) ~init:rev_javac_args ~f:(Fn.flip List.cons)
|
||||
else rev_javac_args
|
||||
in
|
||||
{collecting; rev_javac_args}
|
||||
else {collecting; rev_javac_args} )
|
||||
in
|
||||
if not (List.is_empty res.rev_javac_args) then do_javac_capture res.rev_javac_args
|
@ -0,0 +1,11 @@
|
||||
(*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*)
|
||||
|
||||
open! IStd
|
||||
|
||||
val capture : prog:string -> args:string list -> unit
|
||||
(** do an ant capture with the given prog (i.e. ant) and args *)
|
Loading…
Reference in new issue