>>> Hannu Koivisto <azure@...> seems to think that:
>"Eric M. Ludlam" <eric@...> writes:
>
>>>>> Hannu Koivisto <azure@...> seems to think that:
>
>>>int foo()
>>>{
>>> int kala;
>>> l<M-x semantic-ia-complete-symbol RET>
>>> int lahna;
>>>}
>>>
>>>...semantic completes lahna even though it is not a valid
>>>completion.
>>
>> Interesting. Local variables are captured withing a "scope". That
>> way if you move the cursor in the scope, you can recycle the old
>> data. As such, there is a performance trade-off.
>>
>> What do you think?
>
>While I usually like the "first correct, then fast" way, I would
>agree that this is probably not the most important correctness
>issue :) I noticed it sort of around the corner (with speedbar
>analyzer) -- the example above was artificial -- and I suspected
>this might end up to the "known issues" list, if there is one.
>(Unfortunately) I have seen C++ code where some local variable
>definitions were so far apart that if this worked correctly, it
>might be helpful, but I hope such situations are rare.
The scope object has a couple levels of reset. If the incremental
parser changes the list of includes, for example, the whole thing is
reset. If the cursor moves around inside a single tag, then the local
variables are reset. If the cursor moves into a different tag, then
everything is reset.
In researching this answer, I suspect that trimming back the local
variables list would be ok as it appears that gets redone for cursor
movements already, so no loss. Someone just needs to add that
behavior into the local variable parser somehow. (That would be
`semantic-get-local-variables' if someone wants to give it a try.)
>If I put my programmer hat on, the performance trade-off comment
>is interesting, though. As far as I can see, if I rewrite the
>code like this...
>
>int foo()
>{
> int kala;
> l<...>
> {
> int lahna;
> }
>}
>
>...I get no false completions. Should I now see some real
>performance problem (even if the code was more complex than that
>example)? Why can't one 'recycle the old data' when one moves to
>another scope? Don't you have this same issue when you move the
>cursor from, say, one method to another? I wouldn't want
>performance problems in that case either and intuitively that feels
>like a bigger change.
I don't know if it is a performance "problem" at this point, though I
suppose a fabulously long and complex function could be problematic.
I just go out of my way to cache data as much as I can and have as
many lazy reset options as possible.
>>>Also, is it a known issue that you need to type at least one
>>>character before you can list completions? For example, in the
>>>above scenario, if I hadn't typed "l" before using
>>>semantic-ia-complete-symbol, I wouldn't have gotten any completions.
>>
>> Yes. This is to dodge the 10000 possible completions problem.
>
>Hmm. Presumably the problem with that is generating the
>completions, not displaying them? Just out of curiosity, can you
I don't know. I didn't profile stuff back when I disabled it, though
later experience shows that dumping huge lists of strings into a
display buffer is usually slower than calculating them.
>ask Semantic APIs for completions incrementally by scope,
>i.e. something like "give me completions within local variables"
>(I'm simplifying that there is only one local variable scope),
>"give me completions within class members", "give me completions in
>the innermost namespace" etc?
That's a cool idea, though more of an option for the tool that
performs the completion. It is possible to get the local scope, and
the local typecache and do this work without the context analyzer.
The analyzer API is a one-shot deal with only one level.
While a blank command is a bit of a stretch for auto-generating some
code, I know I'd love to solve problems such as:
const int ma=1, mb=2;
int foo(int a) {
myfcn(-!-
and some universal completion key would fall to a mode where it knows
that the first arg of myfcn is "int", and the most likely candidate is
"a", and just do it, instead of relying on the really complicated
completion system. The next most likely might be ma, or mb, because
those variables are nearby.
For SRecode, it gets more interesting. In place of "myfcn" above, if
the user asked to create a 'for' loop, it might guess that you'd want
to loop from 0 to a. Or perhaps there is a std::vector and you'd want
to generate some iterators for it, and loop over those.
There are many interesting heuristics that would be fun to explore.
>Also, if you have
>
>-- foo.hpp --
>
>class Foo {
>...
>};
>
>-- bar.hpp --
>
>#include "foo.hpp"
>
>class Bar : public Foo {
> int baz();
> ...
>};
>
>int Bar::baz()
>{
> abc<complete>
>}
>
>----
>
>Can you ask Semantic if it _should_ know all applicable Bar members
>starting with abc? Which I believe in this case would translate to
>"do you know Foo?" which again depends on if foo.hpp has been
>parsed, although naturally you can't know if parsing foo.hpp will
>make Foo known until you actually parse it.
In this case, asking for completions will force "foo.hpp" to be
parsed, and to contribute to the completions list. This answer to
your question "do you know Foo?" is in the scope, which would list
Foo as an option.
Use
M-x semantic-calculate-scope RET
to find out what it knows.
Eric
--
Eric Ludlam: eric@...
Siege: http://www.siege-engine.com Emacs: http://cedet.sourceforge.net
|