Browse Source

Add ProjectReference class to NRefactory to simplify creating the type system for a solution with multiple projects.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
9a9485a49d
  1. 18
      ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs
  2. 1
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs
  3. 1
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  4. 64
      ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs
  5. 3
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  6. 33
      ICSharpCode.NRefactory/TypeSystem/DefaultSolutionSnapshot.cs
  7. 20
      ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs
  8. 10
      ICSharpCode.NRefactory/TypeSystem/ISolutionSnapshot.cs
  9. 3
      ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs
  10. 3
      ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs
  11. 56
      ICSharpCode.NRefactory/TypeSystem/ProjectReference.cs

18
ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs

@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp
public class CSharpProjectContent : IProjectContent
{
string assemblyName;
string projectFileName;
string location;
Dictionary<string, IParsedFile> parsedFiles;
List<IAssemblyReference> assemblyReferences;
@ -38,7 +39,6 @@ namespace ICSharpCode.NRefactory.CSharp @@ -38,7 +39,6 @@ namespace ICSharpCode.NRefactory.CSharp
public CSharpProjectContent()
{
this.assemblyName = string.Empty;
this.parsedFiles = new Dictionary<string, IParsedFile>(Platform.FileNameComparer);
this.assemblyReferences = new List<IAssemblyReference>();
this.compilerSettings = new CompilerSettings();
@ -48,6 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -48,6 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected CSharpProjectContent(CSharpProjectContent pc)
{
this.assemblyName = pc.assemblyName;
this.projectFileName = pc.projectFileName;
this.location = pc.location;
this.parsedFiles = new Dictionary<string, IParsedFile>(pc.parsedFiles, Platform.FileNameComparer);
this.assemblyReferences = new List<IAssemblyReference>(pc.assemblyReferences);
@ -62,6 +63,10 @@ namespace ICSharpCode.NRefactory.CSharp @@ -62,6 +63,10 @@ namespace ICSharpCode.NRefactory.CSharp
get { return assemblyReferences; }
}
public string ProjectFileName {
get { return projectFileName; }
}
public string AssemblyName {
get { return assemblyName; }
}
@ -129,11 +134,18 @@ namespace ICSharpCode.NRefactory.CSharp @@ -129,11 +134,18 @@ namespace ICSharpCode.NRefactory.CSharp
pc.assemblyName = newAssemblyName;
return pc;
}
public IProjectContent SetProjectFileName(string newProjectFileName)
{
CSharpProjectContent pc = Clone();
pc.projectFileName = newProjectFileName;
return pc;
}
public IProjectContent SetLocation(string location)
public IProjectContent SetLocation(string newLocation)
{
CSharpProjectContent pc = Clone();
pc.location = location;
pc.location = newLocation;
return pc;
}

1
ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs

@ -194,6 +194,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -194,6 +194,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(object[]), typeof(string[])));
Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(dynamic[]), typeof(string[])));
Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(object[,])));
Assert.AreEqual(C.None, ExplicitConversion(typeof(object[]), typeof(int[])));
Assert.AreEqual(C.None, ExplicitConversion(typeof(short[]), typeof(int[])));
Assert.AreEqual(C.ExplicitReferenceConversion, ExplicitConversion(typeof(Array), typeof(int[])));

1
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -234,6 +234,7 @@ @@ -234,6 +234,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TypeSystem\BlobLoaderTests.cs" />
<Compile Include="TypeSystem\CecilLoaderTests.cs" />
<Compile Include="TypeSystem\CyclicProjectDependency.cs" />
<Compile Include="TypeSystem\GetAllBaseTypesTest.cs" />
<Compile Include="TypeSystem\GetMembersTests.cs" />
<Compile Include="TypeSystem\LazyLoadedCecilLoaderTests.cs" />

64
ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.TypeSystem
{
[TestFixture]
public class CyclicProjectDependency
{
IProjectContent pc1;
IProjectContent pc2;
ISolutionSnapshot solution;
[SetUp]
public void Setup()
{
pc1 = new CSharpProjectContent()
.SetAssemblyName("PC1")
.SetProjectFileName("PC1.csproj")
.AddAssemblyReferences(new IAssemblyReference[] { CecilLoaderTests.Mscorlib, new ProjectReference("PC2.csproj") });
pc2 = new CSharpProjectContent()
.SetAssemblyName("PC2")
.SetProjectFileName("PC2.csproj")
.AddAssemblyReferences(new IAssemblyReference[] { CecilLoaderTests.Mscorlib, new ProjectReference("PC1.csproj") });
solution = new DefaultSolutionSnapshot(new[] { pc1, pc2 });
}
[Test]
public void CreateCompilation1()
{
ICompilation c = solution.GetCompilation(pc1);
Assert.AreEqual(new string[] { "PC1", "mscorlib", "PC2" }, c.Assemblies.Select(asm => asm.AssemblyName).ToArray());
}
[Test]
public void CreateCompilation2()
{
ICompilation c = solution.GetCompilation(pc2);
Assert.AreEqual(new string[] { "PC2", "mscorlib", "PC1" }, c.Assemblies.Select(asm => asm.AssemblyName).ToArray());
}
}
}

3
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -136,6 +136,7 @@ @@ -136,6 +136,7 @@
<Compile Include="TypeSystem\ByReferenceType.cs" />
<Compile Include="TypeSystem\CecilLoader.cs" />
<Compile Include="TypeSystem\ComHelper.cs" />
<Compile Include="TypeSystem\DefaultSolutionSnapshot.cs" />
<Compile Include="TypeSystem\DomRegion.cs" />
<Compile Include="TypeSystem\EntityType.cs" />
<Compile Include="TypeSystem\ExtensionMethods.cs" />
@ -170,7 +171,6 @@ @@ -170,7 +171,6 @@
<Compile Include="TypeSystem\Implementation\DefaultResolvedProperty.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedTypeDefinition.cs" />
<Compile Include="TypeSystem\Implementation\DefaultResolvedTypeParameter.cs" />
<Compile Include="TypeSystem\Implementation\DefaultSolutionSnapshot.cs" />
<Compile Include="TypeSystem\Implementation\DefaultUnresolvedAssembly.cs" />
<Compile Include="TypeSystem\Implementation\DefaultUnresolvedAttribute.cs" />
<Compile Include="TypeSystem\Implementation\DefaultUnresolvedEvent.cs" />
@ -222,6 +222,7 @@ @@ -222,6 +222,7 @@
<Compile Include="TypeSystem\NullableType.cs" />
<Compile Include="TypeSystem\ParameterizedType.cs" />
<Compile Include="TypeSystem\ParameterListComparer.cs" />
<Compile Include="TypeSystem\ProjectReference.cs" />
<Compile Include="TypeSystem\ReflectionNameParseException.cs" />
<Compile Include="TypeSystem\SimpleTypeResolveContext.cs" />
<Compile Include="TypeSystem\TypeKind.cs" />

33
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs → ICSharpCode.NRefactory/TypeSystem/DefaultSolutionSnapshot.cs

@ -18,16 +18,47 @@ @@ -18,16 +18,47 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem
{
/// <summary>
/// Default implementation of ISolutionSnapshot.
/// </summary>
public class DefaultSolutionSnapshot : ISolutionSnapshot
{
readonly Dictionary<string, IProjectContent> projectDictionary = new Dictionary<string, IProjectContent>(Platform.FileNameComparer);
ConcurrentDictionary<IProjectContent, ICompilation> dictionary = new ConcurrentDictionary<IProjectContent, ICompilation>();
/// <summary>
/// Creates a new DefaultSolutionSnapshot with the specified projects.
/// </summary>
public DefaultSolutionSnapshot(IEnumerable<IProjectContent> projects)
{
foreach (var project in projects) {
if (project.ProjectFileName != null)
projectDictionary.Add(project.ProjectFileName, project);
}
}
/// <summary>
/// Creates a new DefaultSolutionSnapshot that does not support <see cref="ProjectReference"/>s.
/// </summary>
public DefaultSolutionSnapshot()
{
}
public IProjectContent GetProjectContent(string projectFileName)
{
IProjectContent pc;
if (projectDictionary.TryGetValue(projectFileName, out pc))
return pc;
else
return null;
}
public ICompilation GetCompilation(IProjectContent project)
{
if (project == null)

20
ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs

@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
public interface IProjectContent : IUnresolvedAssembly
{
/// <summary>
/// Gets the path to the project file (e.g. .csproj).
/// </summary>
string ProjectFileName { get; }
/// <summary>
/// Gets a parsed file by its file name.
/// </summary>
@ -52,7 +57,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -52,7 +57,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Creates a new <see cref="ICompilation"/> that allows resolving within this project.
/// </summary>
/// <remarks>
/// An ICompilation is immutable, it operates on a snapshot of this project.
/// This method does not support <see cref="ProjectReference"/>s. When dealing with a solution
/// containing multiple projects, consider using <see cref="ISolutionSnapshot.GetCompilation"/> instead.
/// </remarks>
ICompilation CreateCompilation();
@ -61,7 +67,10 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -61,7 +67,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
/// <param name="solutionSnapshot">The parent solution snapshot to use for the compilation.</param>
/// <remarks>
/// An ICompilation is immutable, it operates on a snapshot of this project.
/// This method is intended to be called by ISolutionSnapshot implementations. Other code should
/// call <see cref="ISolutionSnapshot.GetCompilation"/> instead.
/// This method always creates a new compilation, even if the solution snapshot already contains
/// one for this project.
/// </remarks>
ICompilation CreateCompilation(ISolutionSnapshot solutionSnapshot);
@ -71,7 +80,12 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -71,7 +80,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
IProjectContent SetAssemblyName(string newAssemblyName);
/// <summary>
/// Changes the location of this project content.
/// Changes the project file name of this project content.
/// </summary>
IProjectContent SetProjectFileName(string newProjectFileName);
/// <summary>
/// Changes the path to the assembly location (the output path where the project compiles to).
/// </summary>
IProjectContent SetLocation(string newLocation);

10
ICSharpCode.NRefactory/TypeSystem/ISolutionSnapshot.cs

@ -25,8 +25,18 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -25,8 +25,18 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </summary>
public interface ISolutionSnapshot
{
/// <summary>
/// Gets the project content with the specified file name.
/// Returns null if no such project exists in the solution.
/// </summary>
/// <remarks>
/// This method is used by the <see cref="ProjectReference"/> class.
/// </remarks>
IProjectContent GetProjectContent(string projectFileName);
/// <summary>
/// Gets the compilation for the specified project.
/// The project must be a part of the solution (passed to the solution snapshot's constructor).
/// </summary>
ICompilation GetCompilation(IProjectContent project);
}

3
ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs

@ -17,9 +17,6 @@ @@ -17,9 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{

3
ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs

@ -18,8 +18,6 @@ @@ -18,8 +18,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
@ -95,7 +93,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -95,7 +93,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
}
[ObsoleteAttribute("Use compilation.Assemblies.Where(asm != compilation.MainAssembly) instead.")]
public IList<IAssembly> ReferencedAssemblies {
get {
if (referencedAssemblies == null)

56
ICSharpCode.NRefactory/TypeSystem/ProjectReference.cs

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.TypeSystem
{
/// <summary>
/// References another project content in the same solution.
/// Using the <see cref="ProjectReference"/> class requires that you
/// </summary>
[Serializable]
public class ProjectReference : IAssemblyReference
{
readonly string projectFileName;
/// <summary>
/// Creates a new reference to the specified project (must be part of the same solution).
/// </summary>
/// <param name="projectFileName">Full path to the file name. Must be identical to <see cref="IProjectContent.ProjectFileName"/> of the target project; do not use a relative path.</param>
public ProjectReference(string projectFileName)
{
this.projectFileName = projectFileName;
}
public IAssembly Resolve(ITypeResolveContext context)
{
var solution = context.Compilation.SolutionSnapshot;
var pc = solution.GetProjectContent(projectFileName);
if (pc != null)
return pc.Resolve(context);
else
return null;
}
public override string ToString()
{
return string.Format("[ProjectReference {0}]", projectFileName);
}
}
}
Loading…
Cancel
Save