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

Eric Ludlam <[email protected]> Mon, 26 Jan 2015 12:43:15 -0500
Newsgroups gmane.emacs.cedet
Message-ID <[email protected]>
On 01/26/2015 10:02 AM, Tu Do wrote:
> Hi Eric,
>
> I implemented some initial refactoring tools using Semantic. You can 
> see the demos here: https://github.com/chrisbarrett/emacs-refactor/pull/5
>
> In the future, I intend to implement Semantic query and replace, in 
> combination with GNU Global to find all references without burdening 
> Semantic up-front parsing. Using GNU Global to retrieve a list of 
> references, then just parse enought the scope of each reference to get 
> sufficient information to decide which symbol is to be replaced, to 
> avoid freezing Emacs for too long.
>
> Is it possible to prevent whole buffer parsing when visiting a buffer 
> with Semantic enabled?

Howdy,

You can temporarily suppress buffer parsing for a specific file by 
adding something to semantic--before-fetch-tags-hook, and you don't need 
to disable semantic for entire modes to do it.

Since your intent is to use GNU Global, you can also use 
`semanticdb-enable-gnu-global-databases' so that whenever a set of file 
tags is needed, it uses GNU Global instead of the usual parsing 
mechanism which also speeds things up.  This is used primarily for 
finding tags by name, not as a replacement when a file is in a buffer, 
as global tags do not have the needed features.

Your project for refactoring tools sounds great.  I had long planned to 
do refactoring as well and have a few core pieces in place.

The `semantic-symref' tool knows how to query GNU Global (and several 
other tools) into a structure you can work with. You should try it out, 
as it has a simple "rename" type feature in it already, and the symref 
mode lets you select which entries you want the rename to operate on in 
case the search gets a false positive.  I didn't get very far with 
refactoring tricks though.

There is a comment deep in the symref code referring to a place where we 
want to verify every hit really is the thing we are looking for which I 
never implemented.  This almost sounds like what you are trying to do 
(verify without parsing everything.)  I hadn't thought of trying to 
shorten parsing like that.  Usually a single buffer parses very quickly.

Parsing a subset of the buffer is the job of `semantic-parse-region', 
and the incremental parser.  Unfortunately, you need the guidelines of a 
previously parsed buffer in order to make it work accurately.

There is also the local context parser you can get to from 
`semantic-get-local-variables' but that also needs a full buffer parsed.

This is why I ended up with using the symref mode where you can take a 
peek and pick out which are safe replacements, and which are not before 
running the operation.  It gets simple functional stuff right almost all 
the time, but it doesn't decipher complex OO constructs where the text 
is the same but the actual referred to thing could be different.  It 
could use the semantic analyzer on the code hits to determine which are 
of the correct class, etc, but that would be pretty slow for a lot of 
hits.  That would require some infrastructure for doing that operation 
in idle-time.  Since each individual analysis is typically under 1 sec 
once key headers are loaded, that should be a problem.

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/