Thread: [CEDET-devel] semantic-analyze-tag-references bug
Brought to you by:
zappo
From: Hannu K. <az...@ik...> - 2009-10-03 02:41:19
|
Greetings, If I have, for example, in foo.hpp class Foo { void sur(); }; and in foo.cpp #include "foo.hpp" void Foo::sur(int a) { } If I move on top of void sur(); prototype in foo.hpp and evaluate (semantic-analyze-current-tag), void Foo::sur(int a) tag is listed as a reference. This means that for example semantic-ia-fast-jump happily jumps from "void sur();" line to "void Foo::sur(int a) {" line. I started to write a tool that generates implementation skeletons for prototypes for which there are no corresponding implementations (and prototypes for implementations for which there are no prototypes) and noticed this. What I would also like to do is update prototypes/implementations when the other one changes but in order to do that properly, I would need tag history information. That is, if the code corresponding to a tag is changed, I'd like to get from the new, updated tag to the previous tag that matched the code before it was changed. But I guess that wouldn't be easy. -- Hannu |
From: Eric M. L. <er...@si...> - 2009-10-03 15:13:32
|
On Sat, 2009-10-03 at 05:40 +0300, Hannu Koivisto wrote: > Greetings, > > If I have, for example, in foo.hpp > > class Foo { > void sur(); > }; > > and in foo.cpp > > #include "foo.hpp" > > void Foo::sur(int a) { > > } > > If I move on top of void sur(); prototype in foo.hpp and evaluate > (semantic-analyze-current-tag), void Foo::sur(int a) tag is listed > as a reference. > > This means that for example semantic-ia-fast-jump happily jumps > from "void sur();" line to "void Foo::sur(int a) {" line. > > I started to write a tool that generates implementation skeletons > for prototypes for which there are no corresponding implementations > (and prototypes for implementations for which there are no > prototypes) and noticed this. > > What I would also like to do is update prototypes/implementations > when the other one changes but in order to do that properly, I > would need tag history information. That is, if the code > corresponding to a tag is changed, I'd like to get from the new, > updated tag to the previous tag that matched the code before it was > changed. But I guess that wouldn't be easy. Hi, That is also a project I wanted to build, but I had to build SRecode first, and have not yet gotten that far. If you are interested in doing that, and can provide paperwork to the FSF to release your work to be included in Emacs, that would be great. If you take a tag parsed from sources with a :prototype-flag attribute of t; (semantic-tag-get-attribute TAG :prototype-flag) you can insert an implementation somewhere else like this: (srecode-semantic-insert-tag F) If the prototype flag is nil, and you want to create a prototype, you can do that like this: (srecode-semantic-insert-tag F '(prototype)) If the tag is properly set up with :parent information, it will also succeed in creating methods in or out of a class declaration, though the parameters to srecode-semantic-insert-tag gets more complex. See cedet/tests/cit-cpp.el for more. I started this in srecode-expandproto.el in 2007, but never finished because I had to build the tag reconstruction templates in SRecode first, which only started working this past winter. For your more detailed question on connecting the two bits of text together in some way such that changes in one get reflected in the other, that is a bit more complex, and sounds like something that would require a new semantic utility. Since Semantic tags are managed in buffers with overlays, you could add add a modification hook that first identifies what tag the current tag might be linked to, and then do that linking. You would then be able to add a semantic-after-partial-cache-change-hook for when the tag changes to do your work. Eric |
From: Hannu K. <az...@ik...> - 2009-12-21 02:01:37
|
"Eric M. Ludlam" <er...@si...> writes: > On Sat, 2009-10-03 at 05:40 +0300, Hannu Koivisto wrote: >> Greetings, >> >> If I have, for example, in foo.hpp >> >> class Foo { >> void sur(); >> }; >> >> and in foo.cpp >> >> #include "foo.hpp" >> >> void Foo::sur(int a) { >> >> } >> >> If I move on top of void sur(); prototype in foo.hpp and evaluate >> (semantic-analyze-current-tag), void Foo::sur(int a) tag is listed >> as a reference. >> >> This means that for example semantic-ia-fast-jump happily jumps >> from "void sur();" line to "void Foo::sur(int a) {" line. You commented on other things in my mail but not this one. Do you consider this as a feature and not a bug, perhaps? -- Hannu |
From: Eric M. L. <er...@si...> - 2009-12-22 01:54:14
|
Hi, Sorry, I've lost the original context to your question. It is a feature for semantic-ia-fast-jump to jump from "sur" to the implementation of "sur". You can use semantic-analyze-proto-impl-toggle to go between a prototype and implementation so long as Semantic has parsed all files related to both. If that is not your question, could you elaborate? Eric Hannu Koivisto wrote: > "Eric M. Ludlam" <er...@si...> writes: > >> On Sat, 2009-10-03 at 05:40 +0300, Hannu Koivisto wrote: >>> Greetings, >>> >>> If I have, for example, in foo.hpp >>> >>> class Foo { >>> void sur(); >>> }; >>> >>> and in foo.cpp >>> >>> #include "foo.hpp" >>> >>> void Foo::sur(int a) { >>> >>> } >>> >>> If I move on top of void sur(); prototype in foo.hpp and evaluate >>> (semantic-analyze-current-tag), void Foo::sur(int a) tag is listed >>> as a reference. >>> >>> This means that for example semantic-ia-fast-jump happily jumps >>> from "void sur();" line to "void Foo::sur(int a) {" line. > > You commented on other things in my mail but not this one. Do you > consider this as a feature and not a bug, perhaps? > |
From: Hannu K. <az...@ik...> - 2009-12-22 10:16:00
|
"Eric M. Ludlam" <er...@si...> writes: > Hi, > > Sorry, I've lost the original context to your question. There was no context beyond that. > It is a feature for semantic-ia-fast-jump to jump from "sur" to the > implementation of "sur". You can use semantic-analyze-proto-impl-toggle ... > If that is not your question, could you elaborate? void Foo::sur(int a) { ... } is not an implementation of void sur(); in class Foo. It would be an implementation of void sur(int); or void sur(const int); (yes, this is a relatively unknown, but sensible feature of C++: cv qualifiers are ignored by the compiler in declarations) and many other things, but not void sur(); or void sur(char* a); etc. Thanks, -- Hannu |
From: Eric M. L. <er...@si...> - 2009-12-26 16:14:24
|
Hannu Koivisto wrote: > "Eric M. Ludlam" <er...@si...> writes: > >> Hi, >> >> Sorry, I've lost the original context to your question. > > There was no context beyond that. > >> It is a feature for semantic-ia-fast-jump to jump from "sur" to the >> implementation of "sur". You can use semantic-analyze-proto-impl-toggle > ... >> If that is not your question, could you elaborate? > > void Foo::sur(int a) { ... } > > is not an implementation of void sur(); in class Foo. > > It would be an implementation of void sur(int); or void sur(const > int); (yes, this is a relatively unknown, but sensible feature of > C++: cv qualifiers are ignored by the compiler in declarations) and > many other things, but not void sur(); or void sur(char* a); etc. Ah, I understand now. The ability to distinguish between to variants of the same function name with different arguments has not been implemented. If you look in semantic-ia--fast-jump-helper you will see that if it finds a list of implementations, it just picks the first one (with 'car) A quick solution would be to have the above fcn provide some little popup that says "hey, there's more than one. Which do you want?". I think the JDEE has some nice menu thingy for that sort of thing. The next solution is to implement a local context parser that can derive the data types of a call, which could then be used to narrow down the possibilities. My longer term strategy is to team up with someone who loves writing Emacs UIs for selecting things to use the CEDET backend for this sort of thing. Maybe that's more of a wish than a strategy. Eric |
From: Hannu K. <az...@ik...> - 2009-10-03 17:08:42
|
"Eric M. Ludlam" <er...@si...> writes: > That is also a project I wanted to build, but I had to build SRecode > first, and have not yet gotten that far. If you are interested in doing > that, and can provide paperwork to the FSF to release your work to be > included in Emacs, that would be great. We'll have to see about that, I'll first try to do something that works for me. > If you take a tag parsed from sources with a :prototype-flag attribute > of t; > > (semantic-tag-get-attribute TAG :prototype-flag) Right, I have a prototype that walks throught the prototypes and decides which one of them are candidates for insertion. It uses that function, among others. > you can insert an implementation somewhere else like this: > > (srecode-semantic-insert-tag F) > If the prototype flag is nil, and you want to create a prototype, you > can do that like this: > > (srecode-semantic-insert-tag F '(prototype)) > > If the tag is properly set up with :parent information, it will also > succeed in creating methods in or out of a class declaration, though the > parameters to srecode-semantic-insert-tag gets more complex. See > cedet/tests/cit-cpp.el for more. I'll have to check that out. A quick test resulted in a failure, apparently because (semantic-current-tag) over a method prototype returned a tag with no :parent information. I wonder why. But this is getting ahead of where I am now. First I need to find out if the thing to be inserted already exists. Right now I don't know how to do that because combination of semantic-analyze-tag-references and semantic-analyze-refs-impl doesn't seem to return reliable information. Once I get that working, I need to figure out where to insert the new thing. Only then I can start worrying about how to insert the thing. This might involve creating a file first and inserting namespace declarations, for example. Or if the file exists, has existing implementations and has no namespace declarations but namespaces are used, then presumably one specifies the namespace in each definition and this needs to be done also for the new skeleton. > For your more detailed question on connecting the two bits of text > together in some way such that changes in one get reflected in the That wasn't really my real question; I was just thinking aloud that handling updates would be nice but I consider that as an optional feature. To clarify, the example I gave wasn't intended to illustrate an update situation; I see that I may have been unclear about that. In the example I had two _different methods_, void Foo::sur() and void Foo::sur(int) and semantic-analyze-tag-references or semantic-analyze-refs-impl didn't seem to work correctly in that situation. > other, that is a bit more complex, and sounds like something that would > require a new semantic utility. > > Since Semantic tags are managed in buffers with overlays, you could add > add a modification hook that first identifies what tag the current tag > might be linked to, and then do that linking. You would then be able to > add a semantic-after-partial-cache-change-hook for when the tag changes > to do your work. Ok, I'll add this on the list of things to consider once the basics work. -- Hannu |