How to get the file(s) containing the definition site(s) for a used name from its analyzed AST?

For example, "while"{Use(Result(4819))} in one AST refers to the following definition of the name “while”:

      "while"{ Def(
                 URI(
                   Language("CBS")
                 , [ID(NablNsName(), "while", Unique(".../Funcons/Computations/Control flow/Normal/Iterating/Indefinite/while.cbs/0"))]
                 )
               )
             }

I’d like to generate ".../Funcons/Computations/Control flow/Normal/Iterating/Indefinite/while.cbs" from "while"{Use(Result(4819))}.

The Spoofax web page about NaBL refers to the Stratego API for looking up names, but the link provided (to svn.strategoxt.org) isn’t working.

Asked by Peter Mosses on 11 February 2016 at 08:57

After analysis you can try: nabl-collect-all-resolved-defs; mapconcat(index-get-all-sources-of) on "while"{...} which gives you a list of source files the definitions (resolved from the use site) are in. This is a list because 1. a use can resolve to multiple definitions, and 2. a non-unique declaration can be defined in multiple files (although this is not the case with your unique definition).

If you want do this during name/type analysis, you’d have to create a task that does this.

Answered by Gabriël Konat on 11 February 2016 at 10:57

Thanks for the solution. To produce the set of all source files containing the definitions relevant to an AST, I used the suggested code as follows:

  gen-referenced-sources = 
  	collect-all(?_{Use(_)}); mapconcat(gen-paths); make-set

  gen-paths = 
  	nabl-collect-all-resolved-defs; mapconcat(index-get-all-sources-of); make-set

I also imported the following additional files:

	lib/runtime/index/core
	lib/runtime/index/query
	lib/runtime/nabl/resolve
	lib/runtime/nabl/entries

It seems necessary to precede the first call of my gen-paths by:

        task-setup(|project-path);
        index-setup(|language-name, project-path);

However, I’m not familiar with the Spoofax runtime library, and there may be a simpler or more efficient way to get the same result.

Answered by Peter Mosses on 16 February 2016 at 01:27