// Copyright 2012 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.

// Package types declares the data structures for representing
// Go types and implements typechecking of package files.
//
// WARNING: THE TYPES API IS SUBJECT TO CHANGE.
//
package types

// Most correct programs should now be accepted by the types package,
// but there are several known bugs which permit incorrect programs to
// pass without errors. Please do not file issues against these for now
// since they are known already:
//
// BUG(gri): Method sets are computed loosely and don't distinguish between ptr vs non-pointer receivers.
// BUG(gri): Method expressions and method values work accidentally and may not be fully checked.
// BUG(gri): Conversions of constants only change the type, not the value (e.g., int(1.1) is wrong).
// BUG(gri): Some built-ins don't check parameters fully, yet (e.g. append).
// BUG(gri): Use of labels is not checked.
// BUG(gri): Unused variables and imports are not reported.
// BUG(gri): Unterface vs non-interface comparisons are not correctly implemented.
// BUG(gri): Switch statements don't check correct use of 'fallthrough'.
// BUG(gri): Switch statements don't check duplicate cases for all types for which it is required.
// BUG(gri): Some built-ins may not be callable if in statement-context.
// BUG(gri): Duplicate declarations in different files may not be reported.
// BUG(gri): The type-checker assumes that the input *ast.Files were created by go/parser.

// The API is still slightly in flux and the following changes are considered:
//
// API(gri): Provide accessors uniformly to all fields and do not export fields directly.
// API(gri): Provide scope information for all objects.
// API(gri): Provide position information for all objects.
// API(gri): The semantics of QualifiedIdent needs to be revisited.
// API(gri): Context.Expr needs to distinguish between constants that have unknown value and nil.
// API(gri): Constants need to be passed via a specific Const type rather than interface{}.
// API(gri): The GcImporter should probably be in its own package - it is only one of possible importers.

import (
	"go/ast"
	"go/token"
)

// A Context specifies the supporting context for type checking.
// An empty Context is a ready-to-use default context.
type Context struct {
	// If Error != nil, it is called with each error found
	// during type checking. The error strings of errors with
	// detailed position information are formatted as follows:
	// filename:line:column: message
	Error func(err error)

	// If Ident != nil, it is called for each identifier id
	// denoting an Object in the files provided to Check, and
	// obj is the denoted object.
	// Ident is not called for fields and methods in struct or
	// interface types or composite literals, or for blank (_)
	// or dot (.) identifiers in dot-imports.
	// TODO(gri) Consider making Fields and Methods ordinary
	// Objects - than we could lift this restriction.
	Ident func(id *ast.Ident, obj Object)

	// If Expr != nil, it is called exactly once for each expression x
	// that is type-checked: typ is the expression type, and val is the
	// value if x is constant, val is nil otherwise.
	//
	// If x is a literal value (constant, composite literal), typ is always
	// the dynamic type of x (never an interface type). Otherwise, typ is x's
	// static type (possibly an interface type).
	//
	// Constants are represented as follows:
	//
	//	bool     ->  bool
	//	numeric  ->  int64, *big.Int, *big.Rat, Complex
	//	string   ->  string
	//	nil      ->  NilType
	//
	// Constant values are normalized, that is, they are represented
	// using the "smallest" possible type that can represent the value.
	// For instance, 1.0 is represented as an int64 because it can be
	// represented accurately as an int64.
	Expr func(x ast.Expr, typ Type, val interface{})

	// If Import != nil, it is called for each imported package.
	// Otherwise, GcImporter is called.
	Import Importer

	// If Alignof != nil, it is called to determine the alignment
	// of the given type. Otherwise DefaultAlignmentof is called.
	// Alignof must implement the alignment guarantees required by
	// the spec.
	Alignof func(Type) int64

	// If Offsetsof != nil, it is called to determine the offsets
	// of the given struct fields, in bytes. Otherwise DefaultOffsetsof
	// is called. Offsetsof must implement the offset guarantees
	// required by the spec.
	Offsetsof func(fields []*Field) []int64

	// If Sizeof != nil, it is called to determine the size of the
	// given type. Otherwise, DefaultSizeof is called. Sizeof must
	// implement the size guarantees required by the spec.
	Sizeof func(Type) int64
}

// An Importer resolves import paths to Package objects.
// The imports map records the packages already imported,
// indexed by package id (canonical import path).
// An Importer must determine the canonical import path and
// check the map to see if it is already present in the imports map.
// If so, the Importer can return the map entry.  Otherwise, the
// Importer should load the package data for the given path into
// a new *Package, record pkg in the imports map, and then
// return pkg.
type Importer func(imports map[string]*Package, path string) (pkg *Package, err error)

// Check resolves and typechecks a set of package files within the given
// context. It returns the package and the first error encountered, if
// any. If the context's Error handler is nil, Check terminates as soon
// as the first error is encountered; otherwise it continues until the
// entire package is checked. If there are errors, the package may be
// only partially type-checked, and the resulting package may be incomplete
// (missing objects, imports, etc.).
func (ctxt *Context) Check(fset *token.FileSet, files []*ast.File) (*Package, error) {
	return check(ctxt, fset, files)
}

// Check is shorthand for ctxt.Check where ctxt is a default (empty) context.
func Check(fset *token.FileSet, files []*ast.File) (*Package, error) {
	var ctxt Context
	return ctxt.Check(fset, files)
}
