Skip to content

Commit

Permalink
Add debug docs and small bug fix to avoid override start method (fino…
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelbey authored Jan 2, 2025
1 parent 4ae02ce commit e3cbb3b
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 41 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea/**
.mvn/**
**/*.iml
**/target
**/lib
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,29 @@ If you're making changes to the `Pure` codebase, it's highly recommended that yo
- To start the server, please use the `Main` class `org.finos.legend.engine.ide.PureIDELight` with the parameters: `server legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light-http-server/src/main/resources/ideLightConfig.json`.
- You can now access the IDE at http://127.0.0.1:9200/ide in a web browser.

#### Debugging Pure Code

![Debugging](docs/debug.gif)

To debug your `Pure` code, you need to use the `meta::pure::ide::debug()` function to create breakpoints.

When you execute the `go` function using _F9_, the execution will be paused at the breakpoint, and a **_summary_** will be printed.

This **_summary_** include the current stack (for easy navigation to the current breakpoint point) and the variables accessible on such breakpoint.

Once in a breakpoint, using the Pure IDE terminal, you can take certain debugging actions:

- `debug` or `debug summary`: print the aforementioned **_summary_**.
- `debug <pure expression>`: evaluate the given expression. All variables on the current breakpoint are available.
- ie. `debug $f->map(x | $x->type())`: introspect variable `f` and apply some functions to it.
- `debug abort`: stop the current execution. Pressing _F9_ after an abort command will start the execution from the beginning (ie. from the `go` function)

To resume the execution to next breakpoint or to completion, just press _F9_ again.

Caveats:
- Editing the code while on a breakpoint will lead to evaluation errors. You need to complete or abort current execution to pick new changes.
- Print commands within the debug expressions won't show on console. Avoid the print and evaluate to a string value instead.

## Roadmap

Visit our [roadmap](https://github.com/finos/legend#roadmap) to know more about the upcoming features.
Expand Down
Binary file added docs/debug.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.finos.legend.engine.ide.helpers.response.IDEResponse;
import org.finos.legend.engine.ide.session.PureSession;
import org.finos.legend.engine.ide.session.SimpleFunction;
import org.finos.legend.engine.pure.ide.interpreted.debug.FunctionExecutionInterpretedWithDebugSupport;
import org.finos.legend.pure.m3.execution.Console;
import org.finos.legend.pure.m3.execution.FunctionExecution;
import org.finos.legend.pure.m3.serialization.runtime.PureRuntime;
Expand Down Expand Up @@ -57,7 +58,14 @@ public void run(PureSession pureSession, JSONObject extraParams, JSONArray modif
console = functionExecution.getConsole();
console.setPrintStream(new JSONPrintStream(outputStream));
console.setConsole(true);
functionExecution.start(function, FastList.<CoreInstance>newList());
if (functionExecution instanceof FunctionExecutionInterpretedWithDebugSupport)
{
((FunctionExecutionInterpretedWithDebugSupport) functionExecution).startDebug(function, FastList.newList());
}
else
{
functionExecution.start(function, FastList.newList());
}
outputStream.write("\"".getBytes());
}
catch (Exception ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public String evaluate(String command)

ListIterable<CoreInstance> newInstances = inMemoryCodeBlock.getNewInstances();

CoreInstance result = this.debugSupport.startRaw(newInstances.get(0), Lists.fixedSize.of());
CoreInstance result = this.debugSupport.start(newInstances.get(0), Lists.fixedSize.of());
CoreInstance lambda = Instance.getValueForMetaPropertyToOneResolved(result, M3Properties.values, this.debugSupport.getProcessorSupport());

ByteArrayOutputStream out = new ByteArrayOutputStream();
Expand All @@ -130,19 +130,23 @@ private static MutableList<Pair<String, CoreInstance>> computeVariables(Variable

private static String computeVariableTypeAndMultiplicity(FunctionExecutionInterpretedWithDebugSupport debugSupport, CoreInstance coreInstance)
{
// todo the GenericType.print has a bug with type arguments, and functions get printed wrong!
// ie. meta::pure::metamodel::function::ConcreteFunctionDefinition<<X> {meta::pure::metamodel::function::Function<{->X[o]}>[1]->X[o]}>
String type;
String multiplicity = Multiplicity.print(coreInstance.getValueForMetaPropertyToOne(M3Properties.multiplicity));

CoreInstance genericType = coreInstance.getValueForMetaPropertyToOne(M3Properties.genericType);
ProcessorSupport processorSupport = debugSupport.getProcessorSupport();
if (processorSupport.type_subTypeOf(coreInstance.getValueForMetaPropertyToOne(M3Properties.genericType).getValueForMetaPropertyToOne(M3Properties.rawType), debugSupport.getPureRuntime().getCoreInstance(M3Paths.Function)))

// todo the GenericType.print has a bug with type arguments on functions, and get printed wrong
// ie. meta::pure::metamodel::function::ConcreteFunctionDefinition<<X> {meta::pure::metamodel::function::Function<{->X[o]}>[1]->X[o]}>
if (processorSupport.type_subTypeOf(genericType.getValueForMetaPropertyToOne(M3Properties.rawType), debugSupport.getPureRuntime().getCoreInstance(M3Paths.ConcreteFunctionDefinition)))
{
type = "Function<Any>";
type = M3Paths.ConcreteFunctionDefinition + "<Any>";
}
else
{
type = GenericType.print(coreInstance.getValueForMetaPropertyToOne(M3Properties.genericType), true, processorSupport);
type = GenericType.print(genericType, true, processorSupport);
}
String multiplicity = Multiplicity.print(coreInstance.getValueForMetaPropertyToOne(M3Properties.multiplicity));

return type + multiplicity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,9 @@

package org.finos.legend.engine.pure.ide.interpreted.debug;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import org.eclipse.collections.api.list.ListIterable;
import org.finos.legend.pure.m3.exception.PureExecutionException;
import org.finos.legend.pure.m3.execution.OutputWriter;
import org.finos.legend.pure.m3.navigation.M3Properties;
import org.finos.legend.pure.m3.navigation.ValueSpecificationBootstrap;
import org.finos.legend.pure.m3.statelistener.VoidExecutionActivityListener;
import org.finos.legend.pure.m4.coreinstance.CoreInstance;
import org.finos.legend.pure.runtime.java.interpreted.FunctionExecutionInterpreted;
Expand Down Expand Up @@ -62,14 +55,13 @@ public void setDebugState(DebugState debugState)
}
}

@Override
public CoreInstance start(CoreInstance function, ListIterable<? extends CoreInstance> arguments)
public void startDebug(CoreInstance function, ListIterable<? extends CoreInstance> arguments)
{
this.resultHandler = new CompletableFuture<>();

if (this.currentExecution == null)
{
this.currentExecution = CompletableFuture.supplyAsync(() -> this.startRaw(function, arguments));
this.currentExecution = CompletableFuture.supplyAsync(() -> this.start(function, arguments));
this.currentExecution.whenComplete((v, e) ->
{
if (e != null)
Expand All @@ -85,38 +77,17 @@ public CoreInstance start(CoreInstance function, ListIterable<? extends CoreInst
}
else
{
this.getConsole().print("Resuming from debug point...");
this.debugState.release();
}

try
{
return this.resultHandler.join();
this.resultHandler.join();
}
catch (CompletionException e)
{
throw (RuntimeException) e.getCause();
}
}

public CoreInstance startRaw(CoreInstance function, ListIterable<? extends CoreInstance> arguments)
{
return super.start(function, arguments);
}

@Override
public void start(CoreInstance func, ListIterable<? extends CoreInstance> arguments, OutputStream
outputStream, OutputWriter writer)
{
CoreInstance result = this.startRaw(func, arguments);

try
{
ListIterable<? extends CoreInstance> values = result.getValueForMetaPropertyToMany(M3Properties.values);
writer.write(values, outputStream);
}
catch (IOException e)
{
throw new UncheckedIOException("Failed to write to output stream", e);
}
}
}

0 comments on commit e3cbb3b

Please sign in to comment.