Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1481)

Side by Side Diff: src/cmd/gofix/reflect.go

Issue 5448088: code review 5448088: cmd: shorten composite literal field values (Closed)
Patch Set: diff -r f91f50b96e10 https://go.googlecode.com/hg/ Created 12 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
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
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: {
gri 2011/12/02 23:11:05 I'd leave this file alone - no real win
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b