From 85068dae60db02b168a29ffd75e1408e30d279e1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 27 Sep 2008 05:31:43 +0000 Subject: Add friendly error messages to both engines. --- .../Shared/CodeTools/CSCodeGenerator.cs | 19 +- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 225 ++++++++++++++------- 2 files changed, 170 insertions(+), 74 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/CodeTools') diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 86d6188..e8f2b71 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -89,7 +89,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools ResetCounters(); Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); // Obviously this needs to be in a try/except block. - LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); + LSL2CSCodeTransformer codeTransformer; + try + { + codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); + } + catch (CSToolsException e) + { + string message; + + // LL start numbering lines at 0 - geeks! + // + message = String.Format("Line ({0},{1}) {2}", + e.slInfo.lineNumber - 1, + e.slInfo.charPosition - 1, e.Message); + + throw new Exception(message); + } + m_astRoot = codeTransformer.Transform(); string retstr = String.Empty; diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index ec864e1..c6026fb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -38,7 +38,7 @@ using OpenSim.Region.ScriptEngine.Interfaces; namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { - public class Compiler + public class Compiler : ICompiler { // private static readonly log4net.ILog m_log // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); @@ -255,18 +255,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools /// Filename to .dll assembly public string PerformScriptCompile(string Script, string asset) { + m_positionMap = null; + string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( m_scriptEngine.World.RegionInfo.RegionID.ToString(), FilePrefix + "_compiled_" + asset + ".dll")); // string OutFile = Path.Combine(ScriptEnginesPath, // FilePrefix + "_compiled_" + asset + ".dll"); - if (File.Exists(OutFile)) - { - m_scriptEngine.Log.DebugFormat("[Compiler] Returning existing assembly for {0}", asset); - return OutFile; - } - if (!Directory.Exists(ScriptEnginesPath)) { try @@ -327,38 +323,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools compileScript = LSL_Converter.Convert(Script); m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; + } - l = enumCompileType.cs; + // Check this late so the map is generated on sim start + // + if (File.Exists(OutFile)) + { + m_scriptEngine.Log.DebugFormat("[Compiler] Returning existing assembly for {0}", asset); + return OutFile; } if (l == enumCompileType.yp) { // Its YP, convert it to C# compileScript = YP_Converter.Convert(Script); - // We have our own processor now - //l = enumCompileType.cs; - } - - // Insert additional assemblies here - - //ADAM: Disabled for the moment until it's working right. - bool enableCommanderLSL = false; - - if (enableCommanderLSL == true && ((l == enumCompileType.cs) || (l == enumCompileType.yp))) - { - foreach (KeyValuePair com - in m_scriptEngine.World.GetCommanders()) - { - compileScript = com.Value.GenerateRuntimeAPI() + compileScript; - } } - // End of insert - switch (l) { case enumCompileType.cs: + case enumCompileType.lsl: compileScript = CreateCSCompilerScript(compileScript); break; case enumCompileType.vb: @@ -372,10 +356,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools break; } -// m_log.Debug("[ScriptEngine.DotNetEngine]: Preparing to compile the following LSL to C# translated code"); -// m_log.Debug(""); -// m_log.Debug(compileScript); - return CompileFromDotNetText(compileScript, l, asset); } @@ -442,26 +422,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // Output assembly name scriptCompileCounter++; string OutFile = Path.Combine(ScriptEnginesPath, Path.Combine( - m_scriptEngine.World.RegionInfo.RegionID.ToString(), - FilePrefix + "_compiled_" + asset + ".dll")); -#if DEBUG -// m_scriptEngine.Log.Debug("[Compiler]: Starting compile of \"" + OutFile + "\"."); -#endif + m_scriptEngine.World.RegionInfo.RegionID.ToString(), + FilePrefix + "_compiled_" + asset + ".dll")); try { File.Delete(OutFile); } - catch (Exception e) // NOTLEGIT - Should be just catching FileIOException + catch (Exception e) // NOTLEGIT - Should be just FileIOException { - //m_scriptEngine.Log.Error("[Compiler]: Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString()); - throw new Exception("Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString()); + throw new Exception("Unable to delete old existing "+ + "script-file before writing new. Compile aborted: " + + e.ToString()); } - //string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll"); // DEBUG - write source to disk if (WriteScriptSourceToDebugFile) { - string srcFileName = FilePrefix + "_source_" + Path.GetFileNameWithoutExtension(OutFile) + ext; + string srcFileName = FilePrefix + "_source_" + + Path.GetFileNameWithoutExtension(OutFile) + ext; try { File.WriteAllText(Path.Combine(Path.Combine( @@ -469,9 +447,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools m_scriptEngine.World.RegionInfo.RegionID.ToString()), srcFileName), Script); } - catch (Exception ex) // NOTLEGIT - Should be just catching FileIOException + catch (Exception ex) //NOTLEGIT - Should be just FileIOException { - m_scriptEngine.Log.Error("[Compiler]: Exception while trying to write script source to file \"" + srcFileName + "\": " + ex.ToString()); + m_scriptEngine.Log.Error("[Compiler]: Exception while "+ + "trying to write script source to file \"" + + srcFileName + "\": " + ex.ToString()); } } @@ -480,22 +460,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools parameters.IncludeDebugInformation = true; - // Add all available assemblies -// foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) -// { -// Console.WriteLine("Adding assembly: " + asm.Location); -// parameters.ReferencedAssemblies.Add(asm.Location); -// } + string rootPath = + Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); - string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); - // string rootPathSE = Path.GetDirectoryName(GetType().Assembly.Location); - //Console.WriteLine("Assembly location: " + rootPath); - parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll")); - parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); + parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, + "OpenSim.Region.ScriptEngine.Shared.dll")); + parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, + "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); if (lang == enumCompileType.yp) { - parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll")); + parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, + "OpenSim.Region.ScriptEngine.Shared.YieldProlog.dll")); } parameters.GenerateExecutable = false; @@ -504,24 +480,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools //parameters.WarningLevel = 1; // Should be 4? parameters.TreatWarningsAsErrors = false; -//Console.WriteLine(Script); CompilerResults results; switch (lang) { case enumCompileType.vb: - results = VBcodeProvider.CompileAssemblyFromSource(parameters, Script); + results = VBcodeProvider.CompileAssemblyFromSource( + parameters, Script); break; case enumCompileType.cs: - results = CScodeProvider.CompileAssemblyFromSource(parameters, Script); + case enumCompileType.lsl: + results = CScodeProvider.CompileAssemblyFromSource( + parameters, Script); break; case enumCompileType.js: - results = JScodeProvider.CompileAssemblyFromSource(parameters, Script); + results = JScodeProvider.CompileAssemblyFromSource( + parameters, Script); break; case enumCompileType.yp: - results = YPcodeProvider.CompileAssemblyFromSource(parameters, Script); + results = YPcodeProvider.CompileAssemblyFromSource( + parameters, Script); break; default: - throw new Exception("Compiler is not able to recongnize language type \"" + lang.ToString() + "\""); + throw new Exception("Compiler is not able to recongnize "+ + "language type \"" + lang.ToString() + "\""); } // Check result @@ -530,11 +511,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // // WARNINGS AND ERRORS // + int display = 5; if (results.Errors.Count > 0) { string errtext = String.Empty; foreach (CompilerError CompErr in results.Errors) { + // Show 5 errors max + // + if (display <= 0) + break; + display--; + string severity = "Error"; if ( CompErr.IsWarning ) { @@ -543,22 +531,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools KeyValuePair lslPos; - try - { - lslPos = m_positionMap[new KeyValuePair(CompErr.Line, CompErr.Column)]; - } - catch (KeyNotFoundException) // we don't have this line/column mapped - { - m_scriptEngine.Log.Debug(String.Format("[Compiler]: Lookup of C# line {0}, column {1} failed.", CompErr.Line, CompErr.Column)); - lslPos = new KeyValuePair(-CompErr.Line, -CompErr.Column); - } + lslPos = FindErrorPosition(CompErr.Line, CompErr.Column); + + string text = CompErr.ErrorText; + + // Use LSL type names + if (lang == enumCompileType.lsl) + text = ReplaceTypes(CompErr.ErrorText); // The Second Life viewer's script editor begins // countingn lines and columns at 0, so we subtract 1. - errtext += String.Format("Line {0}, column {1}, {4} Number: {2}, '{3}'\r\n", lslPos.Key - 1, lslPos.Value - 1, CompErr.ErrorNumber, CompErr.ErrorText, severity); + errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n", + lslPos.Key - 1, lslPos.Value - 1, + CompErr.ErrorNumber, text, severity); } - Console.WriteLine("[COMPILER MESSAGES]: " + errtext); if (!File.Exists(OutFile)) { throw new Exception(errtext); @@ -574,8 +561,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools errtext += "No compile error. But not able to locate compiled file."; throw new Exception(errtext); } - m_scriptEngine.Log.DebugFormat("[Compiler] Compiled new assembly for {0}", asset); + m_scriptEngine.Log.DebugFormat("[Compiler] Compiled new assembly "+ + "for {0}", asset); return OutFile; } + + public KeyValuePair FindErrorPosition(int line, int col) + { + return FindErrorPosition(line, col, m_positionMap); + } + + private class kvpSorter : IComparer> + { + public int Compare(KeyValuePair a, + KeyValuePair b) + { + return a.Key.CompareTo(b.Key); + } + } + + public static KeyValuePair FindErrorPosition(int line, + int col, Dictionary, + KeyValuePair> positionMap) + { + if (positionMap == null || positionMap.Count == 0) + return new KeyValuePair(line, col); + + KeyValuePair ret = new KeyValuePair(); + + if (positionMap.TryGetValue(new KeyValuePair(line, col), + out ret)) + return ret; + + List> sorted = + new List>(positionMap.Keys); + + sorted.Sort(new kvpSorter()); + + int l = 1; + int c = 1; + + foreach (KeyValuePair cspos in sorted) + { + if (cspos.Key >= line) + { + if (cspos.Key > line) + return new KeyValuePair(l, c); + if (cspos.Value > col) + return new KeyValuePair(l, c); + c = cspos.Value; + if (c == 0) + c++; + } + else + { + l = cspos.Key; + } + } + return new KeyValuePair(l, c); + } + + string ReplaceTypes(string message) + { + message = message.Replace( + "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString", + "string"); + + message = message.Replace( + "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger", + "integer"); + + message = message.Replace( + "OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat", + "float"); + + message = message.Replace( + "OpenSim.Region.ScriptEngine.Shared.LSL_Types.list", + "list"); + + return message; + } + + public Dictionary, KeyValuePair> + LineMap() + { + if (m_positionMap == null) + return null; + + Dictionary, KeyValuePair> ret = + new Dictionary, KeyValuePair>(); + + foreach (KeyValuePair kvp in m_positionMap.Keys) + ret.Add(kvp, m_positionMap[kvp]); + + return ret; + } } } -- cgit v1.1