Closeuniversal-ctags/ctags#453.
(This is about a bug spotted in universal-ctags/ctags#453 by @mislav and
in universal-ctags/ctags#11 by @NewAlexandria.)
Kinds C and d are for Rspec.
Parts of code related to above kinds assume a ruby string
comes after Rspec keywords (describe or context).
This is a wrong assumption. A class name can be used there.
It is nice if ctags can handle these rspec code well, but we
don't have enough resource to make it now.
So in this commit I delete rspec related code temporary. I
just reserve a kind letter 'd' for rspec for the future. 'C'
is completely deleted because (1) describe and context have
the same meaning in rspec, and (2) we would like to assign
'C' for Ruby constant as ripper-tags does.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
This patch is intended a bug reported as sf.bug:364.
https://sourceforge.net/p/ctags/bugs/364/
Writing a test case is helped by Dmitry Gutov.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
fuzz target reports canMatch access wrong memory
area when php-anonymous_functions.d/input.php is
given as input.
This patch fixes it.
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Because of the missing "typedef struct TMFoo" it was missing from the gtkdoc
header (the struct listings are always without typedef). This is also
consistent with the rest of geany.
@gironly for TMParserType so it's picked up as well.
Based on 21e74e6a019975045a7975bc611ae63f0917f976 from universal-ctags,
and update the tests accordingly, thanks to @JX7P.
Closes#940.
X-Universal-CTags-Commit-ID: 21e74e6a019975045a7975bc611ae63f0917f976
We should isolate ctags from Geany completely and use separate types. At
the moment langType is shared by both Geany and ctags. For Geany redefine
it as TMParserType (which was currently used as the name of the enum and
was unused) and use everywhere in Geany. At the same time convert some
ints to TMParserType where they denote the parser.
This is strictly speaking an API change but no plugin uses langType at the
moment so its renaming doesn't cause any problems.
The only remaining visible ctags type is tagEntryInfo - it is however
used only inside tagmanager (and can be later removed quite easily too
by slightly reorganizing TM source files).
At the moment the Geany code uses arbitrary combination of the following
synonyms
TM_PARSER_NONE / LANG_IGNORE / -2
TM_PARSER_AUTO / LANG_AUTO / -1
Especially using just the numbers makes things very confusing.
In the Geany code this patch replaces all occurrences of -2 and LANG_IGNORE
with TM_PARSER_NONE. It also removes LANG_IGNORE from the header which
isn't needed any more.
In addition, TM_PARSER_AUTO/LANG_AUTO shouldn't be used at all. We want
filetype detection based on Geany's definitions and not based on the
hard-coded ctags definitions. Remove it completely.
Finally, as it's clearer now what the constants mean, the patch fixes the
implementation of langs_compatible() (tag or file can never be of type
AUTO but we should rather check for NONE filetypes which we should
consider incompatible between each other).
Pop up scope completion dialog for namespaces too; e.g. for
boost::
show all symbols defined in the namespace. Determine whether the namespace
scope completion should be used based on whether user typed a scope
separator. If so, perform completion for namespaces before normal scope
completion - this seems to work better e.g. for Scintilla where
Scintilla::
would otherwise pop up the varible sci instead of showing everything
in the namespace (might be more questionable for languages where
the scope separator is identical to the dereference operator like
Java's "." but we have to make some choice anyway).
The performance seems to be reasonable - for the completion all tags
have to be walked but after testing with big C++ projects like
boost and Mozilla, the completion takes only something like 0.2s
which is acceptable as the delay happens only on typing the scope
completion separator and feels kind of expected.
Also tested with linux kernel sources which normally lack any scope
information by hacking TM a bit and injecting 10-character scope for
each tag - then the completion takes something over 0.5s.
We only perform search based on variable name so if a variable is e.g. of
the type std::Foo, we can drop the std:: prefix and search only for the
Foo type.
This is far from perfect and contains a lot of guessing. It showed
good results based on our tests cases, fixing several issues and not
introducing any more issues (admittedly, after working around a subtle
one regarding D static ifs).
Closes#845.
Also, don't perform subtractions to check pointer bounds, to avoid
unsigned value wraparound. This is very unlikely as it would either
mean a very large `nth` value or a very small value for the current
line pointer, but better safe than sorry.
See http://en.cppreference.com/w/cpp/language/string_literalCloses#877.
---
This contains a pretty ugly hack to fetch the previous character, in
order not to get fooled by string concatenation hidden behind a macro,
like in `FOUR"five"`, which is not a raw string literal but simply the
identifier `FOUR` followed by the string `"five"`.
While this may sound uncommon, it is not and lead to complaints [2][3]
when Scintilla [1] broke this when they introduced C++11 raw string
literal support themselves.
The implementation here still contains a bug with line continuations: a
raw literal of the form:
```c
const char *str = R\
"xxx(...)xxx";
```
is not properly recognized as such, although it's perfectly valid (yet
probably very uncommon). For the record, Scintilla has also suffers
from this but nobody complained about it yet.
[1] http://scintilla.org/
[2] https://sourceforge.net/p/scintilla/bugs/1207/
[3] https://sourceforge.net/p/scintilla/bugs/1454/
Because the tm_source_file_new() is an exported API, it has to be at least a
boxed type to be usable for gobject introspection. The boxed type uses
reference counting as opposed to memory duplication.
The obligatory tm_source_file_dup() is not exported (doesn't have to).
First, the search for existing type with the given scope should be done
also for namespaces.
Second, with the string operations we get no scope as empty string ""
but the rest of TM functions expect scope to be set to NULL in such
case. Fix that.
When we already have a struct-like type in namespace search,
we don't need any extra resolution - we already have the
right type. Skip the whole typedef resolution in this case.
Make sure the anonymous types are from the same file as the
variable of that type (or, when performing typedef resolution, from
the same file as the typedef).
On the way, simplify find_scope_members() a bit and fix some minor
problems.
Make the unused code compile and remove unused tm_get_current_function()
(we have similar symbols_get_current_function() and there's no reason
to keep it)
The main reason for separating m_workspace_find() into two parts is the
fact that when matching only the prefix, the result may contain too
many results and we need to go through all of them, return them and at the
end discard most of them.
For instance, when considering the linux kernel project with 2300000 tags
and when autocompletion is set to be invoked after typing a single character,
we get on average something like 100000 results (tag_num/alphabet_size).
But from these 100000 results, we get only the first 30 which we display
in the popup and discard the rest which means going through the list of
the 100000 tags and comparing them for no reason.
Thanks to using binary search for the start and the end of the sequence of
matching tags (added in a separate patch), we can get the start of the
sequence and the length of the sequence very quickly without going through
it.
For the prefix search we can limit the number of tags we are interested
in and go through at most this number of returned tags (to be precise,
times two, because we need to go both through the workspace array and
global tags array and remove the extras only after sorting the two).
It would be possible to combine both tm_workspace_find() and
tm_workspace_find_prefix() into a single function but the result is a bit
hard to read because some of the logic is used only in tm_workspace_find()
and some only in tm_workspace_find_prefix() so even though there is some
code duplication, I believe it's easier to understand this way.