Browse Source

Silence trailing "1 warning" message from javac when warning is silenced

soong_javac_wrapper is silencing a useless warning:
warning: [options] bootstrap class path not set in conjunction with -source 1.9
but recent versions of javac have started also printing:
1 warning

Read the warning count, subtract the number of silenced warnings, and
reprint it if the non-silenced warning count is nonzero.

Fixes: 144118634
Test: javac_wrapper_test.go
Change-Id: Ie1d0a978188ab7b1c41027f718a1274608628123
Colin Cross 4 years ago
parent
commit
e94272d0b3
2 changed files with 53 additions and 6 deletions
  1. 36 5
      cmd/javac_wrapper/javac_wrapper.go
  2. 17 1
      cmd/javac_wrapper/javac_wrapper_test.go

+ 36 - 5
cmd/javac_wrapper/javac_wrapper.go

@@ -31,6 +31,7 @@ import (
 	"os"
 	"os/exec"
 	"regexp"
+	"strconv"
 	"syscall"
 )
 
@@ -80,10 +81,11 @@ func Main(out io.Writer, name string, args []string) (int, error) {
 
 	pw.Close()
 
+	proc := processor{}
 	// Process subprocess stdout asynchronously
 	errCh := make(chan error)
 	go func() {
-		errCh <- process(pr, out)
+		errCh <- proc.process(pr, out)
 	}()
 
 	// Wait for subprocess to finish
@@ -117,14 +119,18 @@ func Main(out io.Writer, name string, args []string) (int, error) {
 	return 0, nil
 }
 
-func process(r io.Reader, w io.Writer) error {
+type processor struct {
+	silencedWarnings int
+}
+
+func (proc *processor) process(r io.Reader, w io.Writer) error {
 	scanner := bufio.NewScanner(r)
 	// Some javac wrappers output the entire list of java files being
 	// compiled on a single line, which can be very large, set the maximum
 	// buffer size to 2MB.
 	scanner.Buffer(nil, 2*1024*1024)
 	for scanner.Scan() {
-		processLine(w, scanner.Text())
+		proc.processLine(w, scanner.Text())
 	}
 	err := scanner.Err()
 	if err != nil {
@@ -133,12 +139,32 @@ func process(r io.Reader, w io.Writer) error {
 	return nil
 }
 
-func processLine(w io.Writer, line string) {
+func (proc *processor) processLine(w io.Writer, line string) {
+	for _, f := range warningFilters {
+		if f.MatchString(line) {
+			proc.silencedWarnings++
+			return
+		}
+	}
 	for _, f := range filters {
 		if f.MatchString(line) {
 			return
 		}
 	}
+	if match := warningCount.FindStringSubmatch(line); match != nil {
+		c, err := strconv.Atoi(match[1])
+		if err == nil {
+			c -= proc.silencedWarnings
+			if c == 0 {
+				return
+			} else {
+				line = fmt.Sprintf("%d warning", c)
+				if c > 1 {
+					line += "s"
+				}
+			}
+		}
+	}
 	for _, p := range colorPatterns {
 		var matched bool
 		if line, matched = applyColor(line, p.color, p.re); matched {
@@ -170,12 +196,17 @@ var colorPatterns = []struct {
 	{markerRe, green},
 }
 
+var warningCount = regexp.MustCompile(`^([0-9]+) warning(s)?$`)
+
+var warningFilters = []*regexp.Regexp{
+	regexp.MustCompile(`bootstrap class path not set in conjunction with -source`),
+}
+
 var filters = []*regexp.Regexp{
 	regexp.MustCompile(`Note: (Some input files|.*\.java) uses? or overrides? a deprecated API.`),
 	regexp.MustCompile(`Note: Recompile with -Xlint:deprecation for details.`),
 	regexp.MustCompile(`Note: (Some input files|.*\.java) uses? unchecked or unsafe operations.`),
 	regexp.MustCompile(`Note: Recompile with -Xlint:unchecked for details.`),
-	regexp.MustCompile(`bootstrap class path not set in conjunction with -source`),
 
 	regexp.MustCompile(`javadoc: warning - The old Doclet and Taglet APIs in the packages`),
 	regexp.MustCompile(`com.sun.javadoc, com.sun.tools.doclets and their implementations`),

+ 17 - 1
cmd/javac_wrapper/javac_wrapper_test.go

@@ -75,13 +75,29 @@ javadoc: option --boot-class-path not allowed with target 1.9
 `,
 		out: "\n",
 	},
+	{
+		in: `
+warning: [options] bootstrap class path not set in conjunction with -source 1.9\n
+1 warning
+`,
+		out: "\n",
+	},
+	{
+		in: `
+warning: foo
+warning: [options] bootstrap class path not set in conjunction with -source 1.9\n
+2 warnings
+`,
+		out: "\n\x1b[1m\x1b[35mwarning:\x1b[0m\x1b[1m foo\x1b[0m\n1 warning\n",
+	},
 }
 
 func TestJavacColorize(t *testing.T) {
 	for i, test := range testCases {
 		t.Run(strconv.Itoa(i), func(t *testing.T) {
 			buf := new(bytes.Buffer)
-			err := process(bytes.NewReader([]byte(test.in)), buf)
+			proc := processor{}
+			err := proc.process(bytes.NewReader([]byte(test.in)), buf)
 			if err != nil {
 				t.Errorf("error: %q", err)
 			}