static string GetMessage(VASLMethod method, Exception innerException) { if (method == null) { throw new ArgumentNullException(nameof(method)); } if (innerException == null) { throw new ArgumentNullException(nameof(innerException)); } var stackTrace = new StackTrace(innerException, true); var stackTraceSb = new StringBuilder(); foreach (var frame in stackTrace.GetFrames()) { var frameMethod = frame.GetMethod(); var frameModule = frameMethod.Module; var frameVASLMethod = method; if (method.ScriptMethods != null) { frameVASLMethod = method.ScriptMethods.FirstOrDefault(m => frameModule == m.Module); if (frameVASLMethod == null) { continue; } } else if (frameModule != method.Module) { continue; } var frameLine = frame.GetFileLineNumber(); if (frameLine > 0) { var line = frameLine + frameVASLMethod.LineOffset; stackTraceSb.Append($"\n at VASL line {line} in '{frameVASLMethod.Name}'"); } } var exceptionName = innerException.GetType().FullName; var methodName = method.Name ?? "(no name)"; var exceptionMessage = innerException.Message; return($"Exception thrown: '{exceptionName}' in '{methodName}' method:\n{exceptionMessage}\n{stackTraceSb.ToString()}"); }
static string GetMessage(VASLMethod method, CompilerErrorCollection errors) { if (method == null) { throw new ArgumentNullException(nameof(method)); } if (errors == null) { throw new ArgumentNullException(nameof(errors)); } var sb = new StringBuilder($"'{method.Name ?? "(no name)"}' method compilation errors:"); foreach (CompilerError error in errors) { error.Line = error.Line + method.LineOffset; sb.Append($"\nLine {error.Line}, Col {error.Column}: {(error.IsWarning ? "warning" : "error")} {error.ErrorNumber}: {error.ErrorText}"); } return(sb.ToString()); }
public static MethodList ParseScript(string code) { var grammar = new VASLGrammar(); var parser = new Parser(grammar); var tree = parser.Parse(code); if (tree.HasErrors()) { var errorMsg = new StringBuilder("VASL parse error(s):"); foreach (var msg in parser.Context.CurrentParseTree.ParserMessages) { var loc = msg.Location; errorMsg.Append($"\nat Line {loc.Line + 1}, Col {loc.Column + 1}: {msg.Message}"); } throw new Exception(errorMsg.ToString()); } var methodsNode = tree.Root.ChildNodes.First(x => x.Term.Name == "methodList"); // Todo: Aliasing var methods = new MethodList(); foreach (var method in methodsNode.ChildNodes[0].ChildNodes) { var body = (string)method.ChildNodes[2].Token.Value; var methodName = (string)method.ChildNodes[0].Token.Value; var line = method.ChildNodes[2].Token.Location.Line + 1; var script = new VASLMethod(body, methodName, line) { ScriptMethods = methods }; switch (methodName) { case "init": methods.init = script; break; case "exit": methods.exit = script; break; case "update": methods.update = script; break; case "start": methods.start = script; break; case "split": methods.split = script; break; case "isLoading": methods.isLoading = script; break; case "gameTime": methods.gameTime = script; break; case "reset": methods.reset = script; break; case "startup": methods.startup = script; break; case "shutdown": methods.shutdown = script; break; case "undoSplit": methods.undoSplit = script; break; } } return(methods); }
// Run method without counting on being connected to the game (startup/shutdown). private void RunNoProcessMethod(VASLMethod method, LiveSplitState state, bool isStartup = false) { method.Call(state, Vars, GameVersion, isStartup ? Settings.Builder : (object)Settings.Reader, new DeltaOutput()); }
private dynamic RunMethod(VASLMethod method, LiveSplitState state, DeltaOutput d) { var result = method.Call(state, Vars, GameVersion, Settings.Reader, d); return(result); }
public VASLRuntimeException(VASLMethod method, Exception innerException) : base(GetMessage(method, innerException), innerException) { }
public VASLCompilerException(VASLMethod method, CompilerErrorCollection errors) : base(GetMessage(method, errors)) { Method = method; CompilerErrors = errors; }