Re: Is there a way to locally parse from point to the outer most scope, or just current buffer?

Eric Ludlam <[email protected]> Wed, 28 Jan 2015 13:15:37 -0500
Newsgroups gmane.emacs.cedet
Message-ID <[email protected]>
On 01/28/2015 10:40 AM, Tu Do wrote:
> With regard to the refactoring issue, there's more to it than simple 
> renaming semantically. It's 2015 and people are excited about these 
> refactoring features in Visual Studio: 
> http://blogs.msdn.com/b/vcblog/archive/2014/11/14/all-about-c-refactoring-in-visual-studio-2015-preview.aspx 
> . Currently, I already implemented these features: implement all 
> functions (virtual and non-virtual as well as constructor and 
> destructor) in a class in a header files, convert a function 
> implementation into a function prototype, convert function <--> 
> function pointer, convert function pointer to typedef, move a semantic 
> unit (i.e. move function/variables) to another file. Many of these 
> little things are perfectly possible with Semantic, yet there's no 
> satisfiable solution rather than some simple regex hack to the above 
> problem.

Hi Tu,

I agree that there are many other kinds of refactoring aside from 
renames.  I ended up spending all my time getting infrastructure 
together, I never got very far with user facing tools for code 
generation.  You can see the beginnings of some other code-gen tools in 
the SRecode package.  There are tests around a tool for adding a field 
to a structure, and automatically implementing the get/set methods, for 
example.  See cedet/srecode/expandproto.el.   There is also some code 
for creating nice comments in cedet/srecode/document.el.

Using SRecode you can "copy" a tag with "C-c , M-w", and paste it 
elsewhere "C-c , C-y".  The way it is supposed to work is that when you 
paste into a function body, it would call the copied tag, and if you 
paste into an open space, it might insert a prototype (header) or 
implementation.  If you paste into doc, it will create doc.  I don't 
recall how far I got with semantic-insert-foreign-tag.

Anyway, srecode is the best way to take a semantic tag, and insert it 
into a buffer.  You can write high-level code that is language agnostic, 
and let the template files deal with the language specifics.

Probably the best example of using it is in the CEDET/git file 
testd/cit-cpp.el which just has some defvar's full of tags that get 
inserted into a buffer as a way of initiating the test cases.  It 
eventually runs through a simple refactoring case as well.

You can actually parse a file in one language with Semantic, and insert 
just the definitions back into a file in another.  The case I used the 
most was from ELisp -> .Texi files.  It doesn't work with everything of 
course, but that is the general idea.  That makes it easy to use a tool 
like COGRE (which is only in CEDET/git) to make a UML diagram, create 
Semantic tags internally, and write it out as C++ code, or to .dot code 
for making nicer diagrams.

Obviously, SRecode is pretty heavy weight for some kinds of refactoring, 
but if you have as many nifty refactoring tools as you suggest above, if 
they can use SRecode for writing code, it will make it easy to adapt to 
new languages.

> I hope that after introducing these features, people will accept and 
> adopt CEDET more. Currently, they see CEDET as something opaque and 
> time consuming. Creating these features with it is pleasure, compare 
> with when I was using Xtext

I agree.   Thanks!

> I also have some questions:
>
> - I see that Semantic has functions related to scope. What actually is 
> scope in Semantic? How do I access and use it?

semantic/scope.el is all about calculating what symbols are in scope for 
purposes of smart completion.

I rarely calculate only the scope, and instead use 
semantic-analyze-current-context, which happens to include a scope as 
well.  In it you will find local variables, local arguments, types that 
are in scope due to being a method, etc.  Very handy. The scope will 
have methods for looking stuff up as well, but usually it isn't the 
whole picture, so I use the full context for most activities.  The scope 
by itself is helpful for prioritizing stuff, such as assuming the user 
is most likely to use a local variable before some global.

To use, you position point where you need context information, and then 
ask for the context for that location.   The scope (from 
semantic/scope.el) is not calculated during parsing, as you might expect 
from an AST from gcc or some-such.

> - Is there a command that parse only current buffer, not recursively 
> parse the included files. Is this command possible: 
> semanticdb-file-table-object?. It seems that when using 
> semantic-symref, it also tries to parse the included files in a buffer.

Yes.   `semantic-fetch-tags' only gets tags for the current buffer. You 
only get recursive parsing if you use one of the semanticdb-find-* 
functions.  If you see recursive parsing, then you might be using some 
search routine by side effect.  You can restrict what the searches look 
for via the variable `semanticdb-find-default-throttle', though I 
recommend setting it only temporarily.

You can use `semanticdb-find-test-translate-path' to see what it thinks 
is included in a search.  You can also right click on a #include (if you 
have decoration mode enabled) and ask what is up with the headers (which 
are found / not found, etc).

There is also semanticdb-file-table-object if you are starting with a 
filename.

I hope this helps.
Eric

------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/