go/printer: fix indentation of *ast.CallExpr parameters

The current version of go/printer formats the following code
like this:

	foo.Bar().
		Run(func() {
		do()
	}).
		Set(map[string]interface{}{
		"x": "three",
		"y": 4,
	}).
		Run(
		func() {
			do()
		},
	)

This CL changes the go/printer behaviour to make the code look
like this.

	foo.Bar().
		Run(func() {
			do()
		}).
		Set(map[string]interface{}{
			"x": "three",
			"y": 4,
		}).
		Run(
			func() {
				do()
			},
		)

Fixes #12066.

Change-Id: If0f525dae1a5d45f9ba40534dbb65715d7e8001b
Reviewed-on: https://go-review.googlesource.com/13928
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go
index fe04705..35c017d 100644
--- a/src/go/printer/nodes.go
+++ b/src/go/printer/nodes.go
@@ -747,13 +747,7 @@
 		}
 
 	case *ast.SelectorExpr:
-		p.expr1(x.X, token.HighestPrec, depth)
-		p.print(token.PERIOD)
-		if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
-			p.print(indent, newline, x.Sel.Pos(), x.Sel, unindent)
-		} else {
-			p.print(x.Sel.Pos(), x.Sel)
-		}
+		p.selectorExpr(x, depth, false)
 
 	case *ast.TypeAssertExpr:
 		p.expr1(x.X, token.HighestPrec, depth)
@@ -802,13 +796,14 @@
 		if len(x.Args) > 1 {
 			depth++
 		}
+		var wasIndented bool
 		if _, ok := x.Fun.(*ast.FuncType); ok {
 			// conversions to literal function types require parentheses around the type
 			p.print(token.LPAREN)
-			p.expr1(x.Fun, token.HighestPrec, depth)
+			wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
 			p.print(token.RPAREN)
 		} else {
-			p.expr1(x.Fun, token.HighestPrec, depth)
+			wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
 		}
 		p.print(x.Lparen, token.LPAREN)
 		if x.Ellipsis.IsValid() {
@@ -821,6 +816,9 @@
 			p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen)
 		}
 		p.print(x.Rparen, token.RPAREN)
+		if wasIndented {
+			p.print(unindent)
+		}
 
 	case *ast.CompositeLit:
 		// composite literal elements that are composite literals themselves may have the type omitted
@@ -891,6 +889,30 @@
 	return
 }
 
+func (p *printer) possibleSelectorExpr(expr ast.Expr, prec1, depth int) bool {
+	if x, ok := expr.(*ast.SelectorExpr); ok {
+		return p.selectorExpr(x, depth, true)
+	}
+	p.expr1(expr, prec1, depth)
+	return false
+}
+
+// selectorExpr handles an *ast.SelectorExpr node and returns whether x spans
+// multiple lines.
+func (p *printer) selectorExpr(x *ast.SelectorExpr, depth int, isMethod bool) bool {
+	p.expr1(x.X, token.HighestPrec, depth)
+	p.print(token.PERIOD)
+	if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
+		p.print(indent, newline, x.Sel.Pos(), x.Sel)
+		if !isMethod {
+			p.print(unindent)
+		}
+		return true
+	}
+	p.print(x.Sel.Pos(), x.Sel)
+	return false
+}
+
 func (p *printer) expr0(x ast.Expr, depth int) {
 	p.expr1(x, token.LowestPrec, depth)
 }
diff --git a/src/go/printer/testdata/expressions.golden b/src/go/printer/testdata/expressions.golden
index e3d17a4..cab991f 100644
--- a/src/go/printer/testdata/expressions.golden
+++ b/src/go/printer/testdata/expressions.golden
@@ -567,7 +567,7 @@
 	// handle multiline argument list correctly
 	_ = new(T).
 		foo(
-		1).
+			1).
 		foo(2)
 
 	_ = new(T).foo(
@@ -614,7 +614,7 @@
 		Blob.(*Type).
 		Slices[1:4].
 		Method(1, 2,
-		3).
+			3).
 		Thingy
 
 	_ = a.b.c
@@ -684,3 +684,21 @@
 	_ = (func(x int) float)(nil)
 	_ = (func() func() func())(nil)
 }
+
+func _() {
+	_ = f().
+		f(func() {
+			f()
+		}).
+		f(map[int]int{
+			1:	2,
+			3:	4,
+		})
+
+	_ = f().
+		f(
+			func() {
+				f()
+			},
+		)
+}
diff --git a/src/go/printer/testdata/expressions.input b/src/go/printer/testdata/expressions.input
index d20a593..7c88042 100644
--- a/src/go/printer/testdata/expressions.input
+++ b/src/go/printer/testdata/expressions.input
@@ -713,3 +713,21 @@
 	_ = (func(x int)(float))(nil)
 	_ = (func() func() func()())(nil)
 }
+
+func _() {
+	_ = f().
+	f(func() {
+		f()
+	}).
+	f(map[int]int{
+	1: 2,
+	3: 4,
+})
+
+	_ = f().
+	f(
+	func() {
+		f()
+	},
+	)
+}
diff --git a/src/go/printer/testdata/expressions.raw b/src/go/printer/testdata/expressions.raw
index 2357336..d906062 100644
--- a/src/go/printer/testdata/expressions.raw
+++ b/src/go/printer/testdata/expressions.raw
@@ -567,7 +567,7 @@
 	// handle multiline argument list correctly
 	_ = new(T).
 		foo(
-		1).
+			1).
 		foo(2)
 
 	_ = new(T).foo(
@@ -614,7 +614,7 @@
 		Blob.(*Type).
 		Slices[1:4].
 		Method(1, 2,
-		3).
+			3).
 		Thingy
 
 	_ = a.b.c
@@ -684,3 +684,21 @@
 	_ = (func(x int) float)(nil)
 	_ = (func() func() func())(nil)
 }
+
+func _() {
+	_ = f().
+		f(func() {
+			f()
+		}).
+		f(map[int]int{
+			1:	2,
+			3:	4,
+		})
+
+	_ = f().
+		f(
+			func() {
+				f()
+			},
+		)
+}