// Copyright 2016 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 types2

import (
	"cmd/compile/internal/syntax"
	"strings"
	"testing"
)

func parseSrc(path, src string) (*syntax.File, error) {
	return syntax.Parse(syntax.NewFileBase(path), strings.NewReader(src), nil, nil, 0)
}

func TestIsAlias(t *testing.T) {
	check := func(obj *TypeName, want bool) {
		if got := obj.IsAlias(); got != want {
			t.Errorf("%v: got IsAlias = %v; want %v", obj, got, want)
		}
	}

	// predeclared types
	check(Unsafe.Scope().Lookup("Pointer").(*TypeName), false)
	for _, name := range Universe.Names() {
		if obj, _ := Universe.Lookup(name).(*TypeName); obj != nil {
			check(obj, name == "any" || name == "byte" || name == "rune")
		}
	}

	// various other types
	pkg := NewPackage("p", "p")
	t1 := NewTypeName(nopos, pkg, "t1", nil)
	n1 := NewNamed(t1, new(Struct), nil)
	for _, test := range []struct {
		name  *TypeName
		alias bool
	}{
		{NewTypeName(nopos, nil, "t0", nil), false}, // no type yet
		{NewTypeName(nopos, pkg, "t0", nil), false}, // no type yet
		{t1, false}, // type name refers to named type and vice versa
		{NewTypeName(nopos, nil, "t2", &emptyInterface), true}, // type name refers to unnamed type
		{NewTypeName(nopos, pkg, "t3", n1), true},              // type name refers to named type with different type name
		{NewTypeName(nopos, nil, "t4", Typ[Int32]), true},      // type name refers to basic type with different name
		{NewTypeName(nopos, nil, "int32", Typ[Int32]), false},  // type name refers to basic type with same name
		{NewTypeName(nopos, pkg, "int32", Typ[Int32]), true},   // type name is declared in user-defined package (outside Universe)
		{NewTypeName(nopos, nil, "rune", Typ[Rune]), true},     // type name refers to basic type rune which is an alias already
	} {
		check(test.name, test.alias)
	}
}

// TestEmbeddedMethod checks that an embedded method is represented by
// the same Func Object as the original method. See also issue #34421.
func TestEmbeddedMethod(t *testing.T) {
	const src = `package p; type I interface { error }`

	// type-check src
	f, err := parseSrc("", src)
	if err != nil {
		t.Fatalf("parse failed: %s", err)
	}
	var conf Config
	pkg, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
	if err != nil {
		t.Fatalf("typecheck failed: %s", err)
	}

	// get original error.Error method
	eface := Universe.Lookup("error")
	orig, _, _ := LookupFieldOrMethod(eface.Type(), false, nil, "Error")
	if orig == nil {
		t.Fatalf("original error.Error not found")
	}

	// get embedded error.Error method
	iface := pkg.Scope().Lookup("I")
	embed, _, _ := LookupFieldOrMethod(iface.Type(), false, nil, "Error")
	if embed == nil {
		t.Fatalf("embedded error.Error not found")
	}

	// original and embedded Error object should be identical
	if orig != embed {
		t.Fatalf("%s (%p) != %s (%p)", orig, orig, embed, embed)
	}
}
