From: Hannu Niemistö Date: Fri, 12 May 2017 18:47:45 +0000 (+0300) Subject: Merge "(refs #6878) validateOnly flag to ExpressionEvaluator and CommandSession" X-Git-Tag: v1.29.0~54 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=36799f7fc9a4793236d9085aa87ee5baff167376;hp=7a7f73011a6364cbb80ce4ef04424472d345a65a Merge "(refs #6878) validateOnly flag to ExpressionEvaluator and CommandSession" --- 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 82d615ca8..1cf6d0de9 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 @@ -76,7 +76,12 @@ public class CommandSession { THashMap variableTypes = new THashMap(); PrintStream fileOutput; - + + /** + * 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( @@ -320,6 +325,7 @@ public class CommandSession { Function command = (Function)evaluator .localEnvironment(localEnvironment) .decorateExpression(true) + .validateOnly(validateOnly) .eval(); return new CompiledCommand(command, evaluator.getType()); } @@ -361,7 +367,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)); @@ -371,11 +379,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."); @@ -463,6 +475,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; @@ -494,16 +524,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( @@ -632,4 +652,18 @@ 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)); + } + } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java index c1881fbca..2b42bc7ba 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/ExpressionEvaluator.java @@ -27,6 +27,7 @@ import org.simantics.scl.compiler.elaboration.expressions.block.Statement; import org.simantics.scl.compiler.elaboration.java.Builtins; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.environment.LocalEnvironment; +import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.ErrorLog; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.ssa.SSAModule; @@ -77,6 +78,7 @@ public class ExpressionEvaluator { private LocalStorage localStorage; private boolean interpretIfPossible = true; private ExpressionParseMode parseMode = ExpressionParseMode.EXPRESSION; + private boolean validateOnly; public ExpressionEvaluator(RuntimeEnvironment runtimeEnvironment, String expressionText) { @@ -115,6 +117,11 @@ public class ExpressionEvaluator { return this; } + public ExpressionEvaluator validateOnly(boolean validateOnly) { + this.validateOnly = validateOnly; + return this; + } + /** * Sets a local environment that can arbitrarily modify the resolving of the expression. */ @@ -175,6 +182,16 @@ public class ExpressionEvaluator { return "store_" + name; } } + + public CompilationError[] validate() { + try { + validateOnly = true; + eval(); + return CompilationError.EMPTY_ARRAY; + } catch(SCLExpressionCompilationException e) { + return e.getErrors(); + } + } public Object eval() throws SCLExpressionCompilationException { fillDefaults(); @@ -243,6 +260,8 @@ public class ExpressionEvaluator { Types.functionE(type, Types.PROC, Types.UNIT)), new EVar(variableName) ))); + if(validateOnly) + localStorage.store(variableName, null, type); } } if(!(block.getStatements().getLast() instanceof GuardStatement)) @@ -293,6 +312,9 @@ public class ExpressionEvaluator { if(localEnvironment != null) expression = localEnvironment.postDecorateExpression(expression); + + if(validateOnly) + return null; Type type = expression.getType(); type = type.convertMetaVarsToVars(); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLExpressionCompilationException.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLExpressionCompilationException.java index f5b2632d1..a4cb30582 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLExpressionCompilationException.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/top/SCLExpressionCompilationException.java @@ -2,7 +2,7 @@ package org.simantics.scl.compiler.top; import org.simantics.scl.compiler.errors.CompilationError; -public class SCLExpressionCompilationException extends Exception { +public class SCLExpressionCompilationException extends RuntimeException { private static final long serialVersionUID = 970640318254433797L; diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java index 4a9bffd09..784a80b4c 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/TestCommandSession.java @@ -1,12 +1,16 @@ package org.simantics.scl.compiler.tests; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.simantics.scl.compiler.commands.CommandSession; +import org.simantics.scl.compiler.errors.CompilationError; +import org.simantics.scl.compiler.errors.CompilationErrorFormatter; import org.simantics.scl.compiler.module.repository.ModuleRepository; import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler; import org.simantics.scl.runtime.reporting.SCLReportingHandler; + public class TestCommandSession { ModuleRepository moduleRepository; @@ -72,5 +76,33 @@ public class TestCommandSession { session.execute("iter (\\i -> print i) [1,2,3]"); session.execute("iter (\\i -> print i) [(),(),()]"); } + + @Test + public void testValidation() { + { + CompilationError[] errors = CommandSession.validate(moduleRepository, "1+1"); + Assert.assertEquals(0, errors.length); + } + { + CompilationError[] errors = CommandSession.validate(moduleRepository, "\"a\"+1"); + Assert.assertEquals(1, errors.length); + } + { + CompilationError[] errors = CommandSession.validate(moduleRepository, + "a = 1\n" + + "b = 2\n" + + "a + b"); + Assert.assertEquals(0, errors.length); + } + { + String source = + "a = 1\n" + + "b = 2.0\n" + + "a + b"; + CompilationError[] errors = CommandSession.validate(moduleRepository, source); + //System.out.println(CompilationErrorFormatter.toString(source, errors)); + Assert.assertEquals(1, errors.length); + } + } }