1
0
mirror of https://github.com/golang/go synced 2024-11-19 08:04:40 -07:00
Commit Graph

125 Commits

Author SHA1 Message Date
Daniel Martí
37afd3e311 text/template/parse: simplify Tree.pipeline
The pipeline parsing code was unnecessarily complex. It used a for loop
with a trailing break, a complex switch, and up to seven levels of
indentation.

Instead, drop the loop in favor of a single named goto with a comment,
and flatten out the complex switch to be easier to follow. Two lines of
code are now duplicated, but they're simple and only three lines apart.

While at it, move the pipe initialization further up to remove the need
for three variables.

Change-Id: I07b29de195f4000336219aadeadeacaaa4285c58
Reviewed-on: https://go-review.googlesource.com/c/145285
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-29 12:20:11 +00:00
Daniel Martí
1399b52dc4 text/template/parse: error on bad range variables
The package used to accept invalid range pipelines, such as:

	{{range $k, .}}
	{{range $k, 123 := .}}

This is because the logic that allowed a range pipeline to declare
multiple variables was broken. When encountering a single comma inside a
range pipeline, it would happily continue parsing a second variable,
even if we didn't have a variable token at all.

Then, the loop would immediately break, and we'd parse the pipeline we'd
be ranging over. That is, we'd parse {{range $k, .}} as if it were
{{range $k = .}}.

To fix this, only allow the loop to continue if we know we're going to
parse another variable or a token that would end the pipeline. Also add
a few test cases for these error edge cases.

While at it, make use of T.Run, which was useful in debugging
Tree.pipeline via print statements.

Fixes #28437.

Change-Id: Idc9966bf643f0f3bc1b052620357e5b0aa2022ea
Reviewed-on: https://go-review.googlesource.com/c/145282
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Reviewed-by: Rob Pike <r@golang.org>
2018-10-28 20:20:00 +00:00
Daniel Martí
202e903144 text/template: recover panics during function calls
There's precedent in handling panics that happen in functions called
from the standard library. For example, if a fmt.Formatter
implementation fails, fmt will absorb the panic into the output text.

Recovering panics is useful, because otherwise one would have to wrap
some Template.Execute calls with a recover. For example, if there's a
chance that the callbacks may panic, or if part of the input data is nil
when it shouldn't be.

In particular, it's a common confusion amongst new Go developers that
one can call a method on a nil receiver. Expecting text/template to
error on such a call, they encounter a long and confusing panic if the
method expects the receiver to be non-nil.

To achieve this, introduce safeCall, which takes care of handling error
returns as well as recovering panics. Handling panics in the "call"
function isn't strictly necessary, as that func itself is run via
evalCall. However, this makes the code more consistent, and can allow
for better context in panics via the "call" function.

Finally, add some test cases with a mix of funcs, methods, and func
fields that panic.

Fixes #28242.

Change-Id: Id67be22cc9ebaedeb4b17fa84e677b4b6e09ec67
Reviewed-on: https://go-review.googlesource.com/c/143097
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
2018-10-24 09:09:21 +00:00
Alexandre Maari
0cc4c2971d text/template: removed truncation of context in error message
Fixes #27930

Change-Id: I31ad3fdb74d74152268c59ae4c651cc4c8c1716d
Reviewed-on: https://go-review.googlesource.com/c/142217
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-23 00:28:36 +00:00
Seebs
628403fd6b text/template: drop unused sortKeys function
Recent change golang.org/cl/142737 drops the only call site for the
sortKeys function. If it's not in use, it should probably not be there in
the code, lurking and preparing to bite us when someone calls that instead
of the new key sorter in fmtsort, resulting in strange inconsistencies.

Since the function isn't called, this should have no impact.
Related to, but does not fix, #21095.

Change-Id: I4695503ef4d5ce90d989ec952f01ea00cc15c79d
Reviewed-on: https://go-review.googlesource.com/c/143178
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-19 05:17:57 +00:00
Rob Pike
a440cc0d70 fmt: print maps in key-sorted order
For easier testing, change the way maps are printed so they
appear in a consistent order between runs. Do this by printing
them in key-sorted order.

To do this, we add a package at the root, internal/fmtsort,
that implements a general mechanism for sorting map keys
regardless of their type. This is a little messy and probably
slow, but formatted printing of maps has never been fast and
is already always reflection-driven.

The rules are:

The ordering rules are more general than with Go's < operator:

 - when applicable, nil compares low
 - ints, floats, and strings order by <
 - NaN compares less than non-NaN floats
 - bool compares false before true
 - complex compares real, then imag
 - pointers compare by machine address
 - channel values compare by machine address
 - structs compare each field in turn
 - arrays compare each element in turn.
 - interface values compare first by reflect.Type describing the concrete type
   and then by concrete value as described in the previous rules.

The new package is internal because we really do not want
everyone using this to sort things. It is slow, not general, and
only suitable for the subset of types that can be map keys.

Also use the package in text/template, which already had a
weaker version of this mechanism.

This change requires adding a dependency on sort to the fmt
package, but that isn't disruptive to the dependency tree.

Fixes #21095

Change-Id: Ia602115c7de5d95993dbd609611d8bd96e054157
Reviewed-on: https://go-review.googlesource.com/c/142737
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2018-10-18 21:12:24 +00:00
Rob Pike
9a9dc36f97 text/template: explain that integer constants can overflow
This behavior is the same as in Go: constants can be coerced to int
and whether overflow occurs depends on how big an int is, but
this surprises people sometimes, so document it again here.

Fixes #25833.

Change-Id: I557995f1a1e8e871b21004953923d16f36cb9037
Reviewed-on: https://go-review.googlesource.com/c/141378
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-10-11 02:32:47 +00:00
Brad Fitzpatrick
da0d1a44ba all: use strings.ReplaceAll and bytes.ReplaceAll where applicable
I omitted vendor directories and anything necessary for bootstrapping.
(Tested by bootstrapping with Go 1.4)

Updates #27864

Change-Id: I7d9b68d0372d3a34dee22966cca323513ece7e8a
Reviewed-on: https://go-review.googlesource.com/137856
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-09-26 22:14:25 +00:00
Daniel Martí
98fd66808f text/template: simplify line tracking in the lexer
First, move the strings.Count logic out of emit, since only itemText
requires that. Use it in those call sites. itemLeftDelim and
itemRightDelim cannot contain newlines, as they're the "{{" and "}}"
tokens.

Secondly, introduce a startLine lexer field so that we don't have to
keep track of it elsewhere. That's also a requirement to move the
strings.Count out of emit, as emit modifies the start position field.

Change-Id: I69175f403487607a8e5b561b3f1916ee9dc3c0c6
Reviewed-on: https://go-review.googlesource.com/132275
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
2018-09-05 21:27:04 +00:00
Daniel Martí
6fa08c0fdb text/template: fix newline counting in raw strings
lexRawQuote already uses the next method, which keeps track of newlines
on a character by character basis. Adding up newlines in emit again
results in the newlines being counted twice, which can mean bad position
information in error messages.

Fix that, and add a test.

Fixes #27319.

Change-Id: Id803be065c541412dc808d388bc6d8a86a0de41e
Reviewed-on: https://go-review.googlesource.com/131996
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-08-29 20:36:09 +00:00
Michal Bohuslávek
b15a1e3cfb text/template: Put bad function name in quotes in panic from (*Template).Funcs
This turns

	panic: function name  is not a valid identifier

into
	panic: function name "" is not a valid identifier

and also makes it consistent with the func signature check.

This CL also makes the testBadFuncName func a test helper.

Change-Id: Id967cb61ac28228de81e1cd76a39f5195a5ebd11
Reviewed-on: https://go-review.googlesource.com/130998
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-08-23 19:24:40 +00:00
Ben Hoyt
6c7e199e50 text/scanner: don't allow Float exponents with no mantissa
Previously Scanner would allow float literals like "1.5e" and "1e+"
that weren't actually valid Go float literals, and also not valid
when passed to ParseFloat. This commit fixes that behaviour to match
the documentation ("recognizes all literals as defined by the Go
language specification"), and Scanner emits an error in these cases.

Fixes #26374

Change-Id: I6855402ea43febb448c6dff105b9578e31803c01
Reviewed-on: https://go-review.googlesource.com/129095
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-08-20 17:01:34 +00:00
Ian Lance Taylor
c5cb4843e1 html/template: ignore untyped nil arguments to default escapers
CL 95215 changed text/template so that untyped nil arguments were no
longer ignored, but were instead passed to functions as expected.
This had an unexpected effect on html/template, where all data is
implicitly passed to functions: originally untyped nil arguments were
not passed and were thus effectively ignored, but after CL 95215 they
were passed and were printed, typically as an escaped version of "<nil>".

This CL restores some of the behavior of html/template by ignoring
untyped nil arguments passed implicitly to escaper functions.

While eliminating one change to html/template relative to earlier
releases, this unfortunately introduces a different one: originally
values of interface type with the value nil were printed as an escaped
version of "<nil>". With this CL they are ignored as though they were
untyped nil values. My judgement is that this is a less common case.
We'll see.

This CL adds some tests of typed and untyped nil values to
html/template and text/template to capture the current behavior.

Updates #18716
Fixes #25875

Change-Id: I5912983ca32b31ece29e929e72d503b54d7b0cac
Reviewed-on: https://go-review.googlesource.com/121815
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-07-09 21:54:35 +00:00
Andrew Braunstein
578b961727 text/template/parse: fix a comment around the assign operator
Fix a comment that misrepresented the Assign operator (=).

Rename: colon-equals -> equals.

Change-Id: I405b8acfb0bcd1b176a91a95f9bfb61a4e85815f
GitHub-Last-Rev: aec0bf594c
GitHub-Pull-Request: golang/go#26112
Reviewed-on: https://go-review.googlesource.com/121416
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-06-28 19:37:15 +00:00
Daniel Theophanes
bedfa4e1c3 text/template/parse: undo breaking API changes
golang.org/cl/84480 altered the API for the parse package for
clarity and consistency. However, the changes also broke the
API for consumers of the package. This CL reverts the API
to the previous spelling, adding only a single new exported
symbol.

Fixes #25968

Change-Id: Ieb81054b61eeac7df3bc3864ef446df43c26b80f
Reviewed-on: https://go-review.googlesource.com/120355
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Rob Pike <r@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-06-22 08:05:11 +00:00
Josh Bleecher Snyder
cf2c2ea89d text/tabwriter: fix BenchmarkPyramid and BenchmarkRagged again
These were added in CL 106979. I got them wrong.
They were fixed in CL 111643. They were still wrong.
Hopefully this change will be the last fix.

With this fix, CL 106979 is allocation-neutral for BenchmarkRagged.
The performance results for BenchmarkPyramid reported in CL 111643 stand.

Change-Id: Id6a522e6602e5df31f504adf5a3bec9969c18649
Reviewed-on: https://go-review.googlesource.com/116015
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2018-06-04 17:32:17 +00:00
Shengyu Zhang
c8915a0696 text/scanner: return RawString token rather than String for raw string literals
Fixes #23675

Change-Id: I78e13d1ca90400e4dd48674b93bb6e2e30718d97
GitHub-Last-Rev: f2b3a59d2b
GitHub-Pull-Request: golang/go#25287
Reviewed-on: https://go-review.googlesource.com/112037
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-05-08 04:59:41 +00:00
Josh Bleecher Snyder
a33c595753 text/tabwriter: don't mimic previous lines on flush
\f triggers a flush.

This is used (by gofmt, among others) to indicate that
the current aligned segment has ended.

When flushed, it is unlikely that the previous line is
in fact a good predictor of the upcoming line,
so stop treating it as such.

No performance impact on the existing benchmarks,
which do not perform any flushes.

Change-Id: Ifdf3e6d4600713c90db7b51a10e429d9260dc08c
Reviewed-on: https://go-review.googlesource.com/111644
Reviewed-by: Robert Griesemer <gri@golang.org>
2018-05-07 17:53:13 +00:00
Josh Bleecher Snyder
87412a1430 text/tabwriter: fix BenchmarkPyramid and BenchmarkRagged
These were added in CL 106979. They were wrong.

The correct impact of CL 106979 on these benchmarks is:

name            old time/op    new time/op    delta
Pyramid/10-8      6.22µs ± 1%    5.68µs ± 0%    -8.78%  (p=0.000 n=15+13)
Pyramid/100-8      275µs ± 1%     255µs ± 1%    -7.30%  (p=0.000 n=15+13)
Pyramid/1000-8    25.6ms ± 1%    24.8ms ± 1%    -2.88%  (p=0.000 n=15+14)
Ragged/10-8       8.98µs ± 1%    6.74µs ± 0%   -24.98%  (p=0.000 n=15+14)
Ragged/100-8      85.3µs ± 0%    57.5µs ± 1%   -32.51%  (p=0.000 n=13+15)
Ragged/1000-8      847µs ± 1%     561µs ± 1%   -33.85%  (p=0.000 n=14+15)

name            old alloc/op   new alloc/op   delta
Pyramid/10-8      4.74kB ± 0%    4.88kB ± 0%    +3.04%  (p=0.000 n=15+15)
Pyramid/100-8      379kB ± 0%     411kB ± 0%    +8.50%  (p=0.000 n=15+12)
Pyramid/1000-8    35.3MB ± 0%    41.6MB ± 0%   +17.68%  (p=0.000 n=15+15)
Ragged/10-8       4.82kB ± 0%    1.82kB ± 0%   -62.13%  (p=0.000 n=15+15)
Ragged/100-8      45.4kB ± 0%     1.8kB ± 0%   -95.98%  (p=0.000 n=15+15)
Ragged/1000-8      449kB ± 0%       2kB ± 0%   -99.59%  (p=0.000 n=15+15)

name            old allocs/op  new allocs/op  delta
Pyramid/10-8        50.0 ± 0%      35.0 ± 0%   -30.00%  (p=0.000 n=15+15)
Pyramid/100-8        704 ± 0%       231 ± 0%   -67.19%  (p=0.000 n=15+15)
Pyramid/1000-8     10.0k ± 0%      2.1k ± 0%   -79.52%  (p=0.000 n=15+15)
Ragged/10-8         60.0 ± 0%      19.0 ± 0%   -68.33%  (p=0.000 n=15+15)
Ragged/100-8         511 ± 0%        19 ± 0%   -96.28%  (p=0.000 n=15+15)
Ragged/1000-8      5.01k ± 0%     0.02k ± 0%   -99.62%  (p=0.000 n=15+15)


This is an improvement over what was originally reported,
except the increase in alloc/op for the Pyramid benchmarks.

Change-Id: Ib2617c1288ce35f2c78e0172533d231b86e48bc2
Reviewed-on: https://go-review.googlesource.com/111643
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-06 04:27:05 +00:00
Richard Musiol
e3c684777a all: skip unsupported tests for js/wasm
The general policy for the current state of js/wasm is that it only
has to support tests that are also supported by nacl.

The test nilptr3.go makes assumptions about which nil checks can be
removed. Since WebAssembly does not signal on reading a null pointer,
all nil checks have to be explicit.

Updates #18892

Change-Id: I06a687860b8d22ae26b1c391499c0f5183e4c485
Reviewed-on: https://go-review.googlesource.com/110096
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-04-30 19:39:18 +00:00
Zheng Dayu
c6bbfbe708 text/template: improve comment example in doc
Make comment example consistent with its description.
Fixes #24767

Change-Id: Icff54b489040b1ce66c644a21343c6576304cf75
Reviewed-on: https://go-review.googlesource.com/107663
Reviewed-by: Rob Pike <r@golang.org>
2018-04-19 09:21:51 +00:00
Josh Bleecher Snyder
9ee7662cd6 text/tabwriter: reduce allocations from tracking cells
The tabwriter tracks cells on a line-by-line basis.
This can be memory-hungry when working with large input.

This change adds two optimizations.

First, when there's an existing cell slice for a line,
don't overwrite it by appending.
This helps when re-using a Writer,
or when the output is broken into groups,
e.g. by a blank line.
We now re-use that existing cell slice.

Second, we predict that the number of cells in a line
will probably match those of the previous line,
since tabwriter is most often used to format tables.

This has a noticeable impact on cmd/objdump (#24725).
It reduces allocated space by about 55%.
It also speeds it up some.
Using "benchcmd -n 10 Objdump go tool objdump `which go`":

name            old time/op       new time/op       delta
ObjdumpCompile        9.03s ± 1%        8.51s ± 1%  -5.81%  (p=0.000 n=10+10)

It might also imaginably speed up gofmt on some
large machine-generated code.

name                old time/op    new time/op    delta
Table/1x10/new-8            2.89µs ± 1%    2.39µs ± 1%   -17.39%  (p=0.000 n=13+14)
Table/1x10/reuse-8          2.13µs ± 1%    1.29µs ± 2%   -39.58%  (p=0.000 n=14+15)
Table/1x1000/new-8           203µs ± 0%     147µs ± 1%   -27.45%  (p=0.000 n=13+14)
Table/1x1000/reuse-8         194µs ± 1%     113µs ± 2%   -42.01%  (p=0.000 n=14+15)
Table/1x100000/new-8        33.1ms ± 1%    27.5ms ± 2%   -17.08%  (p=0.000 n=15+15)
Table/1x100000/reuse-8      22.0ms ± 3%    11.8ms ± 1%   -46.23%  (p=0.000 n=14+12)
Table/10x10/new-8           8.51µs ± 0%    6.52µs ± 1%   -23.48%  (p=0.000 n=13+15)
Table/10x10/reuse-8         7.41µs ± 0%    4.59µs ± 3%   -38.03%  (p=0.000 n=14+15)
Table/10x1000/new-8          749µs ± 0%     521µs ± 1%   -30.39%  (p=0.000 n=12+15)
Table/10x1000/reuse-8        732µs ± 1%     448µs ± 2%   -38.79%  (p=0.000 n=15+14)
Table/10x100000/new-8        102ms ± 2%      74ms ± 2%   -28.05%  (p=0.000 n=14+15)
Table/10x100000/reuse-8     96.2ms ± 4%    55.4ms ± 3%   -42.36%  (p=0.000 n=15+15)
Table/100x10/new-8          50.3µs ± 1%    43.3µs ± 1%   -13.87%  (p=0.000 n=14+15)
Table/100x10/reuse-8        47.6µs ± 1%    36.1µs ± 1%   -24.09%  (p=0.000 n=14+14)
Table/100x1000/new-8        5.17ms ± 1%    4.11ms ± 1%   -20.40%  (p=0.000 n=14+13)
Table/100x1000/reuse-8      5.00ms ± 1%    3.73ms ± 1%   -25.46%  (p=0.000 n=14+14)
Table/100x100000/new-8       654ms ± 2%     531ms ± 2%   -18.86%  (p=0.000 n=13+14)
Table/100x100000/reuse-8     709ms ± 1%     505ms ± 2%   -28.77%  (p=0.000 n=12+15)
Pyramid/10-8                4.22µs ± 1%    4.21µs ± 1%      ~     (p=0.067 n=14+14)
Pyramid/100-8                378µs ± 0%     378µs ± 0%    +0.17%  (p=0.022 n=13+13)
Pyramid/1000-8               133ms ± 3%     132ms ± 3%      ~     (p=0.148 n=15+15)
Ragged/10-8                 6.10µs ± 0%    5.16µs ± 0%   -15.38%  (p=0.000 n=14+15)
Ragged/100-8                54.5µs ± 0%    43.8µs ± 0%   -19.59%  (p=0.000 n=14+15)
Ragged/1000-8                532µs ± 0%     424µs ± 0%   -20.25%  (p=0.000 n=14+14)

name                old alloc/op   new alloc/op   delta
Table/1x10/new-8            1.76kB ± 0%    1.52kB ± 0%   -13.64%  (p=0.000 n=15+15)
Table/1x10/reuse-8            800B ± 0%        0B       -100.00%  (p=0.000 n=15+15)
Table/1x1000/new-8           131kB ± 0%      99kB ± 0%   -24.30%  (p=0.000 n=15+15)
Table/1x1000/reuse-8        80.0kB ± 0%     0.0kB ± 0%   -99.99%  (p=0.000 n=15+15)
Table/1x100000/new-8        23.1MB ± 0%    19.9MB ± 0%   -13.85%  (p=0.000 n=15+15)
Table/1x100000/reuse-8      8.30MB ± 0%    0.20MB ± 0%   -97.60%  (p=0.000 n=13+12)
Table/10x10/new-8           8.94kB ± 0%    5.06kB ± 0%   -43.47%  (p=0.000 n=15+15)
Table/10x10/reuse-8         7.52kB ± 0%    0.00kB       -100.00%  (p=0.000 n=15+15)
Table/10x1000/new-8          850kB ± 0%     387kB ± 0%   -54.50%  (p=0.000 n=13+15)
Table/10x1000/reuse-8        752kB ± 0%       0kB ± 0%   -99.98%  (p=0.000 n=13+15)
Table/10x100000/new-8       95.7MB ± 0%    49.3MB ± 0%   -48.50%  (p=0.000 n=14+15)
Table/10x100000/reuse-8     76.2MB ± 0%     2.5MB ± 0%   -96.77%  (p=0.000 n=13+15)
Table/100x10/new-8          66.3kB ± 0%    38.0kB ± 0%   -42.65%  (p=0.000 n=15+15)
Table/100x10/reuse-8        61.3kB ± 0%     0.0kB       -100.00%  (p=0.000 n=15+15)
Table/100x1000/new-8        6.69MB ± 0%    3.25MB ± 0%   -51.37%  (p=0.000 n=15+15)
Table/100x1000/reuse-8      6.13MB ± 0%    0.01MB ± 0%   -99.89%  (p=0.000 n=15+15)
Table/100x100000/new-8       684MB ± 0%     340MB ± 0%   -50.29%  (p=0.000 n=14+15)
Table/100x100000/reuse-8     648MB ± 0%     170MB ± 0%   -73.78%  (p=0.000 n=14+13)
Pyramid/10-8                4.40kB ± 0%    4.40kB ± 0%      ~     (all equal)
Pyramid/100-8                652kB ± 0%     652kB ± 0%      ~     (p=0.715 n=15+15)
Pyramid/1000-8              96.7MB ± 0%    96.7MB ± 0%      ~     (p=0.084 n=15+14)
Ragged/10-8                 5.17kB ± 0%    4.51kB ± 0%   -12.69%  (p=0.000 n=15+15)
Ragged/100-8                50.2kB ± 0%    41.1kB ± 0%   -18.04%  (p=0.000 n=15+15)
Ragged/1000-8                492kB ± 0%     401kB ± 0%   -18.61%  (p=0.000 n=15+15)

name                old allocs/op  new allocs/op  delta
Table/1x10/new-8              29.0 ± 0%      21.0 ± 0%   -27.59%  (p=0.000 n=15+15)
Table/1x10/reuse-8            20.0 ± 0%       0.0       -100.00%  (p=0.000 n=15+15)
Table/1x1000/new-8           2.02k ± 0%     1.02k ± 0%   -49.38%  (p=0.000 n=15+15)
Table/1x1000/reuse-8         2.00k ± 0%     0.00k       -100.00%  (p=0.000 n=15+15)
Table/1x100000/new-8          200k ± 0%      100k ± 0%   -49.98%  (p=0.000 n=15+15)
Table/1x100000/reuse-8        200k ± 0%        1k ± 0%   -99.50%  (p=0.000 n=14+15)
Table/10x10/new-8             66.0 ± 0%      31.0 ± 0%   -53.03%  (p=0.000 n=15+15)
Table/10x10/reuse-8           50.0 ± 0%       0.0       -100.00%  (p=0.000 n=15+15)
Table/10x1000/new-8          5.03k ± 0%     1.04k ± 0%   -79.36%  (p=0.000 n=15+15)
Table/10x1000/reuse-8        5.00k ± 0%     0.00k       -100.00%  (p=0.000 n=15+15)
Table/10x100000/new-8         500k ± 0%      100k ± 0%   -79.99%  (p=0.000 n=15+15)
Table/10x100000/reuse-8       500k ± 0%        5k ± 0%   -99.00%  (p=0.000 n=15+15)
Table/100x10/new-8             102 ± 0%        40 ± 0%   -60.78%  (p=0.000 n=15+15)
Table/100x10/reuse-8          80.0 ± 0%       0.0       -100.00%  (p=0.000 n=15+15)
Table/100x1000/new-8         8.04k ± 0%     1.05k ± 0%   -86.91%  (p=0.000 n=15+15)
Table/100x1000/reuse-8       8.00k ± 0%     0.00k ± 0%   -99.98%  (p=0.000 n=15+15)
Table/100x100000/new-8        800k ± 0%      100k ± 0%   -87.49%  (p=0.000 n=15+12)
Table/100x100000/reuse-8      800k ± 0%       50k ± 0%   -93.74%  (p=0.000 n=14+13)
Pyramid/10-8                  20.0 ± 0%      20.0 ± 0%      ~     (all equal)
Pyramid/100-8                 50.0 ± 0%      50.0 ± 0%      ~     (all equal)
Pyramid/1000-8                 109 ± 0%       109 ± 0%      ~     (all equal)
Ragged/10-8                   54.0 ± 0%      34.0 ± 0%   -37.04%  (p=0.000 n=15+15)
Ragged/100-8                   422 ± 0%       188 ± 0%   -55.45%  (p=0.000 n=15+15)
Ragged/1000-8                4.03k ± 0%     1.66k ± 0%   -58.80%  (p=0.000 n=15+15)

Change-Id: I0c0a392b02d5148a0a4b8ad4eaf98fa343980962
Reviewed-on: https://go-review.googlesource.com/106979
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-04-14 14:41:50 +00:00
Ian Lance Taylor
d01322826e text/template: copy Decl field when copying PipeNode
Fixes #24791

Change-Id: I62ac17313e6e09796586911d88191a36d67f9aa1
Reviewed-on: https://go-review.googlesource.com/106115
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-04-10 14:26:58 +00:00
Robert Griesemer
f2b5f750df text/tabwriter: remove internal use of bytes.Buffer (cleanup)
Noticed that we can simply use a []byte slice while investigating
a separate issue. Did the obvious simplification.

Change-Id: I921ebbb42135b5f1a10109236ceb9ae6e94ae7e2
Reviewed-on: https://go-review.googlesource.com/104757
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-04-04 23:51:48 +00:00
Daniel Martí
28c1ad9d35 text/template: add variable assignments
Variables can be declared and shadowing is supported, but modifying
existing variables via assignments was not available.

This meant that modifying a variable from a nested block was not
possible:

	{{ $v := "init" }}
	{{ if true }}
		{{ $v := "changed" }}
	{{ end }}
	v: {{ $v }} {{/* "init" */}}

Introduce the "=" assignment token, such that one can now do:

	{{ $v := "init" }}
	{{ if true }}
		{{ $v = "changed" }}
	{{ end }}
	v: {{ $v }} {{/* "changed" */}}

To avoid confusion, rename PipeNode.Decl to PipeNode.Vars, as the
variables may not always be declared after this change. Also change a
few other names to better reflect the added ambiguity of variables in
pipelines.

Modifying the text/template/parse package in a backwards incompatible
manner is acceptable, given that the package godoc clearly states that
it isn't intended for general use. It's the equivalent of an internal
package, back when internal packages didn't exist yet.

To make the changes to the parse package sit well with the cmd/api test,
update except.txt with the changes that we aren't worried about.

Fixes #10608.

Change-Id: I1f83a4297ee093fd45f9993cebb78fc9a9e81295
Reviewed-on: https://go-review.googlesource.com/84480
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
2018-04-04 15:51:56 +00:00
Adam Woodbeck
32409a2dfc text/scanner: add examples
Added examples for use of Mode, Whitespace, and IsIdentRune properties.

Fixes #23768

Change-Id: I2528e14fde63a4476f3c25510bf0c5b73f38ba5d
Reviewed-on: https://go-review.googlesource.com/93199
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2018-03-10 02:01:58 +00:00
Yury Smolsky
669676b7b3 text/template: fix the documentation of the block action
Fixes #23520

Change-Id: Ia834819f3260691a1a0181034ef4b4b945965688
Reviewed-on: https://go-review.googlesource.com/94761
Reviewed-by: Andrew Gerrand <adg@golang.org>
2018-02-21 20:57:47 +00:00
Kunpei Sakai
af7fc752b1 text/template: avoid assiging unnecessary variable
This follows up CL95235

Change-Id: I62652654e5bb46d2f8f37af468e1fbcc1835bb8a
Reviewed-on: https://go-review.googlesource.com/95295
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-02-20 15:42:01 +00:00
Daniel Martí
eb5925f5ff text/template: remove associate's error return
It's always nil, so simplify its signature. Found with unparam.

Change-Id: I45dd0f868ec2f5de98a970776be686417c8d73b6
Reviewed-on: https://go-review.googlesource.com/95235
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-02-19 22:43:56 +00:00
Daniel Martí
3cb54c8604 text/template: differentiate nil from missing arg
reflect.Value is a struct and does not have a kind nor any flag for
untyped nils. As a result, it is tricky to differentiate when we're
missing a value, from when we have one but it is untyped nil.

We could start using *reflect.Value instead, to add one level of
indirection, using nil for missing values and new(reflect.Value) for
untyped nils. However, that is a fairly invasive change, and would also
mean unnecessary allocations.

Instead, use a special reflect.Value that depicts when a value is
missing. This is the case for the "final" reflect.Value in multiple
scenarios, such as the start of a pipeline. Give it a specific,
unexported type too, to make sure it cannot be mistaken for any other
valid value.

Finally, replace "final.IsValid()" with "final != missingVal", since
final.IsValid() will be false when final is an untyped nil.

Also add a few test cases, all different variants of the untyped nil
versus missing value scenario.

Fixes #18716.

Change-Id: Ia9257a84660ead5a7007fd1cced7782760b62d9d
Reviewed-on: https://go-review.googlesource.com/95215
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
2018-02-19 21:32:13 +00:00
Daniel Martí
618f88d847 text/template: never call reflect.Zero(nil)
It makes no sense to try to get the zero value of a nil type, hence the
panic. When we have a nil type, use reflect.ValueOf(nil) instead.

This was showing itself if one used a missing field on the data between
parentheses, when the data was a nil interface:

	t := template.Must(template.New("test").Parse(`{{ (.).foo }}`))
	var v interface{}
	t.Execute(os.Stdout, v)

Resulting in:

	panic: reflect: Zero(nil) [recovered]
		panic: reflect: Zero(nil)

Fixes #21171.

Change-Id: Ifcc4a0c67e6df425b65bc9f82fde6fcf03828579
Reviewed-on: https://go-review.googlesource.com/84482
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
2018-02-13 22:18:21 +00:00
Ian Lance Taylor
fd7331a821 text/template: revert CL 66410 "add break, continue actions in ranges"
The new break and continue actions do not work in html/template, and
fixing them requires thinking about security issues that seem too
tricky at this stage of the release. We will try again for 1.11.

Original CL description:

    text/template: add break, continue actions in ranges

    Adds the two range control actions "break" and "continue". They act the
    same as the Go keywords break and continue, but are simplified in that
    only the innermost range statement can be broken out of or continued.

    Fixes #20531

Updates #20531
Updates #23683

Change-Id: Ia7fd3c409163e3bcb5dc42947ae90b15bdf89853
Reviewed-on: https://go-review.googlesource.com/92155
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2018-02-06 05:00:01 +00:00
Ariel Mashraki
3e97c42f77 text/template: remove unnecessary lexer field
this change removes the state field from the lexer,
because it's only used by the run method and can be
replaced with a local variable

Change-Id: Ib7a90ab6e9a894716cba2c7d9ed71bf2ad1240c0
Reviewed-on: https://go-review.googlesource.com/47338
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-11-10 04:13:30 +00:00
Ariel Mashraki
2f53fb58a8 text/template: remove unused lexer field
The lastPos field used in the past to track the line number of a token.
it's irrelevant anymore, and we can remove it.

Change-Id: I42c0bf55e884b79574a7da4926489f2d77618cd0
Reviewed-on: https://go-review.googlesource.com/49591
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-11-09 21:24:21 +00:00
Daniel Martí
7cb3e4fb1d all: unindent some if bodies by exiting early
All of these had a return or break in the else body, so flipping the
condition means we can unindent and simplify.

Change-Id: If93e97504480d18a0dac3f2c8ffe57ab8bcb929c
Reviewed-on: https://go-review.googlesource.com/74190
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-10-31 20:07:46 +00:00
Tim Cooper
3be5d55180 text/template: add break, continue actions in ranges
Adds the two range control actions "break" and "continue". They act the
same as the Go keywords break and continue, but are simplified in that
only the innermost range statement can be broken out of or continued.

Fixes #20531

Change-Id: I4412b3bbfd4dadb0ab74ae718e308c1ac7a0a1e9
Reviewed-on: https://go-review.googlesource.com/66410
Reviewed-by: Rob Pike <r@golang.org>
2017-10-17 02:06:15 +00:00
Daniel Martí
57e7d62455 all: use sort.Slice in a few more places
Do the low-hanging fruit - tiny Less functions that are used exactly
once. This reduces the amount of code and puts the logic in a single
place.

Change-Id: I9d4544cd68de5a95e55019bdad1fca0a1dbfae9c
Reviewed-on: https://go-review.googlesource.com/63171
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-09-22 12:39:14 +00:00
Daniel Martí
de22318888 text/template: check ignored error in a test
Found with staticcheck. Not terribly important since the test would
likely fail anyway, but at least it will fail with a better explanation
now.

Change-Id: Ic3f9a94a2152404b7873cc8cd47b6db79d78c2e6
Reviewed-on: https://go-review.googlesource.com/62990
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-09-13 15:06:31 +00:00
Daniel Martí
eb2dc3d3d0 all: remove strings.Contains check around Replace
It doesn't change the outcome. It might have been useful at some point
to avoid Replace from doing work or allocating. However, nowadays the
func returns early without doing any work if Count returns 0.

Change-Id: Id69dc74042a6e39672b405016484db8b50f43d58
Reviewed-on: https://go-review.googlesource.com/62991
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dave Cheney <dave@cheney.net>
2017-09-12 08:58:28 +00:00
Daniel Martí
9b8964bf2d text/template: fix pos info when trimming newlines
The lexer keeps the byte offset and the line for the rune it's currently
on. This was simple enough up until whitespace trimming was introduced.

With whitespace trimming, we might skip over newlines. In that case, the
lexer wasn't properly updating the line counter. Fix it.

Also, TestPos now checks that the line is correct too, which it was
ignoring before. This was necessary to test this scenario in the lexer.

Fixes #21778.

Change-Id: I3880f3adf02662eac8f818d5caa6935cca9cb33b
Reviewed-on: https://go-review.googlesource.com/61870
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-09-07 14:50:23 +00:00
Daniel Martí
fbc8973a6b all: join some chained ifs to unindent code
Found with mvdan.cc/unindent. It skipped the cases where parentheses
would need to be added, where comments would have to be moved elsewhere,
or where actions and simple logic would mix.

One of them was of the form "err != nil && err == io.EOF", so the first
part was removed.

Change-Id: Ie504c2b03a2c87d10ecbca1b9270069be1171b91
Reviewed-on: https://go-review.googlesource.com/57690
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-08-29 20:57:41 +00:00
Daniel Martí
59413d34c9 all: unindent some big chunks of code
Found with mvdan.cc/unindent. Prioritized the ones with the biggest wins
for now.

Change-Id: I2b032e45cdd559fc9ed5b1ee4c4de42c4c92e07b
Reviewed-on: https://go-review.googlesource.com/56470
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-08-18 06:59:48 +00:00
Emmanuel Odeke
590c5b0807 text/template: support indexing into *int* maps
Ensure that we can index maps whose key types are:
* int
* uint
* int32
* uint32
* int64
* uint64
* uintptr

Fixes #20439

Change-Id: I8fa96b14073c8af72786482ff4ffc3508064ea86
Reviewed-on: https://go-review.googlesource.com/43850
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-08-12 00:21:16 +00:00
Brad Fitzpatrick
af2ac479fc all: single space after period
Done with grep & interactive search & replace, to double-check
replacements. Not many remained after CL 20022.

Fixes #18572

Change-Id: Idbe90ba3b584f9b9661d2bbd141607daaadfa41a
Reviewed-on: https://go-review.googlesource.com/45270
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-06-09 20:29:09 +00:00
Robert Griesemer
fca6ad45e2 text/scanner: clarify documentation on Pos and Position
For #20292. (See discussion in that issue.)

Change-Id: I44cd69394fc47a01776905ec34305ba524c89883
Reviewed-on: https://go-review.googlesource.com/43452
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-05-14 20:24:34 +00:00
Robert Griesemer
8f06e217ea text/scanner: use correct token position in example
While at it, unindent source text so column values are easier
to read, remove unnecessary text in output, and simplify the
loop.

Fixes #20346.

Change-Id: I0fde02b9e4242383da427f4cf4c6c13dd0ab3b47
Reviewed-on: https://go-review.googlesource.com/43450
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-05-12 19:45:59 +00:00
Samuel Tan
3a2fee0389 html/template: allow safe usage of predefined escapers in pipelines
Allow the predefined escapers "html", "urlquery", and "js" to be used
in pipelines when they have no potential to affect the correctness or
safety of the escaped pipeline output. Specifically:
- "urlquery" may be used if it is the last command in the pipeline.
- "html" may be used if it is the last command in the pipeline, and
  the pipeline does not occur in an unquoted HTML attribute value
  context.
- "js" may be used in any pipeline, since it does not affect the
  merging of contextual escapers.

This change will loosens the restrictions on predefined escapers
introduced in golang.org/cl/37880, which will hopefully ease the
upgrade path for existing template users.

This change brings back the escaper-merging logic, and associated
unit tests, that were removed in golang.org/cl/37880. However, a
few notable changes have been made:
- "_html_template_nospaceescaper" is no longer considered
  equivalent to "html", since the former escapes spaces, while
  the latter does not (see #19345). This change should not silently
  break any templates, since pipelines where this substituion will
  happen will already trigger an explicit error.
- An "_eval_args_" internal directive has been added to
  handle pipelines containing a single explicit call to a
  predefined escaper, e.g. {{html .X}} (see #19353).

Also, the HTMLEscape function called by the predefined
text/template "html" function now escapes the NULL character as
well. This effectively makes it as secure as the internal
html/template HTML escapers (see #19345). While this change is
backward-incompatible, it will only affect illegitimate uses
of this escaper, since the NULL character is always illegal in
valid HTML.

Fixes #19952

Change-Id: I9b5570a80a3ea284b53901e6a1f842fc59b33d3a
Reviewed-on: https://go-review.googlesource.com/40936
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-05-05 18:56:31 +00:00
Dieter Plaetinck
1acff5fe61 template: warn about interleaved nature of writes
Execute incurs separate writes for each "step", e.g. each
variable that needs to be printed, and the final newline.
While it is correct to state that templates can be executed
concurrently, there is a more subtle nuance that is easily missed:
when writing to the same writer, the writes from concurrent execute
calls can be interleaved, leading to unexpected output.

Change-Id: I0abbd7960d8a8d15e109a8a3eeff3b43b852bbbf
Reviewed-on: https://go-review.googlesource.com/37444
Reviewed-by: Rob Pike <r@golang.org>
2017-05-05 17:58:56 +00:00
Daniel Martí
516e6f6d5d all: remove some unused parameters in test code
Mostly unnecessary *testing.T arguments.

Found with github.com/mvdan/unparam.

Change-Id: Ifb955cb88f2ce8784ee4172f4f94d860fa36ae9a
Reviewed-on: https://go-review.googlesource.com/41691
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-04-25 14:38:10 +00:00
Daniel Martí
ff7994ac10 all: remove redundant returns
Returns at the end of func bodies where the funcs have no return values
are pointless.

Change-Id: I0da5ea78671503e41a9f56dd770df8c919310ce5
Reviewed-on: https://go-review.googlesource.com/41093
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-04-19 20:03:51 +00:00