Skip to content

Commit cdef90a

Browse files
committed
Merge branch 'v1.2.2'
2 parents 9c63122 + 5cef956 commit cdef90a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+541
-231
lines changed

main.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func usage() {
1717
func main() {
1818
flag.Usage = usage
1919
isDebug := flag.Bool("debug", false, "use debug mode")
20+
noLine := flag.Bool("noline", false, "skip line number hint in generated code")
2021
version := flag.Bool("version", false, "show gorazor version info")
2122
quick := flag.Bool("q", false, "enable quick mode; skip template render optimzation")
2223
namespacePrefix := flag.String("prefix", "", "tpl namespace prefix")
@@ -31,12 +32,9 @@ func main() {
3132

3233
options := razorcore.Option{}
3334

34-
if *isDebug {
35-
options["Debug"] = *isDebug
36-
}
37-
if *nameNotChange {
38-
options["NameNotChange"] = *nameNotChange
39-
}
35+
options.IsDebug = *isDebug
36+
options.NameNotChange = *nameNotChange
37+
options.NoLineNumber = *noLine
4038

4139
if len(flag.Args()) != 2 {
4240
flag.Usage()

pkg/razorcore/ast.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package razorcore
2+
3+
import "fmt"
4+
5+
// Ast stores the abstract syntax tree
6+
type Ast struct {
7+
Parent *Ast
8+
Children []interface{}
9+
Mode int
10+
TagName string
11+
}
12+
13+
// ModeStr return string representation of ast mode
14+
func (ast *Ast) ModeStr() string {
15+
switch ast.Mode {
16+
case PRG:
17+
return "PROGRAM"
18+
case MKP:
19+
return "MARKUP"
20+
case BLK:
21+
return "BLOCK"
22+
case EXP:
23+
return "EXP"
24+
default:
25+
return "UNDEF"
26+
}
27+
}
28+
29+
func (ast *Ast) check() {
30+
if len(ast.Children) >= 100000 {
31+
panic("Maximum number of elements exceeded.")
32+
}
33+
}
34+
35+
func (ast *Ast) addChild(child interface{}) {
36+
ast.Children = append(ast.Children, child)
37+
ast.check()
38+
if _a, ok := child.(*Ast); ok {
39+
_a.Parent = ast
40+
}
41+
}
42+
43+
func (ast *Ast) addChildren(children []Token) {
44+
for _, c := range children {
45+
ast.addChild(c)
46+
}
47+
}
48+
49+
func (ast *Ast) addAst(_ast *Ast) {
50+
c := _ast
51+
for {
52+
if len(c.Children) != 1 {
53+
break
54+
}
55+
first := c.Children[0]
56+
if _, ok := first.(*Ast); !ok {
57+
break
58+
}
59+
c = first.(*Ast)
60+
}
61+
if c.Mode != PRG {
62+
ast.addChild(c)
63+
} else {
64+
for _, x := range c.Children {
65+
ast.addChild(x)
66+
}
67+
}
68+
}
69+
70+
func (ast *Ast) popChild() {
71+
l := len(ast.Children)
72+
if l == 0 {
73+
return
74+
}
75+
ast.Children = ast.Children[:l-1]
76+
}
77+
78+
func (ast *Ast) beget(mode int, tag string) *Ast {
79+
child := &Ast{nil, []interface{}{}, mode, tag}
80+
ast.addChild(child)
81+
return child
82+
}
83+
84+
func (ast *Ast) closest(mode int, tag string) *Ast {
85+
p := ast
86+
for {
87+
if p.TagName != tag && p.Parent != nil {
88+
p = p.Parent
89+
} else {
90+
break
91+
}
92+
}
93+
return p
94+
}
95+
96+
func (ast *Ast) hasNonExp() bool {
97+
if ast.Mode != EXP {
98+
return true
99+
}
100+
101+
for _, c := range ast.Children {
102+
if v, ok := c.(*Ast); ok {
103+
if v.hasNonExp() {
104+
return true
105+
}
106+
}
107+
return false
108+
}
109+
110+
return false
111+
}
112+
113+
func (ast *Ast) debug(depth int, max int) {
114+
if depth >= max {
115+
return
116+
}
117+
for i := 0; i < depth; i++ {
118+
fmt.Printf("%c", '-')
119+
}
120+
fmt.Printf("TagName: %s Mode: %s Children: %d [[ \n", ast.TagName, ast.ModeStr(), len(ast.Children))
121+
for _, a := range ast.Children {
122+
if _, ok := a.(*Ast); ok {
123+
b := (*Ast)(a.(*Ast))
124+
b.debug(depth+1, max)
125+
} else {
126+
if depth+1 < max {
127+
aa := (Token)(a.(Token))
128+
for i := 0; i < depth+1; i++ {
129+
fmt.Printf("%c", '-')
130+
}
131+
aa.P()
132+
}
133+
}
134+
}
135+
for i := 0; i < depth; i++ {
136+
fmt.Printf("%c", '-')
137+
}
138+
139+
fmt.Println("]]")
140+
}
Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path"
1010
"path/filepath"
1111
"runtime"
12+
"strconv"
1213
"strings"
1314
)
1415

@@ -54,6 +55,7 @@ func getValStr(e interface{}) string {
5455
type Part struct {
5556
ptype int
5657
value string
58+
line int
5759
}
5860

5961
// Compiler generate go code for gorazor template
@@ -101,8 +103,8 @@ func (cp *Compiler) isLayoutSectionPart(p Part) (is bool, val string) {
101103
}
102104

103105
val = p.value[21 : len(p.value)-3]
104-
for _, p := range cp.paramNames {
105-
if val == p {
106+
for _, name := range cp.paramNames {
107+
if val == name {
106108
return true, val
107109
}
108110
}
@@ -130,6 +132,13 @@ func (cp *Compiler) isLayoutSectionTest(p Part) (is bool, val string) {
130132
return
131133
}
132134

135+
func (cp *Compiler) getLineHint(line int) string {
136+
if cp.options.NoLineNumber {
137+
return ""
138+
}
139+
return "// Line: " + strconv.Itoa(line) + "\n"
140+
}
141+
133142
func (cp *Compiler) genPart() {
134143
res := ""
135144

@@ -141,6 +150,10 @@ func (cp *Compiler) genPart() {
141150
}
142151
if p.value != "" {
143152
p.value = fmt.Sprintf("%#v", p.value)
153+
if p.line > 0 {
154+
res += cp.getLineHint(p.line)
155+
}
156+
144157
res += "_buffer.WriteString(" + p.value + ")\n"
145158
}
146159
} else if p.ptype == CBLK {
@@ -150,6 +163,7 @@ func (cp *Compiler) genPart() {
150163
res += p.value + "\n"
151164
}
152165
} else if ok, val := cp.isLayoutSectionPart(p); ok {
166+
res += cp.getLineHint(p.line)
153167
res += val + "(_buffer)\n"
154168
} else {
155169
res += p.value
@@ -161,7 +175,7 @@ func (cp *Compiler) genPart() {
161175
func makeCompiler(ast *Ast, options Option, input string) *Compiler {
162176
dir := filepath.Base(filepath.Dir(input))
163177
file := strings.Replace(filepath.Base(input), gzExtension, "", 1)
164-
if options["NameNotChange"] == nil {
178+
if !options.NameNotChange {
165179
file = Capitalize(file)
166180
}
167181
cp := &Compiler{
@@ -184,12 +198,12 @@ func makeCompiler(ast *Ast, options Option, input string) *Compiler {
184198
return cp
185199
}
186200

187-
func (cp *Compiler) visitBLK(child interface{}, ast *Ast) {
188-
cp.addPart(Part{CBLK, getValStr(child)})
201+
func (cp *Compiler) visitBLK(child Token) {
202+
cp.addPart(Part{CBLK, getValStr(child), child.Line})
189203
}
190204

191-
func (cp *Compiler) visitMKP(child interface{}, ast *Ast) {
192-
cp.addPart(Part{CMKP, getValStr(child)})
205+
func (cp *Compiler) visitMKP(child Token) {
206+
cp.addPart(Part{CMKP, getValStr(child), child.Line})
193207
}
194208

195209
func (cp *Compiler) settleLayout(layoutFunc string) {
@@ -325,17 +339,27 @@ func (cp *Compiler) visitExp(child interface{}, parent *Ast, idx int, isHomo boo
325339
end += ")"
326340
}
327341

342+
lineHint := ""
343+
lineNumber := 0
328344
if ppNotExp && idx == 0 {
345+
if token, ok := child.(Token); ok {
346+
lineNumber = token.Line
347+
lineHint = cp.getLineHint(token.Line)
348+
}
329349
start = "_buffer.WriteString(" + start
330350
}
331351
if ppNotExp && idx == ppChildCnt-1 {
332352
end += ")\n"
333353
}
334354

335355
if val == "raw" {
336-
cp.addPart(Part{CSTAT, start + end})
356+
cp.addPart(Part{CSTAT, lineHint + start + end, lineNumber})
337357
} else {
338-
cp.addPart(Part{CSTAT, start + val + end})
358+
p := Part{CSTAT, start + val + end, lineNumber}
359+
if ok, _ := cp.isLayoutSectionPart(p); !ok {
360+
p.value = lineHint + p.value
361+
}
362+
cp.addPart(p)
339363
}
340364
}
341365

@@ -358,8 +382,8 @@ func (cp *Compiler) visitAstBlk(ast *Ast) {
358382
if remove && (idx == 0 || idx == len(ast.Children)-1) {
359383
continue
360384
}
361-
if _, ok := c.(Token); ok {
362-
cp.visitBLK(c, ast)
385+
if token, ok := c.(Token); ok {
386+
cp.visitBLK(token)
363387
} else {
364388
cp.visitAst(c.(*Ast))
365389
}
@@ -372,8 +396,8 @@ func (cp *Compiler) visitAst(ast *Ast) {
372396
case MKP:
373397
cp.firstBLK = 1
374398
for _, c := range ast.Children {
375-
if _, ok := c.(Token); ok {
376-
cp.visitMKP(c, ast)
399+
if token, ok := c.(Token); ok {
400+
cp.visitMKP(token)
377401
} else {
378402
cp.visitAst(c.(*Ast))
379403
}
@@ -594,7 +618,7 @@ func run(path string, Options Option) (*Compiler, error) {
594618
}
595619

596620
//DEBUG
597-
if Options["Debug"] != nil {
621+
if Options.IsDebug {
598622
fmt.Println("------------------- TOKEN START -----------------")
599623
for _, elem := range res {
600624
elem.P()
@@ -610,7 +634,7 @@ func run(path string, Options Option) (*Compiler, error) {
610634
}
611635

612636
//DEBUG
613-
if Options["Debug"] != nil {
637+
if Options.IsDebug {
614638
fmt.Println("--------------------- AST START -----------------")
615639
parser.ast.debug(0, 20)
616640
fmt.Println("--------------------- AST END -----------------")

pkg/razorcore/gorazor_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func TestDebug(t *testing.T) {
7878
casedir, _ := filepath.Abs(filepath.Dir("./cases/"))
7979
outdir, _ := filepath.Abs(filepath.Dir("./" + testdata + "/"))
8080
option := Option{}
81-
option["Debug"] = true
81+
option.IsDebug = true
8282
GenFile(casedir+"/var.gohtml", outdir+"/_var.gohtml", option)
8383
}
8484

pkg/razorcore/lexer.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ var typeStr = [...]string{
5656
"TEXT_TAG_OPEN", "COMMENT_TAG_OPEN", "COMMENT_TAG_CLOSE", "WHITESPACE"}
5757

5858
// Option have following options:
59-
// Debug bool
60-
// Watch bool
61-
// NameNotChange bool
62-
type Option map[string]interface{}
59+
type Option struct {
60+
IsDebug bool
61+
NoLineNumber bool
62+
NameNotChange bool
63+
}
6364

6465
// TokenMatch store matched token
6566
type TokenMatch struct {
@@ -194,9 +195,8 @@ func tryPeekNext(text string) (match string, tokVal int, ok bool) {
194195
func (lexer *Lexer) Scan() ([]Token, error) {
195196
toks := []Token{}
196197
text := strings.Replace(lexer.Text, "\r\n", "\n", -1)
197-
text = strings.Replace(text, "\r", "\n", -1)
198198
text += "\n"
199-
cur, line, pos := 0, 0, 0
199+
cur, line, pos := 0, 1, 0
200200
for cur < len(text) {
201201
val, left := text[cur], text[cur:]
202202
var tok Token

0 commit comments

Comments
 (0)