clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.IO;
30 using System.CodeDom.Compiler;
31 using System.Collections.Generic;
32 using Microsoft.CSharp;
33 using NUnit.Framework;
34 using OpenSim.Region.ScriptEngine.Shared.CodeTools;
35 using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
36 using OpenSim.Tests.Common;
37  
38 namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
39 {
40 /// <summary>
41 /// Tests the LSL compiler. Among other things, test that error messages
42 /// generated by the C# compiler can be mapped to prper lines/columns in
43 /// the LSL source.
44 /// </summary>
45 [TestFixture]
46 public class CompilerTest : OpenSimTestCase
47 {
48 private string m_testDir;
49 private CSharpCodeProvider m_CSCodeProvider;
50 private CompilerParameters m_compilerParameters;
51 // private CompilerResults m_compilerResults;
52 private ResolveEventHandler m_resolveEventHandler;
53  
54 /// <summary>
55 /// Creates a temporary directory where build artifacts are stored.
56 /// </summary>
57 [TestFixtureSetUp]
58 public void Init()
59 {
60 m_testDir = Path.Combine(Path.GetTempPath(), "opensim_compilerTest_" + Path.GetRandomFileName());
61  
62 if (!Directory.Exists(m_testDir))
63 {
64 // Create the temporary directory for housing build artifacts.
65 Directory.CreateDirectory(m_testDir);
66 }
67 }
68  
69 [SetUp]
70 public override void SetUp()
71 {
72 base.SetUp();
73  
74 // Create a CSCodeProvider and CompilerParameters.
75 m_CSCodeProvider = new CSharpCodeProvider();
76 m_compilerParameters = new CompilerParameters();
77  
78 string rootPath = System.AppDomain.CurrentDomain.BaseDirectory;
79  
80 m_resolveEventHandler = new ResolveEventHandler(AssemblyResolver.OnAssemblyResolve);
81  
82 System.AppDomain.CurrentDomain.AssemblyResolve += m_resolveEventHandler;
83  
84 m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll"));
85 m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
86 m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenMetaverseTypes.dll"));
87 m_compilerParameters.GenerateExecutable = false;
88 }
89  
90 /// <summary>
91 /// Removes the temporary build directory and any build artifacts
92 /// inside it.
93 /// </summary>
94 [TearDown]
95 public void CleanUp()
96 {
97 System.AppDomain.CurrentDomain.AssemblyResolve -= m_resolveEventHandler;
98  
99 if (Directory.Exists(m_testDir))
100 {
101 // Blow away the temporary directory with artifacts.
102 Directory.Delete(m_testDir, true);
103 }
104 }
105  
106 private CompilerResults CompileScript(
107 string input, out Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap)
108 {
109 m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll");
110  
111 CSCodeGenerator cg = new CSCodeGenerator();
112 string output = cg.Convert(input);
113  
114 output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null);
115 // System.Console.WriteLine(output);
116  
117 positionMap = cg.PositionMap;
118  
119 CompilerResults compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output);
120  
121 // foreach (KeyValuePair<int, int> key in positionMap.Keys)
122 // {
123 // KeyValuePair<int, int> val = positionMap[key];
124 //
125 // System.Console.WriteLine("{0},{1} => {2},{3}", key.Key, key.Value, val.Key, val.Value);
126 // }
127 //
128 // foreach (CompilerError compErr in m_compilerResults.Errors)
129 // {
130 // System.Console.WriteLine("Error: {0},{1} => {2}", compErr.Line, compErr.Column, compErr);
131 // }
132  
133 return compilerResults;
134 }
135  
136 /// <summary>
137 /// Test that line number errors are resolved as expected when preceding code contains a jump.
138 /// </summary>
139 [Test]
140 public void TestJumpAndSyntaxError()
141 {
142 TestHelpers.InMethod();
143  
144 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
145  
146 CompilerResults compilerResults = CompileScript(
147 @"default
148 {
149 state_entry()
150 {
151 jump l;
152 @l;
153 i = 1;
154 }
155 }", out positionMap);
156  
157 Assert.AreEqual(
158 new KeyValuePair<int, int>(7, 9),
159 positionMap[new KeyValuePair<int, int>(compilerResults.Errors[0].Line, compilerResults.Errors[0].Column)]);
160 }
161  
162 /// <summary>
163 /// Test the C# compiler error message can be mapped to the correct
164 /// line/column in the LSL source when an undeclared variable is used.
165 /// </summary>
166 [Test]
167 public void TestUseUndeclaredVariable()
168 {
169 TestHelpers.InMethod();
170  
171 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
172  
173 CompilerResults compilerResults = CompileScript(
174 @"default
175 {
176 state_entry()
177 {
178 integer y = x + 3;
179 }
180 }", out positionMap);
181  
182 Assert.AreEqual(
183 new KeyValuePair<int, int>(5, 21),
184 positionMap[new KeyValuePair<int, int>(compilerResults.Errors[0].Line, compilerResults.Errors[0].Column)]);
185 }
186  
187 /// <summary>
188 /// Test that a string can be cast to string and another string
189 /// concatenated.
190 /// </summary>
191 [Test]
192 public void TestCastAndConcatString()
193 {
194 TestHelpers.InMethod();
195  
196 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap;
197  
198 CompilerResults compilerResults = CompileScript(
199 @"string s = "" a string"";
200  
201 default
202 {
203 state_entry()
204 {
205 key gAvatarKey = llDetectedKey(0);
206 string tmp = (string) gAvatarKey + s;
207 llSay(0, tmp);
208 }
209 }", out positionMap);
210  
211 Assert.AreEqual(0, compilerResults.Errors.Count);
212 }
213 }
214 }