// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements printing of expressions.

package types2

import (
	"bytes"
	"cmd/compile/internal/syntax"
)

// ExprString returns the (possibly shortened) string representation for x.
// Shortened representations are suitable for user interfaces but may not
// necessarily follow Go syntax.
func ExprString(x syntax.Expr) string {
	var buf bytes.Buffer
	WriteExpr(&buf, x)
	return buf.String()
}

// WriteExpr writes the (possibly shortened) string representation for x to buf.
// Shortened representations are suitable for user interfaces but may not
// necessarily follow Go syntax.
func WriteExpr(buf *bytes.Buffer, x syntax.Expr) {
	// The AST preserves source-level parentheses so there is
	// no need to introduce them here to correct for different
	// operator precedences. (This assumes that the AST was
	// generated by a Go parser.)

	// TODO(gri): This assumption is not correct - we need to recreate
	//            parentheses in expressions.

	switch x := x.(type) {
	default:
		buf.WriteString("(ast: bad expr)") // nil, syntax.BadExpr, syntax.KeyValueExpr

	case *syntax.Name:
		buf.WriteString(x.Value)

	case *syntax.DotsType:
		buf.WriteString("...")
		if x.Elem != nil {
			WriteExpr(buf, x.Elem)
		}

	case *syntax.BasicLit:
		buf.WriteString(x.Value)

	case *syntax.FuncLit:
		buf.WriteByte('(')
		WriteExpr(buf, x.Type)
		buf.WriteString(" literal)") // shortened

	case *syntax.CompositeLit:
		buf.WriteByte('(')
		WriteExpr(buf, x.Type)
		buf.WriteString(" literal)") // shortened

	case *syntax.ParenExpr:
		buf.WriteByte('(')
		WriteExpr(buf, x.X)
		buf.WriteByte(')')

	case *syntax.SelectorExpr:
		WriteExpr(buf, x.X)
		buf.WriteByte('.')
		buf.WriteString(x.Sel.Value)

	case *syntax.IndexExpr:
		WriteExpr(buf, x.X)
		buf.WriteByte('[')
		WriteExpr(buf, x.Index) // x.Index may be a *ListExpr
		buf.WriteByte(']')

	case *syntax.SliceExpr:
		WriteExpr(buf, x.X)
		buf.WriteByte('[')
		if x.Index[0] != nil {
			WriteExpr(buf, x.Index[0])
		}
		buf.WriteByte(':')
		if x.Index[1] != nil {
			WriteExpr(buf, x.Index[1])
		}
		if x.Full {
			buf.WriteByte(':')
			if x.Index[2] != nil {
				WriteExpr(buf, x.Index[2])
			}
		}
		buf.WriteByte(']')

	case *syntax.AssertExpr:
		WriteExpr(buf, x.X)
		buf.WriteString(".(")
		WriteExpr(buf, x.Type)
		buf.WriteByte(')')

	case *syntax.CallExpr:
		WriteExpr(buf, x.Fun)
		buf.WriteByte('(')
		writeExprList(buf, x.ArgList)
		if x.HasDots {
			buf.WriteString("...")
		}
		buf.WriteByte(')')

	case *syntax.ListExpr:
		writeExprList(buf, x.ElemList)

	case *syntax.Operation:
		// TODO(gri) This would be simpler if x.X == nil meant unary expression.
		if x.Y == nil {
			// unary expression
			buf.WriteString(x.Op.String())
			WriteExpr(buf, x.X)
		} else {
			// binary expression
			WriteExpr(buf, x.X)
			buf.WriteByte(' ')
			buf.WriteString(x.Op.String())
			buf.WriteByte(' ')
			WriteExpr(buf, x.Y)
		}

		// case *ast.StarExpr:
		// 	buf.WriteByte('*')
		// 	WriteExpr(buf, x.X)

		// case *ast.UnaryExpr:
		// 	buf.WriteString(x.Op.String())
		// 	WriteExpr(buf, x.X)

		// case *ast.BinaryExpr:
		// 	WriteExpr(buf, x.X)
		// 	buf.WriteByte(' ')
		// 	buf.WriteString(x.Op.String())
		// 	buf.WriteByte(' ')
		// 	WriteExpr(buf, x.Y)

	case *syntax.ArrayType:
		if x.Len == nil {
			buf.WriteString("[...]")
		} else {
			buf.WriteByte('[')
			WriteExpr(buf, x.Len)
			buf.WriteByte(']')
		}
		WriteExpr(buf, x.Elem)

	case *syntax.SliceType:
		buf.WriteString("[]")
		WriteExpr(buf, x.Elem)

	case *syntax.StructType:
		buf.WriteString("struct{")
		writeFieldList(buf, x.FieldList, "; ", false)
		buf.WriteByte('}')

	case *syntax.FuncType:
		buf.WriteString("func")
		writeSigExpr(buf, x)

	case *syntax.InterfaceType:
		// separate type list types from method list
		// TODO(gri) we can get rid of this extra code if writeExprList does the separation
		var types []syntax.Expr
		var methods []*syntax.Field
		for _, f := range x.MethodList {
			if f.Name != nil && f.Name.Value == "type" {
				// type list type
				types = append(types, f.Type)
			} else {
				// method or embedded interface
				methods = append(methods, f)
			}
		}

		buf.WriteString("interface{")
		writeFieldList(buf, methods, "; ", true)
		if len(types) > 0 {
			if len(methods) > 0 {
				buf.WriteString("; ")
			}
			buf.WriteString("type ")
			writeExprList(buf, types)
		}
		buf.WriteByte('}')

	case *syntax.MapType:
		buf.WriteString("map[")
		WriteExpr(buf, x.Key)
		buf.WriteByte(']')
		WriteExpr(buf, x.Value)

	case *syntax.ChanType:
		var s string
		switch x.Dir {
		case syntax.SendOnly:
			s = "chan<- "
		case syntax.RecvOnly:
			s = "<-chan "
		default:
			s = "chan "
		}
		buf.WriteString(s)
		if e, _ := x.Elem.(*syntax.ChanType); x.Dir != syntax.SendOnly && e != nil && e.Dir == syntax.RecvOnly {
			// don't print chan (<-chan T) as chan <-chan T (but chan<- <-chan T is ok)
			buf.WriteByte('(')
			WriteExpr(buf, x.Elem)
			buf.WriteByte(')')
		} else {
			WriteExpr(buf, x.Elem)
		}
	}
}

func writeSigExpr(buf *bytes.Buffer, sig *syntax.FuncType) {
	buf.WriteByte('(')
	writeFieldList(buf, sig.ParamList, ", ", false)
	buf.WriteByte(')')

	res := sig.ResultList
	n := len(res)
	if n == 0 {
		// no result
		return
	}

	buf.WriteByte(' ')
	if n == 1 && res[0].Name == nil {
		// single unnamed result
		WriteExpr(buf, res[0].Type)
		return
	}

	// multiple or named result(s)
	buf.WriteByte('(')
	writeFieldList(buf, res, ", ", false)
	buf.WriteByte(')')
}

func writeFieldList(buf *bytes.Buffer, list []*syntax.Field, sep string, iface bool) {
	for i := 0; i < len(list); {
		f := list[i]
		if i > 0 {
			buf.WriteString(sep)
		}

		// if we don't have a name, we have an embedded type
		if f.Name == nil {
			WriteExpr(buf, f.Type)
			i++
			continue
		}

		// types of interface methods consist of signatures only
		if sig, _ := f.Type.(*syntax.FuncType); sig != nil && iface {
			buf.WriteString(f.Name.Value)
			writeSigExpr(buf, sig)
			i++
			continue
		}

		// write the type only once for a sequence of fields with the same type
		t := f.Type
		buf.WriteString(f.Name.Value)
		for i++; i < len(list) && list[i].Type == t; i++ {
			buf.WriteString(", ")
			buf.WriteString(list[i].Name.Value)
		}
		buf.WriteByte(' ')
		WriteExpr(buf, t)
	}
}

func writeExprList(buf *bytes.Buffer, list []syntax.Expr) {
	for i, x := range list {
		if i > 0 {
			buf.WriteString(", ")
		}
		WriteExpr(buf, x)
	}
}
