mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-16 17:10:53 +08:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
2fa3944459
4
app/stage/protyle/js/lute/lute.min.js
vendored
4
app/stage/protyle/js/lute/lute.min.js
vendored
File diff suppressed because one or more lines are too long
@ -93,38 +93,13 @@ func LoadTree(boxID, p string, luteEngine *lute.Lute) (ret *parse.Tree, err erro
|
||||
return
|
||||
}
|
||||
|
||||
func WriteTree(tree *parse.Tree) (err error) {
|
||||
luteEngine := util.NewLute() // 不关注用户的自定义解析渲染选项
|
||||
|
||||
if nil == tree.Root.FirstChild {
|
||||
newP := parse.NewParagraph()
|
||||
tree.Root.AppendChild(newP)
|
||||
tree.Root.SetIALAttr("updated", util.TimeFromID(newP.ID))
|
||||
treenode.ReindexBlockTree(tree)
|
||||
}
|
||||
|
||||
filePath := filepath.Join(util.DataDir, tree.Box, tree.Path)
|
||||
if oldSpec := tree.Root.Spec; "" == oldSpec {
|
||||
luteEngine.NestedInlines2FlattedSpans(tree)
|
||||
tree.Root.Spec = "1"
|
||||
logging.LogInfof("migrated tree [%s] from spec [%s] to [%s]", filePath, oldSpec, tree.Root.Spec)
|
||||
}
|
||||
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions)
|
||||
output := renderer.Render()
|
||||
|
||||
// .sy 文档数据使用格式化好的 JSON 而非单行 JSON
|
||||
buf := bytes.Buffer{}
|
||||
buf.Grow(4096)
|
||||
if err = json.Indent(&buf, output, "", "\t"); nil != err {
|
||||
return
|
||||
}
|
||||
output = buf.Bytes()
|
||||
|
||||
if err = os.MkdirAll(filepath.Dir(filePath), 0755); nil != err {
|
||||
func WriteTreeWithoutChangeTime(tree *parse.Tree) (err error) {
|
||||
data, filePath, err := prepareWriteTree(tree)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
if err = filelock.WriteFile(filePath, output); nil != err {
|
||||
if err = filelock.WriteFileWithoutChangeTime(filePath, data); nil != err {
|
||||
if errors.Is(err, filelock.ErrUnableAccessFile) {
|
||||
return
|
||||
}
|
||||
@ -134,9 +109,66 @@ func WriteTree(tree *parse.Tree) (err error) {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
afterWriteTree(tree)
|
||||
return
|
||||
}
|
||||
|
||||
func WriteTree(tree *parse.Tree) (err error) {
|
||||
data, filePath, err := prepareWriteTree(tree)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
if err = filelock.WriteFile(filePath, data); nil != err {
|
||||
if errors.Is(err, filelock.ErrUnableAccessFile) {
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("write data [%s] failed: %s", filePath, err)
|
||||
logging.LogErrorf(msg)
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
afterWriteTree(tree)
|
||||
return
|
||||
}
|
||||
|
||||
func prepareWriteTree(tree *parse.Tree) (data []byte, filePath string, err error) {
|
||||
luteEngine := util.NewLute() // 不关注用户的自定义解析渲染选项
|
||||
|
||||
if nil == tree.Root.FirstChild {
|
||||
newP := parse.NewParagraph()
|
||||
tree.Root.AppendChild(newP)
|
||||
tree.Root.SetIALAttr("updated", util.TimeFromID(newP.ID))
|
||||
treenode.ReindexBlockTree(tree)
|
||||
}
|
||||
|
||||
filePath = filepath.Join(util.DataDir, tree.Box, tree.Path)
|
||||
if oldSpec := tree.Root.Spec; "" == oldSpec {
|
||||
luteEngine.NestedInlines2FlattedSpans(tree)
|
||||
tree.Root.Spec = "1"
|
||||
logging.LogInfof("migrated tree [%s] from spec [%s] to [%s]", filePath, oldSpec, tree.Root.Spec)
|
||||
}
|
||||
renderer := render.NewJSONRenderer(tree, luteEngine.RenderOptions)
|
||||
data = renderer.Render()
|
||||
|
||||
// .sy 文档数据使用格式化好的 JSON 而非单行 JSON
|
||||
buf := bytes.Buffer{}
|
||||
buf.Grow(4096)
|
||||
if err = json.Indent(&buf, data, "", "\t"); nil != err {
|
||||
return
|
||||
}
|
||||
data = buf.Bytes()
|
||||
|
||||
if err = os.MkdirAll(filepath.Dir(filePath), 0755); nil != err {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func afterWriteTree(tree *parse.Tree) {
|
||||
docIAL := parse.IAL2MapUnEsc(tree.Root.KramdownIAL)
|
||||
cache.PutDocIAL(tree.Path, docIAL)
|
||||
return
|
||||
}
|
||||
|
||||
func recoverParseJSON2Tree(boxID, p, filePath string, luteEngine *lute.Lute) (ret *parse.Tree) {
|
||||
|
@ -5,7 +5,7 @@ go 1.18
|
||||
require (
|
||||
github.com/88250/clipboard v0.1.5
|
||||
github.com/88250/css v0.1.2
|
||||
github.com/88250/gulu v1.2.3-0.20220929123404-da1dc91c9343
|
||||
github.com/88250/gulu v1.2.3-0.20221007162906-ded80d955178
|
||||
github.com/88250/lute v1.7.5-0.20221007145740-d8f6a7398db6
|
||||
github.com/88250/pdfcpu v0.3.13
|
||||
github.com/88250/vitess-sqlparser v0.0.0-20210205111146-56a2ded2aba1
|
||||
@ -23,7 +23,7 @@ require (
|
||||
github.com/flopp/go-findfont v0.1.0
|
||||
github.com/fsnotify/fsnotify v1.5.4
|
||||
github.com/gabriel-vasile/mimetype v1.4.1
|
||||
github.com/getsentry/sentry-go v0.13.0
|
||||
github.com/getsentry/sentry-go v0.14.0
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-contrib/sessions v0.0.5
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
@ -40,7 +40,7 @@ require (
|
||||
github.com/siyuan-note/dejavu v0.0.0-20220930021019-e62491947339
|
||||
github.com/siyuan-note/encryption v0.0.0-20220713091850-5ecd92177b75
|
||||
github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da
|
||||
github.com/siyuan-note/filelock v0.0.0-20220929134814-c00908c4f281
|
||||
github.com/siyuan-note/filelock v0.0.0-20221007163134-7e64809023ef
|
||||
github.com/siyuan-note/httpclient v0.0.0-20220928030253-4f6a778563e9
|
||||
github.com/siyuan-note/logging v0.0.0-20220717040626-f796b05ee520
|
||||
github.com/steambap/captcha v1.4.1
|
||||
@ -113,9 +113,9 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect
|
||||
golang.org/x/exp v0.0.0-20220929160808-de9c53c655b9 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc // indirect
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b // indirect
|
||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 // indirect
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
|
||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
|
@ -17,6 +17,8 @@ github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5 h1:8HdZozCsXS
|
||||
github.com/88250/go-sqlite3 v1.14.13-0.20220714142610-fbbda1ee84f5/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/88250/gulu v1.2.3-0.20220929123404-da1dc91c9343 h1:GJxJRZmA8GkAiU3GswwsSszKqp1/aywhpyFJ+aC7J+k=
|
||||
github.com/88250/gulu v1.2.3-0.20220929123404-da1dc91c9343/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
|
||||
github.com/88250/gulu v1.2.3-0.20221007162906-ded80d955178 h1:+Mvo3MW8qYoXNhLx3bDBmEimPGdemLT87kyxq4cW7tE=
|
||||
github.com/88250/gulu v1.2.3-0.20221007162906-ded80d955178/go.mod h1:I1qBzsksFL2ciGSuqDE7R3XW4BUMrfDgOvSXEk7FsAI=
|
||||
github.com/88250/lute v1.7.5-0.20221007145740-d8f6a7398db6 h1:ScEG5w5lEIhXkRFnO4FJo+BYeS02Of6zDSUkBfjJQjs=
|
||||
github.com/88250/lute v1.7.5-0.20221007145740-d8f6a7398db6/go.mod h1:cEoBGi0zArPqAsp0MdG9SKinvH/xxZZWXU7sRx8vHSA=
|
||||
github.com/88250/pdfcpu v0.3.13 h1:touMWMZkCGalMIbEg9bxYp7rETM+zwb9hXjwhqi4I7Q=
|
||||
@ -92,6 +94,8 @@ github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkF
|
||||
github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M=
|
||||
github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo=
|
||||
github.com/getsentry/sentry-go v0.13.0/go.mod h1:EOsfu5ZdvKPfeHYV6pTVQnsjfp30+XA7//UooKNumH0=
|
||||
github.com/getsentry/sentry-go v0.14.0 h1:rlOBkuFZRKKdUnKO+0U3JclRDQKlRu5vVQtkWSQvC70=
|
||||
github.com/getsentry/sentry-go v0.14.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
@ -104,6 +108,7 @@ github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
@ -151,6 +156,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@ -353,6 +359,8 @@ github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da h1:/jNhl7LC+9
|
||||
github.com/siyuan-note/eventbus v0.0.0-20220916025349-3ac6e75522da/go.mod h1:Sqo4FYX5lAXu7gWkbEdJF0e6P57tNNVV4WDKYDctokI=
|
||||
github.com/siyuan-note/filelock v0.0.0-20220929134814-c00908c4f281 h1:9IiKGJm+MaoZkoOCeHYiptfdg14O1kVW3gtZzt5ScVE=
|
||||
github.com/siyuan-note/filelock v0.0.0-20220929134814-c00908c4f281/go.mod h1:JkoH0JiM865PMbhzRxddkmsnu+yFjrjZPUOkrBBF7Jk=
|
||||
github.com/siyuan-note/filelock v0.0.0-20221007163134-7e64809023ef h1:mbDOxW0N2OHE710oEd9pRE0HxNHQbKzgxKRazQD3/1E=
|
||||
github.com/siyuan-note/filelock v0.0.0-20221007163134-7e64809023ef/go.mod h1:NmpSIVtIGy8eNWapjDIiiCw5+5r5wxC76k40oG+WRXQ=
|
||||
github.com/siyuan-note/httpclient v0.0.0-20220928030253-4f6a778563e9 h1:3fa7E/3isQ+22RQfHctL65sUOFbBspYBq2wiHZPtyCY=
|
||||
github.com/siyuan-note/httpclient v0.0.0-20220928030253-4f6a778563e9/go.mod h1:fa1KsHyCuOedk1CKXDi7Y6USwwU5oNo1Zd4jDo3BpDM=
|
||||
github.com/siyuan-note/logging v0.0.0-20220717040626-f796b05ee520 h1:kscYjMt7jXYdd7Qj2OSUoBnoHc5B0U/E6OSx86VRLr4=
|
||||
@ -465,6 +473,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b h1:6e93nYa3hNqAvLr0pD4PN1fFS+gKzp2zAXqrnTCstqU=
|
||||
golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -513,6 +523,8 @@ golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM=
|
||||
golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20180302201248-b7ef84aaf62a/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -123,9 +123,17 @@ func SetBlockAttrs(id string, nameValues map[string]string) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if err = indexWriteJSONQueue(tree); nil != err {
|
||||
return
|
||||
if 1 == len(nameValues) && "" != nameValues["scroll"] {
|
||||
// 文档滚动状态不产生同步冲突 https://github.com/siyuan-note/siyuan/issues/6076
|
||||
if err = indexWriteJSONQueueWithoutChangeTime(tree); nil != err {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = indexWriteJSONQueue(tree); nil != err {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
IncSync()
|
||||
cache.PutBlockIAL(id, parse.IAL2Map(node.KramdownIAL))
|
||||
|
||||
|
@ -932,11 +932,24 @@ func writeJSONQueue(tree *parse.Tree) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func writeJSONQueueWithoutChangeTime(tree *parse.Tree) (err error) {
|
||||
if err = filesys.WriteTreeWithoutChangeTime(tree); nil != err {
|
||||
return
|
||||
}
|
||||
sql.UpsertTreeQueue(tree)
|
||||
return
|
||||
}
|
||||
|
||||
func indexWriteJSONQueue(tree *parse.Tree) (err error) {
|
||||
treenode.ReindexBlockTree(tree)
|
||||
return writeJSONQueue(tree)
|
||||
}
|
||||
|
||||
func indexWriteJSONQueueWithoutChangeTime(tree *parse.Tree) (err error) {
|
||||
treenode.ReindexBlockTree(tree)
|
||||
return writeJSONQueueWithoutChangeTime(tree)
|
||||
}
|
||||
|
||||
func renameWriteJSONQueue(tree *parse.Tree, oldHPath string) (err error) {
|
||||
if err = filesys.WriteTree(tree); nil != err {
|
||||
return
|
||||
|
@ -196,7 +196,7 @@ func renderTemplate(p, id string) (string, error) {
|
||||
return "", errors.New(msg)
|
||||
}
|
||||
|
||||
var nodesNeedAppendChild []*ast.Node
|
||||
var nodesNeedAppendChild, unlinks []*ast.Node
|
||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
if !entering {
|
||||
return ast.WalkContinue
|
||||
@ -213,11 +213,35 @@ func renderTemplate(p, id string) (string, error) {
|
||||
(ast.NodeBlockquote == n.Type && nil != n.FirstChild && nil != n.FirstChild.Next && ast.NodeKramdownBlockIAL == n.FirstChild.Next.Type) {
|
||||
nodesNeedAppendChild = append(nodesNeedAppendChild, n)
|
||||
}
|
||||
|
||||
// 块引缺失锚文本情况下自动补全 https://github.com/siyuan-note/siyuan/issues/6087
|
||||
if n.IsTextMarkType("block-ref") {
|
||||
if refText := n.Text(); "" == refText {
|
||||
refText = sql.GetRefText(n.TextMarkBlockRefID)
|
||||
if "" != refText {
|
||||
treenode.SetDynamicBlockRefText(n, refText)
|
||||
} else {
|
||||
unlinks = append(unlinks, n)
|
||||
}
|
||||
}
|
||||
} else if ast.NodeBlockRef == n.Type {
|
||||
if idNode := n.ChildByType(ast.NodeBlockRefID); nil != idNode {
|
||||
refText := sql.GetRefText(idNode.TokensStr())
|
||||
if "" != refText {
|
||||
treenode.SetDynamicBlockRefText(n, refText)
|
||||
} else {
|
||||
unlinks = append(unlinks, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.WalkContinue
|
||||
})
|
||||
for _, n := range nodesNeedAppendChild {
|
||||
n.AppendChild(parse.NewParagraph())
|
||||
}
|
||||
for _, n := range unlinks {
|
||||
n.Unlink()
|
||||
}
|
||||
|
||||
// 折叠标题导出为模板后使用会出现内容重复 https://github.com/siyuan-note/siyuan/issues/4488
|
||||
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
|
||||
|
Loading…
Reference in New Issue
Block a user