config/.vim/autoload/omni/cpp/namespaces.vim

839 lines
28 KiB
VimL

" Description: Omni completion script for cpp files
" Maintainer: Vissale NEANG
" Last Change: 26 sept. 2007
let g:omni#cpp#namespaces#CacheResolve = {}
let g:omni#cpp#namespaces#CacheUsing = {}
" TODO: For the next release
"let g:omni#cpp#namespaces#CacheAlias = {}
" Get the using namespace list from a line
function! s:GetNamespaceAliasListFromLine(szLine)
let result = {}
let tokens = omni#cpp#tokenizer#Tokenize(a:szLine)
let szAlias = ''
let szNamespace = ''
let state = 0
for token in tokens
if state==0
let szAlias = ''
let szNamespace = ''
if token.value == '/*'
let state = 1
elseif token.value == '//'
" It's a comment
let state = -1
break
elseif token.value == 'namespace'
let state = 2
endif
elseif state==1
if token.value == '*/'
let state=0
endif
elseif state==2
if token.kind == 'cppWord'
let szAlias .= token.value
let state = 3
else
let state = -1
break
endif
elseif state == 3
if token.value == '='
let state = 4
else
let state = -1
break
endif
elseif state == 4
if token.value == '::'
let szNamespace .= token.value
let state = 5
elseif token.kind == 'cppWord'
let szNamespace .= token.value
let state = 6
" Maybe end of tokens
endif
elseif state==5
if token.kind == 'cppWord'
let szNamespace .= token.value
let state = 6
" Maybe end of tokens
else
" Error, we can't have 'namespace ALIAS = Something::'
let state = -1
break
endif
elseif state==6
if token.value == '::'
let szNamespace .= token.value
let state = 5
else
call extend(result, {szAlias : szNamespace})
let state = 0
endif
endif
endfor
if state == 6
call extend(result, {szAlias : szNamespace})
endif
return result
endfunc
" Get the using namespace list from a line
function! s:GetNamespaceListFromLine(szLine)
let result = []
let tokens = omni#cpp#tokenizer#Tokenize(a:szLine)
let szNamespace = ''
let state = 0
for token in tokens
if state==0
let szNamespace = ''
if token.value == '/*'
let state = 1
elseif token.value == '//'
" It's a comment
let state = -1
break
elseif token.value == 'using'
let state = 2
endif
elseif state==1
if token.value == '*/'
let state=0
endif
elseif state==2
if token.value == 'namespace'
let state = 3
else
" Error, 'using' must be followed by 'namespace'
let state = -1
break
endif
elseif state==3
if token.value == '::'
let szNamespace .= token.value
let state = 4
elseif token.kind == 'cppWord'
let szNamespace .= token.value
let state = 5
" Maybe end of tokens
endif
elseif state==4
if token.kind == 'cppWord'
let szNamespace .= token.value
let state = 5
" Maybe end of tokens
else
" Error, we can't have 'using namespace Something::'
let state = -1
break
endif
elseif state==5
if token.value == '::'
let szNamespace .= token.value
let state = 4
else
call extend(result, [szNamespace])
let state = 0
endif
endif
endfor
if state == 5
call extend(result, [szNamespace])
endif
return result
endfunc
" Get the namespace list from a namespace map
function! s:GetUsingNamespaceListFromMap(namespaceMap, ...)
let stopLine = 0
if a:0>0
let stopLine = a:1
endif
let result = []
let keys = sort(keys(a:namespaceMap), 'omni#common#utils#CompareNumber')
for i in keys
if stopLine != 0 && i > stopLine
break
endif
call extend(result, a:namespaceMap[i])
endfor
return result
endfunc
" Get global using namespace list from the current buffer
function! omni#cpp#namespaces#GetListFromCurrentBuffer(...)
let namespaceMap = s:GetAllUsingNamespaceMapFromCurrentBuffer()
let result = []
if namespaceMap != {}
let result = s:GetUsingNamespaceListFromMap(namespaceMap, (a:0 > 0)? a:1 : line('.'))
endif
return result
endfunc
" Get global using namespace map from the current buffer and include files recursively
function! s:GetAllUsingNamespaceMapFromCurrentBuffer(...)
let includeGuard = (a:0>0)? a:1 : {}
let szBufferName = getreg("%")
let szFilePath = omni#cpp#utils#ResolveFilePath(szBufferName)
let szFilePath = (szFilePath=='')? szBufferName : szFilePath
let namespaceMap = {}
if has_key(includeGuard, szFilePath)
return namespaceMap
else
let includeGuard[szFilePath] = 1
endif
let namespaceMap = omni#cpp#namespaces#GetMapFromCurrentBuffer()
if g:OmniCpp_NamespaceSearch != 2
" We don't search included files if OmniCpp_NamespaceSearch != 2
return namespaceMap
endif
for inc in omni#cpp#includes#GetList()
let lnum = inc.pos[0]
let tmpMap = s:GetAllUsingNamespaceMapFromFile(inc.include, includeGuard)
if tmpMap != {}
if has_key(namespaceMap, lnum)
call extend(namespaceMap[lnum], s:GetUsingNamespaceListFromMap(tmpMap))
else
let namespaceMap[lnum] = s:GetUsingNamespaceListFromMap(tmpMap)
endif
endif
endfor
return namespaceMap
endfunc
" Get global using namespace map from a file and include files recursively
function! s:GetAllUsingNamespaceMapFromFile(szFilePath, ...)
let includeGuard = {}
if a:0 >0
let includeGuard = a:1
endif
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
let szFilePath = (szFilePath=='')? a:szFilePath : szFilePath
let namespaceMap = {}
if has_key(includeGuard, szFilePath)
return namespaceMap
else
let includeGuard[szFilePath] = 1
endif
" If g:OmniCpp_NamespaceSearch == 1 (search namespaces only in the current
" buffer) we don't use cache for the current buffer
let namespaceMap = omni#cpp#namespaces#GetMapFromBuffer(szFilePath, g:OmniCpp_NamespaceSearch==1)
if g:OmniCpp_NamespaceSearch != 2
" We don't search included files if OmniCpp_NamespaceSearch != 2
return namespaceMap
endif
for inc in omni#cpp#includes#GetList(szFilePath)
let lnum = inc.pos[0]
let tmpMap = s:GetAllUsingNamespaceMapFromFile(inc.include, includeGuard)
if tmpMap != {}
if has_key(namespaceMap, lnum)
call extend(namespaceMap[lnum], s:GetUsingNamespaceListFromMap(tmpMap))
else
let namespaceMap[lnum] = s:GetUsingNamespaceListFromMap(tmpMap)
endif
endif
endfor
return namespaceMap
endfunc
" Get global using namespace map from a the current buffer
function! omni#cpp#namespaces#GetMapFromCurrentBuffer()
let namespaceMap = {}
let originalPos = getpos('.')
call setpos('.', [0, 1, 1, 0])
let curPos = [1,1]
while curPos != [0,0]
let curPos = searchpos('\C^using\s\+namespace', 'W')
if curPos != [0,0]
let szLine = getline('.')
let startPos = curPos[1]
let endPos = match(szLine, ';', startPos-1)
if endPos!=-1
" We get the namespace list from the line
let namespaceMap[curPos[0]] = s:GetNamespaceListFromLine(szLine)
endif
endif
endwhile
call setpos('.', originalPos)
return namespaceMap
endfunc
" Get global using namespace map from a file
function! omni#cpp#namespaces#GetMapFromBuffer(szFilePath, ...)
let bUpdate = 0
if a:0 > 0
let bUpdate = a:1
endif
let szFilePath = omni#cpp#utils#ResolveFilePath(a:szFilePath)
let szFilePath = (szFilePath=='')? a:szFilePath : szFilePath
if !bUpdate && has_key(g:omni#cpp#namespaces#CacheUsing, szFilePath)
return copy(g:omni#cpp#namespaces#CacheUsing[szFilePath])
endif
let namespaceMap = {}
" The file exists, we get the global namespaces in this file
let szFixedPath = escape(szFilePath, g:omni#cpp#utils#szEscapedCharacters)
execute 'silent! lvimgrep /\C^using\s\+namespace/gj '.szFixedPath
" key = line number
" value = list of namespaces
let listQuickFix = getloclist(0)
for qf in listQuickFix
let szLine = qf.text
let startPos = qf.col
let endPos = match(szLine, ';', startPos-1)
if endPos!=-1
" We get the namespace list from the line
let namespaceMap[qf.lnum] = s:GetNamespaceListFromLine(szLine)
endif
endfor
if szFixedPath != ''
let g:omni#cpp#namespaces#CacheUsing[szFixedPath] = namespaceMap
endif
return copy(namespaceMap)
endfunc
" Get the stop position when searching for local variables
function! s:GetStopPositionForLocalSearch()
" Stop position when searching a local variable
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let stopPosition = origPos
let curPos = origPos
while curPos !=[0,0]
let stopPosition = curPos
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
endwhile
call setpos('.', originalPos)
return stopPosition
endfunc
" Get namespaces alias used at the cursor postion in a vim buffer
" Note: The result depends on the current cursor position
" @return
" - Map of namespace alias
function! s:GetNamespaceAliasMap()
" We store the cursor position because searchpairpos() moves the cursor
let result = {}
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let stopPos = s:GetStopPositionForLocalSearch()
let stopLine = stopPos[0]
let curPos = origPos
let lastLine = 0
let nextStopLine = origPos[0]
let szReAlias = '\Cnamespace\s\+\w\+\s\+='
while curPos !=[0,0]
let curPos = searchpos('}\|\('. szReAlias .'\)', 'bW',stopLine)
if curPos!=[0,0] && curPos[0]!=lastLine
let lastLine = curPos[0]
let szLine = getline('.')
if origPos[0] == curPos[0]
" We get the line until cursor position
let szLine = szLine[:origPos[1]]
endif
let szLine = omni#cpp#utils#GetCodeFromLine(szLine)
if match(szLine, szReAlias)<0
" We found a '}'
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
else
" We get the namespace alias from the line
call extend(result, s:GetNamespaceAliasListFromLine(szLine))
let nextStopLine = curPos[0]
endif
endif
endwhile
" Setting the cursor to the original position
call setpos('.', originalPos)
call s:ResolveAliasKeys(result)
return result
endfunc
" Resolve an alias
" eg: namespace IAmAnAlias1 = Ns1
" eg: namespace IAmAnAlias2 = IAmAnAlias1::Ns2
" => IAmAnAlias2 = Ns1::Ns2
function! s:ResolveAliasKey(mapNamespaceAlias, szAlias)
let szResult = a:mapNamespaceAlias[a:szAlias]
" ::Ns1::Ns2::Ns3 => ['Ns1', 'Ns2', 'Ns3']
let listNamespace = split(szResult, '::')
if len(listNamespace)
" szBeginPart = 'Ns1'
let szBeginPart = remove(listNamespace, 0)
" Is 'Ns1' an alias ?
if has_key(a:mapNamespaceAlias, szBeginPart) && szBeginPart != a:szAlias
" Resolving alias 'Ns1'
" eg: Ns1 = NsResolved
let szResult = s:ResolveAliasKey(a:mapNamespaceAlias, szBeginPart)
" szEndPart = 'Ns2::Ns3'
let szEndPart = join(listNamespace, '::')
if szEndPart != ''
" Concatenation => szResult = 'NsResolved::Ns2::Ns3'
let szResult .= '::' . szEndPart
endif
endif
endif
return szResult
endfunc
" Resolve all keys in the namespace alias map
function! s:ResolveAliasKeys(mapNamespaceAlias)
let mapNamespaceAlias = a:mapNamespaceAlias
call map(mapNamespaceAlias, 's:ResolveAliasKey(mapNamespaceAlias, v:key)')
endfunc
" Resolve namespace alias
function! omni#cpp#namespaces#ResolveAlias(mapNamespaceAlias, szNamespace)
let szResult = a:szNamespace
" ::Ns1::Ns2::Ns3 => ['Ns1', 'Ns2', 'Ns3']
let listNamespace = split(a:szNamespace, '::')
if len(listNamespace)
" szBeginPart = 'Ns1'
let szBeginPart = remove(listNamespace, 0)
" Is 'Ns1' an alias ?
if has_key(a:mapNamespaceAlias, szBeginPart)
" Resolving alias 'Ns1'
" eg: Ns1 = NsResolved
let szResult = a:mapNamespaceAlias[szBeginPart]
" szEndPart = 'Ns2::Ns3'
let szEndPart = join(listNamespace, '::')
if szEndPart != ''
" Concatenation => szResult = 'NsResolved::Ns2::Ns3'
let szResult .= '::' . szEndPart
endif
" If a:szNamespace starts with '::' we add '::' to the beginning
" of the result
if match(a:szNamespace, '^::')>=0
let szResult = omni#cpp#utils#SimplifyScope('::' . szResult)
endif
endif
endif
return szResult
endfunc
" Resolve namespace alias
function! s:ResolveAliasInNamespaceList(mapNamespaceAlias, listNamespaces)
call map(a:listNamespaces, 'omni#cpp#namespaces#ResolveAlias(a:mapNamespaceAlias, v:val)')
endfunc
" Get namespaces used at the cursor postion in a vim buffer
" Note: The result depends on the current cursor position
" @return
" - List of namespace used in the reverse order
function! omni#cpp#namespaces#GetUsingNamespaces()
" We have to get local using namespace declarations
" We need the current cursor position and the position of the start of the
" current scope
" We store the cursor position because searchpairpos() moves the cursor
let result = []
let originalPos = getpos('.')
let origPos = originalPos[1:2]
let stopPos = s:GetStopPositionForLocalSearch()
let stopLine = stopPos[0]
let curPos = origPos
let lastLine = 0
let nextStopLine = origPos[0]
while curPos !=[0,0]
let curPos = searchpos('\C}\|\(using\s\+namespace\)', 'bW',stopLine)
if curPos!=[0,0] && curPos[0]!=lastLine
let lastLine = curPos[0]
let szLine = getline('.')
if origPos[0] == curPos[0]
" We get the line until cursor position
let szLine = szLine[:origPos[1]]
endif
let szLine = omni#cpp#utils#GetCodeFromLine(szLine)
if match(szLine, '\Cusing\s\+namespace')<0
" We found a '}'
let curPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
else
" We get the namespace list from the line
let result = s:GetNamespaceListFromLine(szLine) + result
let nextStopLine = curPos[0]
endif
endif
endwhile
" Setting the cursor to the original position
call setpos('.', originalPos)
" 2) Now we can get all global using namespace declaration from the
" beginning of the file to nextStopLine
let result = omni#cpp#namespaces#GetListFromCurrentBuffer(nextStopLine) + result
" Resolving alias in the namespace list
" TODO: For the next release
"let g:omni#cpp#namespaces#CacheAlias= s:GetNamespaceAliasMap()
"call s:ResolveAliasInNamespaceList(g:omni#cpp#namespaces#CacheAlias, result)
return ['::'] + result
endfunc
" Resolve a using namespace regarding the current context
" For each namespace used:
" - We get all possible contexts where the namespace
" can be define
" - We do a comparison test of each parent contexts with the current
" context list
" - If one and only one parent context is present in the
" current context list we add the namespace in the current
" context
" - If there is more than one of parent contexts in the
" current context the namespace is ambiguous
" @return
" - result item
" - kind = 0|1
" - 0 = unresolved or error
" - 1 = resolved
" - value = resolved namespace
function! s:ResolveNamespace(namespace, mapCurrentContexts)
let result = {'kind':0, 'value': ''}
" If the namespace is already resolved we add it in the list of
" current contexts
if match(a:namespace, '^::')>=0
let result.kind = 1
let result.value = a:namespace
return result
elseif match(a:namespace, '\w\+::\w\+')>=0
let mapCurrentContextsTmp = copy(a:mapCurrentContexts)
let resolvedItem = {}
for nsTmp in split(a:namespace, '::')
let resolvedItem = s:ResolveNamespace(nsTmp, mapCurrentContextsTmp)
if resolvedItem.kind
" Note: We don't extend the map
let mapCurrentContextsTmp = {resolvedItem.value : 1}
else
break
endif
endfor
if resolvedItem!={} && resolvedItem.kind
let result.kind = 1
let result.value = resolvedItem.value
endif
return result
endif
" We get all possible parent contexts of this namespace
let listTagsOfNamespace = []
if has_key(g:omni#cpp#namespaces#CacheResolve, a:namespace)
let listTagsOfNamespace = g:omni#cpp#namespaces#CacheResolve[a:namespace]
else
let listTagsOfNamespace = omni#common#utils#TagList('^'.a:namespace.'$')
let g:omni#cpp#namespaces#CacheResolve[a:namespace] = listTagsOfNamespace
endif
if len(listTagsOfNamespace)==0
return result
endif
call filter(listTagsOfNamespace, 'v:val.kind[0]=="n"')
" We extract parent context from tags
" We use a map to avoid multiple entries
let mapContext = {}
for tagItem in listTagsOfNamespace
let szParentContext = omni#cpp#utils#ExtractScope(tagItem)
let mapContext[szParentContext] = 1
endfor
let listParentContext = keys(mapContext)
" Now for each parent context we test if the context is in the current
" contexts list
let listResolvedNamespace = []
for szParentContext in listParentContext
if has_key(a:mapCurrentContexts, szParentContext)
call extend(listResolvedNamespace, [omni#cpp#utils#SimplifyScope(szParentContext.'::'.a:namespace)])
endif
endfor
" Now we know if the namespace is ambiguous or not
let len = len(listResolvedNamespace)
if len==1
" Namespace resolved
let result.kind = 1
let result.value = listResolvedNamespace[0]
elseif len > 1
" Ambiguous namespace, possible matches are in listResolvedNamespace
else
" Other cases
endif
return result
endfunc
" Resolve namespaces
"@return
" - List of resolved namespaces
function! omni#cpp#namespaces#ResolveAll(namespacesUsed)
" We add the default context '::'
let contextOrder = 0
let mapCurrentContexts = {}
" For each namespace used:
" - We get all possible contexts where the namespace
" can be define
" - We do a comparison test of each parent contexts with the current
" context list
" - If one and only one parent context is present in the
" current context list we add the namespace in the current
" context
" - If there is more than one of parent contexts in the
" current context the namespace is ambiguous
for ns in a:namespacesUsed
let resolvedItem = s:ResolveNamespace(ns, mapCurrentContexts)
if resolvedItem.kind
let contextOrder+=1
let mapCurrentContexts[resolvedItem.value] = contextOrder
endif
endfor
" Build the list of current contexts from the map, we have to keep the
" order
let mapReorder = {}
for key in keys(mapCurrentContexts)
let mapReorder[ mapCurrentContexts[key] ] = key
endfor
let result = []
for key in sort(keys(mapReorder))
call extend(result, [mapReorder[key]])
endfor
return result
endfunc
" Build the context stack
function! s:BuildContextStack(namespaces, szCurrentScope)
let result = copy(a:namespaces)
if a:szCurrentScope != '::'
let tagItem = omni#cpp#utils#GetResolvedTagItem(a:namespaces, omni#cpp#utils#CreateTypeInfo(a:szCurrentScope))
if has_key(tagItem, 'inherits')
let listBaseClass = omni#cpp#utils#GetClassInheritanceList(a:namespaces, omni#cpp#utils#CreateTypeInfo(a:szCurrentScope))
let result = listBaseClass + result
elseif has_key(tagItem, 'kind') && index(['c', 's', 'u', 'n'], tagItem.kind[0])>=0
call insert(result, omni#cpp#utils#ExtractTypeInfoFromTag(tagItem))
endif
endif
return result
endfunc
" Returns the class scope at the current position of the cursor
" @return a string that represents the class scope
" eg: ::NameSpace1::Class1
" The returned string always starts with '::'
" Note: In term of performance it's the weak point of the script
function! s:GetClassScopeAtCursor()
" We store the cursor position because searchpairpos() moves the cursor
let originalPos = getpos('.')
let endPos = originalPos[1:2]
let listCode = []
let result = {'namespaces': [], 'scope': ''}
while endPos!=[0,0]
let endPos = searchpairpos('{', '', '}', 'bW', g:omni#cpp#utils#expIgnoreComments)
let szReStartPos = '[;{}]\|\%^'
let startPos = searchpairpos(szReStartPos, '', '{', 'bWn', g:omni#cpp#utils#expIgnoreComments)
" If the file starts with a comment so the startPos can be [0,0]
" we change it to [1,1]
if startPos==[0,0]
let startPos = [1,1]
endif
" Get lines backward from cursor position to last ; or { or }
" or when we are at the beginning of the file.
" We store lines in listCode
if endPos!=[0,0]
" We remove the last character which is a '{'
" We also remove starting { or } or ; if exits
let szCodeWithoutComments = substitute(omni#cpp#utils#GetCode(startPos, endPos)[:-2], '^[;{}]', '', 'g')
call insert(listCode, {'startLine' : startPos[0], 'code' : szCodeWithoutComments})
endif
endwhile
" Setting the cursor to the original position
call setpos('.', originalPos)
let listClassScope = []
let bResolved = 0
let startLine = 0
" Now we can check in the list of code if there is a function
for code in listCode
" We get the name of the namespace, class, struct or union
" and we store it in listClassScope
let tokens = omni#cpp#tokenizer#Tokenize(code.code)
let bContinue=0
let bAddNamespace = 0
let state=0
for token in tokens
if state==0
if index(['namespace', 'class', 'struct', 'union'], token.value)>=0
if token.value == 'namespace'
let bAddNamespace = 1
endif
let state= 1
" Maybe end of tokens
endif
elseif state==1
if token.kind == 'cppWord'
" eg: namespace MyNs { class MyCl {}; }
" => listClassScope = [MyNs, MyCl]
call extend( listClassScope , [token.value] )
" Add the namespace in result
if bAddNamespace
call extend(result.namespaces, [token.value])
let bAddNamespace = 0
endif
let bContinue=1
break
endif
endif
endfor
if bContinue==1
continue
endif
" Simple test to check if we have a chance to find a
" class method
let aPos = matchend(code.code, '::\s*\~*\s*\w\+\s*(')
if aPos ==-1
continue
endif
let startLine = code.startLine
let listTmp = []
" eg: 'void MyNamespace::MyClass::foo('
" => tokens = ['MyClass', '::', 'MyNamespace', 'void']
let tokens = reverse(omni#cpp#tokenizer#Tokenize(code.code[:aPos-1])[:-4])
let state = 0
" Reading tokens backward
for token in tokens
if state==0
if token.kind=='cppWord'
call insert(listTmp, token.value)
let state=1
endif
elseif state==1
if token.value=='::'
let state=2
else
break
endif
elseif state==2
if token.kind=='cppWord'
call insert(listTmp, token.value)
let state=1
else
break
endif
endif
endfor
if len(listTmp)
if len(listClassScope)
let bResolved = 1
" Merging class scopes
" eg: current class scope = 'MyNs::MyCl1'
" method class scope = 'MyCl1::MyCl2'
" If we add the method class scope to current class scope
" we'll have MyNs::MyCl1::MyCl1::MyCl2 => it's wrong
" we want MyNs::MyCl1::MyCl2
let index = 0
for methodClassScope in listTmp
if methodClassScope==listClassScope[-1]
let listTmp = listTmp[index+1:]
break
else
let index+=1
endif
endfor
endif
call extend(listClassScope, listTmp)
break
endif
endfor
let szClassScope = '::'
if len(listClassScope)
if bResolved
let szClassScope .= join(listClassScope, '::')
else
let szClassScope = join(listClassScope, '::')
" The class scope is not resolved, we have to check using
" namespace declarations and search the class scope in each
" namespace
if startLine != 0
let namespaces = ['::'] + omni#cpp#namespaces#GetListFromCurrentBuffer(startLine)
let namespaces = omni#cpp#namespaces#ResolveAll(namespaces)
let tagItem = omni#cpp#utils#GetResolvedTagItem(namespaces, omni#cpp#utils#CreateTypeInfo(szClassScope))
if tagItem != {}
let szClassScope = omni#cpp#utils#ExtractTypeInfoFromTag(tagItem)
endif
endif
endif
endif
let result.scope = szClassScope
return result
endfunc
" Get all contexts at the cursor position
function! omni#cpp#namespaces#GetContexts()
" Get the current class scope at the cursor, the result depends on the current cursor position
let scopeItem = s:GetClassScopeAtCursor()
let listUsingNamespace = copy(g:OmniCpp_DefaultNamespaces)
call extend(listUsingNamespace, scopeItem.namespaces)
if g:OmniCpp_NamespaceSearch && &filetype != 'c'
" Get namespaces used in the file until the cursor position
let listUsingNamespace = omni#cpp#namespaces#GetUsingNamespaces() + listUsingNamespace
" Resolving namespaces, removing ambiguous namespaces
let namespaces = omni#cpp#namespaces#ResolveAll(listUsingNamespace)
else
let namespaces = ['::'] + listUsingNamespace
endif
call reverse(namespaces)
" Building context stack from namespaces and the current class scope
return s:BuildContextStack(namespaces, scopeItem.scope)
endfunc