From 460f3c8f2eb2e80a0109f6c40599502ee8a9303c Mon Sep 17 00:00:00 2001 From: Jan Larres Date: Wed, 13 Sep 2017 17:46:34 +1200 Subject: [PATCH] Use function references in prototypes This makes it possible to actually see the function names in stacktraces. It also means that the internal objects of some of the tag prototypes don't need to be public any more. --- autoload/tagbar/prototypes/basetag.vim | 138 +++++++++++-------- autoload/tagbar/prototypes/fileinfo.vim | 58 +++++--- autoload/tagbar/prototypes/kindheadertag.vim | 48 ++++--- autoload/tagbar/prototypes/normaltag.vim | 35 +++-- autoload/tagbar/prototypes/pseudotag.vim | 23 ++-- autoload/tagbar/prototypes/splittag.vim | 15 +- autoload/tagbar/prototypes/typeinfo.vim | 23 +++- 7 files changed, 207 insertions(+), 133 deletions(-) diff --git a/autoload/tagbar/prototypes/basetag.vim b/autoload/tagbar/prototypes/basetag.vim index 9bca5f2..ea7d948 100644 --- a/autoload/tagbar/prototypes/basetag.vim +++ b/autoload/tagbar/prototypes/basetag.vim @@ -4,63 +4,73 @@ let s:visibility_symbols = { \ 'private' : '-' \ } -let s:BaseTag = {} - -let g:tagbar#prototypes#basetag#BaseTag = s:BaseTag - function! tagbar#prototypes#basetag#new(name) abort - let newobj = copy(s:BaseTag) + let newobj = {} - call newobj._init(a:name) + let newobj.name = a:name + let newobj.fields = {} + let newobj.fields.line = 0 + let newobj.fields.column = 0 + let newobj.prototype = '' + let newobj.path = '' + let newobj.fullpath = a:name + let newobj.depth = 0 + let newobj.parent = {} + let newobj.tline = -1 + let newobj.fileinfo = {} + let newobj.typeinfo = {} + let newobj._childlist = [] + let newobj._childdict = {} + + let newobj.isNormalTag = function(s:add_snr('s:isNormalTag')) + let newobj.isPseudoTag = function(s:add_snr('s:isPseudoTag')) + let newobj.isSplitTag = function(s:add_snr('s:isSplitTag')) + let newobj.isKindheader = function(s:add_snr('s:isKindheader')) + let newobj.getPrototype = function(s:add_snr('s:getPrototype')) + let newobj._getPrefix = function(s:add_snr('s:_getPrefix')) + let newobj.initFoldState = function(s:add_snr('s:initFoldState')) + let newobj.getClosedParentTline = function(s:add_snr('s:getClosedParentTline')) + let newobj.isFoldable = function(s:add_snr('s:isFoldable')) + let newobj.isFolded = function(s:add_snr('s:isFolded')) + let newobj.openFold = function(s:add_snr('s:openFold')) + let newobj.closeFold = function(s:add_snr('s:closeFold')) + let newobj.setFolded = function(s:add_snr('s:setFolded')) + let newobj.openParents = function(s:add_snr('s:openParents')) + let newobj.addChild = function(s:add_snr('s:addChild')) + let newobj.getChildren = function(s:add_snr('s:getChildren')) + let newobj.getChildrenByName = function(s:add_snr('s:getChildrenByName')) + let newobj.removeChild = function(s:add_snr('s:removeChild')) return newobj endfunction -" s:BaseTag._init() {{{1 -function! s:BaseTag._init(name) abort dict - let self.name = a:name - let self.fields = {} - let self.fields.line = 0 - let self.fields.column = 0 - let self.prototype = '' - let self.path = '' - let self.fullpath = a:name - let self.depth = 0 - let self.parent = {} - let self.tline = -1 - let self.fileinfo = {} - let self.typeinfo = {} - let self._childlist = [] - let self._childdict = {} -endfunction - -" s:BaseTag.isNormalTag() {{{1 -function! s:BaseTag.isNormalTag() abort dict +" s:isNormalTag() {{{1 +function! s:isNormalTag() abort dict return 0 endfunction -" s:BaseTag.isPseudoTag() {{{1 -function! s:BaseTag.isPseudoTag() abort dict +" s:isPseudoTag() {{{1 +function! s:isPseudoTag() abort dict return 0 endfunction -" s:BaseTag.isSplitTag {{{1 -function! s:BaseTag.isSplitTag() abort dict +" s:isSplitTag {{{1 +function! s:isSplitTag() abort dict return 0 endfunction -" s:BaseTag.isKindheader() {{{1 -function! s:BaseTag.isKindheader() abort dict +" s:isKindheader() {{{1 +function! s:isKindheader() abort dict return 0 endfunction -" s:BaseTag.getPrototype() {{{1 -function! s:BaseTag.getPrototype(short) abort dict +" s:getPrototype() {{{1 +function! s:getPrototype(short) abort dict return self.prototype endfunction -" s:BaseTag._getPrefix() {{{1 -function! s:BaseTag._getPrefix() abort dict +" s:_getPrefix() {{{1 +function! s:_getPrefix() abort dict let fileinfo = self.fileinfo if !empty(self._childlist) @@ -86,8 +96,8 @@ function! s:BaseTag._getPrefix() abort dict return prefix endfunction -" s:BaseTag.initFoldState() {{{1 -function! s:BaseTag.initFoldState(known_files) abort dict +" s:initFoldState() {{{1 +function! s:initFoldState(known_files) abort dict let fileinfo = self.fileinfo if a:known_files.has(fileinfo.fpath) && @@ -105,8 +115,8 @@ function! s:BaseTag.initFoldState(known_files) abort dict endif endfunction -" s:BaseTag.getClosedParentTline() {{{1 -function! s:BaseTag.getClosedParentTline() abort dict +" s:getClosedParentTline() {{{1 +function! s:getClosedParentTline() abort dict let tagline = self.tline " Find the first closed parent, starting from the top of the hierarchy. @@ -126,25 +136,25 @@ function! s:BaseTag.getClosedParentTline() abort dict return tagline endfunction -" s:BaseTag.isFoldable() {{{1 -function! s:BaseTag.isFoldable() abort dict +" s:isFoldable() {{{1 +function! s:isFoldable() abort dict return !empty(self._childlist) endfunction -" s:BaseTag.isFolded() {{{1 -function! s:BaseTag.isFolded() abort dict +" s:isFolded() {{{1 +function! s:isFolded() abort dict return self.fileinfo.tagfolds[self.fields.kind][self.fullpath] endfunction -" s:BaseTag.openFold() {{{1 -function! s:BaseTag.openFold() abort dict +" s:openFold() {{{1 +function! s:openFold() abort dict if self.isFoldable() let self.fileinfo.tagfolds[self.fields.kind][self.fullpath] = 0 endif endfunction -" s:BaseTag.closeFold() {{{1 -function! s:BaseTag.closeFold() abort dict +" s:closeFold() {{{1 +function! s:closeFold() abort dict let newline = line('.') if !empty(self.parent) && self.parent.isKindheader() @@ -165,13 +175,13 @@ function! s:BaseTag.closeFold() abort dict return newline endfunction -" s:BaseTag.setFolded() {{{1 -function! s:BaseTag.setFolded(folded) abort dict +" s:setFolded() {{{1 +function! s:setFolded(folded) abort dict let self.fileinfo.tagfolds[self.fields.kind][self.fullpath] = a:folded endfunction -" s:BaseTag.openParents() {{{1 -function! s:BaseTag.openParents() abort dict +" s:openParents() {{{1 +function! s:openParents() abort dict let parent = self.parent while !empty(parent) @@ -180,8 +190,8 @@ function! s:BaseTag.openParents() abort dict endwhile endfunction -" s:BaseTag.addChild() {{{1 -function! s:BaseTag.addChild(tag) abort dict +" s:addChild() {{{1 +function! s:addChild(tag) abort dict call add(self._childlist, a:tag) if has_key(self._childdict, a:tag.name) @@ -191,18 +201,18 @@ function! s:BaseTag.addChild(tag) abort dict endif endfunction -" s:BaseTag.getChildren() {{{1 -function! s:BaseTag.getChildren() dict abort +" s:getChildren() {{{1 +function! s:getChildren() dict abort return self._childlist endfunction -" s:BaseTag.getChildrenByName() {{{1 -function! s:BaseTag.getChildrenByName(tagname) dict abort +" s:getChildrenByName() {{{1 +function! s:getChildrenByName(tagname) dict abort return get(self._childdict, a:tagname, []) endfunction -" s:BaseTag.removeChild() {{{1 -function! s:BaseTag.removeChild(tag) dict abort +" s:removeChild() {{{1 +function! s:removeChild(tag) dict abort let idx = index(self._childlist, a:tag) if idx >= 0 call remove(self._childlist, idx) @@ -215,5 +225,13 @@ function! s:BaseTag.removeChild(tag) dict abort endif endfunction +" s:add_snr() {{{1 +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/fileinfo.vim b/autoload/tagbar/prototypes/fileinfo.vim index a75e1ff..6cd7e8f 100644 --- a/autoload/tagbar/prototypes/fileinfo.vim +++ b/autoload/tagbar/prototypes/fileinfo.vim @@ -1,7 +1,5 @@ -let s:FileInfo = {} - function! tagbar#prototypes#fileinfo#new(fname, ftype, typeinfo) abort - let newobj = copy(s:FileInfo) + let newobj = {} " The complete file path let newobj.fpath = a:fname @@ -44,11 +42,21 @@ function! tagbar#prototypes#fileinfo#new(fname, ftype, typeinfo) abort " The current foldlevel of the file let newobj.foldlevel = g:tagbar_foldlevel + let newobj.addTag = function(s:add_snr('s:addTag')) + let newobj.getTags = function(s:add_snr('s:getTags')) + let newobj.getTagsByName = function(s:add_snr('s:getTagsByName')) + let newobj.removeTag = function(s:add_snr('s:removeTag')) + let newobj.reset = function(s:add_snr('s:reset')) + let newobj.clearOldFolds = function(s:add_snr('s:clearOldFolds')) + let newobj.sortTags = function(s:add_snr('s:sortTags')) + let newobj.openKindFold = function(s:add_snr('s:openKindFold')) + let newobj.closeKindFold = function(s:add_snr('s:closeKindFold')) + return newobj endfunction -" s:FileInfo.addTag() {{{1 -function! s:FileInfo.addTag(tag) abort dict +" s:addTag() {{{1 +function! s:addTag(tag) abort dict call add(self._taglist, a:tag) if has_key(self._tagdict, a:tag.name) @@ -58,18 +66,18 @@ function! s:FileInfo.addTag(tag) abort dict endif endfunction -" s:FileInfo.getTags() {{{1 -function! s:FileInfo.getTags() dict abort +" s:getTags() {{{1 +function! s:getTags() dict abort return self._taglist endfunction -" s:FileInfo.getTagsByName() {{{1 -function! s:FileInfo.getTagsByName(tagname) dict abort +" s:getTagsByName() {{{1 +function! s:getTagsByName(tagname) dict abort return get(self._tagdict, a:tagname, []) endfunction -" s:FileInfo.removeTag() {{{1 -function! s:FileInfo.removeTag(tag) dict abort +" s:removeTag() {{{1 +function! s:removeTag(tag) dict abort let idx = index(self._taglist, a:tag) if idx >= 0 call remove(self._taglist, idx) @@ -82,10 +90,10 @@ function! s:FileInfo.removeTag(tag) dict abort endif endfunction -" s:FileInfo.reset() {{{1 +" s:reset() {{{1 " Reset stuff that gets regenerated while processing a file and save the old " tag folds -function! s:FileInfo.reset() abort dict +function! s:reset() abort dict let self.mtime = getftime(self.fpath) let self._taglist = [] let self._tagdict = {} @@ -100,15 +108,15 @@ function! s:FileInfo.reset() abort dict endfor endfunction -" s:FileInfo.clearOldFolds() {{{1 -function! s:FileInfo.clearOldFolds() abort dict +" s:clearOldFolds() {{{1 +function! s:clearOldFolds() abort dict if exists('self._tagfolds_old') unlet self._tagfolds_old endif endfunction -" s:FileInfo.sortTags() {{{1 -function! s:FileInfo.sortTags(compare_typeinfo) abort dict +" s:sortTags() {{{1 +function! s:sortTags(compare_typeinfo) abort dict if get(a:compare_typeinfo, 'sort', g:tagbar_sort) call tagbar#sorting#sort(self._taglist, 'kind', a:compare_typeinfo) else @@ -116,15 +124,23 @@ function! s:FileInfo.sortTags(compare_typeinfo) abort dict endif endfunction -" s:FileInfo.openKindFold() {{{1 -function! s:FileInfo.openKindFold(kind) abort dict +" s:openKindFold() {{{1 +function! s:openKindFold(kind) abort dict let self.kindfolds[a:kind.short] = 0 endfunction -" s:FileInfo.closeKindFold() {{{1 -function! s:FileInfo.closeKindFold(kind) abort dict +" s:closeKindFold() {{{1 +function! s:closeKindFold(kind) abort dict let self.kindfolds[a:kind.short] = 1 endfunction +" s:add_snr() {{{1 +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/kindheadertag.vim b/autoload/tagbar/prototypes/kindheadertag.vim index b489167..de67086 100644 --- a/autoload/tagbar/prototypes/kindheadertag.vim +++ b/autoload/tagbar/prototypes/kindheadertag.vim @@ -1,49 +1,61 @@ -let s:KindheaderTag = copy(g:tagbar#prototypes#basetag#BaseTag) - function! tagbar#prototypes#kindheadertag#new(name) abort - let newobj = copy(s:KindheaderTag) + let newobj = tagbar#prototypes#basetag#new(a:name) - call newobj._init(a:name) + let newobj.isKindheader = function(s:add_snr('s:isKindheader')) + let newobj.getPrototype = function(s:add_snr('s:getPrototype')) + let newobj.isFoldable = function(s:add_snr('s:isFoldable')) + let newobj.isFolded = function(s:add_snr('s:isFolded')) + let newobj.openFold = function(s:add_snr('s:openFold')) + let newobj.closeFold = function(s:add_snr('s:closeFold')) + let newobj.toggleFold = function(s:add_snr('s:toggleFold')) return newobj endfunction -" s:KindheaderTag.isKindheader() {{{1 -function! s:KindheaderTag.isKindheader() abort dict +" s:isKindheader() {{{1 +function! s:isKindheader() abort dict return 1 endfunction -" s:KindheaderTag.getPrototype() {{{1 -function! s:KindheaderTag.getPrototype(short) abort dict +" s:getPrototype() {{{1 +function! s:getPrototype(short) abort dict return self.name . ': ' . \ self.numtags . ' ' . (self.numtags > 1 ? 'tags' : 'tag') endfunction -" s:KindheaderTag.isFoldable() {{{1 -function! s:KindheaderTag.isFoldable() abort dict +" s:isFoldable() {{{1 +function! s:isFoldable() abort dict return 1 endfunction -" s:KindheaderTag.isFolded() {{{1 -function! s:KindheaderTag.isFolded() abort dict +" s:isFolded() {{{1 +function! s:isFolded() abort dict return self.fileinfo.kindfolds[self.short] endfunction -" s:KindheaderTag.openFold() {{{1 -function! s:KindheaderTag.openFold() abort dict +" s:openFold() {{{1 +function! s:openFold() abort dict let self.fileinfo.kindfolds[self.short] = 0 endfunction -" s:KindheaderTag.closeFold() {{{1 -function! s:KindheaderTag.closeFold() abort dict +" s:closeFold() {{{1 +function! s:closeFold() abort dict let self.fileinfo.kindfolds[self.short] = 1 return line('.') endfunction -" s:KindheaderTag.toggleFold() {{{1 -function! s:KindheaderTag.toggleFold(fileinfo) abort dict +" s:toggleFold() {{{1 +function! s:toggleFold(fileinfo) abort dict let a:fileinfo.kindfolds[self.short] = !a:fileinfo.kindfolds[self.short] endfunction +" s:add_snr() {{{1 +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/normaltag.vim b/autoload/tagbar/prototypes/normaltag.vim index 879d9b8..9bf8cf3 100644 --- a/autoload/tagbar/prototypes/normaltag.vim +++ b/autoload/tagbar/prototypes/normaltag.vim @@ -1,22 +1,21 @@ -let s:NormalTag = copy(g:tagbar#prototypes#basetag#BaseTag) - -let g:tagbar#prototypes#normaltag#NormalTag = s:NormalTag - function! tagbar#prototypes#normaltag#new(name) abort - let newobj = copy(s:NormalTag) + let newobj = tagbar#prototypes#basetag#new(a:name) - call newobj._init(a:name) + let newobj.isNormalTag = function(s:add_snr('s:isNormalTag')) + let newobj.strfmt = function(s:add_snr('s:strfmt')) + let newobj.str = function(s:add_snr('s:str')) + let newobj.getPrototype = function(s:add_snr('s:getPrototype')) return newobj endfunction -" s:NormalTag.isNormalTag() {{{1 -function! s:NormalTag.isNormalTag() abort dict +" s:isNormalTag() {{{1 +function! s:isNormalTag() abort dict return 1 endfunction -" s:NormalTag.strfmt() {{{1 -function! s:NormalTag.strfmt() abort dict +" s:strfmt() {{{1 +function! s:strfmt() abort dict let typeinfo = self.typeinfo let suffix = get(self.fields, 'signature', '') @@ -29,8 +28,8 @@ function! s:NormalTag.strfmt() abort dict return self._getPrefix() . self.name . suffix endfunction -" s:NormalTag.str() {{{1 -function! s:NormalTag.str(longsig, full) abort dict +" s:str() {{{1 +function! s:str(longsig, full) abort dict if a:full && self.path != '' let str = self.path . self.typeinfo.sro . self.name else @@ -48,8 +47,8 @@ function! s:NormalTag.str(longsig, full) abort dict return str endfunction -" s:NormalTag.getPrototype() {{{1 -function! s:NormalTag.getPrototype(short) abort dict +" s:getPrototype() {{{1 +function! s:getPrototype(short) abort dict if self.prototype != '' let prototype = self.prototype else @@ -108,5 +107,13 @@ function! s:NormalTag.getPrototype(short) abort dict return prototype endfunction +" s:add_snr() {{{1 +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/pseudotag.vim b/autoload/tagbar/prototypes/pseudotag.vim index a99863e..50e4ad1 100644 --- a/autoload/tagbar/prototypes/pseudotag.vim +++ b/autoload/tagbar/prototypes/pseudotag.vim @@ -1,20 +1,19 @@ -let s:PseudoTag = copy(g:tagbar#prototypes#basetag#BaseTag) - function! tagbar#prototypes#pseudotag#new(name) abort - let newobj = copy(s:PseudoTag) + let newobj = tagbar#prototypes#basetag#new(a:name) - call newobj._init(a:name) + let newobj.isPseudoTag = function(s:add_snr('s:isPseudoTag')) + let newobj.strfmt = function(s:add_snr('s:strfmt')) return newobj endfunction -" s:PseudoTag.isPseudoTag() {{{1 -function! s:PseudoTag.isPseudoTag() abort dict +" s:isPseudoTag() {{{1 +function! s:isPseudoTag() abort dict return 1 endfunction -" s:PseudoTag.strfmt() {{{1 -function! s:PseudoTag.strfmt() abort dict +" s:strfmt() {{{1 +function! s:strfmt() abort dict let typeinfo = self.typeinfo let suffix = get(self.fields, 'signature', '') @@ -25,5 +24,13 @@ function! s:PseudoTag.strfmt() abort dict return self._getPrefix() . self.name . '*' . suffix endfunction +" s:add_snr() {{{1 +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/splittag.vim b/autoload/tagbar/prototypes/splittag.vim index ab11d9e..7263cd5 100644 --- a/autoload/tagbar/prototypes/splittag.vim +++ b/autoload/tagbar/prototypes/splittag.vim @@ -3,19 +3,24 @@ " May be replaced during tag processing if it appears as a normal tag later, " just like a pseudo tag. -let s:SplitTag = copy(g:tagbar#prototypes#normaltag#NormalTag) - function! tagbar#prototypes#splittag#new(name) abort - let newobj = copy(s:SplitTag) + let newobj = tagbar#prototypes#normaltag#new(a:name) - call newobj._init(a:name) + let newobj.isSplitTag = function(s:add_snr('s:isSplitTag')) return newobj endfunction -function! s:SplitTag.isSplitTag() abort dict +function! s:isSplitTag() abort dict return 1 endfunction +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1 diff --git a/autoload/tagbar/prototypes/typeinfo.vim b/autoload/tagbar/prototypes/typeinfo.vim index 8ef3791..1c3f452 100644 --- a/autoload/tagbar/prototypes/typeinfo.vim +++ b/autoload/tagbar/prototypes/typeinfo.vim @@ -1,7 +1,5 @@ -let s:TypeInfo = {} - function! tagbar#prototypes#typeinfo#new(...) abort - let newobj = copy(s:TypeInfo) + let newobj = {} let newobj.kinddict = {} @@ -9,18 +7,21 @@ function! tagbar#prototypes#typeinfo#new(...) abort call extend(newobj, a:1) endif + let newobj.getKind = function(s:add_snr('s:getKind')) + let newobj.createKinddict = function(s:add_snr('s:createKinddict')) + return newobj endfunction -" s:TypeInfo.getKind() {{{1 -function! s:TypeInfo.getKind(kind) abort dict +" s:getKind() {{{1 +function! s:getKind(kind) abort dict let idx = self.kinddict[a:kind] return self.kinds[idx] endfunction -" s:TypeInfo.createKinddict() {{{1 +" s:createKinddict() {{{1 " Create a dictionary of the kind order for fast access in sorting functions -function! s:TypeInfo.createKinddict() abort dict +function! s:createKinddict() abort dict let i = 0 for kind in self.kinds let self.kinddict[kind.short] = i @@ -29,5 +30,13 @@ function! s:TypeInfo.createKinddict() abort dict let self.kinddict['?'] = i endfunction +" s:add_snr() {{{1 +function! s:add_snr(funcname) abort + if !exists("s:snr") + let s:snr = matchstr(expand(''), '\d\+_\zeget_snr$') + endif + return s:snr . a:funcname +endfunction + " Modeline {{{1 " vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1