OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // TODO(rsc): Once there is better support for writing | 5 // TODO(rsc): Once there is better support for writing |
6 // multi-package commands, this should really be in | 6 // multi-package commands, this should really be in |
7 // its own package, and then we can drop all the "reflect" | 7 // its own package, and then we can drop all the "reflect" |
8 // prefixes on the global variables and functions. | 8 // prefixes on the global variables and functions. |
9 | 9 |
10 package main | 10 package main |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 call, ok := n.(*ast.CallExpr) | 233 call, ok := n.(*ast.CallExpr) |
234 if !ok || len(call.Args) != 1 || !isTopName(call.Args[0], "nil")
{ | 234 if !ok || len(call.Args) != 1 || !isTopName(call.Args[0], "nil")
{ |
235 return | 235 return |
236 } | 236 } |
237 sel, ok := call.Fun.(*ast.SelectorExpr) | 237 sel, ok := call.Fun.(*ast.SelectorExpr) |
238 if !ok || !isReflectValue[typeof[sel.X]] || sel.Sel.Name != "Set
" { | 238 if !ok || !isReflectValue[typeof[sel.X]] || sel.Sel.Name != "Set
" { |
239 return | 239 return |
240 } | 240 } |
241 call.Args[0] = &ast.CallExpr{ | 241 call.Args[0] = &ast.CallExpr{ |
242 Fun: newPkgDot(call.Args[0].Pos(), "reflect", "Zero"), | 242 Fun: newPkgDot(call.Args[0].Pos(), "reflect", "Zero"), |
243 » » » Args: []ast.Expr{ | 243 » » » Args: { |
244 &ast.CallExpr{ | 244 &ast.CallExpr{ |
245 Fun: &ast.SelectorExpr{ | 245 Fun: &ast.SelectorExpr{ |
246 X: sel.X, | 246 X: sel.X, |
247 » » » » » » Sel: &ast.Ident{Name: "Type"}, | 247 » » » » » » Sel: {Name: "Type"}, |
248 }, | 248 }, |
249 }, | 249 }, |
250 }, | 250 }, |
251 } | 251 } |
252 fixed = true | 252 fixed = true |
253 }) | 253 }) |
254 | 254 |
255 // Rewrite v != nil to v.IsValid(). | 255 // Rewrite v != nil to v.IsValid(). |
256 // Rewrite nil used as reflect.Value (in function argument or return) to
reflect.Value{}. | 256 // Rewrite nil used as reflect.Value (in function argument or return) to
reflect.Value{}. |
257 walk(f, func(n interface{}) { | 257 walk(f, func(n interface{}) { |
258 ptr, ok := n.(*ast.Expr) | 258 ptr, ok := n.(*ast.Expr) |
259 if !ok { | 259 if !ok { |
260 return | 260 return |
261 } | 261 } |
262 if isTopName(*ptr, "nil") && isReflectValue[typeof[*ptr]] { | 262 if isTopName(*ptr, "nil") && isReflectValue[typeof[*ptr]] { |
263 *ptr = ast.NewIdent("reflect.Value{}") | 263 *ptr = ast.NewIdent("reflect.Value{}") |
264 fixed = true | 264 fixed = true |
265 return | 265 return |
266 } | 266 } |
267 nn, ok := (*ptr).(*ast.BinaryExpr) | 267 nn, ok := (*ptr).(*ast.BinaryExpr) |
268 if !ok || (nn.Op != token.EQL && nn.Op != token.NEQ) || !isTopNa
me(nn.Y, "nil") || !isReflectValue[typeof[nn.X]] { | 268 if !ok || (nn.Op != token.EQL && nn.Op != token.NEQ) || !isTopNa
me(nn.Y, "nil") || !isReflectValue[typeof[nn.X]] { |
269 return | 269 return |
270 } | 270 } |
271 var call ast.Expr = &ast.CallExpr{ | 271 var call ast.Expr = &ast.CallExpr{ |
272 Fun: &ast.SelectorExpr{ | 272 Fun: &ast.SelectorExpr{ |
273 X: nn.X, | 273 X: nn.X, |
274 » » » » Sel: &ast.Ident{Name: "IsValid"}, | 274 » » » » Sel: {Name: "IsValid"}, |
275 }, | 275 }, |
276 } | 276 } |
277 if nn.Op == token.EQL { | 277 if nn.Op == token.EQL { |
278 call = &ast.UnaryExpr{Op: token.NOT, X: call} | 278 call = &ast.UnaryExpr{Op: token.NOT, X: call} |
279 } | 279 } |
280 *ptr = call | 280 *ptr = call |
281 fixed = true | 281 fixed = true |
282 }) | 282 }) |
283 | 283 |
284 // Rewrite | 284 // Rewrite |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 if isBlank(x) || x != nil && z != nil && x.Name == z.Name && !as
signsTo(x, ts.Body.List) { | 349 if isBlank(x) || x != nil && z != nil && x.Name == z.Name && !as
signsTo(x, ts.Body.List) { |
350 // Can drop the variable creation. | 350 // Can drop the variable creation. |
351 rcvr = ta.X | 351 rcvr = ta.X |
352 } else { | 352 } else { |
353 // Need to use initialization statement. | 353 // Need to use initialization statement. |
354 if init != nil { | 354 if init != nil { |
355 warn(ts.Pos(), "cannot rewrite reflect type swit
ch with initializing statement") | 355 warn(ts.Pos(), "cannot rewrite reflect type swit
ch with initializing statement") |
356 return false | 356 return false |
357 } | 357 } |
358 init = &ast.AssignStmt{ | 358 init = &ast.AssignStmt{ |
359 » » » » Lhs: []ast.Expr{as.Lhs[0]}, | 359 » » » » Lhs: {as.Lhs[0]}, |
360 TokPos: as.TokPos, | 360 TokPos: as.TokPos, |
361 Tok: token.DEFINE, | 361 Tok: token.DEFINE, |
362 » » » » Rhs: []ast.Expr{ta.X}, | 362 » » » » Rhs: {ta.X}, |
363 } | 363 } |
364 rcvr = as.Lhs[0] | 364 rcvr = as.Lhs[0] |
365 } | 365 } |
366 | 366 |
367 case *ast.ExprStmt: | 367 case *ast.ExprStmt: |
368 rcvr = n.X.(*ast.TypeAssertExpr).X | 368 rcvr = n.X.(*ast.TypeAssertExpr).X |
369 } | 369 } |
370 | 370 |
371 // Prepare rewritten type switch (see large comment above for form). | 371 // Prepare rewritten type switch (see large comment above for form). |
372 sw := &ast.SwitchStmt{ | 372 sw := &ast.SwitchStmt{ |
373 Switch: ts.Switch, | 373 Switch: ts.Switch, |
374 Init: init, | 374 Init: init, |
375 Tag: &ast.CallExpr{ | 375 Tag: &ast.CallExpr{ |
376 Fun: &ast.SelectorExpr{ | 376 Fun: &ast.SelectorExpr{ |
377 X: rcvr, | 377 X: rcvr, |
378 » » » » Sel: &ast.Ident{ | 378 » » » » Sel: { |
379 NamePos: rcvr.End(), | 379 NamePos: rcvr.End(), |
380 Name: "Kind", | 380 Name: "Kind", |
381 Obj: nil, | 381 Obj: nil, |
382 }, | 382 }, |
383 }, | 383 }, |
384 Lparen: rcvr.End(), | 384 Lparen: rcvr.End(), |
385 Rparen: rcvr.End(), | 385 Rparen: rcvr.End(), |
386 }, | 386 }, |
387 » » Body: &ast.BlockStmt{ | 387 » » Body: { |
388 Lbrace: ts.Body.Lbrace, | 388 Lbrace: ts.Body.Lbrace, |
389 List: nil, // to be filled in | 389 List: nil, // to be filled in |
390 Rbrace: ts.Body.Rbrace, | 390 Rbrace: ts.Body.Rbrace, |
391 }, | 391 }, |
392 } | 392 } |
393 | 393 |
394 // Translate cases. | 394 // Translate cases. |
395 for _, tcas := range ts.Body.List { | 395 for _, tcas := range ts.Body.List { |
396 tcas := tcas.(*ast.CaseClause) | 396 tcas := tcas.(*ast.CaseClause) |
397 cas := &ast.CaseClause{ | 397 cas := &ast.CaseClause{ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 var rcvr ast.Expr | 464 var rcvr ast.Expr |
465 if isBlank(x) || | 465 if isBlank(x) || |
466 as.Tok == token.DEFINE && x != nil && z != nil && x.Name == z.Na
me && !assignsTo(x, scope) { | 466 as.Tok == token.DEFINE && x != nil && z != nil && x.Name == z.Na
me && !assignsTo(x, scope) { |
467 // Can drop the statement. | 467 // Can drop the statement. |
468 // If we need to insert a statement later, now we have a slot. | 468 // If we need to insert a statement later, now we have a slot. |
469 *ptr = &ast.EmptyStmt{} | 469 *ptr = &ast.EmptyStmt{} |
470 insert = func(x ast.Stmt) { *ptr = x } | 470 insert = func(x ast.Stmt) { *ptr = x } |
471 rcvr = ta.X | 471 rcvr = ta.X |
472 } else { | 472 } else { |
473 *ptr = &ast.AssignStmt{ | 473 *ptr = &ast.AssignStmt{ |
474 » » » Lhs: []ast.Expr{as.Lhs[0]}, | 474 » » » Lhs: {as.Lhs[0]}, |
475 TokPos: as.TokPos, | 475 TokPos: as.TokPos, |
476 Tok: as.Tok, | 476 Tok: as.Tok, |
477 » » » Rhs: []ast.Expr{ta.X}, | 477 » » » Rhs: {ta.X}, |
478 } | 478 } |
479 rcvr = as.Lhs[0] | 479 rcvr = as.Lhs[0] |
480 } | 480 } |
481 | 481 |
482 // Prepare x.Kind() == T expression appropriate to t. | 482 // Prepare x.Kind() == T expression appropriate to t. |
483 // If x is not a simple identifier, warn that we might be | 483 // If x is not a simple identifier, warn that we might be |
484 // reevaluating x. | 484 // reevaluating x. |
485 if x == nil { | 485 if x == nil { |
486 warn(as.Pos(), "rewrite reevaluates expr with possible side effe
cts: %s", gofmt(as.Lhs[0])) | 486 warn(as.Pos(), "rewrite reevaluates expr with possible side effe
cts: %s", gofmt(as.Lhs[0])) |
487 } | 487 } |
488 yExpr, yNotExpr := reflectKindEq(rcvr, reflectKind[typ]) | 488 yExpr, yNotExpr := reflectKindEq(rcvr, reflectKind[typ]) |
489 | 489 |
490 // Second step is y := x.Kind() == T, unless it's only used once | 490 // Second step is y := x.Kind() == T, unless it's only used once |
491 // or we have no way to insert that statement. | 491 // or we have no way to insert that statement. |
492 var yStmt *ast.AssignStmt | 492 var yStmt *ast.AssignStmt |
493 if as.Tok == token.DEFINE && countUses(y, scope) <= 1 || insert == nil { | 493 if as.Tok == token.DEFINE && countUses(y, scope) <= 1 || insert == nil { |
494 // Can drop the statement and use the expression directly. | 494 // Can drop the statement and use the expression directly. |
495 rewriteUses(y, | 495 rewriteUses(y, |
496 func(token.Pos) ast.Expr { return yExpr }, | 496 func(token.Pos) ast.Expr { return yExpr }, |
497 func(token.Pos) ast.Expr { return yNotExpr }, | 497 func(token.Pos) ast.Expr { return yNotExpr }, |
498 scope) | 498 scope) |
499 } else { | 499 } else { |
500 yStmt = &ast.AssignStmt{ | 500 yStmt = &ast.AssignStmt{ |
501 » » » Lhs: []ast.Expr{as.Lhs[1]}, | 501 » » » Lhs: {as.Lhs[1]}, |
502 TokPos: as.End(), | 502 TokPos: as.End(), |
503 Tok: as.Tok, | 503 Tok: as.Tok, |
504 » » » Rhs: []ast.Expr{yExpr}, | 504 » » » Rhs: {yExpr}, |
505 } | 505 } |
506 insert(yStmt) | 506 insert(yStmt) |
507 } | 507 } |
508 return true | 508 return true |
509 } | 509 } |
510 | 510 |
511 // reflectKindEq returns the expression z.Kind() == kinds[0] || z.Kind() == kind
s[1] || ... | 511 // reflectKindEq returns the expression z.Kind() == kinds[0] || z.Kind() == kind
s[1] || ... |
512 // and its negation. | 512 // and its negation. |
513 // The qualifier "reflect." is inserted before each kinds[i] expression. | 513 // The qualifier "reflect." is inserted before each kinds[i] expression. |
514 func reflectKindEq(z ast.Expr, kinds []string) (ast.Expr, ast.Expr) { | 514 func reflectKindEq(z ast.Expr, kinds []string) (ast.Expr, ast.Expr) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 | 609 |
610 // Tables describing the transformations. | 610 // Tables describing the transformations. |
611 | 611 |
612 // Description of old reflect API for partial type checking. | 612 // Description of old reflect API for partial type checking. |
613 // We pretend the Elem method is on Type and Value instead | 613 // We pretend the Elem method is on Type and Value instead |
614 // of enumerating all the types it is actually on. | 614 // of enumerating all the types it is actually on. |
615 // Also, we pretend that ArrayType etc embeds Type for the | 615 // Also, we pretend that ArrayType etc embeds Type for the |
616 // purposes of describing the API. (In fact they embed commonType, | 616 // purposes of describing the API. (In fact they embed commonType, |
617 // which implements Type.) | 617 // which implements Type.) |
618 var reflectTypeConfig = &TypeConfig{ | 618 var reflectTypeConfig = &TypeConfig{ |
619 » Type: map[string]*Type{ | 619 » Type: { |
620 » » "reflect.ArrayOrSliceType": {Embed: []string{"reflect.Type"}}, | 620 » » "reflect.ArrayOrSliceType": {Embed: {"reflect.Type"}}, |
621 » » "reflect.ArrayOrSliceValue": {Embed: []string{"reflect.Value"}}, | 621 » » "reflect.ArrayOrSliceValue": {Embed: {"reflect.Value"}}, |
622 » » "reflect.ArrayType": {Embed: []string{"reflect.Type"}}, | 622 » » "reflect.ArrayType": {Embed: {"reflect.Type"}}, |
623 » » "reflect.ArrayValue": {Embed: []string{"reflect.Value"}}, | 623 » » "reflect.ArrayValue": {Embed: {"reflect.Value"}}, |
624 » » "reflect.BoolType": {Embed: []string{"reflect.Type"}}, | 624 » » "reflect.BoolType": {Embed: {"reflect.Type"}}, |
625 » » "reflect.BoolValue": {Embed: []string{"reflect.Value"}}, | 625 » » "reflect.BoolValue": {Embed: {"reflect.Value"}}, |
626 » » "reflect.ChanType": {Embed: []string{"reflect.Type"}}, | 626 » » "reflect.ChanType": {Embed: {"reflect.Type"}}, |
627 "reflect.ChanValue": { | 627 "reflect.ChanValue": { |
628 » » » Method: map[string]string{ | 628 » » » Method: { |
629 "Recv": "func() (reflect.Value, bool)", | 629 "Recv": "func() (reflect.Value, bool)", |
630 "TryRecv": "func() (reflect.Value, bool)", | 630 "TryRecv": "func() (reflect.Value, bool)", |
631 }, | 631 }, |
632 » » » Embed: []string{"reflect.Value"}, | 632 » » » Embed: {"reflect.Value"}, |
633 }, | 633 }, |
634 » » "reflect.ComplexType": {Embed: []string{"reflect.Type"}}, | 634 » » "reflect.ComplexType": {Embed: {"reflect.Type"}}, |
635 » » "reflect.ComplexValue": {Embed: []string{"reflect.Value"}}, | 635 » » "reflect.ComplexValue": {Embed: {"reflect.Value"}}, |
636 » » "reflect.FloatType": {Embed: []string{"reflect.Type"}}, | 636 » » "reflect.FloatType": {Embed: {"reflect.Type"}}, |
637 » » "reflect.FloatValue": {Embed: []string{"reflect.Value"}}, | 637 » » "reflect.FloatValue": {Embed: {"reflect.Value"}}, |
638 "reflect.FuncType": { | 638 "reflect.FuncType": { |
639 » » » Method: map[string]string{ | 639 » » » Method: { |
640 "In": "func(int) reflect.Type", | 640 "In": "func(int) reflect.Type", |
641 "Out": "func(int) reflect.Type", | 641 "Out": "func(int) reflect.Type", |
642 }, | 642 }, |
643 » » » Embed: []string{"reflect.Type"}, | 643 » » » Embed: {"reflect.Type"}, |
644 }, | 644 }, |
645 "reflect.FuncValue": { | 645 "reflect.FuncValue": { |
646 » » » Method: map[string]string{ | 646 » » » Method: { |
647 "Call": "func([]reflect.Value) []reflect.Value", | 647 "Call": "func([]reflect.Value) []reflect.Value", |
648 }, | 648 }, |
649 }, | 649 }, |
650 » » "reflect.IntType": {Embed: []string{"reflect.Type"}}, | 650 » » "reflect.IntType": {Embed: {"reflect.Type"}}, |
651 » » "reflect.IntValue": {Embed: []string{"reflect.Value"}}, | 651 » » "reflect.IntValue": {Embed: {"reflect.Value"}}, |
652 » » "reflect.InterfaceType": {Embed: []string{"reflect.Type"}}, | 652 » » "reflect.InterfaceType": {Embed: {"reflect.Type"}}, |
653 » » "reflect.InterfaceValue": {Embed: []string{"reflect.Value"}}, | 653 » » "reflect.InterfaceValue": {Embed: {"reflect.Value"}}, |
654 "reflect.MapType": { | 654 "reflect.MapType": { |
655 » » » Method: map[string]string{ | 655 » » » Method: { |
656 "Key": "func() reflect.Type", | 656 "Key": "func() reflect.Type", |
657 }, | 657 }, |
658 » » » Embed: []string{"reflect.Type"}, | 658 » » » Embed: {"reflect.Type"}, |
659 }, | 659 }, |
660 "reflect.MapValue": { | 660 "reflect.MapValue": { |
661 » » » Method: map[string]string{ | 661 » » » Method: { |
662 "Keys": "func() []reflect.Value", | 662 "Keys": "func() []reflect.Value", |
663 }, | 663 }, |
664 » » » Embed: []string{"reflect.Value"}, | 664 » » » Embed: {"reflect.Value"}, |
665 }, | 665 }, |
666 "reflect.Method": { | 666 "reflect.Method": { |
667 » » » Field: map[string]string{ | 667 » » » Field: { |
668 "Type": "*reflect.FuncType", | 668 "Type": "*reflect.FuncType", |
669 "Func": "*reflect.FuncValue", | 669 "Func": "*reflect.FuncValue", |
670 }, | 670 }, |
671 }, | 671 }, |
672 » » "reflect.PtrType": {Embed: []string{"reflect.Type"}}, | 672 » » "reflect.PtrType": {Embed: {"reflect.Type"}}, |
673 » » "reflect.PtrValue": {Embed: []string{"reflect.Value"}}, | 673 » » "reflect.PtrValue": {Embed: {"reflect.Value"}}, |
674 » » "reflect.SliceType": {Embed: []string{"reflect.Type"}}, | 674 » » "reflect.SliceType": {Embed: {"reflect.Type"}}, |
675 "reflect.SliceValue": { | 675 "reflect.SliceValue": { |
676 » » » Method: map[string]string{ | 676 » » » Method: { |
677 "Slice": "func(int, int) *reflect.SliceValue", | 677 "Slice": "func(int, int) *reflect.SliceValue", |
678 }, | 678 }, |
679 » » » Embed: []string{"reflect.Value"}, | 679 » » » Embed: {"reflect.Value"}, |
680 }, | 680 }, |
681 » » "reflect.StringType": {Embed: []string{"reflect.Type"}}, | 681 » » "reflect.StringType": {Embed: {"reflect.Type"}}, |
682 » » "reflect.StringValue": {Embed: []string{"reflect.Value"}}, | 682 » » "reflect.StringValue": {Embed: {"reflect.Value"}}, |
683 "reflect.StructField": { | 683 "reflect.StructField": { |
684 » » » Field: map[string]string{ | 684 » » » Field: { |
685 "Type": "reflect.Type", | 685 "Type": "reflect.Type", |
686 }, | 686 }, |
687 }, | 687 }, |
688 "reflect.StructType": { | 688 "reflect.StructType": { |
689 » » » Method: map[string]string{ | 689 » » » Method: { |
690 "Field": "func() reflect.StructField", | 690 "Field": "func() reflect.StructField", |
691 "FieldByIndex": "func() reflect.StructField", | 691 "FieldByIndex": "func() reflect.StructField", |
692 "FieldByName": "func() reflect.StructField,b
ool", | 692 "FieldByName": "func() reflect.StructField,b
ool", |
693 "FieldByNameFunc": "func() reflect.StructField,b
ool", | 693 "FieldByNameFunc": "func() reflect.StructField,b
ool", |
694 }, | 694 }, |
695 » » » Embed: []string{"reflect.Type"}, | 695 » » » Embed: {"reflect.Type"}, |
696 }, | 696 }, |
697 "reflect.StructValue": { | 697 "reflect.StructValue": { |
698 » » » Method: map[string]string{ | 698 » » » Method: { |
699 "Field": "func() reflect.Value", | 699 "Field": "func() reflect.Value", |
700 "FieldByIndex": "func() reflect.Value", | 700 "FieldByIndex": "func() reflect.Value", |
701 "FieldByName": "func() reflect.Value", | 701 "FieldByName": "func() reflect.Value", |
702 "FieldByNameFunc": "func() reflect.Value", | 702 "FieldByNameFunc": "func() reflect.Value", |
703 }, | 703 }, |
704 » » » Embed: []string{"reflect.Value"}, | 704 » » » Embed: {"reflect.Value"}, |
705 }, | 705 }, |
706 "reflect.Type": { | 706 "reflect.Type": { |
707 » » » Method: map[string]string{ | 707 » » » Method: { |
708 "Elem": "func() reflect.Type", | 708 "Elem": "func() reflect.Type", |
709 "Method": "func() reflect.Method", | 709 "Method": "func() reflect.Method", |
710 }, | 710 }, |
711 }, | 711 }, |
712 » » "reflect.UintType": {Embed: []string{"reflect.Type"}}, | 712 » » "reflect.UintType": {Embed: {"reflect.Type"}}, |
713 » » "reflect.UintValue": {Embed: []string{"reflect.Value"}}
, | 713 » » "reflect.UintValue": {Embed: {"reflect.Value"}}, |
714 » » "reflect.UnsafePointerType": {Embed: []string{"reflect.Type"}}, | 714 » » "reflect.UnsafePointerType": {Embed: {"reflect.Type"}}, |
715 » » "reflect.UnsafePointerValue": {Embed: []string{"reflect.Value"}}
, | 715 » » "reflect.UnsafePointerValue": {Embed: {"reflect.Value"}}, |
716 "reflect.Value": { | 716 "reflect.Value": { |
717 » » » Method: map[string]string{ | 717 » » » Method: { |
718 "Addr": "func() *reflect.PtrValue", | 718 "Addr": "func() *reflect.PtrValue", |
719 "Elem": "func() reflect.Value", | 719 "Elem": "func() reflect.Value", |
720 "Method": "func() *reflect.FuncValue", | 720 "Method": "func() *reflect.FuncValue", |
721 "SetValue": "func(reflect.Value)", | 721 "SetValue": "func(reflect.Value)", |
722 }, | 722 }, |
723 }, | 723 }, |
724 }, | 724 }, |
725 » Func: map[string]string{ | 725 » Func: { |
726 "reflect.Append": "*reflect.SliceValue", | 726 "reflect.Append": "*reflect.SliceValue", |
727 "reflect.AppendSlice": "*reflect.SliceValue", | 727 "reflect.AppendSlice": "*reflect.SliceValue", |
728 "reflect.Indirect": "reflect.Value", | 728 "reflect.Indirect": "reflect.Value", |
729 "reflect.MakeSlice": "*reflect.SliceValue", | 729 "reflect.MakeSlice": "*reflect.SliceValue", |
730 "reflect.MakeChan": "*reflect.ChanValue", | 730 "reflect.MakeChan": "*reflect.ChanValue", |
731 "reflect.MakeMap": "*reflect.MapValue", | 731 "reflect.MakeMap": "*reflect.MapValue", |
732 "reflect.MakeZero": "reflect.Value", | 732 "reflect.MakeZero": "reflect.Value", |
733 "reflect.NewValue": "reflect.Value", | 733 "reflect.NewValue": "reflect.Value", |
734 "reflect.PtrTo": "*reflect.PtrType", | 734 "reflect.PtrTo": "*reflect.PtrType", |
735 "reflect.Typeof": "reflect.Type", | 735 "reflect.Typeof": "reflect.Type", |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 "*reflect.InterfaceValue": true, | 853 "*reflect.InterfaceValue": true, |
854 "*reflect.MapValue": true, | 854 "*reflect.MapValue": true, |
855 "*reflect.PtrValue": true, | 855 "*reflect.PtrValue": true, |
856 "*reflect.SliceValue": true, | 856 "*reflect.SliceValue": true, |
857 "*reflect.StringValue": true, | 857 "*reflect.StringValue": true, |
858 "*reflect.StructValue": true, | 858 "*reflect.StructValue": true, |
859 "*reflect.UintValue": true, | 859 "*reflect.UintValue": true, |
860 "*reflect.UnsafePointerValue": true, | 860 "*reflect.UnsafePointerValue": true, |
861 "reflect.Value": true, // interface, not pointer | 861 "reflect.Value": true, // interface, not pointer |
862 } | 862 } |
OLD | NEW |