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

Delta Between Two Patch Sets: src/pkg/encoding/json/decode.go

Issue 6460044: code review 6460044: encoding/json: handle anonymous fields (Closed)
Left Patch Set: Created 11 years, 7 months ago
Right Patch Set: diff -r 56c7453d488f https://code.google.com/p/go/ Created 11 years, 6 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:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/encoding/json/decode_test.go » ('j') | src/pkg/encoding/json/encode.go » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2010 The Go Authors. All rights reserved. 1 // Copyright 2010 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 // Represents JSON data structure using native Go types: booleans, floats, 5 // Represents JSON data structure using native Go types: booleans, floats,
6 // strings, arrays, and maps. 6 // strings, arrays, and maps.
7 7
8 package json 8 package json
9 9
10 import ( 10 import (
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 486
487 if mv.IsValid() { 487 if mv.IsValid() {
488 elemType := mv.Type().Elem() 488 elemType := mv.Type().Elem()
489 if !mapElem.IsValid() { 489 if !mapElem.IsValid() {
490 mapElem = reflect.New(elemType).Elem() 490 mapElem = reflect.New(elemType).Elem()
491 } else { 491 } else {
492 mapElem.Set(reflect.Zero(elemType)) 492 mapElem.Set(reflect.Zero(elemType))
493 } 493 }
494 subv = mapElem 494 subv = mapElem
495 } else { 495 } else {
496 » » » var f reflect.StructField 496 » » » var f *field
497 » » » var ok bool 497 » » » fields := cachedTypeFields(sv.Type())
498 » » » st := sv.Type() 498 » » » for i := range fields {
499 » » » for i := 0; i < sv.NumField(); i++ { 499 » » » » ff := &fields[i]
500 » » » » sf := st.Field(i) 500 » » » » if ff.name == key {
501 » » » » tag := sf.Tag.Get("json") 501 » » » » » f = ff
502 » » » » if tag == "-" { 502 » » » » » break
503 » » » » » // Pretend this field doesn't exist.
504 » » » » » continue
505 } 503 }
506 » » » » if sf.Anonymous { 504 » » » » if f == nil && strings.EqualFold(ff.name, key) {
507 » » » » » // Pretend this field doesn't exist, 505 » » » » » f = ff
508 » » » » » // so that we can do a good job with
509 » » » » » // these in a later version.
510 » » » » » continue
511 } 506 }
512 » » » » // First, tag match 507 » » » }
513 » » » » tagName, _ := parseTag(tag) 508 » » » if f != nil {
514 » » » » if tagName != "" { 509 » » » » subv = sv
515 » » » » » if tagName == key { 510 » » » » destring = f.quoted
516 » » » » » » f = sf 511 » » » » for _, i := range f.index {
517 » » » » » » ok = true 512 » » » » » if subv.Kind() == reflect.Ptr {
518 » » » » » » break // no better match possibl e 513 » » » » » » if subv.IsNil() {
514 » » » » » » » subv.Set(reflect.New(sub v.Type().Elem()))
515 » » » » » » }
516 » » » » » » subv = subv.Elem()
519 } 517 }
520 » » » » » // There was a tag, but it didn't match. 518 » » » » » subv = subv.Field(i)
521 » » » » » // Ignore field names.
522 » » » » » continue
523 } 519 }
524 » » » » // Second, exact field name match 520 » » » } else {
525 » » » » if sf.Name == key { 521 » » » » // To give a good error, a quick scan for unexpo rted fields in top level.
526 » » » » » f = sf 522 » » » » st := sv.Type()
527 » » » » » ok = true 523 » » » » for i := 0; i < st.NumField(); i++ {
524 » » » » » f := st.Field(i)
525 » » » » » if f.PkgPath != "" && strings.EqualFold( f.Name, key) {
526 » » » » » » d.saveError(&UnmarshalFieldError {key, st, f})
527 » » » » » }
528 } 528 }
529 // Third, case-insensitive field name match,
530 // but only if a better match hasn't already bee n seen
531 if !ok && strings.EqualFold(sf.Name, key) {
532 f = sf
533 ok = true
534 }
535 }
536
537 // Extract value; name must be exported.
538 if ok {
539 if f.PkgPath != "" {
540 d.saveError(&UnmarshalFieldError{key, st , f})
541 } else {
542 subv = sv.FieldByIndex(f.Index)
543 }
544 _, opts := parseTag(f.Tag.Get("json"))
545 destring = opts.Contains("string")
546 } 529 }
547 } 530 }
548 531
549 // Read : before value. 532 // Read : before value.
550 if op == scanSkipSpace { 533 if op == scanSkipSpace {
551 op = d.scanWhile(scanSkipSpace) 534 op = d.scanWhile(scanSkipSpace)
552 } 535 }
553 if op != scanObjectKey { 536 if op != scanObjectKey {
554 d.error(errPhase) 537 d.error(errPhase)
555 } 538 }
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 981
999 // Coerce to well-formed UTF-8. 982 // Coerce to well-formed UTF-8.
1000 default: 983 default:
1001 rr, size := utf8.DecodeRune(s[r:]) 984 rr, size := utf8.DecodeRune(s[r:])
1002 r += size 985 r += size
1003 w += utf8.EncodeRune(b[w:], rr) 986 w += utf8.EncodeRune(b[w:], rr)
1004 } 987 }
1005 } 988 }
1006 return b[0:w], true 989 return b[0:w], true
1007 } 990 }
1008
1009 // The following is issue 3069.
1010
1011 // BUG(rsc): This package ignores anonymous (embedded) struct fields
1012 // during encoding and decoding. A future version may assign meaning
1013 // to them. To force an anonymous field to be ignored in all future
1014 // versions of this package, use an explicit `json:"-"` tag in the struct
1015 // definition.
LEFTRIGHT

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