Browse Source

Support for highlighting definitions defined in addin files now working again.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5335 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Matt Ward 16 years ago
parent
commit
432d0cb6b8
  1. 16
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditDisplayBinding.cs
  2. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  3. 63
      src/Main/Base/Project/Src/Editor/AddInHighlightingResource.cs
  4. 30
      src/Main/Base/Project/Src/TextEditor/Codons/SyntaxModeDoozer.cs
  5. 169
      src/Main/Base/Test/Highlighting/AddInHighlightingResourceTests.cs
  6. 120
      src/Main/Base/Test/Highlighting/SyntaxDoozerAddsHighlightingToHighlightingManagerTestFixture.cs
  7. 17
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  8. 42
      src/Main/Base/Test/Utils/MockAssembly.cs
  9. 53
      src/Main/Base/Test/Utils/Tests/MockAssemblyTests.cs
  10. 61
      src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs
  11. 44
      src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs
  12. 141
      src/Main/Core/Test/AddInTreeTests/RuntimeLoadAssemblyTests.cs
  13. 7
      src/Main/Core/Test/ICSharpCode.Core.Tests.csproj
  14. 103
      src/Main/Core/Test/Utils/DerivedRuntime.cs
  15. 82
      src/Main/Core/Test/Utils/Tests/DerivedRuntimeTests.cs

16
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/AvalonEditDisplayBinding.cs

@ -5,14 +5,19 @@ @@ -5,14 +5,19 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Gui;
using System;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.AvalonEdit.AddIn
{
public class AvalonEditDisplayBinding : IDisplayBinding
{
const string path = "/SharpDevelop/ViewContent/DefaultTextEditor/SyntaxModes";
bool builtAddInHighlighting;
public bool CanCreateContentForFile(string fileName)
{
return true;
@ -20,7 +25,16 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -20,7 +25,16 @@ namespace ICSharpCode.AvalonEdit.AddIn
public IViewContent CreateContentForFile(OpenedFile file)
{
BuildAddInHighlighting();
return new AvalonEditViewContent(file);
}
void BuildAddInHighlighting()
{
if (!builtAddInHighlighting) {
builtAddInHighlighting = true;
AddInTree.BuildItems<object>(path, this, false);
}
}
}
}

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -68,6 +68,7 @@ @@ -68,6 +68,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Src\Commands\SharpDevelopRoutedCommands.cs" />
<Compile Include="Src\Editor\AddInHighlightingResource.cs" />
<Compile Include="Src\Editor\AvalonEdit\AvalonEditDocumentAdapter.cs" />
<Compile Include="Src\Editor\AvalonEdit\AvalonEditSyntaxHighlighterAdapter.cs" />
<Compile Include="Src\Editor\AvalonEdit\AvalonEditTextEditorAdapter.cs" />

63
src/Main/Base/Project/Src/Editor/AddInHighlightingResource.cs

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.IO;
using System.Reflection;
using System.Xml;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Editor
{
public class AddInHighlightingResource
{
Runtime[] runtimes;
public AddInHighlightingResource(Runtime[] runtimes)
{
this.runtimes = runtimes;
}
public Stream OpenStream(string name)
{
foreach (Runtime runtime in runtimes) {
Assembly assembly = runtime.LoadedAssembly;
if (assembly != null) {
Stream stream = assembly.GetManifestResourceStream(name);
if (stream != null) {
return stream;
}
}
}
ThrowFileNotFoundException(name);
return null;
}
void ThrowFileNotFoundException(string name)
{
string message = String.Format("The resource file '{0}' was not found.", name);
throw new FileNotFoundException(message);
}
public IHighlightingDefinition LoadHighlighting(string name, IHighlightingDefinitionReferenceResolver resolver)
{
if (resolver == null) {
throw new ArgumentNullException("resolver");
}
using (Stream stream = OpenStream(name)) {
using (XmlTextReader reader = new XmlTextReader(stream)) {
XshdSyntaxDefinition xshd = HighlightingLoader.LoadXshd(reader);
return HighlightingLoader.Load(xshd, resolver);
}
}
}
}
}

30
src/Main/Base/Project/Src/TextEditor/Codons/SyntaxModeDoozer.cs

@ -12,7 +12,10 @@ using System.Reflection; @@ -12,7 +12,10 @@ using System.Reflection;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.TextEditor.Document;
using AvalonEdit = ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Highlighting;
namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons
{
@ -60,14 +63,24 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons @@ -60,14 +63,24 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons
/// </returns>
public class SyntaxModeDoozer : IDoozer
{
AvalonEdit.Highlighting.HighlightingManager highlightingManager;
public SyntaxModeDoozer(AvalonEdit.Highlighting.HighlightingManager highlightingManager)
{
this.highlightingManager = highlightingManager;
}
public SyntaxModeDoozer()
: this(AvalonEdit.Highlighting.HighlightingManager.Instance)
{
}
/// <summary>
/// Gets if the doozer handles codon conditions on its own.
/// If this property return false, the item is excluded when the condition is not met.
/// </summary>
public bool HandleConditions {
get {
return false;
}
get { return false; }
}
public object BuildItem(object caller, Codon codon, ArrayList subItems)
@ -81,8 +94,19 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons @@ -81,8 +94,19 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Codons
foreach (Runtime library in codon.AddIn.Runtimes) {
assemblies[i++] = library;
}
highlightingManager.RegisterHighlighting(highlightingName, extensions, LoadHighlighting(assemblies, resource));
return new AddInTreeSyntaxMode(assemblies, resource, highlightingName, extensions);
}
Func<IHighlightingDefinition> LoadHighlighting(Runtime[] runtimes, string resourceName)
{
Func<IHighlightingDefinition> func = delegate {
AddInHighlightingResource highlightingResource = new AddInHighlightingResource(runtimes);
return highlightingResource.LoadHighlighting(resourceName, highlightingManager);
};
return func;
}
}
}

169
src/Main/Base/Test/Highlighting/AddInHighlightingResourceTests.cs

@ -0,0 +1,169 @@ @@ -0,0 +1,169 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using ICSharpCode.Core;
using ICSharpCode.Core.Tests.Utils;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Tests.Utils;
using NUnit.Framework;
namespace ICSharpCode.SharpDevelop.Tests.Highlighting
{
[TestFixture]
public class AddInHighlightingResourceTests
{
AddInHighlightingResource highlightingResource;
Stream predefinedManifestResourceStream;
MockAssembly assembly;
DerivedRuntime testRuntime;
DerivedRuntime unloadedRuntime;
[SetUp]
public void Init()
{
// Create assembly.
byte[] bytes = UnicodeEncoding.UTF8.GetBytesWithPreamble(GetHighlightingDefinitionXml());
predefinedManifestResourceStream = new MemoryStream(bytes);
assembly = new MockAssembly();
assembly.AddManifestResourceStream("ICSharpCode.Xml.xshd", predefinedManifestResourceStream);
// Create addins.
AddIn addIn = AddIn.Load(new StringReader(GetAddInXml()));
addIn.FileName = @"D:\SharpDevelop\AddIns\MyAddIn.addin";
addIn.Enabled = true;
List<AddIn> addIns = new List<AddIn>();
addIns.Add(addIn);
// Create runtimes.
testRuntime = new DerivedRuntime("MyAddIn.dll", String.Empty, addIns);
testRuntime.AssemblyFileNames.Add("MyAddIn.dll", assembly);
unloadedRuntime = new DerivedRuntime("UnLoadedAssembly.dll", String.Empty, addIns);
unloadedRuntime.AssemblyFileNames.Add("UnLoadedAssembly.dll", null);
unloadedRuntime.LoadAssemblyFromExceptionToThrow = new FileNotFoundException("UnloadedAssembly.dll not found.");
List<Runtime> runtimes = new List<Runtime>();
runtimes.Add(testRuntime);
runtimes.Add(unloadedRuntime);
// Create addin highlighting resource.
highlightingResource = new AddInHighlightingResource(runtimes.ToArray());
}
string GetHighlightingDefinitionXml()
{
return
"<SyntaxDefinition name = \"BAT\" extensions = \".bat\">\r\n" +
" <Environment>\r\n" +
" <Default color = \"Yellow\" bgcolor = \"Black\"/>\r\n" +
" <Selection color = \"White\" bgcolor = \"Purple\"/>\r\n" +
" <InvalidLines color = \"Red\"/>\r\n" +
" <LineNumbers color = \"Gray\" bgcolor = \"Black\"/>\r\n" +
" <SelectedFoldLine color = \"Green\" bgcolor=\"Black\"/>\r\n" +
" </Environment>\r\n" +
"\r\n" +
" <Digits name = \"Digits\" bold = \"false\" italic = \"false\" color = \"Yellow\"/>\r\n" +
"\r\n" +
" <RuleSets>\r\n" +
" <RuleSet ignorecase = \"false\">\r\n" +
" <Delimiters> </Delimiters>\r\n" +
" </RuleSet>\r\n" +
" </RuleSets>\r\n" +
"</SyntaxDefinition>";
}
string GetAddInXml()
{
return
"<AddIn name = \"My AddIn\"\r\n" +
" author = \"\"\r\n" +
" copyright = \"prj:///doc/copyright.txt\"\r\n" +
" description = \"\"\r\n" +
" addInManagerHidden = \"preinstalled\">\r\n" +
"\r\n" +
" <Manifest>\r\n" +
" <Identity name = \"ICSharpCode.MyAddIn\"/>\r\n" +
" </Manifest>\r\n" +
"\r\n" +
" <Runtime>\r\n" +
" <Import assembly = \":ICSharpCode.SharpDevelop\"/>\r\n" +
" <Import assembly = \"UnLoadedAssembly.dll\"/>\r\n" +
" <Import assembly = \"MyAddIn.dll\"/>\r\n" +
" </Runtime>\r\n" +
"</AddIn>";
}
[TearDown]
public void TearDown()
{
predefinedManifestResourceStream.Dispose();
}
[Test]
public void OpenStreamThrowsFileNotFoundExceptionForUnknownManifestResourceName()
{
string expectedMessage = "The resource file 'Unknown' was not found.";
FileNotFoundException ex =
Assert.Throws<FileNotFoundException>(delegate { highlightingResource.OpenStream("Unknown"); });
Assert.AreEqual(expectedMessage, ex.Message);
}
[Test]
public void OpenStreamReturnsAssemblyManifestResourceStreamForKnownManifestResourceName()
{
Stream stream = highlightingResource.OpenStream("ICSharpCode.Xml.xshd");
Assert.AreSame(predefinedManifestResourceStream, stream);
}
[Test]
public void MockAssemblyReturnedFromMyAddInRuntime()
{
Assert.IsInstanceOf(typeof(MockAssembly), testRuntime.LoadedAssembly);
}
[Test]
public void UnloadedRunTimeReturnsNullFromLoadedAssembly()
{
Assert.IsNull(unloadedRuntime.LoadedAssembly);
}
[Test]
public void HighlightingDefinitionCanBeLoadedFromXmlViaMemoryStream()
{
using (XmlTextReader reader = new XmlTextReader(predefinedManifestResourceStream)) {
XshdSyntaxDefinition xshd = HighlightingLoader.LoadXshd(reader);
Assert.AreEqual("BAT", xshd.Name);
}
}
[Test]
public void HighlightingDefinitionReturnedFromLoadHighlightingMethod()
{
HighlightingManager manager = new HighlightingManager();
IHighlightingDefinition highlighting = highlightingResource.LoadHighlighting("ICSharpCode.Xml.xshd", manager);
Assert.AreEqual("BAT", highlighting.Name);
}
[Test]
public void LoadHighlightingThrowsArgumentNullExceptionIfResolverParameterIsNull()
{
ArgumentNullException ex =
Assert.Throws<ArgumentNullException>(
delegate { highlightingResource.LoadHighlighting("ICSharpCode.Xml.xshd", null); });
Assert.AreEqual("resolver", ex.ParamName);
}
}
}

120
src/Main/Base/Test/Highlighting/SyntaxDoozerAddsHighlightingToHighlightingManagerTestFixture.cs

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core;
using ICSharpCode.Core.Tests.Utils;
using ICSharpCode.SharpDevelop.DefaultEditor.Codons;
using ICSharpCode.SharpDevelop.Tests.Utils;
using NUnit.Framework;
namespace ICSharpCode.SharpDevelop.Tests.Highlighting
{
[TestFixture]
public class SyntaxDoozerAddsHighlightingToHighlightingManagerTestFixture
{
SyntaxModeDoozer doozer;
HighlightingManager highlightingManager;
IHighlightingDefinition highlightingDefinition;
[SetUp]
public void Init()
{
Properties p = new Properties();
p["name"] = "XML";
p["extensions"] = ".xml;.xsd";
p["resource"] = "ICSharpCode.Highlighting.Resource.xshd";
AddIn addIn = CreateAddIn();
addIn.FileName = @"D:\SharpDevelop\AddIns\XmlEditor.addin";
addIn.Enabled = true;
Codon codon = new Codon(addIn, "SyntaxMode", p, new ICondition[0]);
byte[] bytes = UnicodeEncoding.UTF8.GetBytesWithPreamble(GetHighlightingDefinitionXml());
Stream predefinedManifestResourceStream = new MemoryStream(bytes);
MockAssembly assembly = new MockAssembly();
assembly.AddManifestResourceStream("ICSharpCode.Highlighting.Resource.xshd", predefinedManifestResourceStream);
List<AddIn> addIns = new List<AddIn>();
addIns.Add(addIn);
// Create runtimes.
DerivedRuntime runtime = new DerivedRuntime("XmlEditor.dll", String.Empty, addIns);
runtime.AssemblyFileNames.Add("XmlEditor.dll", assembly);
addIn.Runtimes.Clear();
addIn.Runtimes.Add(runtime);
highlightingManager = new HighlightingManager();
doozer = new SyntaxModeDoozer(highlightingManager);
doozer.BuildItem(null, codon, null);
highlightingDefinition = highlightingManager.GetDefinition("XML");
}
AddIn CreateAddIn()
{
string xml =
"<AddIn name = \"XML Editor\"\r\n" +
" author = \"\"\r\n" +
" copyright = \"prj:///doc/copyright.txt\"\r\n" +
" description = \"XML Editor\"\r\n" +
" addInManagerHidden = \"preinstalled\">\r\n" +
"\r\n" +
" <Manifest>\r\n" +
" <Identity name = \"ICSharpCode.XmlEditor\"/>\r\n" +
" </Manifest>\r\n" +
"\r\n" +
" <Runtime>\r\n" +
" <Import assembly = \"XmlEditor.dll\"/>\r\n" +
" </Runtime>\r\n" +
"</AddIn>";
return AddIn.Load(new StringReader(xml));
}
string GetHighlightingDefinitionXml()
{
return
"<SyntaxDefinition name = \"XML\" extensions = \".xml\">\r\n" +
" <Environment>\r\n" +
" <Default color = \"Yellow\" bgcolor = \"Black\"/>\r\n" +
" <Selection color = \"White\" bgcolor = \"Purple\"/>\r\n" +
" <InvalidLines color = \"Red\"/>\r\n" +
" <LineNumbers color = \"Gray\" bgcolor = \"Black\"/>\r\n" +
" <SelectedFoldLine color = \"Green\" bgcolor=\"Black\"/>\r\n" +
" </Environment>\r\n" +
"\r\n" +
" <Digits name = \"Digits\" bold = \"false\" italic = \"false\" color = \"Yellow\"/>\r\n" +
"\r\n" +
" <RuleSets>\r\n" +
" <RuleSet ignorecase = \"false\">\r\n" +
" <Delimiters> </Delimiters>\r\n" +
" </RuleSet>\r\n" +
" </RuleSets>\r\n" +
"</SyntaxDefinition>";
}
[Test]
public void HighlightingManagerHasHighlightingDefinition()
{
Assert.AreEqual("XML", highlightingDefinition.Name);
}
[Test]
public void XsdFileExtensionRegisteredWithHighlightingManager()
{
IHighlightingDefinition highlightingDefinition = highlightingManager.GetDefinitionByExtension(".xsd");
Assert.AreEqual("XML", highlightingDefinition.Name);
}
}
}

17
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -67,6 +68,8 @@ @@ -67,6 +68,8 @@
<Compile Include="ExceptionClassOverridesTestFixture.cs" />
<Compile Include="GenerateOverrideMethodTests.cs" />
<Compile Include="GetElementByReflectionNameTests.cs" />
<Compile Include="Highlighting\AddInHighlightingResourceTests.cs" />
<Compile Include="Highlighting\SyntaxDoozerAddsHighlightingToHighlightingManagerTestFixture.cs" />
<Compile Include="NRefactoryResolverTests.cs" />
<Compile Include="CollectionClassOverridesTestFixture.cs" />
<Compile Include="OverridableMethodsTestFixture.cs" />
@ -84,6 +87,7 @@ @@ -84,6 +87,7 @@
<Compile Include="StringTagProvider\NullProjectStringTagProviderTestFixture.cs" />
<Compile Include="StringTagProvider\ProjectTagsTestFixture.cs" />
<Compile Include="Utils\MockAmbience.cs" />
<Compile Include="Utils\MockAssembly.cs" />
<Compile Include="Utils\MockClass.cs" />
<Compile Include="Utils\MockComponent.cs" />
<Compile Include="Utils\MockEntity.cs" />
@ -95,6 +99,7 @@ @@ -95,6 +99,7 @@
<Compile Include="Utils\MockSite.cs" />
<Compile Include="Utils\MockTextMarker.cs" />
<Compile Include="Utils\MockTextMarkerService.cs" />
<Compile Include="Utils\Tests\MockAssemblyTests.cs" />
<Compile Include="VBExpressionFinderTests.cs" />
<Compile Include="WebReferences\ValidReferenceNameTests.cs" />
<Compile Include="WebReferences\ValidWebReferenceNamespaceTests.cs" />
@ -131,10 +136,18 @@ @@ -131,10 +136,18 @@
<Compile Include="SharpDevelopColorDialogTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj">
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\ICSharpCode.TextEditor\Project\ICSharpCode.TextEditor.csproj">
<Project>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</Project>
<Name>ICSharpCode.TextEditor</Name>
</ProjectReference>
<ProjectReference Include="..\..\Core\Test\ICSharpCode.Core.Tests.csproj">
<Project>{AD6FAA08-D6F5-4DBA-AF85-F4DA9F40C3B5}</Project>
<Name>ICSharpCode.Core.Tests</Name>
</ProjectReference>
<ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj">
<Project>{2748AD25-9C63-4E12-877B-4DCE96FBED54}</Project>
<Name>ICSharpCode.SharpDevelop</Name>
@ -147,8 +160,10 @@ @@ -147,8 +160,10 @@
<Project>{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}</Project>
<Name>ICSharpCode.Core</Name>
</ProjectReference>
<Folder Include="Highlighting" />
<Folder Include="StringTagProvider" />
<Folder Include="Utils" />
<Folder Include="Utils\Tests" />
<Folder Include="WebReferences" />
<Folder Include="Templates" />
<Folder Include="Services_Navigation" />

42
src/Main/Base/Test/Utils/MockAssembly.cs

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace ICSharpCode.SharpDevelop.Tests.Utils
{
public class MockAssembly : Assembly
{
Dictionary<string, Stream> manifestResourceStreams = new Dictionary<string, Stream>();
public MockAssembly()
{
}
public void AddManifestResourceStream(string name, Stream stream)
{
manifestResourceStreams.Add(name, stream);
}
public override Stream GetManifestResourceStream(string name)
{
Stream stream;
if (manifestResourceStreams.TryGetValue(name, out stream)) {
return stream;
}
return null;
}
public override Type[] GetExportedTypes()
{
return new Type[0];
}
}
}

53
src/Main/Base/Test/Utils/Tests/MockAssemblyTests.cs

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.IO;
using ICSharpCode.SharpDevelop.Tests.Utils;
using NUnit.Framework;
namespace ICSharpCode.SharpDevelop.Tests.Utils.Tests
{
[TestFixture]
public class MockAssemblyTests
{
MockAssembly assembly;
Stream predefinedResourceStream;
[SetUp]
public void Init()
{
assembly = new MockAssembly();
predefinedResourceStream = new MemoryStream();
assembly.AddManifestResourceStream("ICSharpCode.Test.Xml.xshd", predefinedResourceStream);
}
[TearDown]
public void TearDown()
{
predefinedResourceStream.Dispose();
}
[Test]
public void GetManifestResourceStreamReturnsPredefinedStreamForKnownResource()
{
Assert.AreSame(predefinedResourceStream, assembly.GetManifestResourceStream("ICSharpCode.Test.Xml.xshd"));
}
[Test]
public void GetManifestResourceStreamReturnsNullForUnknownResource()
{
Assert.IsNull(assembly.GetManifestResourceStream("UnknownResource.xshd"));
}
[Test]
public void AssemblyExportedTypesReturnsAnEmptyArray()
{
Assert.AreEqual(0, assembly.GetExportedTypes().Length);
}
}
}

61
src/Main/Core/Project/Src/AddInTree/AddIn/AddIn.cs

@ -98,9 +98,7 @@ namespace ICSharpCode.Core @@ -98,9 +98,7 @@ namespace ICSharpCode.Core
/// Action to be set to AddInAction.CustomError.
/// </summary>
public string CustomErrorMessage {
get {
return customErrorMessage;
}
get { return customErrorMessage; }
internal set {
if (value != null) {
Enabled = false;
@ -114,78 +112,51 @@ namespace ICSharpCode.Core @@ -114,78 +112,51 @@ namespace ICSharpCode.Core
/// Action to execute when the application is restarted.
/// </summary>
public AddInAction Action {
get {
return action;
}
set {
action = value;
}
get { return action; }
set { action = value; }
}
public List<Runtime> Runtimes {
get {
return runtimes;
}
get { return runtimes; }
}
public Version Version {
get {
return manifest.PrimaryVersion;
}
get { return manifest.PrimaryVersion; }
}
public string FileName {
get {
return addInFileName;
}
get { return addInFileName; }
set { addInFileName = value; }
}
public string Name {
get {
return properties["name"];
}
get { return properties["name"]; }
}
public AddInManifest Manifest {
get {
return manifest;
}
get { return manifest; }
}
public Dictionary<string, ExtensionPath> Paths {
get {
return paths;
}
get { return paths; }
}
public Properties Properties {
get {
return properties;
}
get { return properties; }
}
public List<string> BitmapResources {
get {
return bitmapResources;
}
set {
bitmapResources = value;
}
get { return bitmapResources; }
set { bitmapResources = value; }
}
public List<string> StringResources {
get {
return stringResources;
}
set {
stringResources = value;
}
get { return stringResources; }
set { stringResources = value; }
}
public bool Enabled {
get {
return enabled;
}
get { return enabled; }
set {
enabled = value;
this.Action = value ? AddInAction.Enable : AddInAction.Disable;

44
src/Main/Core/Project/Src/AddInTree/AddIn/Runtime.cs

@ -22,6 +22,7 @@ namespace ICSharpCode.Core @@ -22,6 +22,7 @@ namespace ICSharpCode.Core
IList<LazyLoadDoozer> definedDoozers = new List<LazyLoadDoozer>();
IList<LazyConditionEvaluator> definedConditionEvaluators = new List<LazyConditionEvaluator>();
ICondition[] conditions;
IList<AddIn> addIns;
bool isActive = true;
bool isAssemblyLoaded;
@ -36,17 +37,21 @@ namespace ICSharpCode.Core @@ -36,17 +37,21 @@ namespace ICSharpCode.Core
}
public Runtime(string assembly, string hintPath)
: this(assembly, hintPath, AddInTree.AddIns)
{
}
public Runtime(string assembly, string hintPath, IList<AddIn> addIns)
{
this.assembly = assembly;
this.hintPath = hintPath;
this.addIns = addIns;
}
public string Assembly {
get {
return assembly;
}
get { return assembly; }
}
/// <summary>
/// Force loading the runtime assembly now.
/// </summary>
@ -54,22 +59,22 @@ namespace ICSharpCode.Core @@ -54,22 +59,22 @@ namespace ICSharpCode.Core
{
if (!isAssemblyLoaded) {
LoggingService.Info("Loading addin " + assembly);
isAssemblyLoaded = true;
try {
if (assembly[0] == ':') {
loadedAssembly = System.Reflection.Assembly.Load(assembly.Substring(1));
loadedAssembly = LoadAssembly(assembly.Substring(1));
} else if (assembly[0] == '$') {
int pos = assembly.IndexOf('/');
if (pos < 0)
throw new CoreException("Expected '/' in path beginning with '$'!");
string referencedAddIn = assembly.Substring(1, pos - 1);
foreach (AddIn addIn in AddInTree.AddIns) {
foreach (AddIn addIn in addIns) {
if (addIn.Enabled && addIn.Manifest.Identities.ContainsKey(referencedAddIn)) {
string assemblyFile = Path.Combine(Path.GetDirectoryName(addIn.FileName),
assembly.Substring(pos + 1));
loadedAssembly = System.Reflection.Assembly.LoadFrom(assemblyFile);
loadedAssembly = LoadAssemblyFrom(assemblyFile);
break;
}
}
@ -77,7 +82,7 @@ namespace ICSharpCode.Core @@ -77,7 +82,7 @@ namespace ICSharpCode.Core
throw new FileNotFoundException("Could not find referenced AddIn " + referencedAddIn);
}
} else {
loadedAssembly = System.Reflection.Assembly.LoadFrom(Path.Combine(hintPath, assembly));
loadedAssembly = LoadAssemblyFrom(Path.Combine(hintPath, assembly));
}
#if DEBUG
@ -85,9 +90,9 @@ namespace ICSharpCode.Core @@ -85,9 +90,9 @@ namespace ICSharpCode.Core
loadedAssembly.GetExportedTypes();
#endif
} catch (FileNotFoundException ex) {
MessageService.ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString());
ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString());
} catch (FileLoadException ex) {
MessageService.ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString());
ShowError("The addin '" + assembly + "' could not be loaded:\n" + ex.ToString());
}
}
}
@ -204,5 +209,20 @@ namespace ICSharpCode.Core @@ -204,5 +209,20 @@ namespace ICSharpCode.Core
runtime.definedConditionEvaluators = (runtime.definedConditionEvaluators as List<LazyConditionEvaluator>).AsReadOnly();
return runtime;
}
protected virtual Assembly LoadAssembly(string assemblyString)
{
return System.Reflection.Assembly.Load(assemblyString);
}
protected virtual Assembly LoadAssemblyFrom(string assemblyFile)
{
return System.Reflection.Assembly.LoadFrom(assemblyFile);
}
protected virtual void ShowError(string message)
{
MessageService.ShowError(message);
}
}
}

141
src/Main/Core/Test/AddInTreeTests/RuntimeLoadAssemblyTests.cs

@ -0,0 +1,141 @@ @@ -0,0 +1,141 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using ICSharpCode.Core;
using ICSharpCode.Core.Tests.Utils;
using NUnit.Framework;
namespace ICSharpCode.Core.Tests.AddInTreeTests
{
[TestFixture]
public class RuntimeLoadAssemblyTests
{
[Test]
public void AssemblyLoadCalledWhenAssemblyNameStartsWithColon()
{
DerivedRuntime runtime = new DerivedRuntime(":ICSharpCode.SharpDevelop", String.Empty);
runtime.Load();
Assert.AreEqual("ICSharpCode.SharpDevelop", runtime.AssemblyNamePassedToLoadAssembly);
}
[Test]
public void RuntimeLoadedAssemblyMatchesAssemblyReturnedFromLoadAssemblyMethod()
{
DerivedRuntime runtime = new DerivedRuntime(":ICSharpCode.SharpDevelop", String.Empty);
runtime.AssemblyNames.Add("ICSharpCode.SharpDevelop", typeof(string).Assembly);
Assembly loadedAssembly = runtime.LoadedAssembly;
string expectedLoadedAssemblyName = "CommonLanguageRuntimeLibrary";
Assert.AreEqual(expectedLoadedAssemblyName, loadedAssembly.ManifestModule.ToString());
}
[Test]
public void AssemblyLoadCalledWhenAssemblyNameDoesNotStartWithColonOrDollar()
{
string hintPath = @"D:\SharpDevelop\AddIns\FormsDesigner";
DerivedRuntime runtime = new DerivedRuntime("FormsDesigner.dll", hintPath);
runtime.Load();
string expectedFileName = @"D:\SharpDevelop\AddIns\FormsDesigner\FormsDesigner.dll";
Assert.AreEqual(expectedFileName, runtime.AssemblyFileNamePassedToLoadAssemblyFrom);
}
[Test]
public void RuntimeLoadedAssemblyMatchesAssemblyReturnedFromLoadAssemblyFromMethod()
{
DerivedRuntime runtime = new DerivedRuntime("MyAddIn.dll", @"d:\projects");
runtime.AssemblyFileNames.Add(@"MyAddIn.dll", typeof(string).Assembly);
Assembly loadedAssembly = runtime.LoadedAssembly;
string expectedLoadedAssemblyName = "CommonLanguageRuntimeLibrary";
Assert.AreEqual(expectedLoadedAssemblyName, loadedAssembly.ManifestModule.ToString());
}
[Test]
public void AssemblyLoadFromCalledWhenAssemblyNameStartsWithDollar()
{
List<AddIn> addIns = GetAddInsList();
DerivedRuntime runtime = new DerivedRuntime("$ICSharpCode.FormsDesigner/FormsDesigner.dll", String.Empty, addIns);
runtime.Load();
Assert.AreEqual(@"D:\SharpDevelop\AddIns\FormsDesigner\FormsDesigner.dll", runtime.AssemblyFileNamePassedToLoadAssemblyFrom);
}
List<AddIn> GetAddInsList()
{
AddIn formsDesignerAddIn = AddIn.Load(new StringReader(GetFormsDesignerAddInXml()));
formsDesignerAddIn.FileName = @"D:\SharpDevelop\AddIns\FormsDesigner\FormsDesigner.addin";
formsDesignerAddIn.Enabled = true;
List<AddIn> addIns = new List<AddIn>();
addIns.Add(formsDesignerAddIn);
return addIns;
}
string GetFormsDesignerAddInXml()
{
return
"<AddIn name = \"Forms Designer\"\r\n" +
" author = \"Mike Krueger\"\r\n" +
" copyright = \"prj:///doc/copyright.txt\"\r\n" +
" description = \"Windows Forms Designer\"\r\n" +
" addInManagerHidden = \"preinstalled\">\r\n" +
"\r\n" +
" <Manifest>\r\n" +
" <Identity name = \"ICSharpCode.FormsDesigner\"/>\r\n" +
" </Manifest>\r\n" +
"\r\n" +
" <Runtime>\r\n" +
" <Import assembly = \"FormsDesigner.dll\"/>\r\n" +
" <Import assembly = \":ICSharpCode.SharpDevelop\"/>\r\n" +
" </Runtime>\r\n" +
"</AddIn>";
}
[Test]
public void CoreExceptionErrorMessageShownAssemblyNameStartsWithDollarButHasNoForwardSlashCharacter()
{
List<AddIn> addIns = GetAddInsList();
DerivedRuntime runtime = new DerivedRuntime("$ICSharpCode.FormsDesigner.dll", String.Empty, addIns);
CoreException ex = Assert.Throws<CoreException>(delegate { runtime.Load(); });
Assert.AreEqual("Expected '/' in path beginning with '$'!", ex.Message);
}
[Test]
public void ErrorMessageShownWhenAddInReferenceCannotBeFound()
{
List<AddIn> addIns = new List<AddIn>();
DerivedRuntime runtime = new DerivedRuntime("$UnknownAddIn/Unknown.dll", String.Empty, addIns);
runtime.Load();
string expectedErrorMessageStart =
"The addin '$UnknownAddIn/Unknown.dll' could not be loaded:\n" +
"System.IO.FileNotFoundException: Could not find referenced AddIn UnknownAddIn";
string errorMessage = runtime.ErrorMessageDisplayed;
Assert.IsTrue(errorMessage.StartsWith(expectedErrorMessageStart), errorMessage);
}
[Test]
public void ErrorMessageShownWhenLoadAssemblyFromThrowsFileLoadException()
{
List<AddIn> addIns = new List<AddIn>();
DerivedRuntime runtime = new DerivedRuntime("Missing.dll", String.Empty, addIns);
FileLoadException ex = new FileLoadException("Test");
runtime.LoadAssemblyFromExceptionToThrow = ex;
runtime.Load();
string expectedErrorMessageStart =
"The addin 'Missing.dll' could not be loaded:\n" +
"System.IO.FileLoadException: Test";
string errorMessage = runtime.ErrorMessageDisplayed;
Assert.IsTrue(errorMessage.StartsWith(expectedErrorMessageStart), errorMessage);
}
}
}

7
src/Main/Core/Test/ICSharpCode.Core.Tests.csproj

@ -49,12 +49,15 @@ @@ -49,12 +49,15 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AddInTreeTests\RuntimeLoadAssemblyTests.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="TopologicalSortTest.cs" />
<Compile Include="StringParserTests.cs" />
<Compile Include="AddInTreeTests\AddInTreeLoadingTests.cs" />
<Compile Include="AddInTreeTests\ExtPathTests.cs" />
<Compile Include="InvalidDirectoryNameTests.cs" />
<Compile Include="Utils\DerivedRuntime.cs" />
<Compile Include="Utils\Tests\DerivedRuntimeTests.cs" />
<Compile Include="ValidDirectoryNameTests.cs" />
</ItemGroup>
<ItemGroup>
@ -63,5 +66,9 @@ @@ -63,5 +66,9 @@
<Name>ICSharpCode.Core</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Utils" />
<Folder Include="Utils\Tests" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>

103
src/Main/Core/Test/Utils/DerivedRuntime.cs

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using ICSharpCode.Core;
namespace ICSharpCode.Core.Tests.Utils
{
public class DerivedRuntime : Runtime
{
string assemblyNamePassedToLoadAssembly;
string assemblyFileNamePassedToLoadAssemblyFrom;
Dictionary<string, Assembly> assemblyNames = new Dictionary<string, Assembly>();
Dictionary<string, Assembly> assemblyFileNames = new Dictionary<string, Assembly>();
string errorMessageDisplayed;
public DerivedRuntime(string assembly, string hintPath)
: this(assembly, hintPath, new List<AddIn>())
{
}
public DerivedRuntime(string assembly, string hintPath, IList<AddIn> addIns)
: base(assembly, hintPath, addIns)
{
}
public string AssemblyNamePassedToLoadAssembly {
get { return assemblyNamePassedToLoadAssembly; }
}
public Exception LoadAssemblyExceptionToThrow { get; set; }
public Assembly CallLoadAssembly(string assemblyString)
{
return LoadAssembly(assemblyString);
}
protected override Assembly LoadAssembly(string assemblyString)
{
assemblyNamePassedToLoadAssembly = assemblyString;
if (LoadAssemblyExceptionToThrow != null) {
throw LoadAssemblyExceptionToThrow;
}
Assembly assembly;
if (assemblyNames.TryGetValue(assemblyString, out assembly)) {
return assembly;
}
return typeof(DerivedRuntime).Assembly;
}
public Dictionary<string, Assembly> AssemblyNames {
get { return assemblyNames; }
}
public string AssemblyFileNamePassedToLoadAssemblyFrom {
get { return assemblyFileNamePassedToLoadAssemblyFrom; }
}
public Exception LoadAssemblyFromExceptionToThrow { get; set; }
public Assembly CallLoadAssemblyFrom(string assemblyFile)
{
return LoadAssemblyFrom(assemblyFile);
}
protected override Assembly LoadAssemblyFrom(string assemblyFile)
{
assemblyFileNamePassedToLoadAssemblyFrom = assemblyFile;
if (LoadAssemblyFromExceptionToThrow != null) {
throw LoadAssemblyFromExceptionToThrow;
}
string fileName = Path.GetFileName(assemblyFile);
Assembly assembly;
if (assemblyFileNames.TryGetValue(fileName, out assembly)) {
return assembly;
}
return typeof(DerivedRuntime).Assembly;
}
public Dictionary<string, Assembly> AssemblyFileNames {
get { return assemblyFileNames; }
}
public string ErrorMessageDisplayed {
get { return errorMessageDisplayed; }
}
protected override void ShowError(string message)
{
errorMessageDisplayed = message;
}
}
}

82
src/Main/Core/Test/Utils/Tests/DerivedRuntimeTests.cs

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Reflection;
using ICSharpCode.Core.Tests.Utils;
using NUnit.Framework;
namespace ICSharpCode.Core.Tests.Utils.Tests
{
[TestFixture]
public class DerivedRuntimeTests
{
[Test]
public void LoadAssemblyFromReturnsICSharpCoreTestsAssemblyForUnknownAssemblyFileName()
{
DerivedRuntime runtime = new DerivedRuntime("MyAddIn.dll", String.Empty);
Assembly loadedAssembly = runtime.CallLoadAssemblyFrom("tests.dll");
string expectedLoadedAssemblyName = "ICSharpCode.Core.Tests.dll";
Assert.AreEqual(expectedLoadedAssemblyName, loadedAssembly.ManifestModule.ToString());
}
[Test]
public void LoadAssemblyFromReturnsKnownAssemblyFromAssemblyFileNamesCollection()
{
DerivedRuntime runtime = new DerivedRuntime("MyAddIn.dll", String.Empty);
runtime.AssemblyFileNames.Add("MyAddIn.dll", typeof(string).Assembly);
Assembly loadedAssembly = runtime.CallLoadAssemblyFrom(@"d:\projects\test\MyAddIn.dll");
string expectedLoadedAssemblyName = "CommonLanguageRuntimeLibrary";
Assert.AreEqual(expectedLoadedAssemblyName, loadedAssembly.ManifestModule.ToString());
}
[Test]
public void LoadAssemblyReturnsICSharpCoreTestsAssemblyForUnknownAssemblyName()
{
DerivedRuntime runtime = new DerivedRuntime(":ICSharpCode.SharpDevelop", String.Empty);
Assembly loadedAssembly = runtime.CallLoadAssembly("Unknown");
string expectedLoadedAssemblyName = "ICSharpCode.Core.Tests.dll";
Assert.AreEqual(expectedLoadedAssemblyName, loadedAssembly.ManifestModule.ToString());
}
[Test]
public void LoadAssemblyReturnsKnownAssemblyFromAssemblyNamesCollection()
{
DerivedRuntime runtime = new DerivedRuntime(":ICSharpCode.SharpDevelop", String.Empty);
runtime.AssemblyNames.Add("ICSharpCode.SharpDevelop", typeof(string).Assembly);
Assembly loadedAssembly = runtime.CallLoadAssembly("ICSharpCode.SharpDevelop");
string expectedLoadedAssemblyName = "CommonLanguageRuntimeLibrary";
Assert.AreEqual(expectedLoadedAssemblyName, loadedAssembly.ManifestModule.ToString());
}
[Test]
public void LoadAssemblyThrowsPredefinedException()
{
DerivedRuntime runtime = new DerivedRuntime(":ICSharpCode.SharpDevelop", String.Empty);
ApplicationException expectedException = new ApplicationException("Test");
runtime.LoadAssemblyExceptionToThrow = expectedException;
ApplicationException ex = Assert.Throws<ApplicationException>(delegate { runtime.CallLoadAssembly("test"); });
Assert.AreEqual("Test", ex.Message);
}
[Test]
public void LoadAssemblyFromThrowsPredefinedException()
{
DerivedRuntime runtime = new DerivedRuntime(":ICSharpCode.SharpDevelop", String.Empty);
ApplicationException expectedException = new ApplicationException("Test");
runtime.LoadAssemblyFromExceptionToThrow = expectedException;
ApplicationException ex = Assert.Throws<ApplicationException>(delegate { runtime.CallLoadAssemblyFrom("test"); });
Assert.AreEqual("Test", ex.Message);
}
}
}
Loading…
Cancel
Save