github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/fix/testdata/reflect.datafmt.go.out (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*	The datafmt package implements syntax-directed, type-driven formatting
     6  	of arbitrary data structures. Formatting a data structure consists of
     7  	two phases: first, a parser reads a format specification and builds a
     8  	"compiled" format. Then, the format can be applied repeatedly to
     9  	arbitrary values. Applying a format to a value evaluates to a []byte
    10  	containing the formatted value bytes, or nil.
    11  
    12  	A format specification is a set of package declarations and format rules:
    13  
    14  		Format      = [ Entry { ";" Entry } [ ";" ] ] .
    15  		Entry       = PackageDecl | FormatRule .
    16  
    17  	(The syntax of a format specification is presented in the same EBNF
    18  	notation as used in the Go language specification. The syntax of white
    19  	space, comments, identifiers, and string literals is the same as in Go.)
    20  
    21  	A package declaration binds a package name (such as 'ast') to a
    22  	package import path (such as '"go/ast"'). Each package used (in
    23  	a type name, see below) must be declared once before use.
    24  
    25  		PackageDecl = PackageName ImportPath .
    26  		PackageName = identifier .
    27  		ImportPath  = string .
    28  
    29  	A format rule binds a rule name to a format expression. A rule name
    30  	may be a type name or one of the special names 'default' or '/'.
    31  	A type name may be the name of a predeclared type (for example, 'int',
    32  	'float32', etc.), the package-qualified name of a user-defined type
    33  	(for example, 'ast.MapType'), or an identifier indicating the structure
    34  	of unnamed composite types ('array', 'chan', 'func', 'interface', 'map',
    35  	or 'ptr'). Each rule must have a unique name; rules can be declared in
    36  	any order.
    37  
    38  		FormatRule  = RuleName "=" Expression .
    39  		RuleName    = TypeName | "default" | "/" .
    40  		TypeName    = [ PackageName "." ] identifier .
    41  
    42  	To format a value, the value's type name is used to select the format rule
    43  	(there is an override mechanism, see below). The format expression of the
    44  	selected rule specifies how the value is formatted. Each format expression,
    45  	when applied to a value, evaluates to a byte sequence or nil.
    46  
    47  	In its most general form, a format expression is a list of alternatives,
    48  	each of which is a sequence of operands:
    49  
    50  		Expression  = [ Sequence ] { "|" [ Sequence ] } .
    51  		Sequence    = Operand { Operand } .
    52  
    53  	The formatted result produced by an expression is the result of the first
    54  	alternative sequence that evaluates to a non-nil result; if there is no
    55  	such alternative, the expression evaluates to nil. The result produced by
    56  	an operand sequence is the concatenation of the results of its operands.
    57  	If any operand in the sequence evaluates to nil, the entire sequence
    58  	evaluates to nil.
    59  
    60  	There are five kinds of operands:
    61  
    62  		Operand     = Literal | Field | Group | Option | Repetition .
    63  
    64  	Literals evaluate to themselves, with two substitutions. First,
    65  	%-formats expand in the manner of fmt.Printf, with the current value
    66  	passed as the parameter. Second, the current indentation (see below)
    67  	is inserted after every newline or form feed character.
    68  
    69  		Literal     = string .
    70  
    71  	This table shows string literals applied to the value 42 and the
    72  	corresponding formatted result:
    73  
    74  		"foo"       foo
    75  		"%x"        2a
    76  		"x = %d"    x = 42
    77  		"%#x = %d"  0x2a = 42
    78  
    79  	A field operand is a field name optionally followed by an alternate
    80  	rule name. The field name may be an identifier or one of the special
    81  	names @ or *.
    82  
    83  		Field       = FieldName [ ":" RuleName ] .
    84  		FieldName   = identifier | "@" | "*" .
    85  
    86  	If the field name is an identifier, the current value must be a struct,
    87  	and there must be a field with that name in the struct. The same lookup
    88  	rules apply as in the Go language (for instance, the name of an anonymous
    89  	field is the unqualified type name). The field name denotes the field
    90  	value in the struct. If the field is not found, formatting is aborted
    91  	and an error message is returned. (TODO consider changing the semantics
    92  	such that if a field is not found, it evaluates to nil).
    93  
    94  	The special name '@' denotes the current value.
    95  
    96  	The meaning of the special name '*' depends on the type of the current
    97  	value:
    98  
    99  		array, slice types   array, slice element (inside {} only, see below)
   100  		interfaces           value stored in interface
   101  		pointers             value pointed to by pointer
   102  
   103  	(Implementation restriction: channel, function and map types are not
   104  	supported due to missing reflection support).
   105  
   106  	Fields are evaluated as follows: If the field value is nil, or an array
   107  	or slice element does not exist, the result is nil (see below for details
   108  	on array/slice elements). If the value is not nil the field value is
   109  	formatted (recursively) using the rule corresponding to its type name,
   110  	or the alternate rule name, if given.
   111  
   112  	The following example shows a complete format specification for a
   113  	struct 'myPackage.Point'. Assume the package
   114  
   115  		package myPackage  // in directory myDir/myPackage
   116  		type Point struct {
   117  			name string;
   118  			x, y int;
   119  		}
   120  
   121  	Applying the format specification
   122  
   123  		myPackage "myDir/myPackage";
   124  		int = "%d";
   125  		hexInt = "0x%x";
   126  		string = "---%s---";
   127  		myPackage.Point = name "{" x ", " y:hexInt "}";
   128  
   129  	to the value myPackage.Point{"foo", 3, 15} results in
   130  
   131  		---foo---{3, 0xf}
   132  
   133  	Finally, an operand may be a grouped, optional, or repeated expression.
   134  	A grouped expression ("group") groups a more complex expression (body)
   135  	so that it can be used in place of a single operand:
   136  
   137  		Group       = "(" [ Indentation ">>" ] Body ")" .
   138  		Indentation = Expression .
   139  		Body        = Expression .
   140  
   141  	A group body may be prefixed by an indentation expression followed by '>>'.
   142  	The indentation expression is applied to the current value like any other
   143  	expression and the result, if not nil, is appended to the current indentation
   144  	during the evaluation of the body (see also formatting state, below).
   145  
   146  	An optional expression ("option") is enclosed in '[]' brackets.
   147  
   148  		Option      = "[" Body "]" .
   149  
   150  	An option evaluates to its body, except that if the body evaluates to nil,
   151  	the option expression evaluates to an empty []byte. Thus an option's purpose
   152  	is to protect the expression containing the option from a nil operand.
   153  
   154  	A repeated expression ("repetition") is enclosed in '{}' braces.
   155  
   156  		Repetition  = "{" Body [ "/" Separator ] "}" .
   157  		Separator   = Expression .
   158  
   159  	A repeated expression is evaluated as follows: The body is evaluated
   160  	repeatedly and its results are concatenated until the body evaluates
   161  	to nil. The result of the repetition is the (possibly empty) concatenation,
   162  	but it is never nil. An implicit index is supplied for the evaluation of
   163  	the body: that index is used to address elements of arrays or slices. If
   164  	the corresponding elements do not exist, the field denoting the element
   165  	evaluates to nil (which in turn may terminate the repetition).
   166  
   167  	The body of a repetition may be followed by a '/' and a "separator"
   168  	expression. If the separator is present, it is invoked between repetitions
   169  	of the body.
   170  
   171  	The following example shows a complete format specification for formatting
   172  	a slice of unnamed type. Applying the specification
   173  
   174  		int = "%b";
   175  		array = { * / ", " };  // array is the type name for an unnamed slice
   176  
   177  	to the value '[]int{2, 3, 5, 7}' results in
   178  
   179  		10, 11, 101, 111
   180  
   181  	Default rule: If a format rule named 'default' is present, it is used for
   182  	formatting a value if no other rule was found. A common default rule is
   183  
   184  		default = "%v"
   185  
   186  	to provide default formatting for basic types without having to specify
   187  	a specific rule for each basic type.
   188  
   189  	Global separator rule: If a format rule named '/' is present, it is
   190  	invoked with the current value between literals. If the separator
   191  	expression evaluates to nil, it is ignored.
   192  
   193  	For instance, a global separator rule may be used to punctuate a sequence
   194  	of values with commas. The rules:
   195  
   196  		default = "%v";
   197  		/ = ", ";
   198  
   199  	will format an argument list by printing each one in its default format,
   200  	separated by a comma and a space.
   201  */
   202  package datafmt
   203  
   204  import (
   205  	"bytes"
   206  	"fmt"
   207  	"go/token"
   208  	"io"
   209  	"os"
   210  	"reflect"
   211  	"runtime"
   212  )
   213  
   214  // ----------------------------------------------------------------------------
   215  // Format representation
   216  
   217  // Custom formatters implement the Formatter function type.
   218  // A formatter is invoked with the current formatting state, the
   219  // value to format, and the rule name under which the formatter
   220  // was installed (the same formatter function may be installed
   221  // under different names). The formatter may access the current state
   222  // to guide formatting and use State.Write to append to the state's
   223  // output.
   224  //
   225  // A formatter must return a boolean value indicating if it evaluated
   226  // to a non-nil value (true), or a nil value (false).
   227  //
   228  type Formatter func(state *State, value interface{}, ruleName string) bool
   229  
   230  // A FormatterMap is a set of custom formatters.
   231  // It maps a rule name to a formatter function.
   232  //
   233  type FormatterMap map[string]Formatter
   234  
   235  // A parsed format expression is built from the following nodes.
   236  //
   237  type (
   238  	expr interface{}
   239  
   240  	alternatives []expr // x | y | z
   241  
   242  	sequence []expr // x y z
   243  
   244  	literal [][]byte // a list of string segments, possibly starting with '%'
   245  
   246  	field struct {
   247  		fieldName string // including "@", "*"
   248  		ruleName  string // "" if no rule name specified
   249  	}
   250  
   251  	group struct {
   252  		indent, body expr // (indent >> body)
   253  	}
   254  
   255  	option struct {
   256  		body expr // [body]
   257  	}
   258  
   259  	repetition struct {
   260  		body, separator expr // {body / separator}
   261  	}
   262  
   263  	custom struct {
   264  		ruleName string
   265  		fun      Formatter
   266  	}
   267  )
   268  
   269  // A Format is the result of parsing a format specification.
   270  // The format may be applied repeatedly to format values.
   271  //
   272  type Format map[string]expr
   273  
   274  // ----------------------------------------------------------------------------
   275  // Formatting
   276  
   277  // An application-specific environment may be provided to Format.Apply;
   278  // the environment is available inside custom formatters via State.Env().
   279  // Environments must implement copying; the Copy method must return an
   280  // complete copy of the receiver. This is necessary so that the formatter
   281  // can save and restore an environment (in case of an absent expression).
   282  //
   283  // If the Environment doesn't change during formatting (this is under
   284  // control of the custom formatters), the Copy function can simply return
   285  // the receiver, and thus can be very light-weight.
   286  //
   287  type Environment interface {
   288  	Copy() Environment
   289  }
   290  
   291  // State represents the current formatting state.
   292  // It is provided as argument to custom formatters.
   293  //
   294  type State struct {
   295  	fmt       Format         // format in use
   296  	env       Environment    // user-supplied environment
   297  	errors    chan os.Error  // not chan *Error (errors <- nil would be wrong!)
   298  	hasOutput bool           // true after the first literal has been written
   299  	indent    bytes.Buffer   // current indentation
   300  	output    bytes.Buffer   // format output
   301  	linePos   token.Position // position of line beginning (Column == 0)
   302  	default_  expr           // possibly nil
   303  	separator expr           // possibly nil
   304  }
   305  
   306  func newState(fmt Format, env Environment, errors chan os.Error) *State {
   307  	s := new(State)
   308  	s.fmt = fmt
   309  	s.env = env
   310  	s.errors = errors
   311  	s.linePos = token.Position{Line: 1}
   312  
   313  	// if we have a default rule, cache it's expression for fast access
   314  	if x, found := fmt["default"]; found {
   315  		s.default_ = x
   316  	}
   317  
   318  	// if we have a global separator rule, cache it's expression for fast access
   319  	if x, found := fmt["/"]; found {
   320  		s.separator = x
   321  	}
   322  
   323  	return s
   324  }
   325  
   326  // Env returns the environment passed to Format.Apply.
   327  func (s *State) Env() interface{} { return s.env }
   328  
   329  // LinePos returns the position of the current line beginning
   330  // in the state's output buffer. Line numbers start at 1.
   331  //
   332  func (s *State) LinePos() token.Position { return s.linePos }
   333  
   334  // Pos returns the position of the next byte to be written to the
   335  // output buffer. Line numbers start at 1.
   336  //
   337  func (s *State) Pos() token.Position {
   338  	offs := s.output.Len()
   339  	return token.Position{Line: s.linePos.Line, Column: offs - s.linePos.Offset, Offset: offs}
   340  }
   341  
   342  // Write writes data to the output buffer, inserting the indentation
   343  // string after each newline or form feed character. It cannot return an error.
   344  //
   345  func (s *State) Write(data []byte) (int, os.Error) {
   346  	n := 0
   347  	i0 := 0
   348  	for i, ch := range data {
   349  		if ch == '\n' || ch == '\f' {
   350  			// write text segment and indentation
   351  			n1, _ := s.output.Write(data[i0 : i+1])
   352  			n2, _ := s.output.Write(s.indent.Bytes())
   353  			n += n1 + n2
   354  			i0 = i + 1
   355  			s.linePos.Offset = s.output.Len()
   356  			s.linePos.Line++
   357  		}
   358  	}
   359  	n3, _ := s.output.Write(data[i0:])
   360  	return n + n3, nil
   361  }
   362  
   363  type checkpoint struct {
   364  	env       Environment
   365  	hasOutput bool
   366  	outputLen int
   367  	linePos   token.Position
   368  }
   369  
   370  func (s *State) save() checkpoint {
   371  	saved := checkpoint{nil, s.hasOutput, s.output.Len(), s.linePos}
   372  	if s.env != nil {
   373  		saved.env = s.env.Copy()
   374  	}
   375  	return saved
   376  }
   377  
   378  func (s *State) restore(m checkpoint) {
   379  	s.env = m.env
   380  	s.output.Truncate(m.outputLen)
   381  }
   382  
   383  func (s *State) error(msg string) {
   384  	s.errors <- os.NewError(msg)
   385  	runtime.Goexit()
   386  }
   387  
   388  // TODO At the moment, unnamed types are simply mapped to the default
   389  //      names below. For instance, all unnamed arrays are mapped to
   390  //      'array' which is not really sufficient. Eventually one may want
   391  //      to be able to specify rules for say an unnamed slice of T.
   392  //
   393  
   394  func typename(typ reflect.Type) string {
   395  	switch typ.Kind() {
   396  	case reflect.Array:
   397  		return "array"
   398  	case reflect.Slice:
   399  		return "array"
   400  	case reflect.Chan:
   401  		return "chan"
   402  	case reflect.Func:
   403  		return "func"
   404  	case reflect.Interface:
   405  		return "interface"
   406  	case reflect.Map:
   407  		return "map"
   408  	case reflect.Ptr:
   409  		return "ptr"
   410  	}
   411  	return typ.String()
   412  }
   413  
   414  func (s *State) getFormat(name string) expr {
   415  	if fexpr, found := s.fmt[name]; found {
   416  		return fexpr
   417  	}
   418  
   419  	if s.default_ != nil {
   420  		return s.default_
   421  	}
   422  
   423  	s.error(fmt.Sprintf("no format rule for type: '%s'", name))
   424  	return nil
   425  }
   426  
   427  // eval applies a format expression fexpr to a value. If the expression
   428  // evaluates internally to a non-nil []byte, that slice is appended to
   429  // the state's output buffer and eval returns true. Otherwise, eval
   430  // returns false and the state remains unchanged.
   431  //
   432  func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
   433  	// an empty format expression always evaluates
   434  	// to a non-nil (but empty) []byte
   435  	if fexpr == nil {
   436  		return true
   437  	}
   438  
   439  	switch t := fexpr.(type) {
   440  	case alternatives:
   441  		// append the result of the first alternative that evaluates to
   442  		// a non-nil []byte to the state's output
   443  		mark := s.save()
   444  		for _, x := range t {
   445  			if s.eval(x, value, index) {
   446  				return true
   447  			}
   448  			s.restore(mark)
   449  		}
   450  		return false
   451  
   452  	case sequence:
   453  		// append the result of all operands to the state's output
   454  		// unless a nil result is encountered
   455  		mark := s.save()
   456  		for _, x := range t {
   457  			if !s.eval(x, value, index) {
   458  				s.restore(mark)
   459  				return false
   460  			}
   461  		}
   462  		return true
   463  
   464  	case literal:
   465  		// write separator, if any
   466  		if s.hasOutput {
   467  			// not the first literal
   468  			if s.separator != nil {
   469  				sep := s.separator // save current separator
   470  				s.separator = nil  // and disable it (avoid recursion)
   471  				mark := s.save()
   472  				if !s.eval(sep, value, index) {
   473  					s.restore(mark)
   474  				}
   475  				s.separator = sep // enable it again
   476  			}
   477  		}
   478  		s.hasOutput = true
   479  		// write literal segments
   480  		for _, lit := range t {
   481  			if len(lit) > 1 && lit[0] == '%' {
   482  				// segment contains a %-format at the beginning
   483  				if lit[1] == '%' {
   484  					// "%%" is printed as a single "%"
   485  					s.Write(lit[1:])
   486  				} else {
   487  					// use s instead of s.output to get indentation right
   488  					fmt.Fprintf(s, string(lit), value.Interface())
   489  				}
   490  			} else {
   491  				// segment contains no %-formats
   492  				s.Write(lit)
   493  			}
   494  		}
   495  		return true // a literal never evaluates to nil
   496  
   497  	case *field:
   498  		// determine field value
   499  		switch t.fieldName {
   500  		case "@":
   501  			// field value is current value
   502  
   503  		case "*":
   504  			// indirection: operation is type-specific
   505  			switch v := value; v.Kind() {
   506  			case reflect.Array:
   507  				if v.Len() <= index {
   508  					return false
   509  				}
   510  				value = v.Index(index)
   511  
   512  			case reflect.Slice:
   513  				if v.IsNil() || v.Len() <= index {
   514  					return false
   515  				}
   516  				value = v.Index(index)
   517  
   518  			case reflect.Map:
   519  				s.error("reflection support for maps incomplete")
   520  
   521  			case reflect.Ptr:
   522  				if v.IsNil() {
   523  					return false
   524  				}
   525  				value = v.Elem()
   526  
   527  			case reflect.Interface:
   528  				if v.IsNil() {
   529  					return false
   530  				}
   531  				value = v.Elem()
   532  
   533  			case reflect.Chan:
   534  				s.error("reflection support for chans incomplete")
   535  
   536  			case reflect.Func:
   537  				s.error("reflection support for funcs incomplete")
   538  
   539  			default:
   540  				s.error(fmt.Sprintf("error: * does not apply to `%s`", value.Type()))
   541  			}
   542  
   543  		default:
   544  			// value is value of named field
   545  			var field reflect.Value
   546  			if sval := value; sval.Kind() == reflect.Struct {
   547  				field = sval.FieldByName(t.fieldName)
   548  				if !field.IsValid() {
   549  					// TODO consider just returning false in this case
   550  					s.error(fmt.Sprintf("error: no field `%s` in `%s`", t.fieldName, value.Type()))
   551  				}
   552  			}
   553  			value = field
   554  		}
   555  
   556  		// determine rule
   557  		ruleName := t.ruleName
   558  		if ruleName == "" {
   559  			// no alternate rule name, value type determines rule
   560  			ruleName = typename(value.Type())
   561  		}
   562  		fexpr = s.getFormat(ruleName)
   563  
   564  		mark := s.save()
   565  		if !s.eval(fexpr, value, index) {
   566  			s.restore(mark)
   567  			return false
   568  		}
   569  		return true
   570  
   571  	case *group:
   572  		// remember current indentation
   573  		indentLen := s.indent.Len()
   574  
   575  		// update current indentation
   576  		mark := s.save()
   577  		s.eval(t.indent, value, index)
   578  		// if the indentation evaluates to nil, the state's output buffer
   579  		// didn't change - either way it's ok to append the difference to
   580  		// the current identation
   581  		s.indent.Write(s.output.Bytes()[mark.outputLen:s.output.Len()])
   582  		s.restore(mark)
   583  
   584  		// format group body
   585  		mark = s.save()
   586  		b := true
   587  		if !s.eval(t.body, value, index) {
   588  			s.restore(mark)
   589  			b = false
   590  		}
   591  
   592  		// reset indentation
   593  		s.indent.Truncate(indentLen)
   594  		return b
   595  
   596  	case *option:
   597  		// evaluate the body and append the result to the state's output
   598  		// buffer unless the result is nil
   599  		mark := s.save()
   600  		if !s.eval(t.body, value, 0) { // TODO is 0 index correct?
   601  			s.restore(mark)
   602  		}
   603  		return true // an option never evaluates to nil
   604  
   605  	case *repetition:
   606  		// evaluate the body and append the result to the state's output
   607  		// buffer until a result is nil
   608  		for i := 0; ; i++ {
   609  			mark := s.save()
   610  			// write separator, if any
   611  			if i > 0 && t.separator != nil {
   612  				// nil result from separator is ignored
   613  				mark := s.save()
   614  				if !s.eval(t.separator, value, i) {
   615  					s.restore(mark)
   616  				}
   617  			}
   618  			if !s.eval(t.body, value, i) {
   619  				s.restore(mark)
   620  				break
   621  			}
   622  		}
   623  		return true // a repetition never evaluates to nil
   624  
   625  	case *custom:
   626  		// invoke the custom formatter to obtain the result
   627  		mark := s.save()
   628  		if !t.fun(s, value.Interface(), t.ruleName) {
   629  			s.restore(mark)
   630  			return false
   631  		}
   632  		return true
   633  	}
   634  
   635  	panic("unreachable")
   636  	return false
   637  }
   638  
   639  // Eval formats each argument according to the format
   640  // f and returns the resulting []byte and os.Error. If
   641  // an error occurred, the []byte contains the partially
   642  // formatted result. An environment env may be passed
   643  // in which is available in custom formatters through
   644  // the state parameter.
   645  //
   646  func (f Format) Eval(env Environment, args ...interface{}) ([]byte, os.Error) {
   647  	if f == nil {
   648  		return nil, os.NewError("format is nil")
   649  	}
   650  
   651  	errors := make(chan os.Error)
   652  	s := newState(f, env, errors)
   653  
   654  	go func() {
   655  		for _, v := range args {
   656  			fld := reflect.ValueOf(v)
   657  			if !fld.IsValid() {
   658  				errors <- os.NewError("nil argument")
   659  				return
   660  			}
   661  			mark := s.save()
   662  			if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct?
   663  				s.restore(mark)
   664  			}
   665  		}
   666  		errors <- nil // no errors
   667  	}()
   668  
   669  	err := <-errors
   670  	return s.output.Bytes(), err
   671  }
   672  
   673  // ----------------------------------------------------------------------------
   674  // Convenience functions
   675  
   676  // Fprint formats each argument according to the format f
   677  // and writes to w. The result is the total number of bytes
   678  // written and an os.Error, if any.
   679  //
   680  func (f Format) Fprint(w io.Writer, env Environment, args ...interface{}) (int, os.Error) {
   681  	data, err := f.Eval(env, args...)
   682  	if err != nil {
   683  		// TODO should we print partial result in case of error?
   684  		return 0, err
   685  	}
   686  	return w.Write(data)
   687  }
   688  
   689  // Print formats each argument according to the format f
   690  // and writes to standard output. The result is the total
   691  // number of bytes written and an os.Error, if any.
   692  //
   693  func (f Format) Print(args ...interface{}) (int, os.Error) {
   694  	return f.Fprint(os.Stdout, nil, args...)
   695  }
   696  
   697  // Sprint formats each argument according to the format f
   698  // and returns the resulting string. If an error occurs
   699  // during formatting, the result string contains the
   700  // partially formatted result followed by an error message.
   701  //
   702  func (f Format) Sprint(args ...interface{}) string {
   703  	var buf bytes.Buffer
   704  	_, err := f.Fprint(&buf, nil, args...)
   705  	if err != nil {
   706  		var i interface{} = args
   707  		fmt.Fprintf(&buf, "--- Sprint(%s) failed: %v", fmt.Sprint(i), err)
   708  	}
   709  	return buf.String()
   710  }