github.com/goplus/gogen@v1.16.0/error_msg_test.go (about) 1 /* 2 Copyright 2021 The GoPlus Authors (goplus.org) 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 */ 13 14 package gogen_test 15 16 import ( 17 "bytes" 18 "fmt" 19 "go/ast" 20 "go/token" 21 "go/types" 22 "path/filepath" 23 "runtime" 24 "strconv" 25 "strings" 26 "sync" 27 "testing" 28 29 "github.com/goplus/gogen" 30 xtoken "github.com/goplus/gogen/token" 31 ) 32 33 type txtNode struct { 34 Msg string 35 pos token.Pos 36 } 37 38 func (p *txtNode) Pos() token.Pos { 39 return p.pos 40 } 41 42 func (p *txtNode) End() token.Pos { 43 return p.pos + token.Pos(len(p.Msg)) 44 } 45 46 var ( 47 mutex sync.Mutex 48 pos2Positions = map[token.Pos]token.Position{} 49 ) 50 51 // text, line, column 52 func source(text string, args ...interface{}) ast.Node { 53 if len(args) < 2 { 54 return &txtNode{Msg: text} 55 } 56 pos := position(args[0].(int), args[1].(int)) 57 return &txtNode{Msg: text, pos: pos} 58 } 59 60 const ( 61 posBits = 16 62 posMask = (1 << posBits) - 1 63 ) 64 65 func position(line, column int) token.Pos { 66 mutex.Lock() 67 defer mutex.Unlock() 68 69 pos := token.Pos(len(pos2Positions)+1) << posBits 70 pos2Positions[pos] = token.Position{Filename: "./foo.gop", Line: line, Column: column} 71 return pos 72 } 73 74 type nodeInterp struct{} 75 76 func (p nodeInterp) Position(pos token.Pos) (ret token.Position) { 77 mutex.Lock() 78 defer mutex.Unlock() 79 ret = pos2Positions[(pos &^ posMask)] 80 ret.Column += int(pos & posMask) 81 return 82 } 83 84 func (p nodeInterp) Caller(node ast.Node) string { 85 t := node.(*txtNode) 86 idx := strings.Index(t.Msg, "(") 87 if idx > 0 { 88 return t.Msg[:idx] 89 } 90 return t.Msg 91 } 92 93 func (p nodeInterp) LoadExpr(node ast.Node) string { 94 t := node.(*txtNode) 95 return t.Msg 96 } 97 98 func codeErrorTest(t *testing.T, msg string, source func(pkg *gogen.Package), disableRecover ...bool) { 99 t.Run(msg, func(t *testing.T) { 100 pkg := newMainPackage() 101 codeErrorTestDo(t, pkg, msg, source, disableRecover...) 102 }) 103 } 104 105 func codeErrorTestEx(t *testing.T, pkg *gogen.Package, msg string, source func(pkg *gogen.Package), disableRecover ...bool) { 106 t.Run(msg, func(t *testing.T) { 107 codeErrorTestDo(t, pkg, msg, source, disableRecover...) 108 }) 109 } 110 111 func codeErrorTestDo(t *testing.T, pkg *gogen.Package, msg string, source func(pkg *gogen.Package), disableRecover ...bool) { 112 pos2Positions = map[token.Pos]token.Position{} 113 if !(disableRecover != nil && disableRecover[0]) { 114 defer func() { 115 if e := recover(); e != nil { 116 switch err := e.(type) { 117 case *gogen.CodeError, *gogen.MatchError: 118 defer recover() 119 pkg.CB().ResetStmt() 120 if ret := err.(error).Error(); ret != msg { 121 t.Fatalf("\nError: \"%s\"\nExpected: \"%s\"\n", ret, msg) 122 } 123 case *gogen.ImportError: 124 if ret := err.Error(); ret != msg { 125 t.Fatalf("\nError: \"%s\"\nExpected: \"%s\"\n", ret, msg) 126 } 127 case error: 128 if ret := err.Error(); ret != msg { 129 t.Fatalf("\nError: \"%s\"\nExpected: \"%s\"\n", ret, msg) 130 } 131 default: 132 t.Fatalf("Unexpected error: %v (%T)\n", e, e) 133 } 134 } else { 135 t.Fatal("no error?") 136 } 137 }() 138 } 139 source(pkg) 140 var b bytes.Buffer 141 gogen.WriteTo(&b, pkg, "") 142 } 143 144 func newFunc( 145 pkg *gogen.Package, line, column int, rline, rcolumn int, 146 recv *gogen.Param, name string, params, results *types.Tuple, variadic bool) *gogen.Func { 147 pos := position(line, column) 148 fn, err := pkg.NewFuncWith( 149 pos, name, types.NewSignatureType(recv, nil, nil, params, results, variadic), func() token.Pos { 150 return position(rline, rcolumn) 151 }) 152 if err != nil { 153 panic(err) 154 } 155 return fn 156 } 157 158 func TestErrIf(t *testing.T) { 159 codeErrorTest(t, "./foo.gop:1:3: non-boolean condition in if statement", 160 func(pkg *gogen.Package) { 161 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 162 If().Val(1, source("1", 1, 3)).Then(source("1", 1, 3)). // if 1 163 End() 164 }) 165 } 166 167 func TestErrSwitch(t *testing.T) { 168 codeErrorTest(t, "./foo.gop:2:5: cannot use 1 (type untyped int) as type string", 169 func(pkg *gogen.Package) { 170 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 171 Switch().Val(`"x"`, source("x", 1, 3)).Then(). // switch "x" 172 Case().Val(1, source("1", 2, 5)).Val(2).Then(). // case 1, 2: 173 /**/ End(). 174 End() 175 }) 176 codeErrorTest(t, "./foo.gop:2:5: cannot use 1 (type untyped int) as type bool", 177 func(pkg *gogen.Package) { 178 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 179 Switch().None().Then(). // switch 180 Case().Val(1, source("1", 2, 5)).Val(2).Then(). // case 1, 2: 181 /**/ End(). 182 End() 183 }) 184 } 185 186 func TestErrTypeRedefined(t *testing.T) { 187 codeErrorTest(t, "./foo.gop:2:5: foo redeclared in this block\n\tprevious declaration at ./foo.gop:1:5", func(pkg *gogen.Package) { 188 typ := pkg.NewType("foo", source("foo", 1, 5)) 189 if typ.Inited() { 190 t.Fatal("NewType failed: inited?") 191 } 192 pkg.NewType("foo", source("foo", 2, 5)) 193 }) 194 } 195 196 func TestErrTypeSwitch(t *testing.T) { 197 codeErrorTest(t, "./foo.gop:2:9: impossible type switch case: v (type interface{Bar()}) cannot have dynamic type int (missing Bar method)", 198 func(pkg *gogen.Package) { 199 methods := []*types.Func{ 200 types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)), 201 } 202 tyInterf := types.NewInterfaceType(methods, nil).Complete() 203 v := pkg.NewParam(token.NoPos, "v", tyInterf) 204 pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). 205 /**/ TypeSwitch("t").Val(v, source("v", 1, 5)).TypeAssertThen(). 206 /**/ TypeCase().Typ(types.Typ[types.Int], source("int", 2, 9)).Then(). 207 /**/ End(). 208 End() 209 }) 210 codeErrorTest(t, "./foo.gop:2:9: 1 (type untyped int) is not a type", 211 func(pkg *gogen.Package) { 212 v := pkg.NewParam(token.NoPos, "v", gogen.TyEmptyInterface) 213 pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). 214 /**/ TypeSwitch("t").Val(v).TypeAssertThen(). 215 /**/ TypeCase().Val(1, source("1", 2, 9)).Then(). 216 /**/ End(). 217 End() 218 }) 219 } 220 221 func TestErrAssignOp(t *testing.T) { 222 codeErrorTest(t, `boundType untyped int => string failed`, 223 func(pkg *gogen.Package) { 224 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 225 NewVar(types.Typ[types.String], "a"). 226 VarRef(ctxRef(pkg, "a"), source("a")).Val(10).AssignOp(token.ADD_ASSIGN). 227 End() 228 }) 229 } 230 231 func TestErrBinaryOp(t *testing.T) { 232 codeErrorTest(t, `-: invalid operation: * (mismatched types int and float64)`, 233 func(pkg *gogen.Package) { 234 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 235 NewVar(types.Typ[types.Int], "a"). 236 NewVar(types.Typ[types.Float64], "b"). 237 VarVal("a").VarVal("b").BinaryOp(token.MUL).EndStmt(). 238 End() 239 }) 240 codeErrorTest(t, `./foo.gop:2:9: invalid operation: a * b (mismatched types int and float64)`, 241 func(pkg *gogen.Package) { 242 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 243 NewVar(types.Typ[types.Int], "a"). 244 NewVar(types.Typ[types.Float64], "b"). 245 VarVal("a").VarVal("b").BinaryOp(token.MUL, source(`a * b`, 2, 9)).EndStmt(). 246 End() 247 }) 248 codeErrorTest(t, `./foo.gop:2:9: invalid operation: v != 3 (mismatched types interface{Bar()} and untyped int)`, 249 func(pkg *gogen.Package) { 250 methods := []*types.Func{ 251 types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)), 252 } 253 tyInterf := types.NewInterfaceType(methods, nil).Complete() 254 params := types.NewTuple(pkg.NewParam(token.NoPos, "v", tyInterf)) 255 pkg.NewFunc(nil, "foo", params, nil, false).BodyStart(pkg). 256 /**/ If().VarVal("v").Val(3).BinaryOp(token.NEQ, source(`v != 3`, 2, 9)).Then(). 257 /**/ End(). 258 End() 259 }) 260 codeErrorTest(t, `./foo.gop:2:9: invalid operation: sl == v (mismatched types []int and interface{Bar()})`, 261 func(pkg *gogen.Package) { 262 methods := []*types.Func{ 263 types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)), 264 } 265 tyInterf := types.NewInterfaceType(methods, nil).Complete() 266 params := types.NewTuple(pkg.NewParam(token.NoPos, "v", tyInterf)) 267 pkg.NewFunc(nil, "foo", params, nil, false).BodyStart(pkg). 268 NewVar(types.NewSlice(types.Typ[types.Int]), "sl"). 269 /**/ If().Val(ctxRef(pkg, "sl")).VarVal("v").BinaryOp(token.EQL, source(`sl == v`, 2, 9)).Then(). 270 /**/ End(). 271 End() 272 }) 273 codeErrorTest(t, `./foo.gop:2:9: invalid operation: 3 == "Hi" (mismatched types untyped int and untyped string)`, 274 func(pkg *gogen.Package) { 275 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 276 /**/ If().Val(3).Val("Hi").BinaryOp(token.EQL, source(`3 == "Hi"`, 2, 9)).Then(). 277 /**/ End(). 278 End() 279 }) 280 } 281 282 func TestErrBinaryOp2(t *testing.T) { 283 codeErrorTest(t, `-: invalid operation: operator <> not defined on a (int)`, 284 func(pkg *gogen.Package) { 285 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 286 NewVar(types.Typ[types.Int], "a"). 287 NewVar(types.Typ[types.Int], "b"). 288 VarVal("a", source("a")).VarVal("b").BinaryOp(xtoken.BIDIARROW).EndStmt(). 289 End() 290 }) 291 } 292 293 func TestErrTypeAssert(t *testing.T) { 294 codeErrorTest(t, "./foo.gop:2:9: impossible type assertion:\n\tstring does not implement bar (missing Bar method)", 295 func(pkg *gogen.Package) { 296 methods := []*types.Func{ 297 types.NewFunc(token.NoPos, pkg.Types, "Bar", types.NewSignatureType(nil, nil, nil, nil, nil, false)), 298 } 299 tyInterf := types.NewInterfaceType(methods, nil).Complete() 300 bar := pkg.NewType("bar").InitType(pkg, tyInterf) 301 params := types.NewTuple(pkg.NewParam(token.NoPos, "v", bar)) 302 pkg.NewFunc(nil, "foo", params, nil, false).BodyStart(pkg). 303 DefineVarStart(0, "x").VarVal("v"). 304 TypeAssert(types.Typ[types.String], false, source("v.(string)", 2, 9)).EndInit(1). 305 End() 306 }) 307 codeErrorTest(t, "./foo.gop:2:9: invalid type assertion: v.(string) (non-interface type int on left)", 308 func(pkg *gogen.Package) { 309 params := types.NewTuple(pkg.NewParam(token.NoPos, "v", types.Typ[types.Int])) 310 pkg.NewFunc(nil, "foo", params, nil, false).BodyStart(pkg). 311 DefineVarStart(0, "x").VarVal("v"). 312 TypeAssert(types.Typ[types.String], false, source("v.(string)", 2, 9)).EndInit(1). 313 End() 314 }) 315 } 316 317 func TestErrConst(t *testing.T) { 318 codeErrorTest(t, "./foo.gop:2:9: cannot use 1 (type untyped int) as type string in assignment", 319 func(pkg *gogen.Package) { 320 pkg.NewConstStart(pkg.Types.Scope(), position(2, 7), types.Typ[types.String], "a").Val(1, source("1", 2, 9)).EndInit(1) 321 }) 322 codeErrorTest(t, "./foo.gop:2:7: missing value in const declaration", 323 func(pkg *gogen.Package) { 324 pkg.NewConstStart(pkg.Types.Scope(), position(2, 7), nil, "a", "b").Val(1).EndInit(1) 325 }) 326 codeErrorTest(t, "./foo.gop:2:7: extra expression in const declaration", 327 func(pkg *gogen.Package) { 328 pkg.NewConstStart(pkg.Types.Scope(), position(2, 7), nil, "a").Val(1).Val(2).EndInit(2) 329 }) 330 codeErrorTest(t, "./foo.gop:2:7: a redeclared in this block\n\tprevious declaration at ./foo.gop:1:5", 331 func(pkg *gogen.Package) { 332 pkg.NewVarStart(position(1, 5), nil, "a").Val(1).EndInit(1) 333 pkg.NewConstStart(pkg.Types.Scope(), position(2, 7), nil, "a").Val(2).EndInit(1) 334 }) 335 codeErrorTest(t, "./foo.gop:2:7: a redeclared in this block\n\tprevious declaration at ./foo.gop:1:5", 336 func(pkg *gogen.Package) { 337 scope := pkg.Types.Scope() 338 pkg.NewConstStart(scope, position(1, 5), nil, "a").Val(2).EndInit(1) 339 pkg.NewVarDefs(scope).New(position(2, 7), types.Typ[types.Int], "a").InitStart(pkg).Val(1).EndInit(1) 340 }) 341 codeErrorTest(t, "./foo.gop:2:7: const initializer len(a) is not a constant", 342 func(pkg *gogen.Package) { 343 pkg.NewVar(position(1, 5), types.NewSlice(types.Typ[types.Int]), "a") 344 pkg.NewConstStart(pkg.Types.Scope(), position(2, 7), nil, "b"). 345 Val(ctxRef(pkg, "len")).VarVal("a").CallWith(1, 0, source("len(a)", 2, 10)).EndInit(1) 346 }) 347 codeErrorTest(t, "./foo.gop:2:9: a redeclared in this block\n\tprevious declaration at ./foo.gop:1:5", 348 func(pkg *gogen.Package) { 349 pkg.NewVarStart(position(1, 5), nil, "a").Val(1).EndInit(1) 350 pkg.NewConstDefs(pkg.Types.Scope()). 351 New(func(cb *gogen.CodeBuilder) int { 352 cb.Val(2) 353 return 1 354 }, 0, position(2, 7), nil, "_"). 355 Next(1, position(2, 9), "a") 356 }) 357 codeErrorTest(t, "./foo.gop:2:9: extra expression in const declaration", 358 func(pkg *gogen.Package) { 359 pkg.NewConstDefs(pkg.Types.Scope()). 360 New(func(cb *gogen.CodeBuilder) int { 361 cb.Val(2) 362 cb.Val(ctxRef(pkg, "iota")) 363 return 2 364 }, 0, position(2, 7), nil, "a", "b"). 365 Next(1, position(2, 9), "c") 366 }) 367 codeErrorTest(t, "./foo.gop:2:9: missing value in const declaration", 368 func(pkg *gogen.Package) { 369 pkg.NewConstDefs(pkg.Types.Scope()). 370 New(func(cb *gogen.CodeBuilder) int { 371 cb.Val(2) 372 cb.Val(ctxRef(pkg, "iota")) 373 return 2 374 }, 0, position(2, 7), nil, "a", "b"). 375 Next(1, position(2, 9), "c", "d", "e") 376 }) 377 } 378 379 func TestErrNewVar(t *testing.T) { 380 codeErrorTest(t, "./foo.gop:2:6: foo redeclared in this block\n\tprevious declaration at ./foo.gop:1:5", 381 func(pkg *gogen.Package) { 382 var x *types.Var 383 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 384 NewAutoVar(position(1, 5), "foo", &x). 385 NewAutoVar(position(2, 6), "foo", &x). 386 End() 387 }) 388 codeErrorTest(t, "./foo.gop:2:9: cannot use 1 (type untyped int) as type string in assignment", 389 func(pkg *gogen.Package) { 390 pkg.NewVarStart(position(2, 7), types.Typ[types.String], "a").Val(1, source("1", 2, 9)).EndInit(1) 391 }) 392 codeErrorTest(t, "./foo.gop:2:7: assignment mismatch: 1 variables but fmt.Println returns 2 values", 393 func(pkg *gogen.Package) { 394 fmt := pkg.Import("fmt") 395 pkg.NewVarStart(position(2, 7), nil, "a"). 396 Val(fmt.Ref("Println")).Val(2).CallWith(1, 0, source("fmt.Println(2)", 2, 11)).EndInit(1) 397 }) 398 codeErrorTest(t, "./foo.gop:2:7: assignment mismatch: 1 variables but 2 values", 399 func(pkg *gogen.Package) { 400 pkg.NewVarStart(position(2, 7), nil, "a").Val(1).Val(2).EndInit(2) 401 }) 402 codeErrorTest(t, "./foo.gop:2:7: assignment mismatch: 2 variables but 1 values", 403 func(pkg *gogen.Package) { 404 pkg.NewVarStart(position(2, 7), nil, "a", "b").Val(2).EndInit(1) 405 }) 406 codeErrorTest(t, "./foo.gop:2:7: a redeclared in this block\n\tprevious declaration at ./foo.gop:1:5", 407 func(pkg *gogen.Package) { 408 pkg.NewVarStart(position(1, 5), nil, "a").Val(1).EndInit(1) 409 pkg.NewVarStart(position(2, 7), nil, "a").Val(2).EndInit(1) 410 }) 411 } 412 413 func TestErrDefineVar(t *testing.T) { 414 handleErr = func(err error) { 415 if err.Error() != "./foo.gop:2:1: no new variables on left side of :=" { 416 t.Fatal("TestErrDefineVar:", err) 417 } 418 } 419 codeErrorTest(t, `./foo.gop:2:6: cannot use "Hi" (type untyped string) as type int in assignment`, 420 func(pkg *gogen.Package) { 421 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 422 DefineVarStart(0, "foo").Val(1).EndInit(1). 423 DefineVarStart(position(2, 1), "foo").Val("Hi", source(`"Hi"`, 2, 6)).EndInit(1). 424 End() 425 }) 426 } 427 428 func TestErrForRange(t *testing.T) { 429 codeErrorTest(t, `./foo.gop:1:17: can't use return/continue/break/goto in for range of udt.Gop_Enum(callback)`, 430 func(pkg *gogen.Package) { 431 foo := pkg.Import("github.com/goplus/gogen/internal/foo") 432 bar := foo.Ref("Foo2").Type() 433 v := pkg.NewParam(token.NoPos, "v", types.NewPointer(bar)) 434 pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). 435 ForRange("a", "b"). 436 Val(v, source("v", 1, 9)). 437 RangeAssignThen(position(1, 17)). 438 Return(0). 439 End(). 440 End() 441 }) 442 codeErrorTest(t, `./foo.gop:1:17: cannot range over v (type *github.com/goplus/gogen/internal/foo.Foo4)`, 443 func(pkg *gogen.Package) { 444 foo := pkg.Import("github.com/goplus/gogen/internal/foo") 445 bar := foo.Ref("Foo4").Type() 446 v := pkg.NewParam(token.NoPos, "v", types.NewPointer(bar)) 447 pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). 448 ForRange(). 449 Val(v, source("v", 1, 9)). 450 RangeAssignThen(position(1, 17)). 451 End(). 452 End() 453 }) 454 codeErrorTest(t, `./foo.gop:1:17: cannot range over v (type *github.com/goplus/gogen/internal/foo.Foo3)`, 455 func(pkg *gogen.Package) { 456 foo := pkg.Import("github.com/goplus/gogen/internal/foo") 457 bar := foo.Ref("Foo3").Type() 458 v := pkg.NewParam(token.NoPos, "v", types.NewPointer(bar)) 459 pkg.NewFunc(nil, "foo", types.NewTuple(v), nil, false).BodyStart(pkg). 460 ForRange("a", "b"). 461 Val(v, source("v", 1, 9)). 462 RangeAssignThen(position(1, 17)). 463 End(). 464 End() 465 }) 466 codeErrorTest(t, `./foo.gop:1:17: cannot range over 13 (type untyped int)`, 467 func(pkg *gogen.Package) { 468 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 469 ForRange("a", "b"). 470 Val(13, source("13", 1, 9)). 471 RangeAssignThen(position(1, 17)). 472 End(). 473 End() 474 }) 475 codeErrorTest(t, `./foo.gop:1:17: cannot range over 13 (type untyped int)`, 476 func(pkg *gogen.Package) { 477 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 478 NewVar(types.Typ[types.Int], "a"). 479 ForRange(). 480 VarRef(ctxRef(pkg, "a")). 481 Val(13, source("13", 1, 9)). 482 RangeAssignThen(position(1, 17)). 483 End(). 484 End() 485 }) 486 codeErrorTest(t, `./foo.gop:1:17: too many variables in range`, 487 func(pkg *gogen.Package) { 488 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 489 NewVar(types.Typ[types.Int], "a", "b", "c"). 490 ForRange(). 491 VarRef(ctxRef(pkg, "a")). 492 VarRef(ctxRef(pkg, "b")). 493 VarRef(ctxRef(pkg, "c")). 494 Val("Hello"). 495 RangeAssignThen(position(1, 17)). 496 End(). 497 End() 498 }) 499 codeErrorTest(t, `./foo.gop:1:17: too many variables in range`, 500 func(pkg *gogen.Package) { 501 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 502 ForRange("a", "b", "c"). 503 Val("Hello"). 504 RangeAssignThen(position(1, 17)). 505 End(). 506 End() 507 }) 508 codeErrorTest(t, `./foo.gop:1:5: cannot assign type string to a (type int) in range`, 509 func(pkg *gogen.Package) { 510 tySlice := types.NewSlice(types.Typ[types.String]) 511 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 512 DefineVarStart(0, "a").Val(1).EndInit(1). 513 NewVar(tySlice, "b"). 514 ForRange(). 515 VarRef(nil). 516 VarRef(ctxRef(pkg, "a"), source("a", 1, 5)). 517 Val(ctxRef(pkg, "b"), source("b", 1, 9)). 518 RangeAssignThen(token.NoPos). 519 End(). 520 End() 521 }) 522 } 523 524 func TestErrAssign(t *testing.T) { 525 codeErrorTest(t, "./foo.gop:1:3: assignment mismatch: 1 variables but bar returns 2 values", 526 func(pkg *gogen.Package) { 527 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 528 retErr := pkg.NewParam(position(1, 15), "", gogen.TyError) 529 newFunc(pkg, 3, 5, 3, 7, nil, "bar", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg).End() 530 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 531 NewVar(types.Typ[types.Int], "x"). 532 VarRef(ctxRef(pkg, "x")). 533 Val(ctxRef(pkg, "bar")). 534 CallWith(0, 0, source("bar()", 1, 5)). 535 AssignWith(1, 1, source("x = bar()", 1, 3)). 536 End() 537 }) 538 codeErrorTest(t, "./foo.gop:1:3: assignment mismatch: 1 variables but 2 values", 539 func(pkg *gogen.Package) { 540 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 541 NewVar(types.Typ[types.Int], "x"). 542 VarRef(ctxRef(pkg, "x")). 543 Val(1).Val(2). 544 AssignWith(1, 2, source("x = 1, 2", 1, 3)). 545 End() 546 }) 547 } 548 549 func TestErrFunc(t *testing.T) { 550 codeErrorTest(t, `./foo.gop:5:1: main redeclared in this block 551 ./foo.gop:1:10: other declaration of main`, 552 func(pkg *gogen.Package) { 553 sig := types.NewSignatureType(nil, nil, nil, nil, nil, false) 554 pkg.NewFuncDecl(position(1, 10), "main", sig).BodyStart(pkg).End() 555 pkg.NewFuncDecl(position(5, 1), "main", sig).BodyStart(pkg).End() 556 }) 557 } 558 559 func TestErrFuncCall(t *testing.T) { 560 codeErrorTest(t, `./foo.gop:2:10: cannot call non-function a() (type int)`, 561 func(pkg *gogen.Package) { 562 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 563 NewVar(types.Typ[types.Int], "a"). 564 VarVal("a").CallWith(0, 0, source("a()", 2, 10)). 565 End() 566 }) 567 codeErrorTest(t, `./foo.gop:2:10: cannot use ... in call to non-variadic foo`, 568 func(pkg *gogen.Package) { 569 pkg.NewFunc(nil, "foo", nil, nil, false).BodyStart(pkg). 570 NewVar(types.Typ[types.Int], "a"). 571 Val(ctxRef(pkg, "foo"), source("foo", 2, 2)).VarVal("a").CallWith(1, 1, source("foo(a...)", 2, 10)). 572 End() 573 }) 574 codeErrorTest(t, `./foo.gop:3:5: cannot use a (type bool) as type int in argument to foo(a)`, 575 func(pkg *gogen.Package) { 576 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 577 newFunc(pkg, 1, 5, 1, 7, nil, "foo", types.NewTuple(retInt), nil, false).BodyStart(pkg). 578 End() 579 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 580 Debug(func(cb *gogen.CodeBuilder) { 581 pkg.NewVar(position(2, 9), types.Typ[types.Bool], "a") 582 }). 583 Val(ctxRef(pkg, "foo")).Val(ctxRef(pkg, "a"), source("a", 3, 5)). 584 CallWith(1, 0, source("foo(a)", 3, 10)). 585 End() 586 }) 587 codeErrorTest(t, `./foo.gop:2:10: not enough arguments in call to foo 588 have (int) 589 want (int, int)`, 590 func(pkg *gogen.Package) { 591 argInt1 := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 592 argInt2 := pkg.NewParam(position(1, 15), "", types.Typ[types.Int]) 593 pkg.NewFunc(nil, "foo", types.NewTuple(argInt1, argInt2), nil, false).BodyStart(pkg). 594 NewVar(types.Typ[types.Int], "a"). 595 Val(ctxRef(pkg, "foo"), source("foo", 2, 2)).VarVal("a").CallWith(1, 0, source("foo(a)", 2, 10)). 596 End() 597 598 }) 599 codeErrorTest(t, `./foo.gop:2:10: too many arguments in call to foo 600 have (int, untyped int, untyped int) 601 want (int, int)`, 602 func(pkg *gogen.Package) { 603 argInt1 := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 604 argInt2 := pkg.NewParam(position(1, 15), "", types.Typ[types.Int]) 605 pkg.NewFunc(nil, "foo", types.NewTuple(argInt1, argInt2), nil, false).BodyStart(pkg). 606 NewVar(types.Typ[types.Int], "a"). 607 Val(ctxRef(pkg, "foo"), source("foo", 2, 2)).VarVal("a").Val(1).Val(2).CallWith(3, 0, source("foo(a, 1, 2)", 2, 10)). 608 End() 609 610 }) 611 codeErrorTest(t, `./foo.gop:2:10: not enough arguments in call to foo 612 have (int) 613 want (int, int, []int)`, 614 func(pkg *gogen.Package) { 615 argInt1 := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 616 argInt2 := pkg.NewParam(position(1, 15), "", types.Typ[types.Int]) 617 argIntSlice3 := pkg.NewParam(position(1, 20), "", types.NewSlice(types.Typ[types.Int])) 618 pkg.NewFunc(nil, "foo", types.NewTuple(argInt1, argInt2, argIntSlice3), nil, true).BodyStart(pkg). 619 NewVar(types.Typ[types.Int], "a"). 620 Val(ctxRef(pkg, "foo"), source("foo", 2, 2)).VarVal("a").CallWith(1, 0, source("foo(a)", 2, 10)). 621 End() 622 }) 623 } 624 625 func TestErrReturn(t *testing.T) { 626 codeErrorTest(t, `./foo.gop:2:9: cannot use "Hi" (type untyped string) as type error in return argument`, 627 func(pkg *gogen.Package) { 628 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 629 retErr := pkg.NewParam(position(1, 15), "", gogen.TyError) 630 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg). 631 Val(1, source("1", 2, 7)). 632 Val("Hi", source(`"Hi"`, 2, 9)). 633 Return(2, source(`return 1, "Hi"`, 2, 5)). 634 End() 635 }) 636 codeErrorTest(t, "./foo.gop:2:5: cannot use byte value as type error in return argument", 637 func(pkg *gogen.Package) { 638 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 639 retErr := pkg.NewParam(position(1, 15), "", gogen.TyError) 640 retInt2 := pkg.NewParam(position(3, 10), "", types.Typ[types.Int]) 641 retByte := pkg.NewParam(position(3, 15), "", gogen.TyByte) 642 newFunc(pkg, 3, 5, 3, 7, nil, "bar", nil, types.NewTuple(retInt2, retByte), false).BodyStart(pkg).End() 643 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg). 644 Val(ctxRef(pkg, "bar")). 645 CallWith(0, 0, source("bar()", 2, 9)). 646 Return(1, source("return bar()", 2, 5)). 647 End() 648 }) 649 codeErrorTest(t, "./foo.gop:2:5: too many arguments to return\n\thave (untyped int, untyped int, untyped int)\n\twant (int, error)", 650 func(pkg *gogen.Package) { 651 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 652 retErr := pkg.NewParam(position(1, 15), "", gogen.TyError) 653 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg). 654 Val(1, source("1", 2, 7)). 655 Val(2, source("2", 2, 9)). 656 Val(3, source("3", 2, 11)). 657 Return(3, source("return 1, 2, 3", 2, 5)). 658 End() 659 }) 660 codeErrorTest(t, "./foo.gop:2:5: too few arguments to return\n\thave (untyped int)\n\twant (int, error)", 661 func(pkg *gogen.Package) { 662 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 663 retErr := pkg.NewParam(position(1, 15), "", gogen.TyError) 664 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg). 665 Val(1, source("1", 2, 7)). 666 Return(1, source("return 1", 2, 5)). 667 End() 668 }) 669 codeErrorTest(t, "./foo.gop:2:5: too few arguments to return\n\thave (byte)\n\twant (int, error)", 670 func(pkg *gogen.Package) { 671 retInt := pkg.NewParam(position(1, 10), "", types.Typ[types.Int]) 672 retErr := pkg.NewParam(position(1, 15), "", gogen.TyError) 673 ret := pkg.NewParam(position(3, 10), "", gogen.TyByte) 674 newFunc(pkg, 3, 5, 3, 7, nil, "bar", nil, types.NewTuple(ret), false).BodyStart(pkg).End() 675 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg). 676 Val(ctxRef(pkg, "bar")). 677 CallWith(0, 0, source("bar()", 2, 9)). 678 Return(1, source("return bar()", 2, 5)). 679 End() 680 }) 681 codeErrorTest(t, "./foo.gop:2:5: too many arguments to return\n\thave (int, error)\n\twant (byte)", 682 func(pkg *gogen.Package) { 683 retInt := pkg.NewParam(position(3, 10), "", types.Typ[types.Int]) 684 retErr := pkg.NewParam(position(3, 15), "", gogen.TyError) 685 newFunc(pkg, 3, 5, 3, 7, nil, "bar", nil, types.NewTuple(retInt, retErr), false).BodyStart(pkg).End() 686 ret := pkg.NewParam(position(1, 10), "", gogen.TyByte) 687 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(ret), false).BodyStart(pkg). 688 Val(ctxRef(pkg, "bar")). 689 CallWith(0, 0, source("bar()", 2, 9)). 690 Return(1, source("return bar()", 2, 5)). 691 End() 692 }) 693 codeErrorTest(t, "./foo.gop:2:5: not enough arguments to return\n\thave ()\n\twant (byte)", 694 func(pkg *gogen.Package) { 695 ret := pkg.NewParam(position(1, 10), "", gogen.TyByte) 696 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, types.NewTuple(ret), false).BodyStart(pkg). 697 Return(0, source("return", 2, 5)). 698 End() 699 }) 700 } 701 702 func TestErrInitFunc(t *testing.T) { 703 codeErrorTest(t, "./foo.gop:1:5: func init must have no arguments and no return values", func(pkg *gogen.Package) { 704 v := pkg.NewParam(token.NoPos, "v", gogen.TyByte) 705 newFunc(pkg, 1, 5, 1, 7, nil, "init", types.NewTuple(v), nil, false).BodyStart(pkg).End() 706 }) 707 } 708 709 func TestErrRecv(t *testing.T) { 710 tySlice := types.NewSlice(gogen.TyByte) 711 codeErrorTest(t, "./foo.gop:1:9: invalid receiver type []byte ([]byte is not a defined type)", func(pkg *gogen.Package) { 712 recv := pkg.NewParam(position(1, 7), "p", tySlice) 713 newFunc(pkg, 1, 5, 1, 9, recv, "foo", nil, nil, false).BodyStart(pkg).End() 714 }) 715 codeErrorTest(t, "./foo.gop:2:9: invalid receiver type []byte ([]byte is not a defined type)", func(pkg *gogen.Package) { 716 recv := pkg.NewParam(position(2, 7), "p", types.NewPointer(tySlice)) 717 newFunc(pkg, 2, 6, 2, 9, recv, "foo", nil, nil, false).BodyStart(pkg).End() 718 }) 719 codeErrorTest(t, "./foo.gop:3:10: invalid receiver type error (error is an interface type)", func(pkg *gogen.Package) { 720 recv := pkg.NewParam(position(3, 9), "p", gogen.TyError) 721 newFunc(pkg, 3, 7, 3, 10, recv, "foo", nil, nil, false).BodyStart(pkg).End() 722 }) 723 codeErrorTest(t, "./foo.gop:3:10: invalid receiver type recv (recv is a pointer type)", func(pkg *gogen.Package) { 724 t := pkg.NewType("recv").InitType(pkg, types.NewPointer(gogen.TyByte)) 725 recv := pkg.NewParam(position(3, 9), "p", t) 726 newFunc(pkg, 3, 7, 3, 10, recv, "foo", nil, nil, false).BodyStart(pkg).End() 727 }) 728 } 729 730 func TestErrLabel(t *testing.T) { 731 codeErrorTest(t, "./foo.gop:2:1: label foo already defined at ./foo.gop:1:1", func(pkg *gogen.Package) { 732 cb := pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg) 733 l := cb.NewLabel(position(1, 1), "foo") 734 cb.NewLabel(position(2, 1), "foo") 735 cb.Goto(l) 736 cb.End() 737 }) 738 codeErrorTest(t, "./foo.gop:1:1: label foo defined and not used", func(pkg *gogen.Package) { 739 cb := pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg) 740 cb.NewLabel(position(1, 1), "foo") 741 cb.End() 742 }) 743 codeErrorTest(t, "./foo.gop:1:1: syntax error: non-declaration statement outside function body", func(pkg *gogen.Package) { 744 pkg.CB().NewLabel(position(1, 1), "foo") 745 }) 746 /* codeErrorTest(t, "./foo.gop:1:1: label foo is not defined", func(pkg *gogen.Package) { 747 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 748 Goto("foo", source("goto foo", 1, 1)). 749 End() 750 }) 751 */ 752 } 753 754 func TestErrStructLit(t *testing.T) { 755 codeErrorTest(t, `./foo.gop:1:7: too many values in struct{x int; y string}{...}`, 756 func(pkg *gogen.Package) { 757 fields := []*types.Var{ 758 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 759 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 760 } 761 tyStruc := types.NewStruct(fields, nil) 762 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 763 Val(1, source(`1`, 1, 1)). 764 Val("1", source(`"1"`, 1, 5)). 765 Val(1, source(`1`, 1, 7)). 766 StructLit(tyStruc, 3, false). 767 EndStmt(). 768 End() 769 }) 770 codeErrorTest(t, `./foo.gop:1:1: too few values in struct{x int; y string}{...}`, 771 func(pkg *gogen.Package) { 772 fields := []*types.Var{ 773 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 774 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 775 } 776 tyStruc := types.NewStruct(fields, nil) 777 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 778 Val(1, source(`1`, 1, 1)). 779 StructLit(tyStruc, 1, false). 780 EndStmt(). 781 End() 782 }) 783 codeErrorTest(t, `./foo.gop:1:5: cannot use 1 (type untyped int) as type string in value of field y`, 784 func(pkg *gogen.Package) { 785 fields := []*types.Var{ 786 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 787 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 788 } 789 tyStruc := types.NewStruct(fields, nil) 790 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 791 Val(1). 792 Val(1, source(`1`, 1, 5)). 793 StructLit(tyStruc, 2, true). 794 EndStmt(). 795 End() 796 }) 797 codeErrorTest(t, `./foo.gop:1:1: cannot use "1" (type untyped string) as type int in value of field x`, 798 func(pkg *gogen.Package) { 799 fields := []*types.Var{ 800 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 801 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 802 } 803 tyStruc := types.NewStruct(fields, nil) 804 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 805 Val("1", source(`"1"`, 1, 1)). 806 Val(1, source(`1`, 1, 5)). 807 StructLit(tyStruc, 2, false). 808 EndStmt(). 809 End() 810 }) 811 } 812 813 func TestErrMapLit(t *testing.T) { 814 codeErrorTest(t, "./foo.gop:2:6: cannot use 1+2 (type untyped int) as type string in map key", 815 func(pkg *gogen.Package) { 816 tyMap := types.NewMap(types.Typ[types.String], types.Typ[types.Int]) 817 cb := pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 818 DefineVarStart(0, "x") 819 cb.ResetInit() 820 cb.Val(1, source("1")). 821 Val(2, source("2")). 822 BinaryOp(token.ADD, source("1+2", 2, 6)). 823 Val(3). 824 MapLit(tyMap, 2). 825 End() 826 }) 827 codeErrorTest(t, `./foo.gop:1:5: cannot use "Hi" + "!" (type untyped string) as type int in map value`, 828 func(pkg *gogen.Package) { 829 tyMap := types.NewMap(types.Typ[types.String], types.Typ[types.Int]) 830 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 831 Val("1"). 832 Val("Hi", source(`"Hi"`)). 833 Val("!", source(`"!"`)). 834 BinaryOp(token.ADD, source(`"Hi" + "!"`, 1, 5)). 835 MapLit(tyMap, 2). 836 EndStmt(). 837 End() 838 }) 839 } 840 841 func TestErrMapLit2(t *testing.T) { 842 codeErrorTest(t, "-: MapLit: invalid arity, can't be odd - 1", 843 func(pkg *gogen.Package) { 844 tyMap := types.NewMap(types.Typ[types.String], types.Typ[types.Int]) 845 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 846 Val("1"). 847 MapLit(tyMap, 1). 848 EndStmt(). 849 End() 850 }) 851 codeErrorTest(t, "-: type string isn't a map", 852 func(pkg *gogen.Package) { 853 tyMap := types.Typ[types.String] 854 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 855 Val("1"). 856 Val("Hi", source(`"Hi"`)). 857 Val("!", source(`"!"`)). 858 BinaryOp(token.ADD, source(`"Hi" + "!"`, 1, 5)). 859 MapLit(tyMap, 2). 860 EndStmt(). 861 End() 862 }) 863 } 864 865 func TestErrArrayLit(t *testing.T) { 866 codeErrorTest(t, "./foo.gop:1:5: cannot use 32 (type untyped int) as type string in array literal", 867 func(pkg *gogen.Package) { 868 tyArray := types.NewArray(types.Typ[types.String], 10) 869 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 870 Val(1, source("1")). 871 Val(32, source("32", 1, 5)). 872 ArrayLit(tyArray, 2, true). 873 EndStmt(). 874 End() 875 }) 876 codeErrorTest(t, "./foo.gop:1:5: cannot use 1+2 (type untyped int) as type string in array literal", 877 func(pkg *gogen.Package) { 878 tyArray := types.NewArray(types.Typ[types.String], 10) 879 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 880 Val(1, source("1")). 881 Val(2, source("2")). 882 BinaryOp(token.ADD, source("1+2", 1, 5)). 883 ArrayLit(tyArray, 1). 884 EndStmt(). 885 End() 886 }) 887 codeErrorTest(t, 888 `./foo.gop:2:10: array index 1 out of bounds [0:1]`, 889 func(pkg *gogen.Package) { 890 tyArray := types.NewArray(types.Typ[types.String], 1) 891 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 892 Val("Hi", source(`"Hi"`, 1, 5)). 893 Val("!", source(`"!"`, 2, 10)). 894 ArrayLit(tyArray, 2, false). 895 EndStmt(). 896 End() 897 }) 898 codeErrorTest(t, 899 `./foo.gop:1:5: array index 12 (value 12) out of bounds [0:10]`, 900 func(pkg *gogen.Package) { 901 tyArray := types.NewArray(types.Typ[types.String], 10) 902 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 903 Val(12, source(`12`, 1, 5)). 904 Val("!", source(`"!"`)). 905 ArrayLit(tyArray, 2, true). 906 EndStmt(). 907 End() 908 }) 909 codeErrorTest(t, 910 `./foo.gop:2:10: array index 10 out of bounds [0:10]`, 911 func(pkg *gogen.Package) { 912 tyArray := types.NewArray(types.Typ[types.String], 10) 913 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 914 Val(9, source(`9`, 1, 5)). 915 Val("!", source(`"!"`)). 916 None(). 917 Val("!!", source(`"!!"`, 2, 10)). 918 ArrayLit(tyArray, 4, true). 919 EndStmt(). 920 End() 921 }) 922 codeErrorTest(t, 923 `./foo.gop:1:5: cannot use "Hi" + "!" as index which must be non-negative integer constant`, 924 func(pkg *gogen.Package) { 925 tyArray := types.NewArray(types.Typ[types.String], 100) 926 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 927 Val("Hi", source(`"Hi"`)). 928 Val("!", source(`"!"`)). 929 BinaryOp(token.ADD, source(`"Hi" + "!"`, 1, 5)). 930 Val("Hi", source(`"Hi"`)). 931 ArrayLit(tyArray, 2, true). 932 EndStmt(). 933 End() 934 }) 935 } 936 937 func TestErrSliceLit(t *testing.T) { 938 codeErrorTest(t, 939 `./foo.gop:1:5: cannot use "10" as index which must be non-negative integer constant`, 940 func(pkg *gogen.Package) { 941 tySlice := types.NewSlice(types.Typ[types.String]) 942 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 943 Val("10", source(`"10"`, 1, 5)). 944 Val("Hi", source(`"Hi"`)). 945 SliceLit(tySlice, 2, true). 946 EndStmt(). 947 End() 948 }) 949 codeErrorTest(t, "./foo.gop:1:5: cannot use 32 (type untyped int) as type string in slice literal", 950 func(pkg *gogen.Package) { 951 tySlice := types.NewSlice(types.Typ[types.String]) 952 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 953 Val(10, source("10")). 954 Val(32, source("32", 1, 5)). 955 SliceLit(tySlice, 2, true). 956 EndStmt(). 957 End() 958 }) 959 codeErrorTest(t, "./foo.gop:1:5: cannot use 1+2 (type untyped int) as type string in slice literal", 960 func(pkg *gogen.Package) { 961 tySlice := types.NewSlice(types.Typ[types.String]) 962 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 963 Val(1, source("1")). 964 Val(2, source("2")). 965 BinaryOp(token.ADD, source("1+2", 1, 5)). 966 SliceLit(tySlice, 1). 967 EndStmt(). 968 End() 969 }) 970 } 971 972 func TestErrSlice(t *testing.T) { 973 codeErrorTest(t, 974 `./foo.gop:1:5: cannot slice true (type untyped bool)`, 975 func(pkg *gogen.Package) { 976 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 977 Val(types.Universe.Lookup("true"), source("true", 1, 5)). 978 Val(1). 979 Val(3). 980 Val(5). 981 Slice(true, source("true[1:3:5]", 1, 5)). 982 EndStmt(). 983 End() 984 }) 985 codeErrorTest(t, 986 `./foo.gop:1:1: cannot slice x (type *byte)`, 987 func(pkg *gogen.Package) { 988 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 989 NewVar(types.NewPointer(gogen.TyByte), "x"). 990 Val(ctxRef(pkg, "x"), source("x", 1, 1)). 991 Val(1). 992 Val(3). 993 Val(5). 994 Slice(true, source("x[1:3:5]", 1, 5)). 995 EndStmt(). 996 End() 997 }) 998 codeErrorTest(t, 999 `./foo.gop:1:5: invalid operation x[1:3:5] (3-index slice of string)`, 1000 func(pkg *gogen.Package) { 1001 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1002 NewVar(types.Typ[types.String], "x"). 1003 Val(ctxRef(pkg, "x")). 1004 Val(1). 1005 Val(3). 1006 Val(5). 1007 Slice(true, source("x[1:3:5]", 1, 5)). 1008 EndStmt(). 1009 End() 1010 }) 1011 } 1012 1013 func TestErrIndex(t *testing.T) { 1014 codeErrorTest(t, 1015 `./foo.gop:1:5: invalid operation: true[1] (type untyped bool does not support indexing)`, 1016 func(pkg *gogen.Package) { 1017 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1018 Val(types.Universe.Lookup("true"), source("true", 1, 5)). 1019 Val(1). 1020 Index(1, true, source("true[1]", 1, 5)). 1021 EndStmt(). 1022 End() 1023 }) 1024 codeErrorTest(t, 1025 `./foo.gop:1:5: assignment mismatch: 2 variables but 1 values`, 1026 func(pkg *gogen.Package) { 1027 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1028 NewVar(types.Typ[types.String], "x"). 1029 Val(ctxRef(pkg, "x")). 1030 Val(1). 1031 Index(1, true, source("x[1]", 1, 5)). 1032 EndStmt(). 1033 End() 1034 }) 1035 } 1036 1037 func TestErrIndexRef(t *testing.T) { 1038 codeErrorTest(t, 1039 `./foo.gop:1:5: cannot assign to x[1] (strings are immutable)`, 1040 func(pkg *gogen.Package) { 1041 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1042 NewVar(types.Typ[types.String], "x"). 1043 Val(ctxRef(pkg, "x")). 1044 Val(1). 1045 IndexRef(1, source("x[1]", 1, 5)). 1046 EndStmt(). 1047 End() 1048 }) 1049 } 1050 1051 func TestErrStar(t *testing.T) { 1052 codeErrorTest(t, 1053 `./foo.gop:1:5: invalid indirect of x (type string)`, 1054 func(pkg *gogen.Package) { 1055 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1056 NewVar(types.Typ[types.String], "x"). 1057 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1058 ElemRef(source("*x", 1, 4)). 1059 EndStmt(). 1060 End() 1061 }) 1062 codeErrorTest(t, 1063 `./foo.gop:1:5: invalid indirect of x (type string)`, 1064 func(pkg *gogen.Package) { 1065 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1066 NewVar(types.Typ[types.String], "x"). 1067 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1068 Elem(source("*x", 1, 4)). 1069 EndStmt(). 1070 End() 1071 }) 1072 codeErrorTest(t, 1073 `./foo.gop:1:5: invalid indirect of x (type string)`, 1074 func(pkg *gogen.Package) { 1075 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1076 NewVar(types.Typ[types.String], "x"). 1077 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1078 Star(source("*x", 1, 4)). 1079 EndStmt(). 1080 End() 1081 }) 1082 } 1083 1084 func TestErrMember(t *testing.T) { 1085 codeErrorTest(t, 1086 `./foo.gop:1:5: T.x undefined (type T has no method x)`, 1087 func(pkg *gogen.Package) { 1088 fields := []*types.Var{ 1089 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 1090 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 1091 } 1092 pkg.NewType("T").InitType(pkg, types.NewStruct(fields, nil)) 1093 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1094 Val(ctxRef(pkg, "T")). 1095 Debug(func(cb *gogen.CodeBuilder) { 1096 _, err := cb.Member("x", gogen.MemberFlagVal, source("T.x", 1, 5)) 1097 if err != nil { 1098 panic(err) 1099 } 1100 }). 1101 EndStmt(). 1102 End() 1103 }) 1104 codeErrorTest(t, 1105 `./foo.gop:1:7: x.y undefined (type string has no field or method y)`, 1106 func(pkg *gogen.Package) { 1107 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1108 NewVar(types.Typ[types.String], "x"). 1109 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1110 Debug(func(cb *gogen.CodeBuilder) { 1111 _, err := cb.Member("y", gogen.MemberFlagVal, source("x.y", 1, 7)) 1112 if err != nil { 1113 panic(err) 1114 } 1115 }). 1116 EndStmt(). 1117 End() 1118 }) 1119 codeErrorTest(t, 1120 `./foo.gop:1:5: x.y undefined (type string has no field or method y)`, 1121 func(pkg *gogen.Package) { 1122 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1123 NewVar(types.Typ[types.String], "x"). 1124 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1125 Debug(func(cb *gogen.CodeBuilder) { 1126 _, err := cb.Member("y", gogen.MemberFlagVal, source("x.y", 1, 5)) 1127 if err != nil { 1128 panic(err) 1129 } 1130 }). 1131 EndStmt(). 1132 End() 1133 }) 1134 } 1135 1136 func TestErrMemberRef(t *testing.T) { 1137 codeErrorTest(t, 1138 `./foo.gop:1:7: x.y undefined (type string has no field or method y)`, 1139 func(pkg *gogen.Package) { 1140 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1141 NewVar(types.Typ[types.String], "x"). 1142 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1143 MemberRef("y", source("x.y", 1, 7)). 1144 EndStmt(). 1145 End() 1146 }) 1147 codeErrorTest(t, 1148 `./foo.gop:1:7: x.y undefined (type aaa has no field or method y)`, 1149 func(pkg *gogen.Package) { 1150 t := pkg.NewType("aaa").InitType(pkg, gogen.TyByte) 1151 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1152 NewVar(t, "x"). 1153 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1154 MemberRef("y", source("x.y", 1, 7)). 1155 EndStmt(). 1156 End() 1157 }) 1158 codeErrorTest(t, 1159 `./foo.gop:1:7: x.z undefined (type struct{x int; y string} has no field or method z)`, 1160 func(pkg *gogen.Package) { 1161 fields := []*types.Var{ 1162 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 1163 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 1164 } 1165 t := types.NewStruct(fields, nil) 1166 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1167 NewVar(t, "x"). 1168 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1169 MemberRef("z", source("x.z", 1, 7)). 1170 EndStmt(). 1171 End() 1172 }) 1173 codeErrorTest(t, 1174 `./foo.gop:1:7: x.z undefined (type aaa has no field or method z)`, 1175 func(pkg *gogen.Package) { 1176 fields := []*types.Var{ 1177 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 1178 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 1179 } 1180 tyStruc := types.NewStruct(fields, nil) 1181 t := pkg.NewType("aaa").InitType(pkg, tyStruc) 1182 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1183 NewVar(t, "x"). 1184 Val(ctxRef(pkg, "x"), source("x", 1, 5)). 1185 MemberRef("z", source("x.z", 1, 7)). 1186 EndStmt(). 1187 End() 1188 }) 1189 } 1190 1191 func TestErrUnsafe(t *testing.T) { 1192 codeErrorTest(t, 1193 `./foo.gop:6:15: missing argument to function call: unsafe.Sizeof()`, 1194 func(pkg *gogen.Package) { 1195 builtin := pkg.Unsafe() 1196 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1197 Val(builtin.Ref("Sizeof")).CallWith(0, 0, source("unsafe.Sizeof()", 6, 2)).EndStmt(). 1198 EndStmt(). 1199 End() 1200 }) 1201 codeErrorTest(t, 1202 `./foo.gop:6:15: too many arguments to function call: unsafe.Sizeof(1, 2)`, 1203 func(pkg *gogen.Package) { 1204 builtin := pkg.Unsafe() 1205 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1206 Val(builtin.Ref("Sizeof")).Val(1).Val(2).CallWith(2, 0, source("unsafe.Sizeof(1, 2)", 6, 2)).EndStmt(). 1207 EndStmt(). 1208 End() 1209 }) 1210 codeErrorTest(t, 1211 `./foo.gop:6:17: invalid expression unsafe.Offsetof(1)`, 1212 func(pkg *gogen.Package) { 1213 builtin := pkg.Unsafe() 1214 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1215 Val(builtin.Ref("Offsetof")).Val(1).CallWith(1, 0, source("unsafe.Offsetof(1)", 6, 2)).EndStmt(). 1216 EndStmt(). 1217 End() 1218 }) 1219 codeErrorTest(t, 1220 `./foo.gop:14:17: invalid expression unsafe.Offsetof(a.Bar): argument is a method value`, 1221 func(pkg *gogen.Package) { 1222 fields := []*types.Var{ 1223 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 1224 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 1225 } 1226 typ := types.NewStruct(fields, nil) 1227 foo := pkg.NewType("foo").InitType(pkg, typ) 1228 recv := pkg.NewParam(token.NoPos, "a", foo) 1229 pkg.NewFunc(recv, "Bar", nil, nil, false).BodyStart(pkg).End() 1230 builtin := pkg.Unsafe() 1231 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1232 NewVar(foo, "a"). 1233 Val(builtin.Ref("Offsetof")).VarVal("a").MemberVal("Bar").CallWith(1, 0, source("unsafe.Offsetof(a.Bar)", 14, 2)).EndStmt(). 1234 EndStmt(). 1235 End() 1236 }) 1237 codeErrorTest(t, `./foo.gop:17:26: invalid expression unsafe.Offsetof(t.M.m): selector implies indirection of embedded t.M`, 1238 func(pkg *gogen.Package) { 1239 builtin := pkg.Unsafe() 1240 fieldsM := []*types.Var{ 1241 types.NewField(token.NoPos, pkg.Types, "m", types.Typ[types.Int], false), 1242 types.NewField(token.NoPos, pkg.Types, "n", types.Typ[types.String], false), 1243 } 1244 typM := types.NewStruct(fieldsM, nil) 1245 tyM := pkg.NewType("M").InitType(pkg, typM) 1246 fieldsT := []*types.Var{ 1247 types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), 1248 types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), 1249 types.NewField(token.NoPos, pkg.Types, "", types.NewPointer(tyM), true), 1250 } 1251 typT := types.NewStruct(fieldsT, nil) 1252 tyT := pkg.NewType("T").InitType(pkg, typT) 1253 pkg.CB().NewVar(tyT, "t") 1254 pkg.CB().NewConstStart(nil, "c"). 1255 Val(builtin.Ref("Offsetof")).Val(ctxRef(pkg, "t"), source("t", 17, 27)).MemberVal("m").CallWith(1, 0, source("unsafe.Offsetof(t.m)", 17, 11)).EndInit(1) 1256 }) 1257 codeErrorTest(t, 1258 `./foo.gop:7:12: cannot use a (type int) as type unsafe.Pointer in argument to unsafe.Add`, 1259 func(pkg *gogen.Package) { 1260 tyInt := types.Typ[types.Int] 1261 builtin := pkg.Unsafe() 1262 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1263 NewVar(tyInt, "a"). 1264 Val(builtin.Ref("Add")).Val(ctxRef(pkg, "a"), source("a", 7, 14)).Val(10).CallWith(2, 0, source("unsafe.Add(a, 10)", 7, 2)).EndStmt(). 1265 End() 1266 }) 1267 codeErrorTest(t, 1268 `./foo.gop:7:12: cannot use "hello" (type untyped string) as type int`, 1269 func(pkg *gogen.Package) { 1270 tyUP := types.Typ[types.UnsafePointer] 1271 builtin := pkg.Unsafe() 1272 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1273 NewVar(tyUP, "a"). 1274 Val(builtin.Ref("Add")).Val(ctxRef(pkg, "a"), source("a", 7, 14)).Val("hello", source(`"hello"`, 7, 16)).CallWith(2, 0, source("unsafe.Add(a, 10)", 7, 2)).EndStmt(). 1275 End() 1276 }) 1277 codeErrorTest(t, 1278 `./foo.gop:7:14: first argument to unsafe.Slice must be pointer; have int`, 1279 func(pkg *gogen.Package) { 1280 tyInt := types.Typ[types.Int] 1281 builtin := pkg.Unsafe() 1282 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1283 NewVar(tyInt, "a"). 1284 Val(builtin.Ref("Slice")).VarVal("a").Val(10).CallWith(2, 0, source(`unsafe.Slice(a, 10)`, 7, 2)).EndStmt(). 1285 End() 1286 }) 1287 codeErrorTest(t, 1288 `./foo.gop:7:14: non-integer len argument in unsafe.Slice - untyped string`, 1289 func(pkg *gogen.Package) { 1290 tyInt := types.Typ[types.Int] 1291 builtin := pkg.Unsafe() 1292 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1293 NewVarStart(nil, "ar"). 1294 Val(1).Val(2).Val(3).ArrayLit(types.NewArray(tyInt, 3), 3).EndInit(1). 1295 Val(builtin.Ref("Slice")).Val(ctxRef(pkg, "ar")).Val(0).Index(1, false).UnaryOp(token.AND).Val("hello").CallWith(2, 0, source(`unsafe.Slice(&a[0],"hello")`, 7, 2)).EndStmt(). 1296 End() 1297 }) 1298 } 1299 1300 func TestImportPkgError(t *testing.T) { 1301 where := "GOROOT" 1302 ver := runtime.Version()[:6] 1303 if ver >= "go1.21" { 1304 where = "std" 1305 } 1306 codeErrorTest(t, 1307 fmt.Sprintf(`./foo.gop:1:7: package bar2 is not in `+where+` (%v) 1308 `, filepath.Join(runtime.GOROOT(), "src", "bar2")), 1309 func(pkg *gogen.Package) { 1310 spec := &ast.ImportSpec{ 1311 Path: &ast.BasicLit{ValuePos: position(1, 7), Kind: token.STRING, Value: strconv.Quote("bar")}, 1312 } 1313 pkg.Import("bar2", spec) 1314 }) 1315 } 1316 1317 func TestDivisionByZero(t *testing.T) { 1318 codeErrorTest(t, 1319 `./foo.gop:1:3: invalid operation: division by zero`, 1320 func(pkg *gogen.Package) { 1321 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1322 Val(1).Val(0, source("0", 1, 3)).BinaryOp(token.QUO). 1323 End() 1324 }) 1325 codeErrorTest(t, 1326 `./foo.gop:1:3: invalid operation: division by zero`, 1327 func(pkg *gogen.Package) { 1328 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1329 Val(1.1).Val(0.0, source("0.0", 1, 3)).BinaryOp(token.QUO). 1330 End() 1331 }) 1332 codeErrorTest(t, 1333 `./foo.gop:1:3: invalid operation: division by zero`, 1334 func(pkg *gogen.Package) { 1335 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1336 Val(&ast.BasicLit{Kind: token.IMAG, Value: "1i"}).Val(&ast.BasicLit{Kind: token.IMAG, Value: "0i"}, source("0i", 1, 3)).BinaryOp(token.QUO). 1337 End() 1338 }) 1339 codeErrorTest(t, 1340 `./foo.gop:1:3: invalid operation: division by zero`, 1341 func(pkg *gogen.Package) { 1342 typ := types.Typ[types.Int] 1343 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1344 NewVar(typ, "a"). 1345 VarVal("a").Val(0, source("0", 1, 3)).BinaryOp(token.QUO). 1346 End() 1347 }) 1348 codeErrorTest(t, 1349 `./foo.gop:1:3: invalid operation: division by zero`, 1350 func(pkg *gogen.Package) { 1351 typ := types.Typ[types.Int] 1352 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1353 NewVar(typ, "a"). 1354 VarVal("a").Val(0.0, source("0.0", 1, 3)).BinaryOp(token.QUO). 1355 End() 1356 }) 1357 codeErrorTest(t, 1358 `./foo.gop:1:3: invalid operation: division by zero`, 1359 func(pkg *gogen.Package) { 1360 typ := types.Typ[types.Int] 1361 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1362 NewVar(typ, "a"). 1363 VarVal("a").Val(&ast.BasicLit{Kind: token.IMAG, Value: "0i"}, source("0i", 1, 3)).BinaryOp(token.QUO). 1364 End() 1365 }) 1366 codeErrorTest(t, 1367 `./foo.gop:1:3: invalid operation: division by zero`, 1368 func(pkg *gogen.Package) { 1369 typ := types.Typ[types.Int] 1370 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1371 NewVar(typ, "a"). 1372 VarRef(ctxRef(pkg, "a")).Val(0, source("0", 1, 3)).AssignOp(token.QUO_ASSIGN). 1373 End() 1374 }) 1375 codeErrorTest(t, 1376 `./foo.gop:1:3: invalid operation: division by zero`, 1377 func(pkg *gogen.Package) { 1378 typ := types.Typ[types.Int] 1379 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1380 NewVar(typ, "a"). 1381 VarRef(ctxRef(pkg, "a")).Val(0.0, source("0.0", 1, 3)).AssignOp(token.QUO_ASSIGN). 1382 End() 1383 }) 1384 codeErrorTest(t, 1385 `./foo.gop:1:3: invalid operation: division by zero`, 1386 func(pkg *gogen.Package) { 1387 typ := types.Typ[types.Int] 1388 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1389 NewVar(typ, "a"). 1390 VarRef(ctxRef(pkg, "a")).Val(&ast.BasicLit{Kind: token.IMAG, Value: "0i"}, source("0i", 1, 3)).AssignOp(token.QUO_ASSIGN). 1391 End() 1392 }) 1393 } 1394 1395 func TestErrUsedNoValue(t *testing.T) { 1396 codeErrorTest(t, 1397 `./foo.gop:3:10: foo() (no value) used as value`, 1398 func(pkg *gogen.Package) { 1399 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, nil, false).BodyStart(pkg). 1400 End() 1401 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1402 NewVarStart(types.Typ[types.Int], "a"). 1403 Val(ctxRef(pkg, "foo")).CallWith(0, 0, source("foo()", 3, 10)).EndInit(1). 1404 End() 1405 }) 1406 codeErrorTest(t, 1407 `./foo.gop:3:10: foo() (no value) used as value`, 1408 func(pkg *gogen.Package) { 1409 newFunc(pkg, 1, 5, 1, 7, nil, "foo", nil, nil, false).BodyStart(pkg). 1410 End() 1411 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1412 NewVar(types.Typ[types.Int], "a"). 1413 VarRef(ctxRef(pkg, "a")).Val(ctxRef(pkg, "foo")).CallWith(0, 0, source("foo()", 3, 10)).Assign(1, 1). 1414 End() 1415 }) 1416 } 1417 1418 func TestErrFieldAccess(t *testing.T) { 1419 const src = `package foo 1420 1421 type M struct { 1422 x int 1423 y int 1424 } 1425 ` 1426 gt := newGoxTest() 1427 _, err := gt.LoadGoPackage("foo", "foo.go", src) 1428 if err != nil { 1429 t.Fatal(err) 1430 } 1431 pkg := gt.NewPackage("", "main") 1432 pkgRef := pkg.Import("foo") 1433 tyM := pkgRef.Ref("M").Type() 1434 1435 codeErrorTestEx(t, pkg, `./foo.gop:3:10: m.x undefined (type foo.M has no field or method x)`, 1436 func(pkg *gogen.Package) { 1437 pkg.NewFunc(nil, "main", nil, nil, false).BodyStart(pkg). 1438 NewVar(tyM, "m"). 1439 VarVal("println").VarVal("m"). 1440 MemberVal("x", source("m.x", 3, 10)).Call(1).EndStmt(). 1441 End() 1442 }) 1443 }