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.
This commit is contained in:
Jan Larres 2017-09-13 17:46:34 +12:00
parent d4a08c33e5
commit 460f3c8f2e
7 changed files with 207 additions and 133 deletions

View File

@ -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('<sfile>'), '<SNR>\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

View File

@ -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('<sfile>'), '<SNR>\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

View File

@ -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('<sfile>'), '<SNR>\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

View File

@ -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('<sfile>'), '<SNR>\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

View File

@ -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('<sfile>'), '<SNR>\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

View File

@ -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('<sfile>'), '<SNR>\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

View File

@ -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('<sfile>'), '<SNR>\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