github.com/goplus/gox@v1.14.13-0.20240308130321-6ff7f61cfae8/ast.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 gox 15 16 import ( 17 "errors" 18 "fmt" 19 "go/ast" 20 "go/constant" 21 "go/token" 22 "go/types" 23 "log" 24 "math/big" 25 "reflect" 26 "strconv" 27 "strings" 28 29 "github.com/goplus/gox/internal" 30 ) 31 32 var ( 33 errTemplateRecvMethodCallUnexpected = errors.New("matchFuncCall (TemplateRecvMethod) unexpected") 34 ) 35 36 // ---------------------------------------------------------------------------- 37 38 var ( 39 underscore = &ast.Ident{Name: "_"} 40 ) 41 42 var ( 43 identTrue = ident("true") 44 identFalse = ident("false") 45 identNil = ident("nil") 46 identAppend = ident("append") 47 identLen = ident("len") 48 identCap = ident("cap") 49 identNew = ident("new") 50 identMake = ident("make") 51 identIota = ident("iota") 52 ) 53 54 func ident(name string) *ast.Ident { 55 return &ast.Ident{Name: name} 56 } 57 58 func boolean(v bool) *ast.Ident { 59 if v { 60 return identTrue 61 } 62 return identFalse 63 } 64 65 func stringLit(val string) *ast.BasicLit { 66 return &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(val)} 67 } 68 69 func toRecv(pkg *Package, recv *types.Var) *ast.FieldList { 70 var names []*ast.Ident 71 if name := recv.Name(); name != "" { 72 names = []*ast.Ident{ident(name)} 73 } 74 fld := &ast.Field{Names: names, Type: toRecvType(pkg, recv.Type())} 75 return &ast.FieldList{List: []*ast.Field{fld}} 76 } 77 78 // ----------------------------------------------------------------------------- 79 // function type 80 81 func toFieldList(pkg *Package, t *types.Tuple) []*ast.Field { 82 if t == nil { 83 return nil 84 } 85 n := t.Len() 86 flds := make([]*ast.Field, n) 87 for i := 0; i < n; i++ { 88 item := t.At(i) 89 var names []*ast.Ident 90 if name := item.Name(); name != "" { 91 names = []*ast.Ident{ident(name)} 92 } 93 typ := toType(pkg, item.Type()) 94 flds[i] = &ast.Field{Names: names, Type: typ} 95 } 96 return flds 97 } 98 99 func toFields(pkg *Package, t *types.Struct) []*ast.Field { 100 n := t.NumFields() 101 flds := make([]*ast.Field, n) 102 for i := 0; i < n; i++ { 103 item := t.Field(i) 104 var names []*ast.Ident 105 if !item.Embedded() { 106 names = []*ast.Ident{{Name: item.Name()}} 107 } 108 typ := toType(pkg, item.Type()) 109 fld := &ast.Field{Names: names, Type: typ} 110 if tag := t.Tag(i); tag != "" { 111 fld.Tag = toTag(tag) 112 } 113 flds[i] = fld 114 } 115 return flds 116 } 117 118 func toTag(tag string) *ast.BasicLit { 119 var s string 120 if strings.ContainsAny(tag, "`\r\n") { 121 s = strconv.Quote(tag) 122 } else { 123 s = "`" + tag + "`" 124 } 125 return &ast.BasicLit{Kind: token.STRING, Value: s} 126 } 127 128 func toVariadic(fld *ast.Field) { 129 t, ok := fld.Type.(*ast.ArrayType) 130 if !ok || t.Len != nil { 131 panic("TODO: not a slice type") 132 } 133 fld.Type = &ast.Ellipsis{Elt: t.Elt} 134 } 135 136 // ----------------------------------------------------------------------------- 137 138 func toType(pkg *Package, typ types.Type) ast.Expr { 139 retry: 140 switch t := typ.(type) { 141 case *types.Basic: // bool, int, etc 142 return toBasicType(pkg, t) 143 case *types.Pointer: 144 return &ast.StarExpr{X: toType(pkg, t.Elem())} 145 case *types.Named: 146 return toNamedType(pkg, t) 147 case *types.Interface: 148 return toInterface(pkg, t) 149 case *types.Slice: 150 return toSliceType(pkg, t) 151 case *types.Array: 152 return toArrayType(pkg, t) 153 case *types.Map: 154 return toMapType(pkg, t) 155 case *types.Struct: 156 return toStructType(pkg, t) 157 case *types.Chan: 158 return toChanType(pkg, t) 159 case *types.Signature: 160 return toFuncType(pkg, t) 161 case *unboundType: 162 if t.tBound == nil { 163 panic("unbound type") 164 } 165 typ = t.tBound 166 goto retry 167 case *TypeParam: 168 return toObjectExpr(pkg, t.Obj()) 169 case *Union: 170 return toUnionType(pkg, t) 171 } 172 log.Panicln("TODO: toType -", reflect.TypeOf(typ)) 173 return nil 174 } 175 176 func toBasicType(pkg *Package, t *types.Basic) ast.Expr { 177 if t.Kind() == types.UnsafePointer { 178 return toObjectExpr(pkg, unsafeRef("Pointer")) 179 } 180 if (t.Info() & types.IsUntyped) != 0 { 181 panic("unexpected: untyped type") 182 } 183 return &ast.Ident{Name: t.Name()} 184 } 185 186 func isUntyped(pkg *Package, typ types.Type) bool { 187 switch t := typ.(type) { 188 case *types.Basic: 189 return (t.Info() & types.IsUntyped) != 0 190 case *types.Named: 191 switch t { 192 case pkg.utBigInt, pkg.utBigRat, pkg.utBigFlt: 193 return true 194 } 195 } 196 return false 197 } 198 199 func toChanType(pkg *Package, t *types.Chan) ast.Expr { 200 return &ast.ChanType{Value: toType(pkg, t.Elem()), Dir: chanDirs[t.Dir()]} 201 } 202 203 var ( 204 chanDirs = [...]ast.ChanDir{ 205 types.SendRecv: ast.SEND | ast.RECV, 206 types.SendOnly: ast.SEND, 207 types.RecvOnly: ast.RECV, 208 } 209 ) 210 211 func toStructType(pkg *Package, t *types.Struct) ast.Expr { 212 list := toFields(pkg, t) 213 return &ast.StructType{Fields: &ast.FieldList{List: list}} 214 } 215 216 func toArrayType(pkg *Package, t *types.Array) ast.Expr { 217 var len ast.Expr 218 if n := t.Len(); n < 0 { 219 len = &ast.Ellipsis{} 220 } else { 221 len = &ast.BasicLit{Kind: token.INT, Value: strconv.FormatInt(t.Len(), 10)} 222 } 223 return &ast.ArrayType{Len: len, Elt: toType(pkg, t.Elem())} 224 } 225 226 func toSliceType(pkg *Package, t *types.Slice) ast.Expr { 227 return &ast.ArrayType{Elt: toType(pkg, t.Elem())} 228 } 229 230 func toMapType(pkg *Package, t *types.Map) ast.Expr { 231 return &ast.MapType{Key: toType(pkg, t.Key()), Value: toType(pkg, t.Elem())} 232 } 233 234 var ( 235 universeAny = types.Universe.Lookup("any") 236 ) 237 238 func toInterface(pkg *Package, t *types.Interface) ast.Expr { 239 if t == universeAny.Type() { 240 return ast.NewIdent("any") 241 } else if interfaceIsImplicit(t) && t.NumEmbeddeds() == 1 { 242 return toType(pkg, t.EmbeddedType(0)) 243 } 244 var flds []*ast.Field 245 for i, n := 0, t.NumEmbeddeds(); i < n; i++ { 246 typ := toType(pkg, t.EmbeddedType(i)) 247 fld := &ast.Field{Type: typ} 248 flds = append(flds, fld) 249 } 250 for i, n := 0, t.NumExplicitMethods(); i < n; i++ { 251 fn := t.ExplicitMethod(i) 252 name := ident(fn.Name()) 253 typ := toFuncType(pkg, fn.Type().(*types.Signature)) 254 fld := &ast.Field{Names: []*ast.Ident{name}, Type: typ} 255 flds = append(flds, fld) 256 } 257 return &ast.InterfaceType{Methods: &ast.FieldList{List: flds}} 258 } 259 260 // ----------------------------------------------------------------------------- 261 // expression 262 263 func toExpr(pkg *Package, val interface{}, src ast.Node) *internal.Elem { 264 if val == nil { 265 return &internal.Elem{ 266 Val: identNil, 267 Type: types.Typ[types.UntypedNil], 268 Src: src, 269 } 270 } 271 switch v := val.(type) { 272 case *ast.BasicLit: 273 return &internal.Elem{ 274 Val: v, 275 Type: types.Typ[toBasicKind(v.Kind)], 276 CVal: constant.MakeFromLiteral(v.Value, v.Kind, 0), 277 Src: src, 278 } 279 case *types.TypeName: 280 switch typ := v.Type(); typ.(type) { 281 case *TyInstruction: // instruction as a type 282 return toObject(pkg, v, src) 283 default: 284 if debugInstr { 285 log.Printf("Val %v => Typ %v", v, typ) 286 } 287 return &internal.Elem{ 288 Val: toType(pkg, typ), Type: NewTypeType(typ), Src: src, 289 } 290 } 291 case *types.Builtin: 292 name := v.Name() 293 o := pkg.builtin.TryRef(name) 294 if o == nil { 295 o = pkg.unsafe_.Ref(name) 296 } 297 return toObject(pkg, o, src) 298 case types.Object: 299 if v == iotaObj { 300 v := pkg.cb.iotav 301 return &internal.Elem{ 302 Val: identIota, 303 Type: types.Typ[types.UntypedInt], 304 CVal: constant.MakeInt64(int64(v)), 305 Src: src, 306 } 307 } 308 return toObject(pkg, v, src) 309 case *Element: 310 return v 311 case int: 312 return &internal.Elem{ 313 Val: &ast.BasicLit{Kind: token.INT, Value: strconv.Itoa(v)}, 314 Type: types.Typ[types.UntypedInt], 315 CVal: constant.MakeInt64(int64(v)), 316 Src: src, 317 } 318 case string: 319 return &internal.Elem{ 320 Val: &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(v)}, 321 Type: types.Typ[types.UntypedString], 322 CVal: constant.MakeString(v), 323 Src: src, 324 } 325 case bool: 326 return &internal.Elem{ 327 Val: boolean(v), 328 Type: types.Typ[types.UntypedBool], 329 CVal: constant.MakeBool(v), 330 Src: src, 331 } 332 case rune: 333 return &internal.Elem{ 334 Val: &ast.BasicLit{Kind: token.CHAR, Value: strconv.QuoteRune(v)}, 335 Type: types.Typ[types.UntypedRune], 336 CVal: constant.MakeInt64(int64(v)), 337 Src: src, 338 } 339 case float64: 340 val := strconv.FormatFloat(v, 'g', -1, 64) 341 if !strings.ContainsAny(val, ".e") { 342 val += ".0" 343 } 344 return &internal.Elem{ 345 Val: &ast.BasicLit{Kind: token.FLOAT, Value: val}, 346 Type: types.Typ[types.UntypedFloat], 347 CVal: constant.MakeFloat64(v), 348 Src: src, 349 } 350 } 351 panic("unexpected: unsupport value type") 352 } 353 354 var ( 355 iotaObj = types.Universe.Lookup("iota") 356 ) 357 358 func toBasicKind(tok token.Token) types.BasicKind { 359 return tok2BasicKinds[tok] 360 } 361 362 var ( 363 tok2BasicKinds = [...]types.BasicKind{ 364 token.INT: types.UntypedInt, 365 token.STRING: types.UntypedString, 366 token.CHAR: types.UntypedRune, 367 token.FLOAT: types.UntypedFloat, 368 token.IMAG: types.UntypedComplex, 369 } 370 ) 371 372 func chgObject(pkg *Package, v types.Object, old *internal.Elem) *internal.Elem { 373 ret := toObject(pkg, v, old.Src) 374 if denoted := getDenoted(old.Val); denoted != nil { 375 setDenoted(ret.Val, denoted) 376 } 377 return ret 378 } 379 380 func toObject(pkg *Package, v types.Object, src ast.Node) *internal.Elem { 381 var cval constant.Value 382 if cv, ok := v.(*types.Const); ok { 383 cval = cv.Val() 384 } 385 return &internal.Elem{ 386 Val: toObjectExpr(pkg, v), Type: realType(v.Type()), CVal: cval, Src: src, 387 } 388 } 389 390 func toObjectExpr(pkg *Package, v types.Object) ast.Expr { 391 atPkg, name := v.Pkg(), v.Name() 392 if atPkg == nil || atPkg == pkg.Types { // at universe or at this package 393 return ident(name) 394 } 395 if atPkg == pkg.builtin.Types { // at builtin package 396 if strings.HasPrefix(name, goxPrefix) { 397 opName := name[len(goxPrefix):] 398 if op, ok := nameToOps[opName]; ok { 399 switch op.Arity { 400 case 2: 401 return &ast.BinaryExpr{Op: op.Tok} 402 case 1: 403 return &ast.UnaryExpr{Op: op.Tok} 404 } 405 } 406 } 407 return ident(name) 408 } 409 x := pkg.file.newImport(atPkg.Name(), atPkg.Path()) 410 return &ast.SelectorExpr{ 411 X: x, 412 Sel: ident(v.Name()), 413 } 414 } 415 416 type operator struct { 417 Tok token.Token 418 Arity int 419 } 420 421 var ( 422 nameToOps = map[string]operator{ 423 "Add": {token.ADD, 2}, 424 "Sub": {token.SUB, 2}, 425 "Mul": {token.MUL, 2}, 426 "Quo": {token.QUO, 2}, 427 "Rem": {token.REM, 2}, 428 "Or": {token.OR, 2}, 429 "Xor": {token.XOR, 2}, 430 "And": {token.AND, 2}, 431 "AndNot": {token.AND_NOT, 2}, 432 433 "LOr": {token.LOR, 2}, 434 "LAnd": {token.LAND, 2}, 435 436 "Lsh": {token.SHL, 2}, 437 "Rsh": {token.SHR, 2}, 438 439 "LT": {token.LSS, 2}, 440 "LE": {token.LEQ, 2}, 441 "GT": {token.GTR, 2}, 442 "GE": {token.GEQ, 2}, 443 "EQ": {token.EQL, 2}, 444 "NE": {token.NEQ, 2}, 445 446 "Neg": {token.SUB, 1}, 447 "Dup": {token.ADD, 1}, 448 "Not": {token.XOR, 1}, 449 "LNot": {token.NOT, 1}, 450 "Recv": {token.ARROW, 1}, 451 "Addr": {token.AND, 1}, 452 } 453 ) 454 455 func toFuncCall(pkg *Package, fn *internal.Elem, args []*internal.Elem, flags InstrFlags) *internal.Elem { 456 ret, err := matchFuncCall(pkg, fn, args, flags) 457 if err != nil { 458 panic(err) 459 } 460 return ret 461 } 462 463 func unaryOp(pkg *Package, tok token.Token, args []*internal.Elem) constant.Value { 464 if len(args) == 1 { 465 if a := args[0].CVal; a != nil { 466 var prec uint 467 if isUnsigned(args[0].Type) { 468 prec = uint(pkg.Sizeof(args[0].Type) * 8) 469 } 470 return constant.UnaryOp(tok, a, prec) 471 } 472 } 473 return nil 474 } 475 476 func isUnsigned(typ types.Type) bool { 477 retry: 478 switch t := typ.(type) { 479 case *types.Basic: 480 return (t.Info() & types.IsUnsigned) != 0 481 case *types.Named: 482 typ = t.Underlying() 483 goto retry 484 } 485 return false 486 } 487 488 func binaryOp(cb *CodeBuilder, tok token.Token, args []*internal.Elem) constant.Value { 489 if len(args) == 2 { 490 if a, b := args[0].CVal, args[1].CVal; a != nil && b != nil { 491 if tok == token.QUO && isNormalInt(cb, args[0]) && isNormalInt(cb, args[1]) { 492 tok = token.QUO_ASSIGN // issue #805 493 } 494 return doBinaryOp(a, tok, b) 495 } 496 } 497 return nil 498 } 499 500 func isBool(cb *CodeBuilder, arg *internal.Elem) bool { // is bool 501 return isBasicKind(cb, arg, types.IsBoolean) 502 } 503 504 func isNormalInt(cb *CodeBuilder, arg *internal.Elem) bool { // is integer but not bigint 505 return isBasicKind(cb, arg, types.IsInteger) 506 } 507 508 func isBasicKind(cb *CodeBuilder, arg *internal.Elem, kind types.BasicInfo) bool { 509 argType := arg.Type 510 retry: 511 switch t := argType.(type) { 512 case *types.Basic: 513 return (t.Info() & kind) != 0 514 case *types.Named: 515 argType = cb.getUnderlying(t) 516 goto retry 517 } 518 return false 519 } 520 521 func doBinaryOp(a constant.Value, tok token.Token, b constant.Value) constant.Value { 522 switch binaryOpKinds[tok] { 523 case binaryOpNormal: 524 return constant.BinaryOp(a, tok, b) 525 case binaryOpCompare: 526 return constant.MakeBool(constant.Compare(a, tok, b)) 527 default: 528 a, b = constant.ToInt(a), constant.ToInt(b) 529 if s, exact := constant.Int64Val(b); exact { 530 return constant.Shift(a, tok, uint(s)) 531 } 532 panic("constant value is overflow") 533 } 534 } 535 536 const ( 537 binaryOpNormal = iota 538 binaryOpCompare 539 binaryOpShift 540 ) 541 542 var ( 543 binaryOpKinds = [...]int{ 544 token.ADD: 0, // + 545 token.SUB: 0, // - 546 token.MUL: 0, // * 547 token.QUO: 0, // / 548 token.REM: 0, // % 549 550 token.AND: 0, // & 551 token.OR: 0, // | 552 token.XOR: 0, // ^ 553 token.AND_NOT: 0, // &^ 554 token.SHL: binaryOpShift, // << 555 token.SHR: binaryOpShift, // >> 556 557 token.LAND: 0, // && 558 token.LOR: 0, // || 559 560 token.LSS: binaryOpCompare, 561 token.LEQ: binaryOpCompare, 562 token.GTR: binaryOpCompare, 563 token.GEQ: binaryOpCompare, 564 token.EQL: binaryOpCompare, 565 token.NEQ: binaryOpCompare, 566 } 567 ) 568 569 func getParamLen(sig *types.Signature) int { 570 n := sig.Params().Len() 571 if sig.Recv() != nil { 572 n++ 573 } 574 return n 575 } 576 577 func getParam(sig *types.Signature, i int) *types.Var { 578 if sig.Recv() != nil { 579 i-- 580 } 581 if i < 0 { 582 return sig.Recv() 583 } 584 return sig.Params().At(i) 585 } 586 587 func getParam1st(sig *types.Signature) int { 588 if sig.Recv() != nil { 589 return 1 590 } 591 return 0 592 } 593 594 // TODO: check if fn.recv != nil 595 func matchFuncCall(pkg *Package, fn *internal.Elem, args []*internal.Elem, flags InstrFlags) (ret *internal.Elem, err error) { 596 fnType := fn.Type 597 if debugMatch { 598 ft := fnType 599 if t, ok := fnType.(*types.Signature); ok { 600 if ftex, ok := CheckSigFuncEx(t); ok { 601 ft = ftex 602 } 603 } 604 log.Println("==> MatchFuncCall", ft, "args:", len(args), "flags:", flags) 605 } 606 var it *instantiated 607 var sig *types.Signature 608 var cval constant.Value 609 retry: 610 switch t := fnType.(type) { 611 case *types.Signature: 612 if t.TypeParams() != nil { 613 if (flags & instrFlagGopxFunc) == 0 { 614 rt, err := inferFunc(pkg, fn, t, nil, args, flags) 615 if err != nil { 616 return nil, pkg.cb.newCodeError(getSrcPos(fn.Src), err.Error()) 617 } 618 sig = rt.(*types.Signature) 619 if debugMatch { 620 log.Println("==> InferFunc", sig) 621 } 622 } else { 623 fn, sig, args, err = boundTypeParams(pkg, fn, t, args, flags) 624 if err != nil { 625 return 626 } 627 flags &= ^instrFlagGopxFunc 628 } 629 break 630 } 631 if fex, ok := CheckFuncEx(t); ok { 632 switch ft := fex.(type) { 633 case *TyOverloadFunc: 634 backup := backupArgs(args) 635 for _, o := range ft.Funcs { 636 if ret, err = matchFuncCall(pkg, chgObject(pkg, o, fn), args, flags); err == nil { 637 if ret.CVal == nil && isUntyped(pkg, ret.Type) { 638 ret.CVal = builtinCall(fn, args) 639 } 640 if pkg.cb.rec != nil { 641 pkg.cb.rec.Call(fn.Src, o) 642 } 643 return 644 } 645 restoreArgs(args, backup) 646 } 647 return 648 case *TyOverloadMethod: 649 backup := backupArgs(args) 650 for _, o := range ft.Methods { 651 mfn := *fn 652 if (flags & instrFlagBinaryOp) != 0 { // from cb.BinaryOp 653 mfn.Type = methodToFuncSig(pkg, o, &mfn) 654 } else { 655 mfn.Val.(*ast.SelectorExpr).Sel = ident(o.Name()) 656 mfn.Type = methodCallSig(o.Type()) 657 } 658 if ret, err = matchFuncCall(pkg, &mfn, args, flags); err == nil { 659 fn.Val, fn.Type = mfn.Val, mfn.Type 660 if pkg.cb.rec != nil { 661 pkg.cb.rec.Call(fn.Src, o) 662 } 663 return 664 } 665 restoreArgs(args, backup) 666 } 667 return 668 case *TyTemplateRecvMethod: 669 err = errTemplateRecvMethodCallUnexpected 670 if denoted := getDenoted(fn.Val); denoted != nil { 671 if recv, ok := denoted.Data.(*Element); ok { 672 backup := backupArgs(args) 673 for i := 0; i < 2; i++ { 674 tfn := toObject(pkg, ft.Func, fn.Src) 675 targs := make([]*internal.Elem, len(args)+1) 676 targ0 := *recv 677 if i == 1 { 678 targ0.Val = &ast.UnaryExpr{Op: token.AND, X: targ0.Val} 679 targ0.Type = types.NewPointer(targ0.Type) 680 } 681 targs[0] = &targ0 682 for j, arg := range args { 683 targs[j+1] = arg 684 } 685 if ret, err = matchFuncCall(pkg, tfn, targs, flags|instrFlagGoptFunc); err == nil { 686 if pkg.cb.rec != nil { 687 if _, ok := CheckFuncEx(ft.Func.Type().(*types.Signature)); !ok { 688 pkg.cb.rec.Call(fn.Src, ft.Func) 689 } 690 } 691 return 692 } 693 if isPointer(targ0.Type) { 694 break 695 } 696 restoreArgs(args, backup) 697 } 698 } 699 } 700 return 701 case *tyTypeAsParams: 702 return matchFuncCall(pkg, chgObject(pkg, ft.obj, fn), args, flags|instrFlagGopxFunc) 703 } 704 } else if IsCSignature(t) { 705 sig = types.NewSignatureType(nil, nil, nil, t.Params(), t.Results(), t.Variadic()) 706 } else { 707 sig = t 708 } 709 case *TemplateSignature: // template function 710 sig, it = t.instantiate() 711 if t.isUnaryOp() { 712 cval = unaryOp(pkg, t.tok(), args) 713 } else if t.isOp() { 714 cval = binaryOp(&pkg.cb, t.tok(), args) 715 } else if t.hasApproxType() { 716 flags |= instrFlagApproxType 717 } 718 case *TyInstruction: 719 return t.instr.Call(pkg, args, flags, fn.Src) 720 case *TypeType: // type convert 721 if on, ok := CheckOverloadNamed(t.typ); ok { 722 return matchOverloadNamedTypeCast(pkg, on.Obj, fn.Src, args, flags) 723 } 724 return matchTypeCast(pkg, t.typ, fn, args, flags) 725 case *types.Named: 726 fnType = pkg.cb.getUnderlying(t) 727 goto retry 728 case *inferFuncType: 729 sig = t.InstanceWithArgs(args, flags) 730 if debugMatch { 731 log.Println("==> InferFunc", sig) 732 } 733 default: 734 src, pos := pkg.cb.loadExpr(fn.Src) 735 pkg.cb.panicCodeErrorf(pos, "cannot call non-function %s (type %v)", src, fn.Type) 736 } 737 if err = matchFuncType(pkg, args, flags, sig, fn); err != nil { 738 return 739 } 740 tyRet := toRetType(sig.Results(), it) 741 if cval != nil { // untyped bigint/bigrat 742 if ret, ok := untypeBig(pkg, cval, tyRet); ok { 743 return ret, nil 744 } 745 } 746 switch t := fn.Val.(type) { 747 case *ast.BinaryExpr: 748 t.X, t.Y = checkParenExpr(args[0].Val), checkParenExpr(args[1].Val) 749 return &internal.Elem{Val: t, Type: tyRet, CVal: cval}, nil 750 case *ast.UnaryExpr: 751 t.X = args[0].Val 752 return &internal.Elem{Val: t, Type: tyRet, CVal: cval}, nil 753 } 754 var valArgs []ast.Expr 755 var recv = getParam1st(sig) 756 if n := len(args); n > recv { // for method, args[0] is already in fn.Val 757 valArgs = make([]ast.Expr, n-recv) 758 for i := recv; i < n; i++ { 759 valArgs[i-recv] = args[i].Val 760 } 761 } 762 return &internal.Elem{ 763 Type: tyRet, CVal: cval, 764 Val: &ast.CallExpr{ 765 Fun: fn.Val, Args: valArgs, Ellipsis: token.Pos(flags & InstrFlagEllipsis)}, 766 }, nil 767 } 768 769 func matchOverloadNamedTypeCast(pkg *Package, t *types.TypeName, src ast.Node, args []*internal.Elem, flags InstrFlags) (ret *internal.Elem, err error) { 770 cast := gopxPrefix + t.Name() + "_Cast" 771 o := t.Pkg().Scope().Lookup(cast) 772 if o == nil { 773 err := pkg.cb.newCodeErrorf(getSrcPos(src), "typecast %v not found", t.Type()) 774 return nil, err 775 } 776 fn := toObject(pkg, o, src) 777 return matchFuncCall(pkg, fn, args, flags|instrFlagGopxFunc) 778 } 779 780 func matchTypeCast(pkg *Package, typ types.Type, fn *internal.Elem, args []*internal.Elem, flags InstrFlags) (ret *internal.Elem, err error) { 781 fnVal := fn.Val 782 switch typ.(type) { 783 case *types.Pointer, *types.Chan: 784 fnVal = &ast.ParenExpr{X: fnVal} 785 } 786 if len(args) == 1 && ConvertibleTo(pkg, args[0].Type, typ) { 787 if args[0].CVal != nil { 788 if t, ok := typ.(*types.Named); ok { 789 o := t.Obj() 790 if at := o.Pkg(); at != nil { 791 tname := o.Name() 792 if checkUntypedOverflows(at.Scope(), tname, args[0]) { 793 src, pos := pkg.cb.loadExpr(args[0].Src) 794 err = pkg.cb.newCodeError(pos, fmt.Sprintf("cannot convert %v (untyped int constant %v) to type %v", src, args[0].CVal, tname)) 795 return 796 } 797 } 798 } 799 } 800 goto finish 801 } 802 803 switch t := typ.(type) { 804 case *types.Basic: 805 if len(args) == 1 { 806 if ret, ok := CastFromBool(&pkg.cb, typ, args[0]); ok { 807 return ret, nil 808 } 809 } 810 case *types.Named: 811 o := t.Obj() 812 if at := o.Pkg(); at != nil { 813 tname := o.Name() 814 scope := at.Scope() 815 name := tname + "_Cast" 816 if cast := scope.Lookup(name); cast != nil { 817 if len(args) == 1 && args[0].CVal != nil { 818 if checkUntypedOverflows(scope, tname, args[0]) { 819 src, pos := pkg.cb.loadExpr(args[0].Src) 820 err = pkg.cb.newCodeError(pos, fmt.Sprintf("cannot convert %v (untyped int constant %v) to type %v", src, args[0].CVal, tname)) 821 return 822 } 823 } 824 castFn := &internal.Elem{Val: toObjectExpr(pkg, cast), Type: cast.Type()} 825 if ret, err = matchFuncCall(pkg, castFn, args, flags); err == nil { 826 if ret.CVal == nil && len(args) == 1 && checkUntypedType(scope, tname) { 827 ret.CVal = args[0].CVal 828 } 829 return 830 } 831 } 832 } 833 } 834 835 switch len(args) { 836 case 1: 837 arg := args[0] 838 switch t := arg.Type.(type) { 839 case *types.Named: 840 if m := lookupMethod(t, "Gop_Rcast"); m != nil { 841 switch mt := m.Type().(type) { 842 case *types.Signature: 843 if funcs, ok := CheckOverloadMethod(mt); ok { 844 for _, o := range funcs { 845 if ret, err = matchRcast(pkg, arg, o, typ, flags); err == nil { 846 return 847 } 848 } 849 } else if ret, err = matchRcast(pkg, arg, m, typ, flags); err == nil { 850 return 851 } 852 } 853 } 854 } 855 case 0: 856 // T() means to return zero value of T 857 return pkg.cb.ZeroLit(typ).stk.Pop(), nil 858 } 859 860 finish: 861 valArgs := make([]ast.Expr, len(args)) 862 for i, v := range args { // TODO: type check 863 valArgs[i] = v.Val 864 } 865 ret = &internal.Elem{ 866 Val: &ast.CallExpr{Fun: fnVal, Args: valArgs, Ellipsis: token.Pos(flags & InstrFlagEllipsis)}, 867 Type: typ, 868 } 869 if len(args) == 1 { // TODO: const value may changed by type-convert 870 ret.CVal = args[0].CVal 871 } 872 return 873 } 874 875 func matchRcast(pkg *Package, fn *internal.Elem, m types.Object, typ types.Type, flags InstrFlags) (ret *internal.Elem, err error) { 876 sig := m.Type().(*types.Signature) 877 if sig.Params().Len() != 0 { 878 log.Panicf("TODO: method %v should haven't no arguments\n", m) 879 } 880 n := 1 881 if (flags & InstrFlagTwoValue) != 0 { 882 n = 2 883 } 884 results := sig.Results() 885 if results.Len() != n { 886 return nil, fmt.Errorf("TODO: %v should return %d results", m, n) 887 } 888 if types.Identical(results.At(0).Type(), typ) { 889 return pkg.cb.Val(fn).MemberVal(m.Name()).CallWith(0, flags).stk.Pop(), nil 890 } 891 return nil, &MatchError{ 892 Src: fn.Src, Arg: fn.Type, Param: typ, At: "Gop_Rcast", 893 Fset: pkg.cb.fset, intr: pkg.cb.interp, 894 } 895 } 896 897 // CastFromBool tries to cast a bool expression into integer. typ must be an integer type. 898 func CastFromBool(cb *CodeBuilder, typ types.Type, v *Element) (ret *Element, ok bool) { 899 if ok = isBool(cb, v); ok { 900 if v.CVal != nil { // untyped bool 901 var val int 902 if constant.BoolVal(v.CVal) { 903 val = 1 904 } 905 return toExpr(nil, val, v.Src), true 906 } 907 pkg := cb.pkg 908 results := types.NewTuple(types.NewParam(token.NoPos, pkg.Types, "", typ)) 909 ret = cb.NewClosure(nil, results, false).BodyStart(pkg). 910 If().Val(v).Then().Val(1).Return(1). 911 Else().Val(0).Return(1). 912 End(). 913 End().Call(0). 914 stk.Pop() 915 } 916 return 917 } 918 919 func isPointer(typ types.Type) bool { 920 _, ok := typ.(*types.Pointer) 921 return ok 922 } 923 924 func checkParenExpr(x ast.Expr) ast.Expr { 925 switch v := x.(type) { 926 case *ast.CompositeLit: 927 return &ast.ParenExpr{X: x} 928 case *ast.SelectorExpr: 929 v.X = checkParenExpr(v.X) 930 } 931 return x 932 } 933 934 type backupElem struct { 935 typ types.Type 936 val ast.Expr 937 } 938 939 func backupArgs(args []*internal.Elem) []backupElem { 940 backup := make([]backupElem, len(args)) 941 for i, arg := range args { 942 backup[i].typ, backup[i].val = arg.Type, arg.Val 943 } 944 return backup 945 } 946 947 func restoreArgs(args []*internal.Elem, backup []backupElem) { 948 for i, arg := range args { 949 arg.Type, arg.Val = backup[i].typ, backup[i].val 950 } 951 } 952 953 func copyArgs(args []*internal.Elem) []*internal.Elem { 954 backup := make([]*internal.Elem, len(args)) 955 copy(backup, args) 956 return backup 957 } 958 959 func untypeBig(pkg *Package, cval constant.Value, tyRet types.Type) (*internal.Elem, bool) { 960 switch tyRet { 961 case pkg.utBigInt: 962 var val *big.Int 963 switch v := constant.Val(cval).(type) { 964 case int64: 965 val = big.NewInt(v) 966 case *big.Int: 967 val = v 968 case *big.Rat: 969 return pkg.cb.UntypedBigRat(v).stk.Pop(), true 970 default: 971 panic("unexpected constant") 972 } 973 return pkg.cb.UntypedBigInt(val).stk.Pop(), true 974 case pkg.utBigRat: 975 var val *big.Rat 976 switch v := constant.Val(cval).(type) { 977 case int64: 978 val = big.NewRat(v, 1) 979 case *big.Rat: 980 val = v 981 case *big.Int: 982 val = new(big.Rat).SetInt(v) 983 default: 984 panic("unexpected constant") 985 } 986 return pkg.cb.UntypedBigRat(val).stk.Pop(), true 987 case types.Typ[types.UntypedBool], types.Typ[types.Bool]: 988 return &internal.Elem{ 989 Val: boolean(constant.BoolVal(cval)), Type: tyRet, CVal: cval, 990 }, true 991 } 992 return nil, false 993 } 994 995 func toRetType(t *types.Tuple, it *instantiated) types.Type { 996 if t == nil { 997 return nil 998 } else if t.Len() == 1 { 999 return it.normalize(t.At(0).Type()) 1000 } 1001 return it.normalizeTuple(t) 1002 } 1003 1004 func matchFuncType( 1005 pkg *Package, args []*internal.Elem, flags InstrFlags, sig *types.Signature, fn *internal.Elem) error { 1006 if (flags & InstrFlagTwoValue) != 0 { 1007 if n := sig.Results().Len(); n != 2 { 1008 caller, pos := getFunExpr(fn) 1009 return pkg.cb.newCodeErrorf(pos, "assignment mismatch: 2 variables but %v returns %v values", caller, n) 1010 } 1011 } 1012 var t *types.Tuple 1013 n := len(args) 1014 if len(args) == 1 && checkTuple(&t, args[0].Type) { 1015 n = t.Len() 1016 args = make([]*internal.Elem, n) 1017 for i := 0; i < n; i++ { 1018 args[i] = &internal.Elem{Type: t.At(i).Type()} 1019 } 1020 } else if (flags&instrFlagApproxType) != 0 && n > 0 { 1021 if typ, ok := args[0].Type.(*types.Named); ok { 1022 switch t := pkg.cb.getUnderlying(typ).(type) { 1023 case *types.Slice, *types.Map, *types.Chan: 1024 args[0].Type = t 1025 } 1026 } 1027 } 1028 var at interface{} 1029 if fn == nil { 1030 at = "closure argument" // fn = nil means it is a closure 1031 } else { 1032 at = func() string { 1033 src, _ := pkg.cb.loadExpr(fn.Src) 1034 return "argument to " + src 1035 } 1036 } 1037 if sig.Variadic() { 1038 if (flags & InstrFlagEllipsis) == 0 { 1039 n1 := getParamLen(sig) - 1 1040 if n < n1 { 1041 caller, pos := getFunExpr(fn) 1042 return pkg.cb.newCodeErrorf(pos, "not enough arguments in call to %v\n\thave (%v)\n\twant %v", 1043 caller, getTypes(args), sig.Params()) 1044 } 1045 tyVariadic, ok := getParam(sig, n1).Type().(*types.Slice) 1046 if !ok { 1047 return errors.New("TODO: tyVariadic not a slice") 1048 } 1049 if err := matchFuncArgs(pkg, args[:n1], sig, at); err != nil { 1050 return err 1051 } 1052 return matchElemType(pkg, args[n1:], tyVariadic.Elem(), at) 1053 } 1054 } else if (flags & InstrFlagEllipsis) != 0 { 1055 caller, pos := getFunExpr(fn) 1056 return pkg.cb.newCodeErrorf(pos, "cannot use ... in call to non-variadic %v", caller) 1057 } 1058 if nreq := getParamLen(sig); nreq != n { 1059 fewOrMany := "not enough" 1060 if n > nreq { 1061 fewOrMany = "too many" 1062 } 1063 caller, pos := getFunExpr(fn) 1064 return pkg.cb.newCodeErrorf(pos, 1065 "%s arguments in call to %s\n\thave (%v)\n\twant %v", fewOrMany, caller, getTypes(args), sig.Params()) 1066 } 1067 return matchFuncArgs(pkg, args, sig, at) 1068 } 1069 1070 func matchFuncArgs( 1071 pkg *Package, args []*internal.Elem, sig *types.Signature, at interface{}) error { 1072 for i, arg := range args { 1073 if err := matchType(pkg, arg, getParam(sig, i).Type(), at); err != nil { 1074 return err 1075 } 1076 } 1077 return nil 1078 } 1079 1080 func checkFuncResults(pkg *Package, rets []*internal.Elem, results *types.Tuple, src ast.Node) { 1081 n := len(rets) 1082 need := results.Len() 1083 switch n { 1084 case 0: 1085 if need > 0 && isUnnamedParams(results) { 1086 pos := getSrcPos(src) 1087 pkg.cb.panicCodeErrorf( 1088 pos, "not enough arguments to return\n\thave ()\n\twant %v", results) 1089 } 1090 return 1091 case 1: 1092 if t, ok := rets[0].Type.(*types.Tuple); ok { 1093 if n1 := t.Len(); n1 != need { 1094 fewOrMany := "few" 1095 if n1 > need { 1096 fewOrMany = "many" 1097 } 1098 pos := getSrcPos(src) 1099 pkg.cb.panicCodeErrorf( 1100 pos, "too %s arguments to return\n\thave %v\n\twant %v", fewOrMany, t, results) 1101 } 1102 for i := 0; i < need; i++ { 1103 arg := &internal.Elem{Type: t.At(i).Type(), Src: src} 1104 if err := matchType(pkg, arg, results.At(i).Type(), "return argument"); err != nil { 1105 panic(err) 1106 } 1107 } 1108 return 1109 } 1110 } 1111 if n == need { 1112 for i := 0; i < need; i++ { 1113 if err := matchType(pkg, rets[i], results.At(i).Type(), "return argument"); err != nil { 1114 panic(err) 1115 } 1116 } 1117 return 1118 } 1119 fewOrMany := "few" 1120 if n > need { 1121 fewOrMany = "many" 1122 } 1123 pos := getSrcPos(src) 1124 pkg.cb.panicCodeErrorf( 1125 pos, "too %s arguments to return\n\thave (%v)\n\twant %v", fewOrMany, getTypes(rets), results) 1126 } 1127 1128 func getTypes(rets []*internal.Elem) string { 1129 typs := make([]string, len(rets)) 1130 for i, ret := range rets { 1131 typs[i] = ret.Type.String() 1132 } 1133 return strings.Join(typs, ", ") 1134 } 1135 1136 func isUnnamedParams(t *types.Tuple) bool { 1137 if t == nil { 1138 return true 1139 } 1140 for i, n := 0, t.Len(); i < n; i++ { 1141 if t.At(i).Name() == "" { 1142 return true 1143 } 1144 } 1145 return false 1146 } 1147 1148 func matchElemType(pkg *Package, vals []*internal.Elem, elt types.Type, at interface{}) error { 1149 for _, val := range vals { 1150 if err := matchType(pkg, val, elt, at); err != nil { 1151 return err 1152 } 1153 } 1154 return nil 1155 } 1156 1157 func checkAssignType(pkg *Package, varRef types.Type, val *internal.Elem) { 1158 if rt, ok := varRef.(*refType); ok { 1159 if err := matchType(pkg, val, rt.typ, "assignment"); err != nil { 1160 panic(err) 1161 } 1162 } else if varRef == nil { // underscore 1163 // do nothing 1164 if t, ok := val.Type.(*inferFuncType); ok { 1165 t.Instance() 1166 } 1167 } else { 1168 panic("TODO: unassignable") 1169 } 1170 } 1171 1172 func checkAssign(pkg *Package, ref *internal.Elem, val types.Type, at string) { 1173 if rt, ok := ref.Type.(*refType); ok { 1174 elem := &internal.Elem{Type: val} 1175 if err := matchType(pkg, elem, rt.typ, at); err != nil { 1176 src, pos := pkg.cb.loadExpr(ref.Src) 1177 pkg.cb.panicCodeErrorf( 1178 pos, "cannot assign type %v to %s (type %v) in %s", val, src, rt.typ, at) 1179 } 1180 } else if ref.Type == nil { // underscore 1181 // do nothing 1182 } else { 1183 panic("TODO: unassignable") 1184 } 1185 } 1186 1187 type MatchError struct { 1188 Fset dbgPositioner 1189 Src ast.Node 1190 Arg types.Type 1191 Param types.Type 1192 At interface{} 1193 1194 intr NodeInterpreter 1195 fstmt bool 1196 } 1197 1198 func strval(at interface{}) string { 1199 switch v := at.(type) { 1200 case string: 1201 return v 1202 case func() string: 1203 return v() 1204 default: 1205 panic("strval unexpected: unknown type") 1206 } 1207 } 1208 1209 func (p *MatchError) Message(fileLine string) string { 1210 if p.fstmt { 1211 return fmt.Sprintf( 1212 "%scannot use %v value as type %v in %s", fileLine, p.Arg, p.Param, strval(p.At)) 1213 } 1214 src := "" 1215 if p.Src != nil { 1216 src = p.intr.LoadExpr(p.Src) 1217 } 1218 return fmt.Sprintf( 1219 "%scannot use %s (type %v) as type %v in %s", fileLine, src, p.Arg, p.Param, strval(p.At)) 1220 } 1221 1222 func (p *MatchError) Pos() token.Pos { 1223 return getSrcPos(p.Src) 1224 } 1225 1226 func (p *MatchError) Error() string { 1227 pos := p.Fset.Position(p.Pos()) 1228 return p.Message(pos.String() + ": ") 1229 } 1230 1231 // TODO: use matchType to all assignable check 1232 func matchType(pkg *Package, arg *internal.Elem, param types.Type, at interface{}) error { 1233 if debugMatch { 1234 cval := "" 1235 if arg.CVal != nil { 1236 cval = fmt.Sprintf(" (%v)", arg.CVal) 1237 } 1238 log.Printf("==> MatchType %v%s, %v\n", arg.Type, cval, param) 1239 } 1240 if arg.Type == nil { 1241 src, pos := pkg.cb.loadExpr(arg.Src) 1242 return pkg.cb.newCodeError(pos, fmt.Sprintf("%v (no value) used as value", src)) 1243 } 1244 // check untyped big int/rat/flt => interface 1245 switch arg.Type { 1246 case pkg.utBigInt, pkg.utBigRat, pkg.utBigFlt: 1247 typ := param 1248 retry: 1249 switch t := typ.(type) { 1250 case *types.Interface: 1251 arg.Type = DefaultConv(pkg, arg.Type, arg) 1252 if t.NumMethods() == 0 { 1253 return nil 1254 } 1255 case *types.Named: 1256 typ = t.Underlying() 1257 goto retry 1258 } 1259 } 1260 switch t := param.(type) { 1261 case *types.Named: 1262 if t2, ok := arg.Type.(*types.Basic); ok { 1263 if t == pkg.utBigInt { 1264 switch t2.Kind() { 1265 case types.UntypedInt: 1266 val, _ := new(big.Int).SetString(arg.CVal.ExactString(), 10) 1267 arg.Val = pkg.cb.UntypedBigInt(val).stk.Pop().Val 1268 return nil 1269 case types.UntypedFloat: 1270 val, ok := new(big.Int).SetString(arg.CVal.ExactString(), 10) 1271 if !ok { 1272 code, pos := pkg.cb.loadExpr(arg.Src) 1273 pkg.cb.panicCodeErrorf(pos, "cannot convert %v (untyped float constant) to %v", code, t) 1274 } 1275 arg.Val = pkg.cb.UntypedBigInt(val).stk.Pop().Val 1276 return nil 1277 } 1278 } 1279 } 1280 case *unboundType: // variable to bound type 1281 if t2, ok := arg.Type.(*unboundType); ok { 1282 if t2.tBound == nil { 1283 if t == t2 { 1284 return nil 1285 } 1286 return fmt.Errorf("TODO: can't match two unboundTypes") 1287 } 1288 arg.Type = t2.tBound 1289 } 1290 if t.tBound == nil { 1291 arg.Type = DefaultConv(pkg, arg.Type, arg) 1292 t.boundTo(pkg, arg.Type) 1293 } 1294 param = t.tBound 1295 case *unboundMapElemType: 1296 if t2, ok := arg.Type.(*unboundType); ok { 1297 if t2.tBound == nil { 1298 panic("TODO: don't pass unbound variables") 1299 } 1300 arg.Type = t2.tBound 1301 } 1302 arg.Type = DefaultConv(pkg, arg.Type, arg) 1303 mapTy := types.NewMap(Default(pkg, t.key), arg.Type) 1304 t.typ.boundTo(pkg, mapTy) 1305 return nil 1306 default: 1307 if isUnboundParam(param) { 1308 if t, ok := arg.Type.(*unboundType); ok { 1309 if t.tBound == nil { 1310 // panic("TODO: don't pass unbound variables as template function params.") 1311 return nil 1312 } 1313 arg.Type = t.tBound 1314 } 1315 return boundType(pkg, arg.Type, param, arg) 1316 } 1317 } 1318 if AssignableConv(pkg, arg.Type, param, arg) { 1319 return nil 1320 } 1321 return &MatchError{ 1322 Src: arg.Src, Arg: arg.Type, Param: param, At: at, fstmt: arg.Val == nil, 1323 Fset: pkg.cb.fset, intr: pkg.cb.interp, 1324 } 1325 } 1326 1327 // ----------------------------------------------------------------------------- 1328 1329 func boundElementType(pkg *Package, elts []*internal.Elem, base, max, step int) types.Type { 1330 var tBound types.Type 1331 for i := base; i < max; i += step { 1332 e := elts[i] 1333 if tBound == e.Type { 1334 // nothing to do 1335 } else if tBound == nil || AssignableTo(pkg, tBound, e.Type) { 1336 tBound = e.Type 1337 } else if !AssignableTo(pkg, e.Type, tBound) { 1338 return TyEmptyInterface 1339 } 1340 } 1341 return tBound 1342 } 1343 1344 func constantToBigInt(v constant.Value) (*big.Int, bool) { 1345 if v.Kind() == constant.Int { 1346 return new(big.Int).SetString(v.String(), 10) 1347 } 1348 return new(big.Int).SetString(v.ExactString(), 10) 1349 } 1350 1351 func checkUntypedType(scope *types.Scope, tname string) bool { 1352 c, ok := scope.Lookup(tname + "_IsUntyped").(*types.Const) 1353 if ok { 1354 if val := c.Val(); val != nil && val.Kind() == constant.Bool { 1355 return constant.BoolVal(val) 1356 } 1357 } 1358 return false 1359 } 1360 1361 func checkUntypedOverflows(scope *types.Scope, tname string, arg *internal.Elem) bool { 1362 cmax, ok1 := scope.Lookup(tname + "_Max").(*types.Const) 1363 cmin, ok2 := scope.Lookup(tname + "_Min").(*types.Const) 1364 if ok1 || ok2 { 1365 cv, ok := constantToBigInt(arg.CVal) 1366 if ok { 1367 if ok1 { 1368 if max, ok := constantToBigInt(cmax.Val()); ok { 1369 if cv.Cmp(max) > 0 { 1370 return true 1371 } 1372 } 1373 } 1374 if ok2 { 1375 if min, ok := constantToBigInt(cmin.Val()); ok { 1376 if cv.Cmp(min) < 0 { 1377 return true 1378 } 1379 } 1380 } 1381 } 1382 } 1383 return false 1384 } 1385 1386 // -----------------------------------------------------------------------------