Custom nabl-constraint with nabl-lookup call triggers "Cannot delay task" RuntimeException
As soon as I add a hand-written nabl-constraint like the following, all my example files fail analysis…
nabl-constraint(|ctx): Decl(_,n) -> <fail> where lookup := <nabl-lookup-lexical-parent(|ctx)> n ; <task-create-error-on-success(|ctx, lookup, $[Shadowing (duplicate) definition])> n
I tried right-clicking on projects and selecting Spoofax > Reload analysis data. It doesn’t help.
How do I work around this?
Stratego stack trace:
Internal error evaluating editor-analyze (InterpreterException; see error log) rewriting failed, trace: editor_analyze_0_0 analysis_default_editor_0_0 analysis_single_default_interface_0_0 analysis_single_default_3_1 analysis_single_default_4_1 analysis_files_spoofax_4_2 analysis_files_spoofax_5_2 analysis_files_4_2 analysis_files_no_builtins_6_2 measure_time_2_0 x_652 map_1_0 analysis_collect_1_2 d_706 preserve_annos_1_0 origin_track_forced_1_0 m_857 nabl_siblings_0_4 nabl_siblings_0_4 nabl_collect_1_4 preserve_annos_1_0 origin_track_forced_1_0 m_857 nabl_siblings_0_4 nabl_collect_1_4 preserve_annos_1_0 origin_track_forced_1_0 m_857 nabl_siblings_0_4 nabl_siblings_0_4 nabl_collect_1_4 preserve_annos_1_0 origin_track_forced_1_0 m_857 nabl_siblings_0_4 nabl_siblings_0_4 nabl_collect_1_4 preserve_annos_1_0 origin_track_forced_1_0 m_857 nabl_siblings_0_4 nabl_siblings_0_4 nabl_collect_1_4 nabl_annotate_properties_0_4 try_1_0 nabl_constraint_0_4 nabl_constraint_0_3 nabl_constraint_0_1 nabl_lookup_lexical_0_1 nabl_uri_0_0 fetch_elem_1_0 nabl_collect_one_resolved_def_0_0 insert_results_or_delay_0_0 task_delay_0_0 task_api_delay_0_1
Part of the Java stacktrace:Submitted by Jeff Smits on 11 June 2015 at 22:06
Caused by: java.lang.RuntimeException: Cannot delay task while no task evaluation is in progress. at org.metaborg.runtime.task.primitives.task_api_delay_0_1.call(task_api_delay_0_1.java:26) at org.spoofax.interpreter.stratego.PrimT.eval(PrimT.java:63) at org.spoofax.interpreter.stratego.Strategy.evaluate(Strategy.java:76) at org.spoofax.interpreter.stratego.SDefT.evaluate(SDefT.java:213) at org.strategoxt.lang.InteropStrategy.invokeDynamic(InteropStrategy.java:57)
I’m not sure if you can do
nabl-lookup-lexical-parentduring collection time, but I think this is ok.
I have tasks using
nabl-lookup-lexical, maybe it helps you to look at it: https://github.com/metaborg/relations/blob/master/relations/trans/lib/nabl-ext.str
This error indicates that you are trying to use task results outside of task evaluation. I’m not entirely sure what
nabl-lookup-lexical-parentdoes, but it seems to get a URI, but this requires resolving a use to a def with
nabl_collect_one_resolved_def, and then fails because this task has not been computed yet, and task evaluation has not been started yet. Maybe
nor its annotations have a use in them?
Ok that makes sense. I don’t want to resolve names at that point. I just want to get back a task that will do the lookup later. What do I need to call for that?
I have code that checks for duplicate names in separate namespaces - which is quite similar to looking wether you shadow a name in an above namespace.
On definitions you can just use the non-task strategies on names and uri’s: and find the name and namespace you want to do something with.
Then in the end you can use tasks to do the lookup:
role-defs := <_nabl-lookup-lexical(|ctx, conflict-ns)> a-name; <_task-create-error-on-success(|ctx, role-defs, ["Conflicting ", <_pp-ns>ns, " and ", <_pp-ns>conflict-ns, " ", a-name, " in ", <_pp-ns>parent-ns, " ", parent])> a-name
rules // check if there are no name collisions in attributes, roles, inverses and shortcuts ns-conflict-error = ![ [NablNsAttribute(), NablNsRole(), NablNsInverse(), NablNsShortcut()] ]
rules // api for conflicting nses error messages nabl-constraint(|ctx): a -> <fail> where <is-string>a; //on all strings name := <nabl-get-name>a; //that have an nabl name <not(_nabl-has-reference)>name; //and this name is a def uri := <_nabl-uri> name; ns := <_nabl-uri-namespace> uri; nses := <ns-conflict-error;filter(fetch(?ns));Hd>ns //get the list of nses that this ns is in (where-fail if there is no such list) with <name-nses-conflict(|ctx, nses)>name name-nses-conflict(|ctx,nses): a-name -> <id> with <map(name-ns-conflict(|ctx, a-name))>nses name-ns-conflict(|ctx, a-name): conflict-ns -> <id> with uri := <_nabl-uri> a-name; ns := <_nabl-uri-namespace> uri; if <not(eq)> (conflict-ns, ns) then uri':= <_nabl-uri-parent> uri; parent:= <_nabl-uri-name> uri'; parent-ns := <_nabl-uri-namespace> uri'; role-defs := <_nabl-lookup-lexical(|ctx, conflict-ns)> a-name; <_task-create-error-on-success(|ctx, role-defs, ["Conflicting ", <_pp-ns>ns, " and ", <_pp-ns>conflict-ns, " ", a-name, " in ", <_pp-ns>parent-ns, " ", parent])> a-name end ns-conflict-error = fail // interface implemented by language nabl-get-name = fail // generated by nabl
@gohla was right that I’m using
nabl-lookupon a reference, not a definition. It’s been a while since I wrote these rules manually and I thought I had to do an
nabl-lookup, but I didn’t. The task inside the
Useannotation was enough.
So the piece of Stratego causing all this was:
nabl-constraint(|ctx) = ?term; one(?i@Implicit()) ; lookup := <nabl-lookup-lexical(|ctx)> i ; <task-create-error-on-multiple(|ctx, lookup, $[Multiple graphs found, specify associated graph])> term ; fail
And I should have used:
nabl-constraint(|ctx) = ?term; one(?i@Implicit()) ; <has-annotation(?Use(lookup))> i ; <task-create-error-on-multiple(|ctx, lookup, $[Multiple graphs found, specify associated graph])> term ; fail
The runtime exception is rather awful though. Can the library or runtime be patched, so you get something that at least hints at what you’re doing wrong?
Log in to post comments