// Copyright 2015 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 defines the check for unused results of calls to certain
// pure functions.

package main

import (
	"flag"
	"go/ast"
	"go/token"
	"go/types"
	"strings"
)

var unusedFuncsFlag = flag.String("unusedfuncs",
	"errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse",
	"comma-separated list of functions whose results must be used")

var unusedStringMethodsFlag = flag.String("unusedstringmethods",
	"Error,String",
	"comma-separated list of names of methods of type func() string whose results must be used")

func init() {
	register("unusedresult",
		"check for unused result of calls to functions in -unusedfuncs list and methods in -unusedstringmethods list",
		checkUnusedResult,
		exprStmt)
}

// func() string
var sigNoArgsStringResult = types.NewSignature(nil, nil,
	types.NewTuple(types.NewVar(token.NoPos, nil, "", types.Typ[types.String])),
	false)

var unusedFuncs = make(map[string]bool)
var unusedStringMethods = make(map[string]bool)

func initUnusedFlags() {
	commaSplit := func(s string, m map[string]bool) {
		if s != "" {
			for _, name := range strings.Split(s, ",") {
				if len(name) == 0 {
					flag.Usage()
				}
				m[name] = true
			}
		}
	}
	commaSplit(*unusedFuncsFlag, unusedFuncs)
	commaSplit(*unusedStringMethodsFlag, unusedStringMethods)
}

func checkUnusedResult(f *File, n ast.Node) {
	call, ok := unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
	if !ok {
		return // not a call statement
	}
	fun := unparen(call.Fun)

	if f.pkg.types[fun].IsType() {
		return // a conversion, not a call
	}

	selector, ok := fun.(*ast.SelectorExpr)
	if !ok {
		return // neither a method call nor a qualified ident
	}

	sel, ok := f.pkg.selectors[selector]
	if ok && sel.Kind() == types.MethodVal {
		// method (e.g. foo.String())
		obj := sel.Obj().(*types.Func)
		sig := sel.Type().(*types.Signature)
		if types.Identical(sig, sigNoArgsStringResult) {
			if unusedStringMethods[obj.Name()] {
				f.Badf(call.Lparen, "result of (%s).%s call not used",
					sig.Recv().Type(), obj.Name())
			}
		}
	} else if !ok {
		// package-qualified function (e.g. fmt.Errorf)
		obj, _ := f.pkg.uses[selector.Sel]
		if obj, ok := obj.(*types.Func); ok {
			qname := obj.Pkg().Path() + "." + obj.Name()
			if unusedFuncs[qname] {
				f.Badf(call.Lparen, "result of %v call not used", qname)
			}
		}
	}
}
