X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fcommands%2FCommandSession.java;h=9ff2ebabb0b3492c27814e0d0dd013b552b50044;hp=e463a4e6a4ca420c8308e405c4dc0017dd321d8c;hb=c26cba49344b973fba8022c9e6d12adea93abd48;hpb=eecd74faded034bd067094b42bbac0d286d8d9fa diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java index e463a4e6a..9ff2ebabb 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/commands/CommandSession.java @@ -11,12 +11,11 @@ import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import org.simantics.scl.compiler.common.names.Name; +import org.simantics.scl.compiler.common.names.Names; import org.simantics.scl.compiler.constants.StringConstant; import org.simantics.scl.compiler.elaboration.expressions.EApply; import org.simantics.scl.compiler.elaboration.expressions.EBlock; @@ -43,11 +42,11 @@ import org.simantics.scl.compiler.module.ImportDeclaration; import org.simantics.scl.compiler.module.repository.ImportFailure; import org.simantics.scl.compiler.module.repository.ImportFailureException; import org.simantics.scl.compiler.module.repository.ModuleRepository; +import org.simantics.scl.compiler.module.repository.UpdateListener; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; import org.simantics.scl.compiler.top.ExpressionEvaluator; import org.simantics.scl.compiler.top.LocalStorage; import org.simantics.scl.compiler.top.SCLExpressionCompilationException; -import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.runtime.SCLContext; @@ -77,11 +76,13 @@ public class CommandSession { THashMap variableTypes = new THashMap(); PrintStream fileOutput; - - private static final String CONTEXT_MODULE = "Expressions/Context"; - private static final TCon CONTEXT_TYPE = Types.con(CONTEXT_MODULE, "Context"); - private static final Name CONTEXT_GET = Name.create(CONTEXT_MODULE, "contextGet"); - + private UpdateListener dependenciesListener; + + /** + * Only checks the commands for compilation errors but does not run them. + */ + private boolean validateOnly; + public CommandSession(ModuleRepository moduleRepository, SCLReportingHandler handler) { this.moduleRepository = moduleRepository; this.defaultHandler = new PrintDecorator( @@ -108,10 +109,13 @@ public class CommandSession { runtimeEnvironment = null; try { + if(dependenciesListener != null) + dependenciesListener.stopListening(); try { runtimeEnvironment = moduleRepository.createRuntimeEnvironment( environmentSpecification, - getClass().getClassLoader()); + getClass().getClassLoader(), + dependenciesListener); } catch(ImportFailureException e) { THashSet failedModules = new THashSet(); for(ImportFailure failure : e.failures) { @@ -129,7 +133,7 @@ public class CommandSession { try { runtimeEnvironment = moduleRepository.createRuntimeEnvironment( environmentSpecification, - getClass().getClassLoader()); + getClass().getClassLoader()); // no listener here, because should listen also failed modules } catch (ImportFailureException e1) { for(ImportFailure failure : e1.failures) defaultHandler.printError(failure.toString()); @@ -202,7 +206,7 @@ public class CommandSession { }, Types.functionE(Types.STRING, Types.PROC, Types.UNIT))); LOCAL_FUNCTIONS.put("reset", new LocalFunction(new FunctionImpl2() { @Override - public Tuple0 apply(CommandSession commandSession, Tuple0 _) { + public Tuple0 apply(CommandSession commandSession, Tuple0 dummy) { commandSession.removeTransientImports(); commandSession.removeVariables(); commandSession.moduleRepository.getSourceRepository().checkUpdates(); @@ -212,7 +216,7 @@ public class CommandSession { }, Types.functionE(Types.UNIT, Types.PROC, Types.UNIT))); LOCAL_FUNCTIONS.put("variables", new LocalFunction(new FunctionImpl2>() { @Override - public List apply(CommandSession commandSession, Tuple0 _) { + public List apply(CommandSession commandSession, Tuple0 dummy) { ArrayList result = new ArrayList(commandSession.variableTypes.keySet()); Collections.sort(result); return result; @@ -255,7 +259,7 @@ public class CommandSession { }, Types.functionE(Types.STRING, Types.PROC, Types.UNIT))); LOCAL_FUNCTIONS.put("stopPrintingToFile", new LocalFunction(new FunctionImpl2() { @Override - public Tuple0 apply(final CommandSession commandSession, Tuple0 _) { + public Tuple0 apply(final CommandSession commandSession, Tuple0 dummy) { if(commandSession.fileOutput != null) { commandSession.fileOutput.close(); commandSession.fileOutput = null; @@ -267,13 +271,13 @@ public class CommandSession { private LocalEnvironment createLocalEnvironment() { return new AbstractLocalEnvironment() { - Variable contextVariable = new Variable("context", CONTEXT_TYPE); + Variable contextVariable = new Variable("context", Names.Expressions_Context_Context); @Override public Expression resolve(Environment environment, String localName) { Type type = variableTypes.get(localName); if(type != null) return new EApply( - new EConstant(environment.getValue(CONTEXT_GET), type), + new EConstant(environment.getValue(Names.Expressions_Context_contextGet), type), new EVariable(contextVariable), new ELiteral(new StringConstant(localName)) ); @@ -325,6 +329,7 @@ public class CommandSession { Function command = (Function)evaluator .localEnvironment(localEnvironment) .decorateExpression(true) + .validateOnly(validateOnly) .eval(); return new CompiledCommand(command, evaluator.getType()); } @@ -366,7 +371,9 @@ public class CommandSession { handler.printCommand(reader.extractString(expression.location)); command = compile(expression); } catch (SCLExpressionCompilationException e) { - CompilationError[] errors = ((SCLExpressionCompilationException)e).getErrors(); + if(validateOnly) + throw e; + CompilationError[] errors = e.getErrors(); for(CompilationError error : errors) { if(error.location != Locations.NO_LOCATION) handler.printError(reader.locationUnderlining(error.location)); @@ -376,11 +383,15 @@ public class CommandSession { } reader.forgetEverythingBefore(Locations.endOf(expression.location)); - Object resultValue = command.command.apply(variableValues); - String resultString = toString(resultValue, command.type); - if(!resultString.isEmpty()) - handler.print(resultString); + if(!validateOnly) { + Object resultValue = command.command.apply(variableValues); + String resultString = toString(resultValue, command.type); + if(!resultString.isEmpty()) + handler.print(resultString); + } } catch(Exception e) { + if(validateOnly) + throw e; if(!(e instanceof CancelExecution)) { if(e instanceof InterruptedException) handler.printError("Execution interrupted."); @@ -416,10 +427,9 @@ public class CommandSession { void finishBlock() { if(currentBlock != null) { checkInterrupted(); - LinkedList statements = currentBlock.getStatements(); currentBlock.location = Locations.combine( - statements.getFirst().location, - statements.getLast().location); + currentBlock.getFirst().location, + currentBlock.getLast().location); execute(reader, currentBlock, handler); currentBlock = null; } @@ -468,6 +478,24 @@ public class CommandSession { } } + private CompilationError[] validate(Reader commandReader) { + CommandParser parser = new CommandParser(defaultHandler, new MemoReader(commandReader)); + validateOnly = true; + try { + parser.parseCommands(); + parser.finishBlock(); + return CompilationError.EMPTY_ARRAY; + } catch(SCLExpressionCompilationException e) { + return e.getErrors(); + } catch(SCLSyntaxErrorException e) { + return new CompilationError[] { new CompilationError(e.location, e.getMessage()) }; + } catch(Exception e) { + return new CompilationError[] { new CompilationError(Locations.NO_LOCATION, e.getMessage()) }; + } finally { + validateOnly = false; + } + } + public void execute(Reader commandReader, SCLReportingHandler handler) { if(handler == null) handler = defaultHandler; @@ -483,7 +511,7 @@ public class CommandSession { if(e.location != Locations.NO_LOCATION) handler.printError(parser.reader.locationUnderlining(e.location)); handler.printError(e.getMessage()); - } catch(Exception e) { + } catch (Exception | AssertionError e) { if(e instanceof InterruptedException) handler.printError("Execution interrupted."); else @@ -499,16 +527,6 @@ public class CommandSession { execute(new StringReader(command), handler); } - public CompilationError[] validate(String command) { - return CompilationError.EMPTY_ARRAY; - /*try { - compile(command); - return CompilationError.EMPTY_ARRAY; - } catch(SCLExpressionCompilationException e) { - return e.getErrors(); - }*/ - } - private static final String THIS_CLASS_NAME = CommandSession.class.getName(); public static void formatException( @@ -637,4 +655,21 @@ public class CommandSession { formatException(handler, e); } } + + public static CompilationError[] validate(ModuleRepository moduleRepository,StringReader commandReader) { + CommandSession session = new CommandSession(moduleRepository, null); + return session.validate(commandReader); + } + + public static CompilationError[] validate(ModuleRepository moduleRepository,String command) { + return validate(moduleRepository, new StringReader(command)); + } + + public CompilationError[] validate(String command) { + return validate(new StringReader(command)); + } + + public void setDependenciesListener(UpdateListener dependenciesListener) { + this.dependenciesListener = dependenciesListener; + } }