CompilerTest.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. /* test too depedent on counting lines and columns maping code generation changes
  117. erros position is better tested on viewers
  118. /// <summary>
  119. /// Test that line number errors are resolved as expected when preceding code contains a jump.
  120. /// </summary>
  121. [Test]
  122. public void TestJumpAndSyntaxError()
  123. {
  124. TestHelpers.InMethod();
  125. Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
  126. CompilerResults compilerResults = CompileScript(
  127. @"default
  128. {
  129. state_entry()
  130. {
  131. jump l;
  132. @l;
  133. i = 1;
  134. }
  135. }", out positionMap);
  136. Assert.AreEqual(
  137. new KeyValuePair<int, int>(7, 9),
  138. positionMap[new KeyValuePair<int, int>(compilerResults.Errors[0].Line, compilerResults.Errors[0].Column)]);
  139. }
  140. /// <summary>
  141. /// Test the C# compiler error message can be mapped to the correct
  142. /// line/column in the LSL source when an undeclared variable is used.
  143. /// </summary>
  144. [Test]
  145. public void TestUseUndeclaredVariable()
  146. {
  147. TestHelpers.InMethod();
  148. Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
  149. CompilerResults compilerResults = CompileScript(
  150. @"default
  151. {
  152. state_entry()
  153. {
  154. integer y = x + 3;
  155. }
  156. }", out positionMap);
  157. Assert.AreEqual(
  158. new KeyValuePair<int, int>(5, 21),
  159. positionMap[new KeyValuePair<int, int>(compilerResults.Errors[0].Line, compilerResults.Errors[0].Column)]);
  160. }
  161. */
  162. /// <summary>
  163. /// Test that a string can be cast to string and another string
  164. /// concatenated.
  165. /// </summary>
  166. [Test]
  167. public void TestCastAndConcatString()
  168. {
  169. TestHelpers.InMethod();
  170. Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
  171. CompilerResults compilerResults = CompileScript(
  172. @"string s = "" a string"";
  173. default
  174. {
  175. state_entry()
  176. {
  177. key gAvatarKey = llDetectedKey(0);
  178. string tmp = (string) gAvatarKey + s;
  179. llSay(0, tmp);
  180. }
  181. }", out positionMap);
  182. Assert.AreEqual(0, compilerResults.Errors.Count);
  183. }
  184. }
  185. }