From aa2dc78830969e4d4f5af17b4dd5b8faba64a415 Mon Sep 17 00:00:00 2001 From: Nevkontakte Date: Sun, 31 Jul 2022 15:43:59 +0100 Subject: [PATCH] Yield explicit errors when encountering typeparams. Even though the compiler was usually able to compile them into _something_, the code was likely incorrect in all cases. To prevent users from tripping up on that the compiler will return an error if it encounters type params until https://github.com/gopherjs/gopherjs/issues/1013 is resolved. --- build/build.go | 2 ++ compiler/natives/src/go/doc/doc_test.go | 37 ++++++++++++++++++++ compiler/natives/src/reflect/reflect_test.go | 3 ++ compiler/package.go | 16 +++++++++ 4 files changed, 58 insertions(+) create mode 100644 compiler/natives/src/go/doc/doc_test.go diff --git a/build/build.go b/build/build.go index 293cd60b2..6b0be814c 100644 --- a/build/build.go +++ b/build/build.go @@ -279,6 +279,8 @@ func parseAndAugment(xctx XContext, pkg *PackageData, isTest bool, fileSet *toke s := spec.(*ast.TypeSpec) if replacedDeclNames[s.Name.Name] { s.Name = ast.NewIdent("_") + s.Type = &ast.StructType{Struct: s.Pos(), Fields: &ast.FieldList{}} + s.TypeParams = nil } } case token.VAR, token.CONST: diff --git a/compiler/natives/src/go/doc/doc_test.go b/compiler/natives/src/go/doc/doc_test.go new file mode 100644 index 000000000..4d35e880c --- /dev/null +++ b/compiler/natives/src/go/doc/doc_test.go @@ -0,0 +1,37 @@ +//go:build js + +package doc + +import ( + "fmt" + "testing" +) + +func compareSlices(t *testing.T, name string, got, want interface{}, compareElem interface{}) { + // TODO(nevkontakte): Remove this override after generics are supported. + // https://github.com/gopherjs/gopherjs/issues/1013. + switch got.(type) { + case []*Func: + got := got.([]*Func) + want := want.([]*Func) + compareElem := compareElem.(func(t *testing.T, msg string, got, want *Func)) + if len(got) != len(want) { + t.Errorf("%s: got %d, want %d", name, len(got), len(want)) + } + for i := 0; i < len(got) && i < len(want); i++ { + compareElem(t, fmt.Sprintf("%s[%d]", name, i), got[i], want[i]) + } + case []*Type: + got := got.([]*Type) + want := want.([]*Type) + compareElem := compareElem.(func(t *testing.T, msg string, got, want *Type)) + if len(got) != len(want) { + t.Errorf("%s: got %d, want %d", name, len(got), len(want)) + } + for i := 0; i < len(got) && i < len(want); i++ { + compareElem(t, fmt.Sprintf("%s[%d]", name, i), got[i], want[i]) + } + default: + t.Errorf("unexpected argument type %T", got) + } +} diff --git a/compiler/natives/src/reflect/reflect_test.go b/compiler/natives/src/reflect/reflect_test.go index 9c3c5668d..0ba5f29d5 100644 --- a/compiler/natives/src/reflect/reflect_test.go +++ b/compiler/natives/src/reflect/reflect_test.go @@ -285,6 +285,9 @@ func TestMethodCallValueCodePtr(t *testing.T) { t.Skip("methodValueCallCodePtr() is not applicable in GopherJS") } +type B struct{} + +//gopherjs:prune-original func TestIssue50208(t *testing.T) { t.Skip("This test required generics, which are not yet supported: https://github.com/gopherjs/gopherjs/issues/1013") } diff --git a/compiler/package.go b/compiler/package.go index 331ccc2c5..a042f216d 100644 --- a/compiler/package.go +++ b/compiler/package.go @@ -6,6 +6,7 @@ import ( "fmt" "go/ast" "go/constant" + "go/scanner" "go/token" "go/types" "sort" @@ -398,6 +399,13 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor var mainFunc *types.Func for _, fun := range functions { o := funcCtx.pkgCtx.Defs[fun.Name].(*types.Func) + + if fun.Type.TypeParams.NumFields() > 0 { + return nil, scanner.Error{ + Pos: fileSet.Position(fun.Type.TypeParams.Pos()), + Msg: fmt.Sprintf("function %s: type parameters are not supported by GopherJS: https://github.com/gopherjs/gopherjs/issues/1013", o.Name()), + } + } funcInfo := funcCtx.pkgCtx.FuncDeclInfos[o] d := Decl{ FullName: o.FullName(), @@ -480,6 +488,14 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor continue } typeName := funcCtx.objectName(o) + + if named, ok := o.Type().(*types.Named); ok && named.TypeParams().Len() > 0 { + return nil, scanner.Error{ + Pos: fileSet.Position(o.Pos()), + Msg: fmt.Sprintf("type %s: type parameters are not supported by GopherJS: https://github.com/gopherjs/gopherjs/issues/1013", o.Name()), + } + } + d := Decl{ Vars: []string{typeName}, DceObjectFilter: o.Name(),