Browse Source

Update solution-loading logic in ConsistencyCheck.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
1f6c4f037e
  1. 54
      ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs
  2. 14
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs
  3. 68
      ICSharpCode.NRefactory.ConsistencyCheck/CSharpFile.cs
  4. 179
      ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs
  5. 11
      ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs
  6. 2
      ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj
  7. 4
      ICSharpCode.NRefactory.ConsistencyCheck/Program.cs
  8. 4
      ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs
  9. 4
      ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs
  10. 2
      ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs
  11. 23
      ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs
  12. 8
      ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs
  13. 9
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs
  14. 2
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs

54
ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp
public class ArrayInitializerExpression : Expression
{
/// <summary>
/// For ease of use purposes in the resolver the ast representation
/// For ease of use purposes in the resolver the ast representation
/// of { a, b, c } is { {a}, {b}, {c} }.
/// If IsSingleElement is true then this array initializer expression is a generated one.
/// That has no meaning in the source code (and contains no brace tokens).
@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -73,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void AcceptVisitor (IAstVisitor visitor)
{
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return default (T);
@ -107,7 +107,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -107,7 +107,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
visitor.VisitArrayInitializerExpression (this);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitArrayInitializerExpression (this);
@ -138,8 +138,54 @@ namespace ICSharpCode.NRefactory.CSharp @@ -138,8 +138,54 @@ namespace ICSharpCode.NRefactory.CSharp
return true;
}
}
}
#region PatternPlaceholder
public static implicit operator ArrayInitializerExpression(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : ArrayInitializerExpression, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override NodeType NodeType {
get { return NodeType.Pattern; }
}
public override void AcceptVisitor (IAstVisitor visitor)
{
visitor.VisitPatternPlaceholder(this, child);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitPatternPlaceholder(this, child);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
}
}

14
ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs

@ -42,11 +42,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -42,11 +42,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Use this overload if you are resolving within a complete C# file.
/// </summary>
/// <param name="compilation">The current compilation.</param>
/// <param name="syntaxTree">The syntax tree corresponding to the specified parsed file.</param>
/// <param name="syntaxTree">The syntax tree to be resolved.</param>
/// <param name="unresolvedFile">
/// Optional: Result of the <see cref="TypeSystemConvertVisitor"/> for the file being resolved.
/// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
/// <para>
/// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
/// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
/// </para>
/// <para>
/// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
@ -72,11 +72,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -72,11 +72,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// Use this overload if you are resolving code snippets (not necessarily complete files).
/// </summary>
/// <param name="resolver">The resolver state at the root node (to be more precise: just outside the root node).</param>
/// <param name="rootNode">The root node of the resolved tree.</param>
/// <param name="rootNode">The root node of the tree to be resolved.</param>
/// <param name="unresolvedFile">
/// Optional: Result of the <see cref="TypeSystemConvertVisitor"/> for the file being resolved.
/// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
/// <para>
/// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
/// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
/// </para>
/// <para>
/// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
@ -119,7 +119,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -119,7 +119,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
/// <summary>
/// Gets the parsed file used by this CSharpAstResolver.
/// Gets the unresolved file used by this CSharpAstResolver.
/// Can return null.
/// </summary>
public CSharpUnresolvedFile UnresolvedFile {

68
ICSharpCode.NRefactory.ConsistencyCheck/CSharpFile.cs

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
public class CSharpFile
{
public readonly CSharpProject Project;
public readonly string FileName;
public readonly string OriginalText;
public SyntaxTree SyntaxTree;
public CSharpUnresolvedFile UnresolvedTypeSystemForFile;
public CSharpFile(CSharpProject project, string fileName)
{
this.Project = project;
this.FileName = fileName;
CSharpParser p = new CSharpParser(project.CompilerSettings);
// using (var stream = File.OpenRead(fileName)) {
// this.CompilationUnit = p.Parse(stream, fileName);
// }
// Keep the original text around; we might use it for a refactoring later
this.OriginalText = File.ReadAllText(fileName);
this.SyntaxTree = p.Parse(this.OriginalText, fileName);
if (p.HasErrors) {
Console.WriteLine("Error parsing " + fileName + ":");
foreach (var error in p.ErrorsAndWarnings) {
Console.WriteLine(" " + error.Region + " " + error.Message);
}
}
this.UnresolvedTypeSystemForFile = this.SyntaxTree.ToTypeSystem();
}
public CSharpAstResolver CreateResolver()
{
return new CSharpAstResolver(Project.Compilation, SyntaxTree, UnresolvedTypeSystemForFile);
}
}
}

179
ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs

@ -20,145 +20,128 @@ using System; @@ -20,145 +20,128 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using Microsoft.Build.Framework;
using Microsoft.Build.Logging;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
/// <summary>
/// Represents a C# project (.csproj file)
/// </summary>
public class CSharpProject
{
/// <summary>
/// Parent solution.
/// </summary>
public readonly Solution Solution;
/// <summary>
/// Title is the project name as specified in the .sln file.
/// </summary>
public readonly string Title;
/// <summary>
/// Name of the output assembly.
/// </summary>
public readonly string AssemblyName;
/// <summary>
/// Full path to the .csproj file.
/// </summary>
public readonly string FileName;
public readonly List<CSharpFile> Files = new List<CSharpFile>();
public readonly CompilerSettings CompilerSettings = new CompilerSettings();
public IProjectContent ProjectContent;
/// <summary>
/// The unresolved type system for this project.
/// </summary>
public readonly IProjectContent ProjectContent;
public ICompilation Compilation {
get {
return Solution.SolutionSnapshot.GetCompilation(ProjectContent);
}
}
/// <summary>
/// The resolved type system for this project.
/// This field is initialized once all projects have been loaded (in Solution constructor).
/// </summary>
public ICompilation Compilation;
public CSharpProject(Solution solution, string title, string fileName)
{
// Normalize the file name
fileName = Path.GetFullPath(fileName);
this.Solution = solution;
this.Title = title;
this.FileName = fileName;
var p = new Microsoft.Build.Evaluation.Project(fileName);
this.AssemblyName = p.GetPropertyValue("AssemblyName");
this.CompilerSettings.AllowUnsafeBlocks = GetBoolProperty(p, "AllowUnsafeBlocks") ?? false;
this.CompilerSettings.CheckForOverflow = GetBoolProperty(p, "CheckForOverflowUnderflow") ?? false;
foreach (string symbol in p.GetPropertyValue("DefineConstants").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) {
// Use MSBuild to open the .csproj
var msbuildProject = new Microsoft.Build.Evaluation.Project(fileName);
// Figure out some compiler settings
this.AssemblyName = msbuildProject.GetPropertyValue("AssemblyName");
this.CompilerSettings.AllowUnsafeBlocks = GetBoolProperty(msbuildProject, "AllowUnsafeBlocks") ?? false;
this.CompilerSettings.CheckForOverflow = GetBoolProperty(msbuildProject, "CheckForOverflowUnderflow") ?? false;
string defineConstants = msbuildProject.GetPropertyValue("DefineConstants");
foreach (string symbol in defineConstants.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
this.CompilerSettings.ConditionalSymbols.Add(symbol.Trim());
// Initialize the unresolved type system
IProjectContent pc = new CSharpProjectContent();
pc = pc.SetAssemblyName(this.AssemblyName);
pc = pc.SetProjectFileName(fileName);
pc = pc.SetCompilerSettings(this.CompilerSettings);
// Parse the C# code files
foreach (var item in msbuildProject.GetItems("Compile")) {
var file = new CSharpFile(this, Path.Combine(msbuildProject.DirectoryPath, item.EvaluatedInclude));
Files.Add(file);
}
foreach (var item in p.GetItems("Compile")) {
Files.Add(new CSharpFile(this, Path.Combine(p.DirectoryPath, item.EvaluatedInclude)));
}
List<IAssemblyReference> references = new List<IAssemblyReference>();
string mscorlib = FindAssembly(Program.AssemblySearchPaths, "mscorlib");
if (mscorlib != null) {
references.Add(Program.LoadAssembly(mscorlib));
} else {
Console.WriteLine("Could not find mscorlib");
}
bool hasSystemCore = false;
foreach (var item in p.GetItems("Reference")) {
string assemblyFileName = null;
if (item.HasMetadata("HintPath")) {
assemblyFileName = Path.Combine(p.DirectoryPath, item.GetMetadataValue("HintPath"));
if (!File.Exists(assemblyFileName))
assemblyFileName = null;
}
if (assemblyFileName == null) {
assemblyFileName = FindAssembly(Program.AssemblySearchPaths, item.EvaluatedInclude);
}
if (assemblyFileName != null) {
if (Path.GetFileName(assemblyFileName).Equals("System.Core.dll", StringComparison.OrdinalIgnoreCase))
hasSystemCore = true;
references.Add(Program.LoadAssembly(assemblyFileName));
} else {
Console.WriteLine("Could not find referenced assembly " + item.EvaluatedInclude);
}
// Add parsed files to the type system
pc = pc.AddOrUpdateFiles(Files.Select(f => f.UnresolvedTypeSystemForFile));
// Add referenced assemblies:
foreach (string assemblyFile in ResolveAssemblyReferences(msbuildProject)) {
IUnresolvedAssembly assembly = solution.LoadAssembly(assemblyFile);
pc = pc.AddAssemblyReferences(new [] { assembly });
}
if (!hasSystemCore && FindAssembly(Program.AssemblySearchPaths, "System.Core") != null)
references.Add(Program.LoadAssembly(FindAssembly(Program.AssemblySearchPaths, "System.Core")));
foreach (var item in p.GetItems("ProjectReference")) {
references.Add(new ProjectReference(item.EvaluatedInclude));
// Add project references:
foreach (var item in msbuildProject.GetItems("ProjectReference")) {
string referencedFileName = Path.Combine(msbuildProject.DirectoryPath, item.EvaluatedInclude);
// Normalize the path; this is required to match the name with the referenced project's file name
referencedFileName = Path.GetFullPath(referencedFileName);
pc = pc.AddAssemblyReferences(new[] { new ProjectReference(referencedFileName) });
}
this.ProjectContent = new CSharpProjectContent()
.SetAssemblyName(this.AssemblyName)
.SetCompilerSettings(this.CompilerSettings)
.AddAssemblyReferences(references)
.AddOrUpdateFiles(Files.Select(f => f.UnresolvedFile));
this.ProjectContent = pc;
}
string FindAssembly(IEnumerable<string> assemblySearchPaths, string evaluatedInclude)
IEnumerable<string> ResolveAssemblyReferences(Microsoft.Build.Evaluation.Project project)
{
if (evaluatedInclude.IndexOf(',') >= 0)
evaluatedInclude = evaluatedInclude.Substring(0, evaluatedInclude.IndexOf(','));
foreach (string searchPath in assemblySearchPaths) {
string assemblyFile = Path.Combine(searchPath, evaluatedInclude + ".dll");
if (File.Exists(assemblyFile))
return assemblyFile;
}
return null;
// Use MSBuild to figure out the full path of the referenced assemblies
var projectInstance = project.CreateProjectInstance();
projectInstance.SetProperty("BuildingProject", "false");
project.SetProperty("DesignTimeBuild", "true");
projectInstance.Build("ResolveAssemblyReferences", new [] { new ConsoleLogger(LoggerVerbosity.Minimal) });
var items = projectInstance.GetItems("_ResolveAssemblyReferenceResolvedFiles");
string baseDirectory = Path.GetDirectoryName(this.FileName);
return items.Select(i => Path.Combine(baseDirectory, i.GetMetadataValue("Identity")));
}
static bool? GetBoolProperty(Microsoft.Build.Evaluation.Project p, string propertyName)
{
string val = p.GetPropertyValue(propertyName);
if (val.Equals("true", StringComparison.OrdinalIgnoreCase))
return true;
if (val.Equals("false", StringComparison.OrdinalIgnoreCase))
return false;
return null;
bool result;
if (bool.TryParse(val, out result))
return result;
else
return null;
}
public override string ToString()
{
return string.Format("[CSharpProject AssemblyName={0}]", AssemblyName);
}
public CSharpFile GetFile(string fileName)
{
return Files.Single(f => f.FileName == fileName);
}
}
public class CSharpFile
{
public readonly CSharpProject Project;
public readonly string FileName;
public readonly ITextSource Content;
public readonly int LinesOfCode;
public SyntaxTree SyntaxTree;
public CSharpUnresolvedFile UnresolvedFile;
public CSharpFile(CSharpProject project, string fileName)
{
this.Project = project;
this.FileName = fileName;
this.Content = new StringTextSource(File.ReadAllText(FileName));
this.LinesOfCode = 1 + this.Content.Text.Count(c => c == '\n');
CSharpParser p = new CSharpParser(project.CompilerSettings);
this.SyntaxTree = p.Parse(Content, fileName);
if (p.HasErrors) {
Console.WriteLine("Error parsing " + fileName + ":");
foreach (var error in p.ErrorsAndWarnings) {
Console.WriteLine(" " + error.Region + " " + error.Message);
}
}
this.UnresolvedFile = this.SyntaxTree.ToTypeSystem();
}
}
}

11
ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs

@ -59,8 +59,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -59,8 +59,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
}
}
);
var resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile);
resolver.ApplyNavigator(navigator);
file.CreateResolver().ApplyNavigator(navigator);
}
}
Console.WriteLine("For each entity, find all references...");
@ -103,18 +102,18 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -103,18 +102,18 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
var interestingFiles = new HashSet<CSharpFile>();
foreach (var searchScope in searchScopes) {
foreach (var unresolvedFile in fr.GetInterestingFiles(searchScope, project.Compilation)) {
var file = project.GetFile(unresolvedFile.FileName);
Debug.Assert(file.UnresolvedFile == unresolvedFile);
var file = project.Files.Single(f => f.FileName == unresolvedFile.FileName);
Debug.Assert(file.UnresolvedTypeSystemForFile == unresolvedFile);
// Skip file if it doesn't contain the search term
if (searchScope.SearchTerm != null && file.Content.IndexOf(searchScope.SearchTerm, 0, file.Content.TextLength, StringComparison.Ordinal) < 0)
if (searchScope.SearchTerm != null && file.OriginalText.IndexOf(searchScope.SearchTerm, StringComparison.Ordinal) < 0)
continue;
interestingFiles.Add(file);
}
}
foreach (var file in interestingFiles) {
fr.FindReferencesInFile(searchScopes, file.UnresolvedFile, file.SyntaxTree, project.Compilation,
fr.FindReferencesInFile(searchScopes, file.UnresolvedTypeSystemForFile, file.SyntaxTree, project.Compilation,
delegate(AstNode node, ResolveResult result) {
foundReferences.Add(node);
}, CancellationToken.None);

2
ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj

@ -53,6 +53,7 @@ @@ -53,6 +53,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build" />
<Reference Include="Microsoft.Build.Framework" />
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@ -70,6 +71,7 @@ @@ -70,6 +71,7 @@
<Compile Include="..\ICSharpCode.NRefactory\Properties\GlobalAssemblyInfo.cs">
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="CSharpFile.cs" />
<Compile Include="CSharpProject.cs" />
<Compile Include="FindReferencesConsistencyCheck.cs" />
<Compile Include="TypeSystemTests.cs" />

4
ICSharpCode.NRefactory.ConsistencyCheck/Program.cs

@ -52,8 +52,8 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -52,8 +52,8 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
}
Console.WriteLine("Loaded {0} lines of code ({1:f1} MB) in {2} files in {3} projects.",
solution.AllFiles.Sum(f => f.LinesOfCode),
solution.AllFiles.Sum(f => f.Content.TextLength) / 1024.0 / 1024.0,
solution.AllFiles.Sum(f => 1 + f.OriginalText.Count(c => c == '\n')),
solution.AllFiles.Sum(f => f.OriginalText.Length) / 1024.0 / 1024.0,
solution.AllFiles.Count(),
solution.Projects.Count);

4
ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs

@ -45,9 +45,9 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -45,9 +45,9 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
Random rnd = new Random(seed);
var test = new RandomizedOrderResolverTest();
// Resolve all nodes, but in a random order without using a navigator.
test.resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile);
test.resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedTypeSystemForFile);
// For comparing whether the results are equivalent, we also use a normal 'resolve all' resolver:
test.resolveAllResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile);
test.resolveAllResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedTypeSystemForFile);
test.resolveAllResolver.ApplyNavigator(new ResolveAllNavigator(), CancellationToken.None);
// Prepare list of actions that we need to verify:
var actions = new List<Func<bool>>();

4
ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
{
public static void RunTest(CSharpFile file)
{
CSharpAstResolver resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile);
CSharpAstResolver resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedTypeSystemForFile);
var navigator = new ValidatingResolveAllNavigator(file.FileName);
resolver.ApplyNavigator(navigator, CancellationToken.None);
navigator.Validate(resolver, file.SyntaxTree);
@ -109,7 +109,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -109,7 +109,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
resolver.ApplyNavigator(navigator, CancellationToken.None);
navigator.Validate(resolver, file.SyntaxTree);
CSharpAstResolver originalResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile);
CSharpAstResolver originalResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedTypeSystemForFile);
foreach (var node in file.SyntaxTree.DescendantsAndSelf) {
var originalResult = originalResolver.Resolve(node);
var result = resolver.Resolve(node);

2
ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs

@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
{
public static void RunTest(CSharpFile file)
{
string code = file.Content.Text.Replace("\r\n", "\n");
string code = file.OriginalText.Replace("\r\n", "\n");
Debug.Assert(code.IndexOf('\r') < 0);
if (code.Contains("#pragma"))
return; // skip code with preprocessor directives

23
ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs

@ -17,12 +17,14 @@ @@ -17,12 +17,14 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.ConsistencyCheck
{
@ -62,6 +64,25 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -62,6 +64,25 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
}
}
}
// Create compilations (resolved type systems) after all projects have been loaded.
// (we can't do this earlier because project A might have a reference to project B, where A is loaded before B)
// To allow NRefactory to resolve project references, we need to use a 'DefaultSolutionSnapshot'
// instead of calling CreateCompilation() on each project individually.
var solutionSnapshot = new DefaultSolutionSnapshot(this.Projects.Select(p => p.ProjectContent));
foreach (CSharpProject project in this.Projects) {
project.Compilation = solutionSnapshot.GetCompilation(project.ProjectContent);
}
}
ConcurrentDictionary<string, IUnresolvedAssembly> assemblyDict = new ConcurrentDictionary<string, IUnresolvedAssembly>(Platform.FileNameComparer);
/// <summary>
/// Loads a referenced assembly from a .dll.
/// Returns the existing instance if the assembly was already loaded.
/// </summary>
public IUnresolvedAssembly LoadAssembly(string assemblyFileName)
{
return assemblyDict.GetOrAdd(assemblyFileName, file => new CecilLoader().LoadAssemblyFile(file));
}
}
}

8
ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -38,7 +38,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
IUnresolvedFile GetFile(string fileName);
/// <summary>
/// Gets the list of all parsed files in the project content.
/// Gets the list of all files in the project content.
/// </summary>
IEnumerable<IUnresolvedFile> Files { get; }
@ -113,12 +113,18 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -113,12 +113,18 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Adds the specified files to the project content.
/// If a file with the same name already exists, updated the existing file.
/// </summary>
/// <remarks>
/// You can create an unresolved file by calling <c>ToTypeSystem()</c> on a syntax tree.
/// </remarks>
IProjectContent AddOrUpdateFiles(IEnumerable<IUnresolvedFile> newFiles);
/// <summary>
/// Adds the specified files to the project content.
/// If a file with the same name already exists, this method updates the existing file.
/// </summary>
/// <remarks>
/// You can create an unresolved file by calling <c>ToTypeSystem()</c> on a syntax tree.
/// </remarks>
IProjectContent AddOrUpdateFiles(params IUnresolvedFile[] newFiles);
/// <summary>

9
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs

@ -87,14 +87,5 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -87,14 +87,5 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
protected virtual void FreezeInternal()
{
}
/*
protected static IList<T> CopyList<T>(IList<T> inputList)
{
if (inputList == null || inputList.Count == 0)
return null;
else
return new List<T>(inputList);
}*/
}
}

2
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
public DefaultAssemblyReference(string assemblyName)
{
int pos = assemblyName.IndexOf(',');
int pos = assemblyName != null ? assemblyName.IndexOf(',') : -1;
if (pos >= 0)
shortName = assemblyName.Substring(0, pos);
else

Loading…
Cancel
Save