CompilerTest.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.IO;
  29. using System.CodeDom.Compiler;
  30. using System.Collections.Generic;
  31. using Microsoft.CSharp;
  32. using NUnit.Framework;
  33. using OpenSim.Region.ScriptEngine.Shared.CodeTools;
  34. using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
  35. using OpenSim.Tests.Common;
  36. namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
  37. {
  38. /// <summary>
  39. /// Tests the LSL compiler. Among other things, test that error messages
  40. /// generated by the C# compiler can be mapped to prper lines/columns in
  41. /// the LSL source.
  42. /// </summary>
  43. [TestFixture]
  44. public class CompilerTest : OpenSimTestCase
  45. {
  46. private string m_testDir;
  47. private CSharpCodeProvider m_CSCodeProvider;
  48. private CompilerParameters m_compilerParameters;
  49. // private CompilerResults m_compilerResults;
  50. private ResolveEventHandler m_resolveEventHandler;
  51. /// <summary>
  52. /// Creates a temporary directory where build artifacts are stored.
  53. /// </summary>
  54. [TestFixtureSetUp]
  55. public void Init()
  56. {
  57. m_testDir = Path.Combine(Path.GetTempPath(), "opensim_compilerTest_" + Path.GetRandomFileName());
  58. if (!Directory.Exists(m_testDir))
  59. {
  60. // Create the temporary directory for housing build artifacts.
  61. Directory.CreateDirectory(m_testDir);
  62. }
  63. }
  64. [SetUp]
  65. public override void SetUp()
  66. {
  67. base.SetUp();
  68. // Create a CSCodeProvider and CompilerParameters.
  69. m_CSCodeProvider = new CSharpCodeProvider();
  70. m_compilerParameters = new CompilerParameters();
  71. string rootPath = System.AppDomain.CurrentDomain.BaseDirectory;
  72. m_resolveEventHandler = new ResolveEventHandler(AssemblyResolver.OnAssemblyResolve);
  73. System.AppDomain.CurrentDomain.AssemblyResolve += m_resolveEventHandler;
  74. m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll"));
  75. m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
  76. m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenMetaverseTypes.dll"));
  77. m_compilerParameters.GenerateExecutable = false;
  78. }
  79. /// <summary>
  80. /// Removes the temporary build directory and any build artifacts
  81. /// inside it.
  82. /// </summary>
  83. [TearDown]
  84. public void CleanUp()
  85. {
  86. System.AppDomain.CurrentDomain.AssemblyResolve -= m_resolveEventHandler;
  87. if (Directory.Exists(m_testDir))
  88. {
  89. // Blow away the temporary directory with artifacts.
  90. Directory.Delete(m_testDir, true);
  91. }
  92. }
  93. private CompilerResults CompileScript(
  94. string input, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap)
  95. {
  96. m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll");
  97. CSCodeGenerator cg = new CSCodeGenerator();
  98. string output = cg.Convert(input);
  99. output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null);
  100. // System.Console.WriteLine(output);
  101. positionMap = cg.PositionMap;
  102. CompilerResults compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output);
  103. // foreach (KeyValuePair<int, int> key in positionMap.Keys)
  104. // {
  105. // KeyValuePair<int, int> val = positionMap[key];
  106. //
  107. // System.Console.WriteLine("{0},{1} => {2},{3}", key.Key, key.Value, val.Key, val.Value);
  108. // }
  109. //
  110. // foreach (CompilerError compErr in m_compilerResults.Errors)
  111. // {
  112. // System.Console.WriteLine("Error: {0},{1} => {2}", compErr.Line, compErr.Column, compErr);
  113. // }
  114. return compilerResults;
  115. }
  116. /// <summary>
  117. /// Test that line number errors are resolved as expected when preceding code contains a jump.
  118. /// </summary>
  119. [Test]
  120. public void TestJumpAndSyntaxError()
  121. {
  122. TestHelpers.InMethod();
  123. Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
  124. CompilerResults compilerResults = CompileScript(
  125. @"default
  126. {
  127. state_entry()
  128. {
  129. jump l;
  130. @l;
  131. i = 1;
  132. }
  133. }", out positionMap);
  134. Assert.AreEqual(
  135. new KeyValuePair<int, int>(7, 9),
  136. positionMap[new KeyValuePair<int, int>(compilerResults.Errors[0].Line, compilerResults.Errors[0].Column)]);
  137. }
  138. /// <summary>
  139. /// Test the C# compiler error message can be mapped to the correct
  140. /// line/column in the LSL source when an undeclared variable is used.
  141. /// </summary>
  142. [Test]
  143. public void TestUseUndeclaredVariable()
  144. {
  145. TestHelpers.InMethod();
  146. Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
  147. CompilerResults compilerResults = CompileScript(
  148. @"default
  149. {
  150. state_entry()
  151. {
  152. integer y = x + 3;
  153. }
  154. }", out positionMap);
  155. Assert.AreEqual(
  156. new KeyValuePair<int, int>(5, 21),
  157. positionMap[new KeyValuePair<int, int>(compilerResults.Errors[0].Line, compilerResults.Errors[0].Column)]);
  158. }
  159. /// <summary>
  160. /// Test that a string can be cast to string and another string
  161. /// concatenated.
  162. /// </summary>
  163. [Test]
  164. public void TestCastAndConcatString()
  165. {
  166. TestHelpers.InMethod();
  167. Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
  168. CompilerResults compilerResults = CompileScript(
  169. @"string s = "" a string"";
  170. default
  171. {
  172. state_entry()
  173. {
  174. key gAvatarKey = llDetectedKey(0);
  175. string tmp = (string) gAvatarKey + s;
  176. llSay(0, tmp);
  177. }
  178. }", out positionMap);
  179. Assert.AreEqual(0, compilerResults.Errors.Count);
  180. }
  181. }
  182. }