From 9a9485a49dd58e1dbf7ba8ff917f89214dd6b4ee Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 3 Aug 2012 18:15:18 +0200 Subject: [PATCH 1/6] Add ProjectReference class to NRefactory to simplify creating the type system for a solution with multiple projects. --- .../CSharpProjectContent.cs | 18 +++++- .../Resolver/ExplicitConversionsTest.cs | 1 + .../ICSharpCode.NRefactory.Tests.csproj | 1 + .../TypeSystem/CyclicProjectDependency.cs | 64 +++++++++++++++++++ .../ICSharpCode.NRefactory.csproj | 3 +- .../DefaultSolutionSnapshot.cs | 33 +++++++++- .../TypeSystem/IProjectContent.cs | 20 +++++- .../TypeSystem/ISolutionSnapshot.cs | 10 +++ .../Implementation/MinimalCorlib.cs | 3 - .../Implementation/SimpleCompilation.cs | 3 - .../TypeSystem/ProjectReference.cs | 56 ++++++++++++++++ 11 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs rename ICSharpCode.NRefactory/TypeSystem/{Implementation => }/DefaultSolutionSnapshot.cs (67%) create mode 100644 ICSharpCode.NRefactory/TypeSystem/ProjectReference.cs diff --git a/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs b/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs index a890c1ea41..2dfac4a1ad 100644 --- a/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs +++ b/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs @@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp public class CSharpProjectContent : IProjectContent { string assemblyName; + string projectFileName; string location; Dictionary parsedFiles; List assemblyReferences; @@ -38,7 +39,6 @@ namespace ICSharpCode.NRefactory.CSharp public CSharpProjectContent() { - this.assemblyName = string.Empty; this.parsedFiles = new Dictionary(Platform.FileNameComparer); this.assemblyReferences = new List(); this.compilerSettings = new CompilerSettings(); @@ -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(pc.parsedFiles, Platform.FileNameComparer); this.assemblyReferences = new List(pc.assemblyReferences); @@ -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 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; } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs index c72d67312b..f8395cdabf 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ExplicitConversionsTest.cs @@ -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[]))); diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 7f1bbcdb46..66900628a5 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -234,6 +234,7 @@ + diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs new file mode 100644 index 0000000000..f734002859 --- /dev/null +++ b/ICSharpCode.NRefactory.Tests/TypeSystem/CyclicProjectDependency.cs @@ -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()); + } + } +} diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 50ec131c12..d648f746e0 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -136,6 +136,7 @@ + @@ -170,7 +171,6 @@ - @@ -222,6 +222,7 @@ + diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs b/ICSharpCode.NRefactory/TypeSystem/DefaultSolutionSnapshot.cs similarity index 67% rename from ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs rename to ICSharpCode.NRefactory/TypeSystem/DefaultSolutionSnapshot.cs index f32676c220..16d07a08dc 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultSolutionSnapshot.cs +++ b/ICSharpCode.NRefactory/TypeSystem/DefaultSolutionSnapshot.cs @@ -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 { /// /// Default implementation of ISolutionSnapshot. /// public class DefaultSolutionSnapshot : ISolutionSnapshot { + readonly Dictionary projectDictionary = new Dictionary(Platform.FileNameComparer); ConcurrentDictionary dictionary = new ConcurrentDictionary(); + /// + /// Creates a new DefaultSolutionSnapshot with the specified projects. + /// + public DefaultSolutionSnapshot(IEnumerable projects) + { + foreach (var project in projects) { + if (project.ProjectFileName != null) + projectDictionary.Add(project.ProjectFileName, project); + } + } + + /// + /// Creates a new DefaultSolutionSnapshot that does not support s. + /// + 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) diff --git a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs index 4a731c42ce..120701d04b 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs @@ -27,6 +27,11 @@ namespace ICSharpCode.NRefactory.TypeSystem /// public interface IProjectContent : IUnresolvedAssembly { + /// + /// Gets the path to the project file (e.g. .csproj). + /// + string ProjectFileName { get; } + /// /// Gets a parsed file by its file name. /// @@ -52,7 +57,8 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Creates a new that allows resolving within this project. /// /// - /// An ICompilation is immutable, it operates on a snapshot of this project. + /// This method does not support s. When dealing with a solution + /// containing multiple projects, consider using instead. /// ICompilation CreateCompilation(); @@ -61,7 +67,10 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The parent solution snapshot to use for the compilation. /// - /// 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 instead. + /// This method always creates a new compilation, even if the solution snapshot already contains + /// one for this project. /// ICompilation CreateCompilation(ISolutionSnapshot solutionSnapshot); @@ -71,7 +80,12 @@ namespace ICSharpCode.NRefactory.TypeSystem IProjectContent SetAssemblyName(string newAssemblyName); /// - /// Changes the location of this project content. + /// Changes the project file name of this project content. + /// + IProjectContent SetProjectFileName(string newProjectFileName); + + /// + /// Changes the path to the assembly location (the output path where the project compiles to). /// IProjectContent SetLocation(string newLocation); diff --git a/ICSharpCode.NRefactory/TypeSystem/ISolutionSnapshot.cs b/ICSharpCode.NRefactory/TypeSystem/ISolutionSnapshot.cs index 052dc1a798..888233d0e0 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ISolutionSnapshot.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ISolutionSnapshot.cs @@ -25,8 +25,18 @@ namespace ICSharpCode.NRefactory.TypeSystem /// public interface ISolutionSnapshot { + /// + /// Gets the project content with the specified file name. + /// Returns null if no such project exists in the solution. + /// + /// + /// This method is used by the class. + /// + IProjectContent GetProjectContent(string projectFileName); + /// /// Gets the compilation for the specified project. + /// The project must be a part of the solution (passed to the solution snapshot's constructor). /// ICompilation GetCompilation(IProjectContent project); } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs index a6c90a6e88..0c019b06ac 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/MinimalCorlib.cs @@ -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 { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs index 08c5eb6d8b..cfff5fae10 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs @@ -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 } } - [ObsoleteAttribute("Use compilation.Assemblies.Where(asm != compilation.MainAssembly) instead.")] public IList ReferencedAssemblies { get { if (referencedAssemblies == null) diff --git a/ICSharpCode.NRefactory/TypeSystem/ProjectReference.cs b/ICSharpCode.NRefactory/TypeSystem/ProjectReference.cs new file mode 100644 index 0000000000..928ec796de --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ProjectReference.cs @@ -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 +{ + /// + /// References another project content in the same solution. + /// Using the class requires that you + /// + [Serializable] + public class ProjectReference : IAssemblyReference + { + readonly string projectFileName; + + /// + /// Creates a new reference to the specified project (must be part of the same solution). + /// + /// Full path to the file name. Must be identical to of the target project; do not use a relative path. + 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); + } + } +} From 7a3b25b4dc85643ec1550e68afda45c864e370cf Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 3 Aug 2012 18:15:32 +0200 Subject: [PATCH 2/6] Add WriteTextTo() method to ITextSource. --- ICSharpCode.NRefactory/Editor/ITextSource.cs | 10 ++++++ .../Editor/ReadOnlyDocument.cs | 12 +++++++ .../Editor/StringBuilderDocument.cs | 34 +++++++++++++++++++ .../Editor/StringTextSource.cs | 12 +++++++ 4 files changed, 68 insertions(+) diff --git a/ICSharpCode.NRefactory/Editor/ITextSource.cs b/ICSharpCode.NRefactory/Editor/ITextSource.cs index c8810571de..148aee0d29 100644 --- a/ICSharpCode.NRefactory/Editor/ITextSource.cs +++ b/ICSharpCode.NRefactory/Editor/ITextSource.cs @@ -94,6 +94,16 @@ namespace ICSharpCode.NRefactory.Editor /// offset or length is outside the valid range. string GetText(ISegment segment); + /// + /// Writes the text from this document into the TextWriter. + /// + void WriteTextTo(TextWriter writer); + + /// + /// Writes the text from this document into the TextWriter. + /// + void WriteTextTo(TextWriter writer, int offset, int length); + /// /// Gets the index of the first occurrence of the character in the specified array. /// diff --git a/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs b/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs index 2a36ccda33..0cc4b68dc5 100644 --- a/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs +++ b/ICSharpCode.NRefactory/Editor/ReadOnlyDocument.cs @@ -359,6 +359,18 @@ namespace ICSharpCode.NRefactory.Editor return textSource.CreateReader(offset, length); } + /// + public void WriteTextTo(System.IO.TextWriter writer) + { + textSource.WriteTextTo(writer); + } + + /// + public void WriteTextTo(System.IO.TextWriter writer, int offset, int length) + { + textSource.WriteTextTo(writer, offset, length); + } + /// public char GetCharAt(int offset) { diff --git a/ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs b/ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs index f69070a196..d310f34c4a 100644 --- a/ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs +++ b/ICSharpCode.NRefactory/Editor/StringBuilderDocument.cs @@ -41,11 +41,27 @@ namespace ICSharpCode.NRefactory.Editor b = new StringBuilder(); } + /// + /// Creates a new StringBuilderDocument with the specified initial text. + /// public StringBuilderDocument(string text) { + if (text == null) + throw new ArgumentNullException("text"); b = new StringBuilder(text); } + /// + /// Creates a new StringBuilderDocument with the initial text copied from the specified text source. + /// + public StringBuilderDocument(ITextSource textSource) + { + if (textSource == null) + throw new ArgumentNullException("textSource"); + b = new StringBuilder(textSource.TextLength); + textSource.WriteTextTo(new StringWriter(b)); + } + /// public event EventHandler TextChanging; @@ -273,6 +289,22 @@ namespace ICSharpCode.NRefactory.Editor { return new StringReader(GetText(offset, length)); } + + /// + public void WriteTextTo(TextWriter writer) + { + if (writer == null) + throw new ArgumentNullException("writer"); + writer.Write(this.Text); + } + + /// + public void WriteTextTo(TextWriter writer, int offset, int length) + { + if (writer == null) + throw new ArgumentNullException("writer"); + writer.Write(GetText(offset, length)); + } #endregion #region GetText / IndexOf @@ -310,6 +342,8 @@ namespace ICSharpCode.NRefactory.Editor /// public string GetText(ISegment segment) { + if (segment == null) + throw new ArgumentNullException("segment"); return b.ToString(segment.Offset, segment.Length); } diff --git a/ICSharpCode.NRefactory/Editor/StringTextSource.cs b/ICSharpCode.NRefactory/Editor/StringTextSource.cs index 36780954bd..99a81f02a7 100644 --- a/ICSharpCode.NRefactory/Editor/StringTextSource.cs +++ b/ICSharpCode.NRefactory/Editor/StringTextSource.cs @@ -95,6 +95,18 @@ namespace ICSharpCode.NRefactory.Editor return new StringReader(text.Substring(offset, length)); } + /// + public void WriteTextTo(TextWriter writer) + { + writer.Write(text); + } + + /// + public void WriteTextTo(TextWriter writer, int offset, int length) + { + writer.Write(text.Substring(offset, length)); + } + /// public char GetCharAt(int offset) { From 4a6a43d0d156ae45c5ae5fe9e4d6d4da4a41970c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 3 Aug 2012 19:09:58 +0200 Subject: [PATCH 3/6] Change output path - build everything into \bin\Debug in NRefactory directory (not into ICSharpCode.NRefactory subdirectory). --- .gitignore | 2 + .../.gitignore | 3 - ICSharpCode.NRefactory.CSharp/.gitignore | 3 - .../ICSharpCode.NRefactory.CSharp.csproj | 7 +-- .../.gitignore | 3 - ...arpCode.NRefactory.ConsistencyCheck.csproj | 11 +--- ICSharpCode.NRefactory.Demo/.gitignore | 3 - .../ICSharpCode.NRefactory.Demo.csproj | 15 ++--- ICSharpCode.NRefactory.GtkDemo/.gitignore | 3 - ICSharpCode.NRefactory.Tests/.gitignore | 3 - .../ICSharpCode.NRefactory.Tests.csproj | 59 ++----------------- ICSharpCode.NRefactory.VB.Tests/.gitignore | 3 - ICSharpCode.NRefactory.VB/.gitignore | 3 - ICSharpCode.NRefactory.Xml/.gitignore | 3 - .../ICSharpCode.NRefactory.Xml.csproj | 11 ++-- ICSharpCode.NRefactory/.gitignore | 3 - .../ICSharpCode.NRefactory.csproj | 11 ++-- 17 files changed, 25 insertions(+), 121 deletions(-) delete mode 100644 ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore delete mode 100644 ICSharpCode.NRefactory.CSharp/.gitignore delete mode 100644 ICSharpCode.NRefactory.ConsistencyCheck/.gitignore delete mode 100644 ICSharpCode.NRefactory.Demo/.gitignore delete mode 100644 ICSharpCode.NRefactory.GtkDemo/.gitignore delete mode 100644 ICSharpCode.NRefactory.Tests/.gitignore delete mode 100644 ICSharpCode.NRefactory.VB.Tests/.gitignore delete mode 100644 ICSharpCode.NRefactory.VB/.gitignore delete mode 100644 ICSharpCode.NRefactory.Xml/.gitignore delete mode 100644 ICSharpCode.NRefactory/.gitignore diff --git a/.gitignore b/.gitignore index 1027b084e5..0031dcbe29 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +bin +obj /lib/*.dll /ICSharpCode.NRefactory.Tests/PartCover/* _ReSharper*/* diff --git a/ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore b/ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.CSharp/.gitignore b/ICSharpCode.NRefactory.CSharp/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.CSharp/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index 40f1c5eedc..f41d9e706f 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -18,8 +18,9 @@ ..\ICSharpCode.NRefactory.snk False File - ..\ICSharpCode.NRefactory\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml + ..\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml 1591,1587,1570 + ..\bin\$(Configuration)\ AnyCPU @@ -29,13 +30,11 @@ 4096 - ..\ICSharpCode.NRefactory\bin\Debug\ False False DEBUG;TRACE;FULL_AST - ..\ICSharpCode.NRefactory\bin\Release\ True False TRACE;FULL_AST @@ -48,7 +47,6 @@ True - ..\ICSharpCode.NRefactory\bin\Debug\ False False DEBUG;TRACE;FULL_AST;NET45 @@ -59,7 +57,6 @@ True - ..\ICSharpCode.NRefactory\bin\Release\ True False TRACE;FULL_AST;NET45 diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/.gitignore b/ICSharpCode.NRefactory.ConsistencyCheck/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.ConsistencyCheck/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj b/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj index e125b6b5ab..9b331997fc 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj +++ b/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj @@ -15,12 +15,12 @@ False 4 false + bin\$(Configuration)\ x86 - bin\Debug\ true Full False @@ -28,9 +28,7 @@ DEBUG;TRACE - bin\Release\ - False - None + PdbOnly True False TRACE @@ -39,7 +37,6 @@ AnyCPU - bin\Debug\ true Full False @@ -48,9 +45,7 @@ v4.5 - bin\Release\ - False - None + PdbOnly True False TRACE diff --git a/ICSharpCode.NRefactory.Demo/.gitignore b/ICSharpCode.NRefactory.Demo/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.Demo/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj b/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj index 87e5417f75..0773ff3946 100644 --- a/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj +++ b/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj @@ -10,12 +10,12 @@ Properties 10.0.0 2.0 + ..\bin\$(Configuration)\ x86 - bin\Debug\ True Full False @@ -23,9 +23,7 @@ DEBUG;TRACE - bin\Release\ - False - None + PdbOnly True False TRACE @@ -46,13 +44,12 @@ 4 - bin\Debug\ True Full False True DEBUG;TRACE - v4.5 + v4.5 4 @@ -61,13 +58,11 @@ 4 - bin\Release\ - False - None + PdbOnly True False TRACE - v4.5 + v4.5 4 diff --git a/ICSharpCode.NRefactory.GtkDemo/.gitignore b/ICSharpCode.NRefactory.GtkDemo/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.GtkDemo/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Tests/.gitignore b/ICSharpCode.NRefactory.Tests/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.Tests/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 66900628a5..2bd1636f38 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -14,9 +14,9 @@ False 4 false + ..\bin\$(Configuration)\ - bin\Debug\ true Full False @@ -24,49 +24,26 @@ DEBUG;TRACE - bin\Release\ - False - None + PdbOnly True False TRACE - - ..\ICSharpCode.NRefactory\bin\Debug\ - False - Auto - 4194304 - 4096 - AnyCPU - - - ..\ICSharpCode.NRefactory\bin\Release\ + False Auto 4194304 4096 AnyCPU - - AnyCPU + False Auto 4194304 4096 - - - ..\ICSharpCode.NRefactory\bin\Debug\ - x86 - - - ..\ICSharpCode.NRefactory\bin\Release\ - x86 - - x86 - bin\Debug\ true Full False @@ -74,39 +51,13 @@ DEBUG;TRACE;NET45 v4.5 - - ..\ICSharpCode.NRefactory\bin\Debug\ - False - Auto - 4194304 - 4096 - AnyCPU - - - ..\ICSharpCode.NRefactory\bin\Debug\ - x86 - - bin\Release\ - False - None + PdbOnly True False TRACE;NET45 v4.5 - - ..\ICSharpCode.NRefactory\bin\Release\ - False - Auto - 4194304 - 4096 - AnyCPU - - - ..\ICSharpCode.NRefactory\bin\Release\ - x86 - diff --git a/ICSharpCode.NRefactory.VB.Tests/.gitignore b/ICSharpCode.NRefactory.VB.Tests/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.VB.Tests/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.VB/.gitignore b/ICSharpCode.NRefactory.VB/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.VB/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Xml/.gitignore b/ICSharpCode.NRefactory.Xml/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory.Xml/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj index 603112ad9c..bd4cc4b338 100644 --- a/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj +++ b/ICSharpCode.NRefactory.Xml/ICSharpCode.NRefactory.Xml.csproj @@ -12,13 +12,14 @@ False 4 false - ..\ICSharpCode.NRefactory\bin\$(Configuration)\ICSharpCode.NRefactory.Xml.xml true ..\ICSharpCode.NRefactory.snk False File 10.0.0 2.0 + ..\bin\$(Configuration)\ + ..\bin\$(Configuration)\ICSharpCode.NRefactory.Xml.xml AnyCPU @@ -28,13 +29,11 @@ 4096 - ..\ICSharpCode.NRefactory\bin\Debug\ False True DEBUG;TRACE - ..\ICSharpCode.NRefactory\bin\Release\ True False TRACE @@ -48,22 +47,20 @@ false - ..\ICSharpCode.NRefactory\bin\Debug\ False True DEBUG;TRACE;NET45 - v4.5 + v4.5 full true - ..\ICSharpCode.NRefactory\bin\Release\ True False TRACE;NET45 - v4.5 + v4.5 PdbOnly diff --git a/ICSharpCode.NRefactory/.gitignore b/ICSharpCode.NRefactory/.gitignore deleted file mode 100644 index 9ce745d95d..0000000000 --- a/ICSharpCode.NRefactory/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ - -bin/ -obj/ \ No newline at end of file diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index d648f746e0..7799ed8acb 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -19,9 +19,10 @@ ..\ICSharpCode.NRefactory.snk False File - bin\$(Configuration)\ICSharpCode.NRefactory.xml 4 1591 + ..\bin\$(Configuration)\ + ..\bin\$(Configuration)\ICSharpCode.NRefactory.xml AnyCPU @@ -31,14 +32,12 @@ 4096 - bin\Debug\ False DEBUG;TRACE True Project - bin\Release\ True TRACE False @@ -48,10 +47,9 @@ True - none + PdbOnly - bin\Debug\ False DEBUG;TRACE;NET45 True @@ -63,14 +61,13 @@ True - bin\Release\ True TRACE;NET45 False v4.5 - none + PdbOnly From 16aa0c6c286a552a6fe86bb09b3dabbe2cae415d Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Fri, 3 Aug 2012 20:04:26 +0200 Subject: [PATCH 4/6] Rename IParsedFile -> IUnresolvedFile to make clear it belongs to the unresolved type system. --- .../Ast/SyntaxTree.cs | 4 +- .../CSharpProjectContent.cs | 85 +++++++++++++++---- .../Completion/CSharpCompletionEngine.cs | 4 +- .../Completion/CSharpCompletionEngineBase.cs | 4 +- .../Completion/ICompletionContextProvider.cs | 16 ++-- .../ICSharpCode.NRefactory.CSharp.csproj | 2 +- .../OutputVisitor/CodeDomConvertVisitor.cs | 6 +- .../Refactoring/BaseRefactoringContext.cs | 4 +- .../CodeActions/InlineLocalVariableAction.cs | 2 +- .../Resolver/CSharpAstResolver.cs | 30 +++---- .../Resolver/FindReferences.cs | 54 ++++++------ .../Resolver/ResolveAtLocation.cs | 16 ++-- .../Resolver/ResolveVisitor.cs | 40 ++++----- .../TypeSystem/CSharpAssembly.cs | 6 +- ...pParsedFile.cs => CSharpUnresolvedFile.cs} | 8 +- .../TypeSystem/TypeSystemConvertVisitor.cs | 38 ++++----- .../CSharpProject.cs | 26 +----- .../FindReferencesConsistencyCheck.cs | 10 +-- .../Program.cs | 2 +- .../RandomizedOrderResolverTest.cs | 4 +- .../ResolverTest.cs | 8 +- .../VisitorBenchmark.cs | 5 -- ICSharpCode.NRefactory.Demo/CSDemo.cs | 16 ++-- ICSharpCode.NRefactory.GtkDemo/MainWindow.cs | 6 +- .../CodeActions/TestRefactoringContext.cs | 12 +-- .../CodeCompletion/CodeCompletionBugTests.cs | 16 ++-- .../ParameterCompletionTests.cs | 12 +-- .../CSharp/CodeDomConvertVisitorTests.cs | 12 +-- .../CSharp/Parser/ParseSelfTests.cs | 10 +-- .../Parser/TypeSystemConvertVisitorTests.cs | 4 +- .../Refactoring/TypeSystemAstBuilderTests.cs | 8 +- .../CSharp/Resolver/FindReferencesTest.cs | 8 +- .../CSharp/Resolver/MemberLookupTests.cs | 20 ++--- .../CSharp/Resolver/ResolverTestBase.cs | 12 +-- .../Documentation/CSharpCrefLookupTests.cs | 2 +- .../Documentation/CSharpDocumentationTests.cs | 2 +- .../TypeSystem/GetAllBaseTypesTest.cs | 4 +- .../TypeSystem/TypeSystemHelper.cs | 12 +-- .../ICSharpCode.NRefactory.csproj | 2 +- .../TypeSystem/ExtensionMethods.cs | 6 +- ICSharpCode.NRefactory/TypeSystem/IEntity.cs | 2 +- .../TypeSystem/IProjectContent.cs | 42 ++++++++- .../{IParsedFile.cs => IUnresolvedFile.cs} | 5 +- .../Implementation/AbstractResolvedMember.cs | 2 +- .../AbstractUnresolvedEntity.cs | 8 +- .../DefaultResolvedTypeDefinition.cs | 2 +- .../Implementation/DefaultUnresolvedEvent.cs | 2 +- .../Implementation/DefaultUnresolvedField.cs | 2 +- .../Implementation/DefaultUnresolvedMethod.cs | 2 +- .../DefaultUnresolvedProperty.cs | 2 +- .../DefaultUnresolvedTypeDefinition.cs | 2 +- doc/XML Documentation.html | 2 +- 52 files changed, 340 insertions(+), 271 deletions(-) rename ICSharpCode.NRefactory.CSharp/TypeSystem/{CSharpParsedFile.cs => CSharpUnresolvedFile.cs} (95%) rename ICSharpCode.NRefactory/TypeSystem/{IParsedFile.cs => IUnresolvedFile.cs} (95%) diff --git a/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs b/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs index 2fc1405dee..2906696b36 100644 --- a/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs +++ b/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs @@ -146,13 +146,13 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Converts this syntax tree into a parsed file that can be stored in the type system. /// - public CSharpParsedFile ToTypeSystem () + public CSharpUnresolvedFile ToTypeSystem () { if (string.IsNullOrEmpty (this.FileName)) throw new InvalidOperationException ("Cannot use ToTypeSystem() on a syntax tree without file name."); var v = new TypeSystemConvertVisitor (this.FileName); v.VisitSyntaxTree (this); - return v.ParsedFile; + return v.UnresolvedFile; } public static SyntaxTree Parse (string program, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) diff --git a/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs b/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs index 2dfac4a1ad..fccba4622f 100644 --- a/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs +++ b/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs @@ -33,13 +33,13 @@ namespace ICSharpCode.NRefactory.CSharp string assemblyName; string projectFileName; string location; - Dictionary parsedFiles; + Dictionary unresolvedFiles; List assemblyReferences; CompilerSettings compilerSettings; public CSharpProjectContent() { - this.parsedFiles = new Dictionary(Platform.FileNameComparer); + this.unresolvedFiles = new Dictionary(Platform.FileNameComparer); this.assemblyReferences = new List(); this.compilerSettings = new CompilerSettings(); compilerSettings.Freeze(); @@ -50,13 +50,13 @@ namespace ICSharpCode.NRefactory.CSharp this.assemblyName = pc.assemblyName; this.projectFileName = pc.projectFileName; this.location = pc.location; - this.parsedFiles = new Dictionary(pc.parsedFiles, Platform.FileNameComparer); + this.unresolvedFiles = new Dictionary(pc.unresolvedFiles, Platform.FileNameComparer); this.assemblyReferences = new List(pc.assemblyReferences); this.compilerSettings = pc.compilerSettings; } - public IEnumerable Files { - get { return parsedFiles.Values; } + public IEnumerable Files { + get { return unresolvedFiles.Values; } } public IEnumerable AssemblyReferences { @@ -101,10 +101,10 @@ namespace ICSharpCode.NRefactory.CSharp } } - public IParsedFile GetFile(string fileName) + public IUnresolvedFile GetFile(string fileName) { - IParsedFile file; - if (parsedFiles.TryGetValue(fileName, out file)) + IUnresolvedFile file; + if (unresolvedFiles.TryGetValue(fileName, out file)) return file; else return null; @@ -160,6 +160,11 @@ namespace ICSharpCode.NRefactory.CSharp } public IProjectContent AddAssemblyReferences(IEnumerable references) + { + return AddAssemblyReferences(references.ToArray()); + } + + public IProjectContent AddAssemblyReferences(params IAssemblyReference[] references) { CSharpProjectContent pc = Clone(); pc.assemblyReferences.AddRange(references); @@ -167,13 +172,62 @@ namespace ICSharpCode.NRefactory.CSharp } public IProjectContent RemoveAssemblyReferences(IEnumerable references) + { + return RemoveAssemblyReferences(references.ToArray()); + } + + public IProjectContent RemoveAssemblyReferences(params IAssemblyReference[] references) + { + CSharpProjectContent pc = Clone(); + foreach (var r in references) + pc.assemblyReferences.Remove(r); + return pc; + } + + /// + /// Adds the specified files to the project content. + /// If a file with the same name already exists, updated the existing file. + /// + public IProjectContent AddOrUpdateFiles(IEnumerable newFiles) + { + CSharpProjectContent pc = Clone(); + foreach (var file in newFiles) { + pc.unresolvedFiles[file.FileName] = file; + } + return pc; + } + + /// + /// Adds the specified files to the project content. + /// If a file with the same name already exists, this method updates the existing file. + /// + public IProjectContent AddOrUpdateFiles(params IUnresolvedFile[] newFiles) + { + return AddOrUpdateFiles((IEnumerable)newFiles); + } + + /// + /// Removes the files with the specified names. + /// + public IProjectContent RemoveFiles(IEnumerable fileNames) { CSharpProjectContent pc = Clone(); - pc.assemblyReferences.RemoveAll(r => references.Contains(r)); + foreach (var fileName in fileNames) { + pc.unresolvedFiles.Remove(fileName); + } return pc; } - public IProjectContent UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile) + /// + /// Removes the files with the specified names. + /// + public IProjectContent RemoveFiles(params string[] fileNames) + { + return RemoveFiles((IEnumerable)fileNames); + } + + [Obsolete("Use RemoveFiles/AddOrUpdateFiles instead")] + public IProjectContent UpdateProjectContent(IUnresolvedFile oldFile, IUnresolvedFile newFile) { if (oldFile == null && newFile == null) return this; @@ -183,23 +237,24 @@ namespace ICSharpCode.NRefactory.CSharp } CSharpProjectContent pc = Clone(); if (newFile == null) - pc.parsedFiles.Remove(oldFile.FileName); + pc.unresolvedFiles.Remove(oldFile.FileName); else - pc.parsedFiles[newFile.FileName] = newFile; + pc.unresolvedFiles[newFile.FileName] = newFile; return pc; } - public IProjectContent UpdateProjectContent(IEnumerable oldFiles, IEnumerable newFiles) + [Obsolete("Use RemoveFiles/AddOrUpdateFiles instead")] + public IProjectContent UpdateProjectContent(IEnumerable oldFiles, IEnumerable newFiles) { CSharpProjectContent pc = Clone(); if (oldFiles != null) { foreach (var oldFile in oldFiles) { - pc.parsedFiles.Remove(oldFile.FileName); + pc.unresolvedFiles.Remove(oldFile.FileName); } } if (newFiles != null) { foreach (var newFile in newFiles) { - pc.parsedFiles.Add(newFile.FileName, newFile); + pc.unresolvedFiles.Add(newFile.FileName, newFile); } } return pc; diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 32b776b823..4897520b12 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -723,7 +723,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion // var astResolver = new CSharpAstResolver( // GetState(), // identifierStart.Unit, - // CSharpParsedFile + // CSharpUnresolvedFile // ); // // foreach (var type in CreateFieldAction.GetValidTypes(astResolver, (Expression)n)) { @@ -1172,7 +1172,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (csResolver == null) { if (node != null) { csResolver = GetState(); - //var astResolver = new CSharpAstResolver (csResolver, node, xp != null ? xp.Item1 : CSharpParsedFile); + //var astResolver = new CSharpAstResolver (csResolver, node, xp != null ? xp.Item1 : CSharpUnresolvedFile); try { //csResolver = astResolver.GetResolverStateBefore (node); diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs index 8e36405a45..fa71c629e6 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -494,13 +494,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion state.CurrentMember = currentMember; state.CurrentTypeDefinition = currentType; - state.CurrentUsingScope = CSharpParsedFile.GetUsingScope (location); + state.CurrentUsingScope = CSharpUnresolvedFile.GetUsingScope (location); if (state.CurrentMember != null) { var node = Unit.GetNodeAt (location); if (node == null) return state; var navigator = new NodeListResolveVisitorNavigator (new[] { node }); - var visitor = new ResolveVisitor (state, CSharpParsedFile, navigator); + var visitor = new ResolveVisitor (state, CSharpUnresolvedFile, navigator); Unit.AcceptVisitor (visitor, null); try { var newState = visitor.GetResolverStateBefore (node); diff --git a/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs b/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs index b477dc1bbf..91ee3f2bba 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs @@ -1,4 +1,4 @@ -// +// // IMemberProvider.cs // // Author: @@ -45,16 +45,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion public class DefaultCompletionContextProvider : ICompletionContextProvider { readonly IDocument document; - readonly CSharpParsedFile parsedFile; + readonly CSharpUnresolvedFile unresolvedFile; - public DefaultCompletionContextProvider (IDocument document, CSharpParsedFile parsedFile) + public DefaultCompletionContextProvider (IDocument document, CSharpUnresolvedFile unresolvedFile) { if (document == null) throw new ArgumentNullException("document"); - if (parsedFile == null) - throw new ArgumentNullException("parsedFile"); + if (unresolvedFile == null) + throw new ArgumentNullException("unresolvedFile"); this.document = document; - this.parsedFile = parsedFile; + this.unresolvedFile = unresolvedFile; } public void GetCurrentMembers(int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember) @@ -64,7 +64,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion currentType = null; - foreach (var type in parsedFile.TopLevelTypeDefinitions) { + foreach (var type in unresolvedFile.TopLevelTypeDefinitions) { if (type.Region.Begin < location) currentType = type; } @@ -189,7 +189,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion public CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode) { - return new CSharpAstResolver (resolver, rootNode, parsedFile); + return new CSharpAstResolver (resolver, rootNode, unresolvedFile); } diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index f41d9e706f..f0d1294c9f 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -300,7 +300,7 @@ - + diff --git a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs index ca3e70ab5b..b7db647027 100644 --- a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs @@ -64,19 +64,19 @@ namespace ICSharpCode.NRefactory.CSharp /// /// The input syntax tree. /// The current compilation. - /// CSharpParsedFile, used for resolving. + /// CSharpUnresolvedFile, used for resolving. /// Converted CodeCompileUnit /// /// This conversion process requires a resolver because it needs to distinguish field/property/event references etc. /// - public CodeCompileUnit Convert(ICompilation compilation, SyntaxTree syntaxTree, CSharpParsedFile parsedFile) + public CodeCompileUnit Convert(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile) { if (syntaxTree == null) throw new ArgumentNullException("syntaxTree"); if (compilation == null) throw new ArgumentNullException("compilation"); - CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); return (CodeCompileUnit)Convert(syntaxTree, resolver); } diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs index 449be597dc..56c7487a1c 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/BaseRefactoringContext.cs @@ -72,9 +72,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring } } - public virtual CSharpParsedFile ParsedFile { + public virtual CSharpUnresolvedFile UnresolvedFile { get { - return resolver.ParsedFile; + return resolver.UnresolvedFile; } } diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InlineLocalVariableAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InlineLocalVariableAction.cs index 263e5570f8..a8bec696c8 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InlineLocalVariableAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/InlineLocalVariableAction.cs @@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring yield break; } yield return new CodeAction(context.TranslateString("Inline local variable"), script => { - refFinder.FindLocalReferences(resolveResult.Variable, context.ParsedFile, unit, context.Compilation, (n, r) => script.Replace(n, initializer.Initializer.Clone()), default(CancellationToken)); + refFinder.FindLocalReferences(resolveResult.Variable, context.UnresolvedFile, unit, context.Compilation, (n, r) => script.Replace(n, initializer.Initializer.Clone()), default(CancellationToken)); script.Remove(node); }); } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs index ae5d3478a1..2ddc57c691 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { readonly CSharpResolver initialResolverState; readonly AstNode rootNode; - readonly CSharpParsedFile parsedFile; + readonly CSharpUnresolvedFile unresolvedFile; readonly ResolveVisitor resolveVisitor; bool resolverInitialized; @@ -43,19 +43,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// The current compilation. /// The syntax tree corresponding to the specified parsed file. - /// + /// /// Optional: Result of the for the file being resolved. /// /// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation. /// /// - /// When a parsedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify + /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify /// member declarations in the AST with members in the type system. - /// When no parsedFile is specified (null value for this parameter), the resolver will instead compare the + /// When no unresolvedFile is specified (null value for this parameter), the resolver will instead compare the /// member's signature in the AST with the signature in the type system. /// /// - public CSharpAstResolver(ICompilation compilation, SyntaxTree syntaxTree, CSharpParsedFile parsedFile = null) + public CSharpAstResolver(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile = null) { if (compilation == null) throw new ArgumentNullException("compilation"); @@ -63,8 +63,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver throw new ArgumentNullException("syntaxTree"); this.initialResolverState = new CSharpResolver(compilation); this.rootNode = syntaxTree; - this.parsedFile = parsedFile; - this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile); + this.unresolvedFile = unresolvedFile; + this.resolveVisitor = new ResolveVisitor(initialResolverState, unresolvedFile); } /// @@ -73,19 +73,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// The resolver state at the root node (to be more precise: just outside the root node). /// The root node of the resolved tree. - /// + /// /// Optional: Result of the for the file being resolved. /// /// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation. /// /// - /// When a parsedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify + /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify /// member declarations in the AST with members in the type system. - /// When no parsedFile is specified (null value for this parameter), the resolver will instead compare the + /// When no unresolvedFile is specified (null value for this parameter), the resolver will instead compare the /// member's signature in the AST with the signature in the type system. /// /// - public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpParsedFile parsedFile = null) + public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpUnresolvedFile unresolvedFile = null) { if (resolver == null) throw new ArgumentNullException("resolver"); @@ -93,8 +93,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver throw new ArgumentNullException("rootNode"); this.initialResolverState = resolver; this.rootNode = rootNode; - this.parsedFile = parsedFile; - this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile); + this.unresolvedFile = unresolvedFile; + this.resolveVisitor = new ResolveVisitor(initialResolverState, unresolvedFile); } /// @@ -122,8 +122,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// Gets the parsed file used by this CSharpAstResolver. /// Can return null. /// - public CSharpParsedFile ParsedFile { - get { return parsedFile; } + public CSharpUnresolvedFile UnresolvedFile { + get { return unresolvedFile; } } /// diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs index d754e1b30a..c269f581d1 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs @@ -290,7 +290,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// Gets the file names that possibly contain references to the element being searched for. /// - public IEnumerable GetInterestingFiles(IFindReferenceSearchScope searchScope, ICompilation compilation) + public IEnumerable GetInterestingFiles(IFindReferenceSearchScope searchScope, ICompilation compilation) { if (searchScope == null) throw new ArgumentNullException("searchScope"); @@ -303,47 +303,47 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver ITypeDefinition topLevelTypeDef = compilation.Import(searchScope.TopLevelTypeDefinition); if (topLevelTypeDef == null) { // This compilation cannot have references to the target entity. - return EmptyList.Instance; + return EmptyList.Instance; } switch (searchScope.Accessibility) { case Accessibility.None: case Accessibility.Private: if (topLevelTypeDef.ParentAssembly == compilation.MainAssembly) - return topLevelTypeDef.Parts.Select(p => p.ParsedFile).OfType().Distinct(); + return topLevelTypeDef.Parts.Select(p => p.UnresolvedFile).OfType().Distinct(); else - return EmptyList.Instance; + return EmptyList.Instance; case Accessibility.Protected: return GetInterestingFilesProtected(topLevelTypeDef); case Accessibility.Internal: if (topLevelTypeDef.ParentAssembly.InternalsVisibleTo(compilation.MainAssembly)) - return pc.Files.OfType(); + return pc.Files.OfType(); else - return EmptyList.Instance; + return EmptyList.Instance; case Accessibility.ProtectedAndInternal: if (topLevelTypeDef.ParentAssembly.InternalsVisibleTo(compilation.MainAssembly)) return GetInterestingFilesProtected(topLevelTypeDef); else - return EmptyList.Instance; + return EmptyList.Instance; case Accessibility.ProtectedOrInternal: if (topLevelTypeDef.ParentAssembly.InternalsVisibleTo(compilation.MainAssembly)) - return pc.Files.OfType(); + return pc.Files.OfType(); else return GetInterestingFilesProtected(topLevelTypeDef); default: - return pc.Files.OfType(); + return pc.Files.OfType(); } } else { - return pc.Files.OfType(); + return pc.Files.OfType(); } } - IEnumerable GetInterestingFilesProtected(ITypeDefinition referencedTypeDefinition) + IEnumerable GetInterestingFilesProtected(ITypeDefinition referencedTypeDefinition) { return (from typeDef in referencedTypeDefinition.Compilation.MainAssembly.GetAllTypeDefinitions() where typeDef.IsDerivedFrom(referencedTypeDefinition) from part in typeDef.Parts - select part.ParsedFile - ).OfType().Distinct(); + select part.UnresolvedFile + ).OfType().Distinct(); } #endregion @@ -352,35 +352,35 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// Finds all references in the given file. /// /// The search scope for which to look. - /// The type system representation of the file being searched. + /// The type system representation of the file being searched. /// The syntax tree of the file being searched. /// The compilation for the project that contains the file. /// Callback used to report the references that were found. /// CancellationToken that may be used to cancel the operation. - public void FindReferencesInFile(IFindReferenceSearchScope searchScope, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, + public void FindReferencesInFile(IFindReferenceSearchScope searchScope, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken) { if (searchScope == null) throw new ArgumentNullException("searchScope"); - FindReferencesInFile(new[] { searchScope }, parsedFile, syntaxTree, compilation, callback, cancellationToken); + FindReferencesInFile(new[] { searchScope }, unresolvedFile, syntaxTree, compilation, callback, cancellationToken); } /// /// Finds all references in the given file. /// /// The search scopes for which to look. - /// The type system representation of the file being searched. + /// The type system representation of the file being searched. /// The syntax tree of the file being searched. /// The compilation for the project that contains the file. /// Callback used to report the references that were found. /// CancellationToken that may be used to cancel the operation. - public void FindReferencesInFile(IList searchScopes, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, + public void FindReferencesInFile(IList searchScopes, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken) { if (searchScopes == null) throw new ArgumentNullException("searchScopes"); - if (parsedFile == null) - throw new ArgumentNullException("parsedFile"); + if (unresolvedFile == null) + throw new ArgumentNullException("unresolvedFile"); if (syntaxTree == null) throw new ArgumentNullException("syntaxTree"); if (compilation == null) @@ -404,7 +404,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver cancellationToken.ThrowIfCancellationRequested(); combinedNavigator = new DetectSkippableNodesNavigator(combinedNavigator, syntaxTree); cancellationToken.ThrowIfCancellationRequested(); - CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); resolver.ApplyNavigator(combinedNavigator, cancellationToken); foreach (var n in navigators) { var frn = n as FindReferenceNavigator; @@ -1171,19 +1171,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// Finds all references of a given variable. /// /// The variable for which to look. - /// The type system representation of the file being searched. + /// The type system representation of the file being searched. /// The syntax tree of the file being searched. /// The compilation. /// Callback used to report the references that were found. /// Cancellation token that may be used to cancel the operation. - public void FindLocalReferences(IVariable variable, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, + public void FindLocalReferences(IVariable variable, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken) { if (variable == null) throw new ArgumentNullException("variable"); var searchScope = new SearchScope(c => new FindLocalReferencesNavigator(variable)); searchScope.declarationCompilation = compilation; - FindReferencesInFile(searchScope, parsedFile, syntaxTree, compilation, callback, cancellationToken); + FindReferencesInFile(searchScope, unresolvedFile, syntaxTree, compilation, callback, cancellationToken); } class FindLocalReferencesNavigator : FindReferenceNavigator @@ -1225,12 +1225,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// Finds all references of a given type parameter. /// /// The type parameter for which to look. - /// The type system representation of the file being searched. + /// The type system representation of the file being searched. /// The syntax tree of the file being searched. /// The compilation. /// Callback used to report the references that were found. /// Cancellation token that may be used to cancel the operation. - public void FindTypeParameterReferences(IType typeParameter, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, + public void FindTypeParameterReferences(IType typeParameter, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken) { if (typeParameter == null) @@ -1240,7 +1240,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver var searchScope = new SearchScope(c => new FindTypeParameterReferencesNavigator((ITypeParameter)typeParameter)); searchScope.declarationCompilation = compilation; searchScope.accessibility = Accessibility.Private; - FindReferencesInFile(searchScope, parsedFile, syntaxTree, compilation, callback, cancellationToken); + FindReferencesInFile(searchScope, unresolvedFile, syntaxTree, compilation, callback, cancellationToken); } class FindTypeParameterReferencesNavigator : FindReferenceNavigator diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs index d3dc835b22..43cc5ff3d7 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveAtLocation.cs @@ -30,24 +30,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// public static class ResolveAtLocation { - public static ResolveResult Resolve (ICompilation compilation, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, TextLocation location, + public static ResolveResult Resolve (ICompilation compilation, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, TextLocation location, CancellationToken cancellationToken = default(CancellationToken)) { - return Resolve (new Lazy(() => compilation), parsedFile, syntaxTree, location, cancellationToken); + return Resolve (new Lazy(() => compilation), unresolvedFile, syntaxTree, location, cancellationToken); } - public static ResolveResult Resolve(Lazy compilation, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, TextLocation location, + public static ResolveResult Resolve(Lazy compilation, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, TextLocation location, CancellationToken cancellationToken = default(CancellationToken)) { AstNode node; - return Resolve(compilation, parsedFile, syntaxTree, location, out node, cancellationToken); + return Resolve(compilation, unresolvedFile, syntaxTree, location, out node, cancellationToken); } - public static ResolveResult Resolve (ICompilation compilation, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, TextLocation location, out AstNode node, + public static ResolveResult Resolve (ICompilation compilation, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, TextLocation location, out AstNode node, CancellationToken cancellationToken = default(CancellationToken)) { - return Resolve (new Lazy(() => compilation), parsedFile, syntaxTree, location, out node, cancellationToken); + return Resolve (new Lazy(() => compilation), unresolvedFile, syntaxTree, location, out node, cancellationToken); } - public static ResolveResult Resolve(Lazy compilation, CSharpParsedFile parsedFile, SyntaxTree syntaxTree, TextLocation location, out AstNode node, + public static ResolveResult Resolve(Lazy compilation, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, TextLocation location, out AstNode node, CancellationToken cancellationToken = default(CancellationToken)) { node = syntaxTree.GetNodeAt(location); @@ -96,7 +96,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } // TODO: I think we should provide an overload so that an existing CSharpAstResolver can be reused - CSharpAstResolver resolver = new CSharpAstResolver(compilation.Value, syntaxTree, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(compilation.Value, syntaxTree, unresolvedFile); ResolveResult rr = resolver.Resolve(node, cancellationToken); if (rr is MethodGroupResolveResult && parentInvocation != null) return resolver.Resolve(parentInvocation); diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index 9e7e789d05..c7f82cc8ef 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -64,7 +64,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// We do not have to put this into the stored state (resolver) because /// query expressions are always resolved in a single operation. ResolveResult currentQueryResult; - readonly CSharpParsedFile parsedFile; + readonly CSharpUnresolvedFile unresolvedFile; readonly Dictionary resolveResultCache = new Dictionary(); readonly Dictionary resolverBeforeDict = new Dictionary(); readonly Dictionary resolverAfterDict = new Dictionary(); @@ -93,12 +93,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// /// Creates a new ResolveVisitor instance. /// - public ResolveVisitor(CSharpResolver resolver, CSharpParsedFile parsedFile) + public ResolveVisitor(CSharpResolver resolver, CSharpUnresolvedFile unresolvedFile) { if (resolver == null) throw new ArgumentNullException("resolver"); this.resolver = resolver; - this.parsedFile = parsedFile; + this.unresolvedFile = unresolvedFile; this.navigator = skipAllNavigator; } @@ -534,12 +534,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { CSharpResolver previousResolver = resolver; try { - if (parsedFile != null) { - resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(resolver.Compilation)); + if (unresolvedFile != null) { + resolver = resolver.WithCurrentUsingScope(unresolvedFile.RootUsingScope.Resolve(resolver.Compilation)); } else { var cv = new TypeSystemConvertVisitor(unit.FileName ?? string.Empty); ApplyVisitorToUsings(cv, unit.Children); - PushUsingScope(cv.ParsedFile.RootUsingScope); + PushUsingScope(cv.UnresolvedFile.RootUsingScope); } ScanChildren(unit); return voidResult; @@ -567,8 +567,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { CSharpResolver previousResolver = resolver; try { - if (parsedFile != null) { - resolver = resolver.WithCurrentUsingScope(parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation)); + if (unresolvedFile != null) { + resolver = resolver.WithCurrentUsingScope(unresolvedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation)); } else { string fileName = namespaceDeclaration.GetRegion().FileName ?? string.Empty; // Fetch parent using scope @@ -589,7 +589,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver // Last using scope: usingScope = new UsingScope(resolver.CurrentUsingScope.UnresolvedUsingScope, identifiers.Last().Name); usingScope.Region = region; - var cv = new TypeSystemConvertVisitor(new CSharpParsedFile(region.FileName ?? string.Empty), usingScope); + var cv = new TypeSystemConvertVisitor(new CSharpUnresolvedFile(region.FileName ?? string.Empty), usingScope); ApplyVisitorToUsings(cv, namespaceDeclaration.Children); PushUsingScope(usingScope); } @@ -673,7 +673,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver for (AstNode node = fieldOrEventDeclaration.FirstChild; node != null; node = node.NextSibling) { if (node.Role == Roles.Variable) { IMember member; - if (parsedFile != null) { + if (unresolvedFile != null) { member = GetMemberFromLocation(node); } else { string name = ((VariableInitializer)node).Name; @@ -699,7 +699,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver TextLocation location = TypeSystemConvertVisitor.GetStartLocationAfterAttributes(node); return typeDef.GetMembers( delegate (IUnresolvedMember m) { - if (m.ParsedFile != parsedFile) + if (m.UnresolvedFile != unresolvedFile) return false; DomRegion region = m.Region; return !region.IsEmpty && region.Begin <= location && region.End > location; @@ -792,7 +792,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver CSharpResolver oldResolver = resolver; try { IMember member; - if (parsedFile != null) { + if (unresolvedFile != null) { member = GetMemberFromLocation(memberDeclaration); } else { // Re-discover the method: @@ -855,7 +855,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver CSharpResolver oldResolver = resolver; try { IMember member; - if (parsedFile != null) { + if (unresolvedFile != null) { member = GetMemberFromLocation(propertyOrIndexerDeclaration); } else { // Re-discover the property: @@ -911,7 +911,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver CSharpResolver oldResolver = resolver; try { IMember member; - if (parsedFile != null) { + if (unresolvedFile != null) { member = GetMemberFromLocation(eventDeclaration); } else { string name = eventDeclaration.Name; @@ -1034,7 +1034,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver Scan(attributeSection); IMember member = null; - if (parsedFile != null) { + if (unresolvedFile != null) { member = GetMemberFromLocation(enumMemberDeclaration); } else if (resolver.CurrentTypeDefinition != null) { string name = enumMemberDeclaration.Name; @@ -1958,8 +1958,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver DomRegion MakeRegion(AstNode node) { - if (parsedFile != null) - return new DomRegion(parsedFile.FileName, node.StartLocation, node.EndLocation); + if (unresolvedFile != null) + return new DomRegion(unresolvedFile.FileName, node.StartLocation, node.EndLocation); else return node.GetRegion(); } @@ -2148,7 +2148,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver readonly QuerySelectClause selectClause; readonly CSharpResolver storedContext; - readonly CSharpParsedFile parsedFile; + readonly CSharpUnresolvedFile unresolvedFile; readonly List hypotheses = new List(); internal IList parameters = new List(); @@ -2186,7 +2186,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { this.parentVisitor = parentVisitor; this.storedContext = parentVisitor.resolver; - this.parsedFile = parentVisitor.parsedFile; + this.unresolvedFile = parentVisitor.unresolvedFile; this.bodyResult = parentVisitor.voidResult; } @@ -2254,7 +2254,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver if (ok) return h; } - ResolveVisitor visitor = new ResolveVisitor(storedContext, parsedFile); + ResolveVisitor visitor = new ResolveVisitor(storedContext, unresolvedFile); var newHypothesis = new LambdaTypeHypothesis(this, parameterTypes, visitor, lambda != null ? lambda.Parameters : null); hypotheses.Add(newHypothesis); return newHypothesis; diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs index fe72e9b576..ec9b9cfeb4 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs @@ -73,9 +73,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem return result; } else { result = new List(); - foreach (var parsedFile in projectContent.Files.OfType()) { - var attributes = assemblyAttributes ? parsedFile.AssemblyAttributes : parsedFile.ModuleAttributes; - var context = new CSharpTypeResolveContext(this, parsedFile.RootUsingScope.Resolve(compilation)); + foreach (var unresolvedFile in projectContent.Files.OfType()) { + var attributes = assemblyAttributes ? unresolvedFile.AssemblyAttributes : unresolvedFile.ModuleAttributes; + var context = new CSharpTypeResolveContext(this, unresolvedFile.RootUsingScope.Resolve(compilation)); foreach (var unresolvedAttr in attributes) { result.Add(unresolvedAttr.CreateResolvedAttribute(context)); } diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedFile.cs similarity index 95% rename from ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs rename to ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedFile.cs index 186961031f..ac5da75885 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpParsedFile.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedFile.cs @@ -30,7 +30,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem /// Represents a file that was parsed and converted for the type system. /// [Serializable] - public sealed class CSharpParsedFile : AbstractFreezable, IParsedFile, IUnresolvedDocumentationProvider + public sealed class CSharpUnresolvedFile : AbstractFreezable, IUnresolvedFile, IUnresolvedDocumentationProvider { readonly string fileName; readonly UsingScope rootUsingScope; @@ -51,7 +51,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem usingScopes = FreezableHelper.FreezeListAndElements(usingScopes); } - public CSharpParsedFile(string fileName) + public CSharpUnresolvedFile(string fileName) { if (fileName == null) throw new ArgumentNullException("fileName"); @@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem this.rootUsingScope = new UsingScope(); } - public CSharpParsedFile(string fileName, UsingScope rootUsingScope) + public CSharpUnresolvedFile(string fileName, UsingScope rootUsingScope) { if (fileName == null) throw new ArgumentNullException("fileName"); @@ -178,7 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem return rctx; } - ITypeResolveContext IParsedFile.GetTypeResolveContext (ICompilation compilation, TextLocation loc) + ITypeResolveContext IUnresolvedFile.GetTypeResolveContext (ICompilation compilation, TextLocation loc) { return GetTypeResolveContext (compilation, loc); } diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs index 0958a9c616..98228ac423 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem /// public class TypeSystemConvertVisitor : DepthFirstAstVisitor { - readonly CSharpParsedFile parsedFile; + readonly CSharpUnresolvedFile unresolvedFile; UsingScope usingScope; CSharpUnresolvedTypeDefinition currentTypeDefinition; DefaultUnresolvedMethod currentMethod; @@ -64,32 +64,32 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem { if (fileName == null) throw new ArgumentNullException("fileName"); - this.parsedFile = new CSharpParsedFile(fileName); - this.usingScope = parsedFile.RootUsingScope; + this.unresolvedFile = new CSharpUnresolvedFile(fileName); + this.usingScope = unresolvedFile.RootUsingScope; } /// /// Creates a new TypeSystemConvertVisitor and initializes it with a given context. /// - /// The parsed file to which members should be added. + /// The parsed file to which members should be added. /// The current using scope. /// The current type definition. - public TypeSystemConvertVisitor(CSharpParsedFile parsedFile, UsingScope currentUsingScope = null, CSharpUnresolvedTypeDefinition currentTypeDefinition = null) + public TypeSystemConvertVisitor(CSharpUnresolvedFile unresolvedFile, UsingScope currentUsingScope = null, CSharpUnresolvedTypeDefinition currentTypeDefinition = null) { - if (parsedFile == null) - throw new ArgumentNullException("parsedFile"); - this.parsedFile = parsedFile; - this.usingScope = currentUsingScope ?? parsedFile.RootUsingScope; + if (unresolvedFile == null) + throw new ArgumentNullException("unresolvedFile"); + this.unresolvedFile = unresolvedFile; + this.usingScope = currentUsingScope ?? unresolvedFile.RootUsingScope; this.currentTypeDefinition = currentTypeDefinition; } - public CSharpParsedFile ParsedFile { - get { return parsedFile; } + public CSharpUnresolvedFile UnresolvedFile { + get { return unresolvedFile; } } DomRegion MakeRegion(TextLocation start, TextLocation end) { - return new DomRegion(parsedFile.FileName, start.Line, start.Column, end.Line, end.Column); + return new DomRegion(unresolvedFile.FileName, start.Line, start.Column, end.Line, end.Column); } DomRegion MakeRegion(AstNode node) @@ -122,7 +122,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem #region Compilation Unit public override IUnresolvedEntity VisitSyntaxTree (SyntaxTree unit) { - parsedFile.Errors = unit.Errors; + unresolvedFile.Errors = unit.Errors; return base.VisitSyntaxTree (unit); } #endregion @@ -167,7 +167,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem usingScope.Region = region; } base.VisitNamespaceDeclaration(namespaceDeclaration); - parsedFile.UsingScopes.Add(usingScope); // add after visiting children so that nested scopes come first + unresolvedFile.UsingScopes.Add(usingScope); // add after visiting children so that nested scopes come first usingScope = previousUsingScope; return null; } @@ -184,9 +184,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem currentTypeDefinition.NestedTypes.Add(newType); } else { newType = new CSharpUnresolvedTypeDefinition(usingScope, name); - parsedFile.TopLevelTypeDefinitions.Add(newType); + unresolvedFile.TopLevelTypeDefinitions.Add(newType); } - newType.ParsedFile = parsedFile; + newType.UnresolvedFile = unresolvedFile; newType.HasExtensionMethods = false; // gets set to true when an extension method is added return newType; } @@ -868,9 +868,9 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem { // non-assembly attributes are handled by their parent entity if (attributeSection.AttributeTarget == "assembly") { - ConvertAttributes(parsedFile.AssemblyAttributes, attributeSection); + ConvertAttributes(unresolvedFile.AssemblyAttributes, attributeSection); } else if (attributeSection.AttributeTarget == "module") { - ConvertAttributes(parsedFile.ModuleAttributes, attributeSection); + ConvertAttributes(unresolvedFile.ModuleAttributes, attributeSection); } return null; } @@ -1197,7 +1197,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem } if (documentation != null) { documentation.Reverse(); // bring documentation in correct order - parsedFile.AddDocumentation(entity, string.Join(Environment.NewLine, documentation)); + unresolvedFile.AddDocumentation(entity, string.Join(Environment.NewLine, documentation)); } } diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs b/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs index 111e4dd7f9..e5072c4f32 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs @@ -91,13 +91,13 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck 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(solution, item.GetMetadataValue("Name"))); + references.Add(new ProjectReference(item.EvaluatedInclude)); } this.ProjectContent = new CSharpProjectContent() .SetAssemblyName(this.AssemblyName) .SetCompilerSettings(this.CompilerSettings) .AddAssemblyReferences(references) - .UpdateProjectContent(null, Files.Select(f => f.ParsedFile)); + .AddOrUpdateFiles(Files.Select(f => f.UnresolvedFile)); } string FindAssembly(IEnumerable assemblySearchPaths, string evaluatedInclude) @@ -133,24 +133,6 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck } } - public class ProjectReference : IAssemblyReference - { - readonly Solution solution; - readonly string projectTitle; - - public ProjectReference(Solution solution, string projectTitle) - { - this.solution = solution; - this.projectTitle = projectTitle; - } - - public IAssembly Resolve(ITypeResolveContext context) - { - var project = solution.Projects.Single(p => string.Equals(p.Title, projectTitle, StringComparison.OrdinalIgnoreCase)); - return project.ProjectContent.Resolve(context); - } - } - public class CSharpFile { public readonly CSharpProject Project; @@ -159,7 +141,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck public readonly ITextSource Content; public readonly int LinesOfCode; public SyntaxTree SyntaxTree; - public CSharpParsedFile ParsedFile; + public CSharpUnresolvedFile UnresolvedFile; public CSharpFile(CSharpProject project, string fileName) { @@ -176,7 +158,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck Console.WriteLine(" " + error.Region + " " + error.Message); } } - this.ParsedFile = this.SyntaxTree.ToTypeSystem(); + this.UnresolvedFile = this.SyntaxTree.ToTypeSystem(); } } } diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs b/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs index 896a0e21c8..324ffb38a5 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs @@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck } } ); - var resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.ParsedFile); + var resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile); resolver.ApplyNavigator(navigator); } } @@ -102,9 +102,9 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck HashSet foundReferences = new HashSet(); var interestingFiles = new HashSet(); foreach (var searchScope in searchScopes) { - foreach (var parsedFile in fr.GetInterestingFiles(searchScope, project.Compilation)) { - var file = project.GetFile(parsedFile.FileName); - Debug.Assert(file.ParsedFile == parsedFile); + foreach (var unresolvedFile in fr.GetInterestingFiles(searchScope, project.Compilation)) { + var file = project.GetFile(unresolvedFile.FileName); + Debug.Assert(file.UnresolvedFile == 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) @@ -114,7 +114,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck } } foreach (var file in interestingFiles) { - fr.FindReferencesInFile(searchScopes, file.ParsedFile, file.SyntaxTree, project.Compilation, + fr.FindReferencesInFile(searchScopes, file.UnresolvedFile, file.SyntaxTree, project.Compilation, delegate(AstNode node, ResolveResult result) { foundReferences.Add(node); }, CancellationToken.None); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs b/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs index 88ee1489c2..842f7fcdd1 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs @@ -63,7 +63,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck using (new Timer("Resolve unresolved members... ")) TypeSystemTests.ResolvedUnresolvedMembers(solution); //RunTestOnAllFiles("Roundtripping test", RoundtripTest.RunTest); RunTestOnAllFiles("Resolver test", ResolverTest.RunTest); - RunTestOnAllFiles("Resolver test (no parsed file)", ResolverTest.RunTestWithoutParsedFile); + RunTestOnAllFiles("Resolver test (no parsed file)", ResolverTest.RunTestWithoutUnresolvedFile); RunTestOnAllFiles("Resolver test (randomized order)", RandomizedOrderResolverTest.RunTest); new FindReferencesConsistencyCheck(solution).Run(); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs b/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs index 06906f310b..e5ae47b941 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs @@ -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.ParsedFile); + test.resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile); // 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.ParsedFile); + test.resolveAllResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile); test.resolveAllResolver.ApplyNavigator(new ResolveAllNavigator(), CancellationToken.None); // Prepare list of actions that we need to verify: var actions = new List>(); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs b/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs index 23ee726b96..21bc31c8fd 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck { public static void RunTest(CSharpFile file) { - CSharpAstResolver resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.ParsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile); var navigator = new ValidatingResolveAllNavigator(file.FileName); resolver.ApplyNavigator(navigator, CancellationToken.None); navigator.Validate(resolver, file.SyntaxTree); @@ -102,19 +102,19 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck } } - public static void RunTestWithoutParsedFile(CSharpFile file) + public static void RunTestWithoutUnresolvedFile(CSharpFile file) { CSharpAstResolver resolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree); var navigator = new ValidatingResolveAllNavigator(file.FileName); resolver.ApplyNavigator(navigator, CancellationToken.None); navigator.Validate(resolver, file.SyntaxTree); - CSharpAstResolver originalResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.ParsedFile); + CSharpAstResolver originalResolver = new CSharpAstResolver(file.Project.Compilation, file.SyntaxTree, file.UnresolvedFile); foreach (var node in file.SyntaxTree.DescendantsAndSelf) { var originalResult = originalResolver.Resolve(node); var result = resolver.Resolve(node); if (!RandomizedOrderResolverTest.IsEqualResolveResult(result, originalResult)) { - Console.WriteLine("Got different without IParsedFile at " + file.FileName + ":" + node.StartLocation); + Console.WriteLine("Got different without IUnresolvedFile at " + file.FileName + ":" + node.StartLocation); } } } diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/VisitorBenchmark.cs b/ICSharpCode.NRefactory.ConsistencyCheck/VisitorBenchmark.cs index 9c58ef543e..855f09fea0 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/VisitorBenchmark.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/VisitorBenchmark.cs @@ -50,11 +50,6 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck visitor.EnterIdentifierExpression += list.Add; syntaxTree.AcceptVisitor(visitor); }); - RunTest("ObservableAstVisitor", files, (syntaxTree, list) => { - var visitor = new ObservableAstVisitor(); - visitor.IdentifierExpressionVisited += (id, data) => list.Add(id); - syntaxTree.AcceptVisitor(visitor, null); - }); } static void WalkTreeForEach(AstNode node, List list) diff --git a/ICSharpCode.NRefactory.Demo/CSDemo.cs b/ICSharpCode.NRefactory.Demo/CSDemo.cs index 025815ac11..4380dc96b9 100644 --- a/ICSharpCode.NRefactory.Demo/CSDemo.cs +++ b/ICSharpCode.NRefactory.Demo/CSDemo.cs @@ -204,8 +204,8 @@ namespace ICSharpCode.NRefactory.Demo void ResolveButtonClick(object sender, EventArgs e) { IProjectContent project = new CSharpProjectContent(); - var parsedFile = syntaxTree.ToTypeSystem(); - project = project.UpdateProjectContent(null, parsedFile); + var unresolvedFile = syntaxTree.ToTypeSystem(); + project = project.AddOrUpdateFiles(unresolvedFile); project = project.AddAssemblyReferences(builtInLibs.Value); ICompilation compilation = project.CreateCompilation(); @@ -213,12 +213,12 @@ namespace ICSharpCode.NRefactory.Demo ResolveResult result; if (csharpTreeView.SelectedNode != null) { var selectedNode = (AstNode)csharpTreeView.SelectedNode.Tag; - CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); result = resolver.Resolve(selectedNode); // CSharpAstResolver.Resolve() never returns null } else { TextLocation location = GetTextLocation(csharpCodeTextBox, csharpCodeTextBox.SelectionStart); - result = ResolveAtLocation.Resolve(compilation, parsedFile, syntaxTree, location); + result = ResolveAtLocation.Resolve(compilation, unresolvedFile, syntaxTree, location); if (result == null) { MessageBox.Show("Could not find a resolvable node at the caret location."); return; @@ -248,12 +248,12 @@ namespace ICSharpCode.NRefactory.Demo return; IProjectContent project = new CSharpProjectContent(); - var parsedFile = syntaxTree.ToTypeSystem(); - project = project.UpdateProjectContent(null, parsedFile); + var unresolvedFile = syntaxTree.ToTypeSystem(); + project = project.AddOrUpdateFiles(unresolvedFile); project = project.AddAssemblyReferences(builtInLibs.Value); ICompilation compilation = project.CreateCompilation(); - CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag; IEntity entity; @@ -276,7 +276,7 @@ namespace ICSharpCode.NRefactory.Demo var searchScopes = fr.GetSearchScopes(entity); Debug.WriteLine("Find references to " + entity.ReflectionName); - fr.FindReferencesInFile(searchScopes, parsedFile, syntaxTree, compilation, callback, CancellationToken.None); + fr.FindReferencesInFile(searchScopes, unresolvedFile, syntaxTree, compilation, callback, CancellationToken.None); MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName); } diff --git a/ICSharpCode.NRefactory.GtkDemo/MainWindow.cs b/ICSharpCode.NRefactory.GtkDemo/MainWindow.cs index 0b2743c087..1ac66ac3dd 100644 --- a/ICSharpCode.NRefactory.GtkDemo/MainWindow.cs +++ b/ICSharpCode.NRefactory.GtkDemo/MainWindow.cs @@ -223,14 +223,14 @@ namespace ICSharpCode.NRefactory.GtkDemo var parser = new CSharpParser (); var unit = parser.Parse (textview1.Buffer.Text, "dummy.cs"); - var parsedFile = unit.ToTypeSystem(); + var unresolvedFile = unit.ToTypeSystem(); IProjectContent project = new CSharpProjectContent (); - project = project.UpdateProjectContent (null, parsedFile); + project = project.AddOrUpdateFiles (unresolvedFile); project = project.AddAssemblyReferences (builtInLibs.Value); - CSharpAstResolver resolver = new CSharpAstResolver(project.CreateCompilation (), unit, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(project.CreateCompilation (), unit, unresolvedFile); ShowUnit (unit, resolver); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs index 5ee12c755b..b71740a9e4 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/TestRefactoringContext.cs @@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions { FindReferences refFinder = new FindReferences (); refFinder.FindReferencesInFile (refFinder.GetSearchScopes (entity), - context.ParsedFile, + context.UnresolvedFile, context.RootNode as SyntaxTree, context.Compilation, (n, r) => Rename (n, name), context.CancellationToken); @@ -168,7 +168,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions { FindReferences refFinder = new FindReferences (); refFinder.FindLocalReferences (variable, - context.ParsedFile, + context.UnresolvedFile, context.RootNode as SyntaxTree, context.Compilation, (n, r) => Rename (n, name), context.CancellationToken); @@ -178,7 +178,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions { FindReferences refFinder = new FindReferences (); refFinder.FindTypeParameterReferences (type, - context.ParsedFile, + context.UnresolvedFile, context.RootNode as SyntaxTree, context.Compilation, (n, r) => Rename (n, name), context.CancellationToken); @@ -258,14 +258,14 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions Console.WriteLine (error.Message); Assert.IsFalse (parser.HasErrors, "File contains parsing errors."); unit.Freeze (); - var parsedFile = unit.ToTypeSystem (); + var unresolvedFile = unit.ToTypeSystem (); IProjectContent pc = new CSharpProjectContent (); - pc = pc.UpdateProjectContent (null, parsedFile); + pc = pc.AddOrUpdateFiles (unresolvedFile); pc = pc.AddAssemblyReferences (new[] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore }); var compilation = pc.CreateCompilation (); - var resolver = new CSharpAstResolver (compilation, unit, parsedFile); + var resolver = new CSharpAstResolver (compilation, unit, unresolvedFile); TextLocation location = TextLocation.Empty; if (idx >= 0) location = doc.GetLocation (idx); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs index dc25ca4b5b..948902409a 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs @@ -225,16 +225,16 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion var syntaxTree = new CSharpParser().Parse(parsedText, "program.cs"); syntaxTree.Freeze(); - var parsedFile = syntaxTree.ToTypeSystem(); - pctx = pctx.UpdateProjectContent(null, parsedFile); + var unresolvedFile = syntaxTree.ToTypeSystem(); + pctx = pctx.AddOrUpdateFiles(unresolvedFile); var cmp = pctx.CreateCompilation(); var loc = cursorPosition > 0 ? doc.GetLocation(cursorPosition) : new TextLocation (1, 1); var rctx = new CSharpTypeResolveContext(cmp.MainAssembly); - rctx = rctx.WithUsingScope(parsedFile.GetUsingScope(loc).Resolve(cmp)); + rctx = rctx.WithUsingScope(unresolvedFile.GetUsingScope(loc).Resolve(cmp)); - var curDef = parsedFile.GetInnermostTypeDefinition(loc); + var curDef = unresolvedFile.GetInnermostTypeDefinition(loc); if (curDef != null) { var resolvedDef = curDef.Resolve(rctx).GetDefinition(); rctx = rctx.WithCurrentTypeDefinition(resolvedDef); @@ -243,7 +243,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion rctx = rctx.WithCurrentMember(curMember); } } - var mb = new DefaultCompletionContextProvider(doc, parsedFile); + var mb = new DefaultCompletionContextProvider(doc, unresolvedFile); var engine = new CSharpCompletionEngine(doc, mb, new TestFactory(), pctx, rctx); engine.EolMarker = Environment.NewLine; @@ -270,12 +270,12 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion var doc = new ReadOnlyDocument(text); IProjectContent pctx = new CSharpProjectContent(); pctx = pctx.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore }); - var parsedFile = syntaxTree.ToTypeSystem(); + var unresolvedFile = syntaxTree.ToTypeSystem(); - pctx = pctx.UpdateProjectContent(null, parsedFile); + pctx = pctx.AddOrUpdateFiles(unresolvedFile); var cmp = pctx.CreateCompilation(); - var mb = new DefaultCompletionContextProvider(doc, parsedFile); + var mb = new DefaultCompletionContextProvider(doc, unresolvedFile); var engine = new CSharpCompletionEngine (doc, mb, new TestFactory (), pctx, new CSharpTypeResolveContext (cmp.MainAssembly)); engine.EolMarker = Environment.NewLine; engine.FormattingPolicy = FormattingOptionsFactory.CreateMono (); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs index f69988b756..85bfea561a 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs @@ -275,23 +275,23 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion var syntaxTree = new CSharpParser().Parse(parsedText, "program.cs"); syntaxTree.Freeze(); - var parsedFile = syntaxTree.ToTypeSystem(); - pctx = pctx.UpdateProjectContent(null, parsedFile); + var unresolvedFile = syntaxTree.ToTypeSystem(); + pctx = pctx.AddOrUpdateFiles(unresolvedFile); var cmp = pctx.CreateCompilation(); var loc = doc.GetLocation(cursorPosition); var rctx = new CSharpTypeResolveContext(cmp.MainAssembly); - rctx = rctx.WithUsingScope(parsedFile.GetUsingScope(loc).Resolve(cmp)); - var curDef = parsedFile.GetInnermostTypeDefinition(loc); + rctx = rctx.WithUsingScope(unresolvedFile.GetUsingScope(loc).Resolve(cmp)); + var curDef = unresolvedFile.GetInnermostTypeDefinition(loc); if (curDef != null) { rctx = rctx.WithCurrentTypeDefinition(curDef.Resolve(rctx).GetDefinition()); - var curMember = parsedFile.GetMember(loc); + var curMember = unresolvedFile.GetMember(loc); if (curMember != null) { rctx = rctx.WithCurrentMember(curMember.CreateResolved(rctx)); } } - var mb = new DefaultCompletionContextProvider(doc, parsedFile); + var mb = new DefaultCompletionContextProvider(doc, unresolvedFile); var engine = new CSharpParameterCompletionEngine (doc, mb, new TestFactory (pctx), pctx, rctx); return engine.GetParameterDataProvider (cursorPosition, doc.GetCharAt (cursorPosition - 1)); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs index bb12f7f9d3..77e7246a64 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs @@ -34,15 +34,15 @@ namespace ICSharpCode.NRefactory.CSharp public class CodeDomConvertVisitorTests : ResolverTestBase { CodeDomConvertVisitor convertVisitor; - CSharpParsedFile parsedFile; + CSharpUnresolvedFile unresolvedFile; public override void SetUp() { base.SetUp(); - parsedFile = new CSharpParsedFile("test.cs"); - parsedFile.RootUsingScope.Usings.Add(MakeReference("System")); - parsedFile.RootUsingScope.Usings.Add(MakeReference("System.Collections.Generic")); - parsedFile.RootUsingScope.Usings.Add(MakeReference("System.Linq")); + unresolvedFile = new CSharpUnresolvedFile("test.cs"); + unresolvedFile.RootUsingScope.Usings.Add(MakeReference("System")); + unresolvedFile.RootUsingScope.Usings.Add(MakeReference("System.Collections.Generic")); + unresolvedFile.RootUsingScope.Usings.Add(MakeReference("System.Linq")); convertVisitor = new CodeDomConvertVisitor(); convertVisitor.AllowSnippetNodes = false; @@ -53,7 +53,7 @@ namespace ICSharpCode.NRefactory.CSharp string ConvertHelper(AstNode node, Action action) { CSharpResolver resolver = new CSharpResolver(compilation); - resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(compilation)); + resolver = resolver.WithCurrentUsingScope(unresolvedFile.RootUsingScope.Resolve(compilation)); resolver = resolver.WithCurrentTypeDefinition(compilation.FindType(KnownTypeCode.Object).GetDefinition()); var codeObj = convertVisitor.Convert(node, new CSharpAstResolver(resolver, node)); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs index ff103783fd..2bc9f88760 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs @@ -54,15 +54,15 @@ namespace ICSharpCode.NRefactory.CSharp.Parser using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) { syntaxTree = parser.Parse(fs, fileName); } - var parsedFile = syntaxTree.ToTypeSystem(); - foreach (var td in parsedFile.GetAllTypeDefinitions()) { - Assert.AreSame(parsedFile, td.ParsedFile); + var unresolvedFile = syntaxTree.ToTypeSystem(); + foreach (var td in unresolvedFile.GetAllTypeDefinitions()) { + Assert.AreSame(unresolvedFile, td.UnresolvedFile); foreach (var member in td.Members) { - Assert.AreSame(parsedFile, member.ParsedFile); + Assert.AreSame(unresolvedFile, member.UnresolvedFile); Assert.AreSame(td, member.DeclaringTypeDefinition); } } - pc = pc.UpdateProjectContent(null, parsedFile); + pc = pc.AddOrUpdateFiles(unresolvedFile); } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs index d80a78390b..2f1d58eb09 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs @@ -47,9 +47,9 @@ namespace ICSharpCode.NRefactory.CSharp.Parser syntaxTree = parser.Parse(s, fileName); } - var parsedFile = syntaxTree.ToTypeSystem(); + var unresolvedFile = syntaxTree.ToTypeSystem(); return new CSharpProjectContent() - .UpdateProjectContent(null, parsedFile) + .AddOrUpdateFiles(unresolvedFile) .AddAssemblyReferences(new[] { CecilLoaderTests.Mscorlib }) .SetAssemblyName(typeof(TypeSystemTests).Assembly.GetName().Name); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs index 374847c0af..5f02fda804 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs @@ -56,15 +56,15 @@ namespace OtherNS { IProjectContent pc; ICompilation compilation; ITypeDefinition baseClass, derivedClass, nestedClass, systemClass; - CSharpParsedFile parsedFile; + CSharpUnresolvedFile unresolvedFile; [SetUp] public void SetUp() { pc = new CSharpProjectContent(); pc = pc.SetAssemblyName("MyAssembly"); - parsedFile = SyntaxTree.Parse(program, "program.cs").ToTypeSystem(); - pc = pc.UpdateProjectContent(null, parsedFile); + unresolvedFile = SyntaxTree.Parse(program, "program.cs").ToTypeSystem(); + pc = pc.AddOrUpdateFiles(unresolvedFile); pc = pc.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib }); compilation = pc.CreateCompilation(); @@ -77,7 +77,7 @@ namespace OtherNS { TypeSystemAstBuilder CreateBuilder(ITypeDefinition currentTypeDef = null) { - UsingScope usingScope = currentTypeDef != null ? parsedFile.GetUsingScope(currentTypeDef.Region.Begin) : parsedFile.RootUsingScope; + UsingScope usingScope = currentTypeDef != null ? unresolvedFile.GetUsingScope(currentTypeDef.Region.Begin) : unresolvedFile.RootUsingScope; return new TypeSystemAstBuilder(new CSharpResolver( new CSharpTypeResolveContext(compilation.MainAssembly, usingScope.Resolve(compilation), currentTypeDef))); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/FindReferencesTest.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/FindReferencesTest.cs index 64aed01c54..87cf3cc3cf 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/FindReferencesTest.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/FindReferencesTest.cs @@ -31,15 +31,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver public class FindReferencesTest { SyntaxTree syntaxTree; - CSharpParsedFile parsedFile; + CSharpUnresolvedFile unresolvedFile; ICompilation compilation; FindReferences findReferences; void Init(string code) { syntaxTree = SyntaxTree.Parse(code, "test.cs"); - parsedFile = syntaxTree.ToTypeSystem(); - compilation = TypeSystemHelper.CreateCompilation(parsedFile); + unresolvedFile = syntaxTree.ToTypeSystem(); + compilation = TypeSystemHelper.CreateCompilation(unresolvedFile); findReferences = new FindReferences(); } @@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { var result = new List(); var searchScopes = findReferences.GetSearchScopes(entity); - findReferences.FindReferencesInFile(searchScopes, parsedFile, syntaxTree, compilation, + findReferences.FindReferencesInFile(searchScopes, unresolvedFile, syntaxTree, compilation, (node, rr) => result.Add(node), CancellationToken.None); return result.OrderBy(n => n.StartLocation).ToArray(); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs index bb734a450f..882273873d 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs @@ -38,13 +38,13 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver lookup = new MemberLookup(null, compilation.MainAssembly); } - CSharpParsedFile Parse(string program) + CSharpUnresolvedFile Parse(string program) { SyntaxTree syntaxTree = SyntaxTree.Parse(program, "test.cs"); - CSharpParsedFile parsedFile = syntaxTree.ToTypeSystem(); - project = project.UpdateProjectContent(null, parsedFile); + CSharpUnresolvedFile unresolvedFile = syntaxTree.ToTypeSystem(); + project = project.AddOrUpdateFiles(unresolvedFile); compilation = project.CreateCompilation(); - return parsedFile; + return unresolvedFile; } [Test] @@ -60,8 +60,8 @@ class Middle : Base { class Derived : Middle { public override void Method() {} }"; - var parsedFile = Parse(program); - ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(parsedFile.TopLevelTypeDefinitions[2]); + var unresolvedFile = Parse(program); + ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(unresolvedFile.TopLevelTypeDefinitions[2]); var rr = lookup.Lookup(new ResolveResult(derived), "Method", EmptyList.Instance, true) as MethodGroupResolveResult; Assert.AreEqual(2, rr.MethodsGroupedByDeclaringType.Count()); @@ -87,8 +87,8 @@ class Derived : Base { public override void Method(int a) {} public override void Method(string a) {} }"; - var parsedFile = Parse(program); - ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(parsedFile.TopLevelTypeDefinitions[1]); + var unresolvedFile = Parse(program); + ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(unresolvedFile.TopLevelTypeDefinitions[1]); var rr = lookup.Lookup(new ResolveResult(derived), "Method", EmptyList.Instance, true) as MethodGroupResolveResult; Assert.AreEqual(2, rr.MethodsGroupedByDeclaringType.Count()); @@ -115,8 +115,8 @@ class Base { class Derived : Base { public override void Method(S a) {} }"; - var parsedFile = Parse(program); - ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(parsedFile.TopLevelTypeDefinitions[1]); + var unresolvedFile = Parse(program); + ITypeDefinition derived = compilation.MainAssembly.GetTypeDefinition(unresolvedFile.TopLevelTypeDefinitions[1]); var rr = lookup.Lookup(new ResolveResult(derived), "Method", EmptyList.Instance, true) as MethodGroupResolveResult; Assert.AreEqual(1, rr.MethodsGroupedByDeclaringType.Count()); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs index 095fe78b4e..f42a9e7457 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs @@ -168,11 +168,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver SetUp(); - CSharpParsedFile parsedFile = syntaxTree.ToTypeSystem(); - project = project.UpdateProjectContent(null, parsedFile); + CSharpUnresolvedFile unresolvedFile = syntaxTree.ToTypeSystem(); + project = project.AddOrUpdateFiles(unresolvedFile); compilation = project.CreateCompilation(); - CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, parsedFile); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); return Tuple.Create(resolver, FindNode(syntaxTree, dollars[0], dollars[1])); } @@ -253,11 +253,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver SetUp(); - CSharpParsedFile parsedFile = syntaxTree.ToTypeSystem(); - project = project.UpdateProjectContent(null, parsedFile); + CSharpUnresolvedFile unresolvedFile = syntaxTree.ToTypeSystem(); + project = project.AddOrUpdateFiles(unresolvedFile); compilation = project.CreateCompilation(); - ResolveResult rr = Resolver.ResolveAtLocation.Resolve(compilation, parsedFile, syntaxTree, dollars[0]); + ResolveResult rr = Resolver.ResolveAtLocation.Resolve(compilation, unresolvedFile, syntaxTree, dollars[0]); return rr; } diff --git a/ICSharpCode.NRefactory.Tests/Documentation/CSharpCrefLookupTests.cs b/ICSharpCode.NRefactory.Tests/Documentation/CSharpCrefLookupTests.cs index e1af99d29f..71141ae2b7 100644 --- a/ICSharpCode.NRefactory.Tests/Documentation/CSharpCrefLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/Documentation/CSharpCrefLookupTests.cs @@ -56,7 +56,7 @@ class Impl : IGeneric[,], T> { var pc = new CSharpProjectContent().AddAssemblyReferences(new[] { CecilLoaderTests.Mscorlib }); var syntaxTree = SyntaxTree.Parse(program, "program.cs"); - var compilation = pc.UpdateProjectContent(null, syntaxTree.ToTypeSystem()).CreateCompilation(); + var compilation = pc.AddOrUpdateFiles(syntaxTree.ToTypeSystem()).CreateCompilation(); var typeDefinition = compilation.MainAssembly.TopLevelTypeDefinitions.First(); IEntity entity = typeDefinition.Documentation.ResolveCref(cref); Assert.IsNotNull(entity, "ResolveCref() returned null."); diff --git a/ICSharpCode.NRefactory.Tests/Documentation/CSharpDocumentationTests.cs b/ICSharpCode.NRefactory.Tests/Documentation/CSharpDocumentationTests.cs index 7140bbae42..08673dd0c2 100644 --- a/ICSharpCode.NRefactory.Tests/Documentation/CSharpDocumentationTests.cs +++ b/ICSharpCode.NRefactory.Tests/Documentation/CSharpDocumentationTests.cs @@ -36,7 +36,7 @@ namespace ICSharpCode.NRefactory.Documentation { var pc = new CSharpProjectContent().AddAssemblyReferences(new[] { CecilLoaderTests.Mscorlib }); var syntaxTree = SyntaxTree.Parse(program, "program.cs"); - compilation = pc.UpdateProjectContent(null, syntaxTree.ToTypeSystem()).CreateCompilation(); + compilation = pc.AddOrUpdateFiles(syntaxTree.ToTypeSystem()).CreateCompilation(); typeDefinition = compilation.MainAssembly.TopLevelTypeDefinitions.FirstOrDefault(); } diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs index 1600e5372a..b53ef9d30f 100644 --- a/ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs +++ b/ICSharpCode.NRefactory.Tests/TypeSystem/GetAllBaseTypesTest.cs @@ -67,8 +67,8 @@ namespace System.Collections.Generic { [SetUp] public void SetUp() { - var parsedFile = new CSharpParser().Parse(corlib, "corlib.cs").ToTypeSystem(); - compilation = new CSharpProjectContent().SetAssemblyName("mscorlib").UpdateProjectContent(null, parsedFile).CreateCompilation(); + var unresolvedFile = new CSharpParser().Parse(corlib, "corlib.cs").ToTypeSystem(); + compilation = new CSharpProjectContent().SetAssemblyName("mscorlib").AddOrUpdateFiles(unresolvedFile).CreateCompilation(); } IType[] GetAllBaseTypes(Type type) diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs index 24bbd57ba7..d5c94561e4 100644 --- a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs +++ b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemHelper.cs @@ -27,20 +27,20 @@ namespace ICSharpCode.NRefactory.TypeSystem { public static ICompilation CreateCompilation() { - return CreateCompilation(new IParsedFile[0]); + return CreateCompilation(new IUnresolvedFile[0]); } public static ICompilation CreateCompilation(params IUnresolvedTypeDefinition[] unresolvedTypeDefinitions) { - var parsedFile = new CSharpParsedFile("dummy.cs"); + var unresolvedFile = new CSharpUnresolvedFile("dummy.cs"); foreach (var typeDef in unresolvedTypeDefinitions) - parsedFile.TopLevelTypeDefinitions.Add(typeDef); - return CreateCompilation(parsedFile); + unresolvedFile.TopLevelTypeDefinitions.Add(typeDef); + return CreateCompilation(unresolvedFile); } - public static ICompilation CreateCompilation(params IParsedFile[] parsedFiles) + public static ICompilation CreateCompilation(params IUnresolvedFile[] unresolvedFiles) { - var pc = new CSharpProjectContent().UpdateProjectContent(null, parsedFiles); + var pc = new CSharpProjectContent().AddOrUpdateFiles(unresolvedFiles); pc = pc.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib, CecilLoaderTests.SystemCore }); return pc.CreateCompilation(); } diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 7799ed8acb..34b8e4d855 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -206,7 +206,7 @@ - + diff --git a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs index 0f02617087..f15885817c 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs @@ -268,7 +268,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets all unresolved type definitions from the file. /// For partial classes, each part is returned. /// - public static IEnumerable GetAllTypeDefinitions (this IParsedFile file) + public static IEnumerable GetAllTypeDefinitions (this IUnresolvedFile file) { return TreeTraversal.PreOrder(file.TopLevelTypeDefinitions, t => t.NestedTypes); } @@ -300,7 +300,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets the type (potentially a nested type) defined at the specified location. /// Returns null if no type is defined at that location. /// - public static IUnresolvedTypeDefinition GetInnermostTypeDefinition (this IParsedFile file, int line, int column) + public static IUnresolvedTypeDefinition GetInnermostTypeDefinition (this IUnresolvedFile file, int line, int column) { return file.GetInnermostTypeDefinition (new TextLocation (line, column)); } @@ -309,7 +309,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets the member defined at the specified location. /// Returns null if no member is defined at that location. /// - public static IUnresolvedMember GetMember (this IParsedFile file, int line, int column) + public static IUnresolvedMember GetMember (this IUnresolvedFile file, int line, int column) { return file.GetMember (new TextLocation (line, column)); } diff --git a/ICSharpCode.NRefactory/TypeSystem/IEntity.cs b/ICSharpCode.NRefactory/TypeSystem/IEntity.cs index 192f77be39..236ad4b944 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IEntity.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IEntity.cs @@ -54,7 +54,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets the parsed file in which this entity is defined. /// Returns null if this entity wasn't parsed from source code (e.g. loaded from a .dll with CecilLoader). /// - IParsedFile ParsedFile { get; } + IUnresolvedFile UnresolvedFile { get; } /// /// Gets the attributes on this entity. diff --git a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs index 120701d04b..89db1ace15 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs @@ -35,12 +35,12 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Gets a parsed file by its file name. /// - IParsedFile GetFile(string fileName); + IUnresolvedFile GetFile(string fileName); /// /// Gets the list of all parsed files in the project content. /// - IEnumerable Files { get; } + IEnumerable Files { get; } /// /// Gets the referenced assemblies. @@ -94,20 +94,54 @@ namespace ICSharpCode.NRefactory.TypeSystem /// IProjectContent AddAssemblyReferences(IEnumerable references); + /// + /// Add assembly references to this project content. + /// + IProjectContent AddAssemblyReferences(params IAssemblyReference[] references); + /// /// Removes assembly references from this project content. /// IProjectContent RemoveAssemblyReferences(IEnumerable references); + /// + /// Removes assembly references from this project content. + /// + IProjectContent RemoveAssemblyReferences(params IAssemblyReference[] references); + + /// + /// Adds the specified files to the project content. + /// If a file with the same name already exists, updated the existing file. + /// + IProjectContent AddOrUpdateFiles(IEnumerable newFiles); + + /// + /// Adds the specified files to the project content. + /// If a file with the same name already exists, this method updates the existing file. + /// + IProjectContent AddOrUpdateFiles(params IUnresolvedFile[] newFiles); + + /// + /// Removes the files with the specified names. + /// + IProjectContent RemoveFiles(IEnumerable fileNames); + + /// + /// Removes the files with the specified names. + /// + IProjectContent RemoveFiles(params string[] fileNames); + /// /// Removes types and attributes from oldFile from the project, and adds those from newFile. /// - IProjectContent UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile); + [Obsolete("Use RemoveFiles()/AddOrUpdateFiles() instead")] + IProjectContent UpdateProjectContent(IUnresolvedFile oldFile, IUnresolvedFile newFile); /// /// Removes types and attributes from oldFiles from the project, and adds those from newFiles. /// - IProjectContent UpdateProjectContent(IEnumerable oldFiles, IEnumerable newFiles); + [Obsolete("Use RemoveFiles()/AddOrUpdateFiles() instead")] + IProjectContent UpdateProjectContent(IEnumerable oldFiles, IEnumerable newFiles); /// /// Sets the compiler settings object. diff --git a/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs b/ICSharpCode.NRefactory/TypeSystem/IUnresolvedFile.cs similarity index 95% rename from ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs rename to ICSharpCode.NRefactory/TypeSystem/IUnresolvedFile.cs index 0a9a04f83e..98dbaf96a3 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IUnresolvedFile.cs @@ -21,10 +21,13 @@ using System.Collections.Generic; namespace ICSharpCode.NRefactory.TypeSystem { + [Obsolete("IParsedFile was renamed to IUnresolvedFile", true)] + public interface IParsedFile {} + /// /// Represents a single file that was parsed. /// - public interface IParsedFile + public interface IUnresolvedFile { /// /// Returns the full path of the file. diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs index 0ff0b25a58..47ea6e407c 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs @@ -92,7 +92,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public override DocumentationComment Documentation { get { - IUnresolvedDocumentationProvider docProvider = unresolved.ParsedFile as IUnresolvedDocumentationProvider; + IUnresolvedDocumentationProvider docProvider = unresolved.UnresolvedFile as IUnresolvedDocumentationProvider; if (docProvider != null) { var doc = docProvider.GetDocumentation(unresolved, this); if (doc != null) diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs index 66d29b8c0c..da96ec4233 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedEntity.cs @@ -101,7 +101,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation { internal DomRegion region; internal DomRegion bodyRegion; - internal IParsedFile parsedFile; + internal IUnresolvedFile unresolvedFile; protected internal virtual void FreezeInternal() { @@ -148,11 +148,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } } - public IParsedFile ParsedFile { - get { return rareFields != null ? rareFields.parsedFile : null; } + public IUnresolvedFile UnresolvedFile { + get { return rareFields != null ? rareFields.unresolvedFile : null; } set { if (value != null || rareFields != null) - WriteRareFields().parsedFile = value; + WriteRareFields().unresolvedFile = value; } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs index 902d1c9094..84580ae2ff 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs @@ -589,7 +589,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public virtual DocumentationComment Documentation { get { foreach (var part in parts) { - var unresolvedProvider = part.ParsedFile as IUnresolvedDocumentationProvider; + var unresolvedProvider = part.UnresolvedFile as IUnresolvedDocumentationProvider; if (unresolvedProvider != null) { var doc = unresolvedProvider.GetDocumentation(part, this); if (doc != null) diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs index 64d940f9fe..6ffc9d7635 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedEvent.cs @@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation this.DeclaringTypeDefinition = declaringType; this.Name = name; if (declaringType != null) - this.ParsedFile = declaringType.ParsedFile; + this.UnresolvedFile = declaringType.UnresolvedFile; } public bool CanAdd { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs index 850ffe3937..3e6406e27d 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedField.cs @@ -51,7 +51,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation this.DeclaringTypeDefinition = declaringType; this.Name = name; if (declaringType != null) - this.ParsedFile = declaringType.ParsedFile; + this.UnresolvedFile = declaringType.UnresolvedFile; } public bool IsConst { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs index 8b0e16d345..f10dd086ba 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedMethod.cs @@ -63,7 +63,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation this.DeclaringTypeDefinition = declaringType; this.Name = name; if (declaringType != null) - this.ParsedFile = declaringType.ParsedFile; + this.UnresolvedFile = declaringType.UnresolvedFile; } public IList ReturnTypeAttributes { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs index aa86d31145..998d462955 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedProperty.cs @@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation this.DeclaringTypeDefinition = declaringType; this.Name = name; if (declaringType != null) - this.ParsedFile = declaringType.ParsedFile; + this.UnresolvedFile = declaringType.UnresolvedFile; } public bool IsIndexer { diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs index d719372f6c..66658ea91e 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedTypeDefinition.cs @@ -72,7 +72,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation this.DeclaringTypeDefinition = declaringTypeDefinition; this.namespaceName = declaringTypeDefinition.Namespace; this.Name = name; - this.ParsedFile = declaringTypeDefinition.ParsedFile; + this.UnresolvedFile = declaringTypeDefinition.UnresolvedFile; } public TypeKind Kind { diff --git a/doc/XML Documentation.html b/doc/XML Documentation.html index c3cae8ba0c..889866ff76 100644 --- a/doc/XML Documentation.html +++ b/doc/XML Documentation.html @@ -20,7 +20,7 @@ property is accessed.
For this purpose, the type system casts the parsed file to IUnresolvedDocumentationProvider and tries to get the documentation. - This way, the CSharpParsedFile can provide the documentation from the XML comments.
+ This way, the CSharpUnresolvedFile can provide the documentation from the XML comments.
If this fails, the type system casts the unresolved assembly/project content to IDocumentationProvider. This is the way the request for documentation gets to the CecilLoader, which in turn forwards it to the user-provided IDocumentationProvider. From 1f6c4f037ee17e75c884b1d7febff12ddda91e1c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 8 Aug 2012 17:19:16 +0200 Subject: [PATCH 5/6] Update solution-loading logic in ConsistencyCheck. --- .../Expressions/ArrayInitializerExpression.cs | 54 +++++- .../Resolver/CSharpAstResolver.cs | 14 +- .../CSharpFile.cs | 68 +++++++ .../CSharpProject.cs | 179 ++++++++---------- .../FindReferencesConsistencyCheck.cs | 11 +- ...arpCode.NRefactory.ConsistencyCheck.csproj | 2 + .../Program.cs | 4 +- .../RandomizedOrderResolverTest.cs | 4 +- .../ResolverTest.cs | 4 +- .../RoundtripTest.cs | 2 +- .../Solution.cs | 23 ++- .../TypeSystem/IProjectContent.cs | 8 +- .../Implementation/AbstractFreezable.cs | 9 - .../DefaultAssemblyReference.cs | 2 +- 14 files changed, 250 insertions(+), 134 deletions(-) create mode 100644 ICSharpCode.NRefactory.ConsistencyCheck/CSharpFile.cs diff --git a/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs b/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs index ec01a9e406..0bfc1c1d76 100644 --- a/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs +++ b/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.CSharp public class ArrayInitializerExpression : Expression { /// - /// 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 public override void AcceptVisitor (IAstVisitor visitor) { } - + public override T AcceptVisitor (IAstVisitor visitor) { return default (T); @@ -107,7 +107,7 @@ namespace ICSharpCode.NRefactory.CSharp { visitor.VisitArrayInitializerExpression (this); } - + public override T AcceptVisitor (IAstVisitor visitor) { return visitor.VisitArrayInitializerExpression (this); @@ -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 (IAstVisitor visitor) + { + return visitor.VisitPatternPlaceholder(this, child); + } + + public override S AcceptVisitor(IAstVisitor 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 } } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs index 2ddc57c691..6b33502c70 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs @@ -42,11 +42,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// Use this overload if you are resolving within a complete C# file. /// /// The current compilation. - /// The syntax tree corresponding to the specified parsed file. + /// The syntax tree to be resolved. /// - /// Optional: Result of the for the file being resolved. + /// Optional: Result of for the file being resolved. /// - /// 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. /// /// /// 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 /// Use this overload if you are resolving code snippets (not necessarily complete files). ///
/// The resolver state at the root node (to be more precise: just outside the root node). - /// The root node of the resolved tree. + /// The root node of the tree to be resolved. /// - /// Optional: Result of the for the file being resolved. + /// Optional: Result of for the file being resolved. /// - /// 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. /// /// /// 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 } /// - /// Gets the parsed file used by this CSharpAstResolver. + /// Gets the unresolved file used by this CSharpAstResolver. /// Can return null. /// public CSharpUnresolvedFile UnresolvedFile { diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/CSharpFile.cs b/ICSharpCode.NRefactory.ConsistencyCheck/CSharpFile.cs new file mode 100644 index 0000000000..addcd9e23a --- /dev/null +++ b/ICSharpCode.NRefactory.ConsistencyCheck/CSharpFile.cs @@ -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); + } + } +} diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs b/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs index e5072c4f32..d6deadb933 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/CSharpProject.cs @@ -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 { + /// + /// Represents a C# project (.csproj file) + /// public class CSharpProject { + /// + /// Parent solution. + /// public readonly Solution Solution; + + /// + /// Title is the project name as specified in the .sln file. + /// public readonly string Title; + + /// + /// Name of the output assembly. + /// public readonly string AssemblyName; + + /// + /// Full path to the .csproj file. + /// public readonly string FileName; public readonly List Files = new List(); public readonly CompilerSettings CompilerSettings = new CompilerSettings(); - public IProjectContent ProjectContent; + /// + /// The unresolved type system for this project. + /// + public readonly IProjectContent ProjectContent; - public ICompilation Compilation { - get { - return Solution.SolutionSnapshot.GetCompilation(ProjectContent); - } - } + /// + /// The resolved type system for this project. + /// This field is initialized once all projects have been loaded (in Solution constructor). + /// + 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 references = new List(); - 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 assemblySearchPaths, string evaluatedInclude) + IEnumerable 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(); - } } } diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs b/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs index 324ffb38a5..839a6c54ff 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/FindReferencesConsistencyCheck.cs @@ -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 var interestingFiles = new HashSet(); 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); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj b/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj index 9b331997fc..d1351a7ff5 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj +++ b/ICSharpCode.NRefactory.ConsistencyCheck/ICSharpCode.NRefactory.ConsistencyCheck.csproj @@ -53,6 +53,7 @@ + 3.5 @@ -70,6 +71,7 @@ Properties\GlobalAssemblyInfo.cs + diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs b/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs index 842f7fcdd1..936edfab6e 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs @@ -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); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs b/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs index e5ae47b941..a0610c4b1f 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/RandomizedOrderResolverTest.cs @@ -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>(); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs b/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs index 21bc31c8fd..be51723e5c 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/ResolverTest.cs @@ -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 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); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs b/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs index 48d29ce843..35f503d5bd 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/RoundtripTest.cs @@ -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 diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs b/ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs index 279dd81c8f..0cdde17897 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/Solution.cs @@ -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 } } } + // 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 assemblyDict = new ConcurrentDictionary(Platform.FileNameComparer); + + /// + /// Loads a referenced assembly from a .dll. + /// Returns the existing instance if the assembly was already loaded. + /// + public IUnresolvedAssembly LoadAssembly(string assemblyFileName) + { + return assemblyDict.GetOrAdd(assemblyFileName, file => new CecilLoader().LoadAssemblyFile(file)); } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs index 89db1ace15..6987d780ae 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs @@ -38,7 +38,7 @@ namespace ICSharpCode.NRefactory.TypeSystem IUnresolvedFile GetFile(string fileName); /// - /// Gets the list of all parsed files in the project content. + /// Gets the list of all files in the project content. /// IEnumerable Files { get; } @@ -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. ///
+ /// + /// You can create an unresolved file by calling ToTypeSystem() on a syntax tree. + /// IProjectContent AddOrUpdateFiles(IEnumerable newFiles); /// /// Adds the specified files to the project content. /// If a file with the same name already exists, this method updates the existing file. /// + /// + /// You can create an unresolved file by calling ToTypeSystem() on a syntax tree. + /// IProjectContent AddOrUpdateFiles(params IUnresolvedFile[] newFiles); /// diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs index 97f33cc2e2..79f2bcf90c 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs @@ -87,14 +87,5 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation protected virtual void FreezeInternal() { } - - /* - protected static IList CopyList(IList inputList) - { - if (inputList == null || inputList.Count == 0) - return null; - else - return new List(inputList); - }*/ } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs index 8987e65bf2..eb4795cac5 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAssemblyReference.cs @@ -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 From c3a31c9c81c0fb5db71e194d24c27df16336bb91 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 8 Aug 2012 18:18:49 +0200 Subject: [PATCH 6/6] Fix #92: The resolver does not check type constraints on calls to generic methods --- .../Resolver/OverloadResolution.cs | 107 +++++++++++++----- .../Resolver/OverloadResolutionErrors.cs | 15 ++- .../CSharp/Parser/ParseSelfTests.cs | 2 +- .../CSharp/Resolver/InvocationTests.cs | 28 ++++- 4 files changed, 123 insertions(+), 29 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs index ba407c76fa..e94ffa42a2 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolution.cs @@ -118,7 +118,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver public void AddError(OverloadResolutionErrors newError) { this.Errors |= newError; - this.ErrorCount++; + if (!IsApplicable(newError)) + this.ErrorCount++; } } @@ -130,6 +131,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver Candidate bestCandidate; Candidate bestCandidateAmbiguousWith; IType[] explicitlyGivenTypeArguments; + bool bestCandidateWasValidated; + OverloadResolutionErrors bestCandidateValidationResult; #region Constructor public OverloadResolution(ICompilation compilation, ResolveResult[] arguments, string[] argumentNames = null, IType[] typeArguments = null, CSharpConversions conversions = null) @@ -155,6 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } #endregion + #region Input Properties /// /// Gets/Sets whether the methods are extension methods that are being called using extension method syntax. /// @@ -183,21 +187,36 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver public IList Arguments { get { return arguments; } } + #endregion #region AddCandidate + /// + /// Adds a candidate to overload resolution. + /// + /// The candidate member to add. + /// The errors that prevent the member from being applicable, if any. + /// Note: this method does not return errors that do not affect applicability. public OverloadResolutionErrors AddCandidate(IParameterizedMember member) { return AddCandidate(member, OverloadResolutionErrors.None); } + /// + /// Adds a candidate to overload resolution. + /// + /// The candidate member to add. + /// Additional errors that apply to the candidate. + /// This is used to represent errors during member lookup (e.g. OverloadResolutionErrors.Inaccessible) + /// in overload resolution. + /// The errors that prevent the member from being applicable, if any. + /// Note: this method does not return errors that do not affect applicability. public OverloadResolutionErrors AddCandidate(IParameterizedMember member, OverloadResolutionErrors additionalErrors) { if (member == null) throw new ArgumentNullException("member"); Candidate c = new Candidate(member, false); - if (additionalErrors != OverloadResolutionErrors.None) - c.AddError(additionalErrors); + c.AddError(additionalErrors); if (CalculateCandidate(c)) { //candidates.Add(c); } @@ -206,8 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver && member.Parameters[member.Parameters.Count - 1].IsParams) { Candidate expandedCandidate = new Candidate(member, true); - if (additionalErrors != OverloadResolutionErrors.None) - expandedCandidate.AddError(additionalErrors); + expandedCandidate.AddError(additionalErrors); // consider expanded form only if it isn't obviously wrong if (CalculateCandidate(expandedCandidate)) { //candidates.Add(expandedCandidate); @@ -219,11 +237,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return c.Errors; } - public static bool IsApplicable(OverloadResolutionErrors errors) - { - return (errors & ~OverloadResolutionErrors.AmbiguousMatch) == OverloadResolutionErrors.None; - } - /// /// Calculates applicability etc. for the candidate. /// @@ -236,6 +249,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver RunTypeInference(candidate); CheckApplicability(candidate); ConsiderIfNewCandidateIsBest(candidate); + ValidateMethodConstraints(candidate); return true; } @@ -432,20 +446,36 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver #endregion #region Validate Constraints + OverloadResolutionErrors ValidateMethodConstraints(Candidate candidate) + { + // If type inference already failed, we won't check the constraints: + if ((candidate.Errors & OverloadResolutionErrors.TypeInferenceFailed) != 0) + return OverloadResolutionErrors.None; + + IMethod method = candidate.Member as IMethod; + if (method == null || method.TypeParameters.Count == 0) + return OverloadResolutionErrors.None; // the method isn't generic + var substitution = GetSubstitution(candidate); + for (int i = 0; i < method.TypeParameters.Count; i++) { + if (!ValidateConstraints(method.TypeParameters[i], substitution.MethodTypeArguments[i], substitution)) + return OverloadResolutionErrors.MethodConstraintsNotSatisfied; + } + return OverloadResolutionErrors.None; + } + /// /// Validates whether the given type argument satisfies the constraints for the given type parameter. /// /// The type parameter. /// The type argument. /// The substitution that defines how type parameters are replaced with type arguments. - /// The substitution is used to check constraints that depend on other type parameters (or recursively on the same type parameter). + /// The substitution is used to check constraints that depend on other type parameters (or recursively on the same type parameter). + /// May be null if no substitution should be used. /// True if the constraints are satisfied; false otherwise. - public static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution) + public static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution = null) { if (typeParameter == null) throw new ArgumentNullException("typeParameter"); - if (typeParameter.Owner == null) - throw new ArgumentNullException("typeParameter.Owner"); if (typeArgument == null) throw new ArgumentNullException("typeArgument"); return ValidateConstraints(typeParameter, typeArgument, substitution, CSharpConversions.Get(typeParameter.Owner.Compilation)); @@ -490,6 +520,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver #endregion #region CheckApplicability + /// + /// Returns whether a candidate with the given errors is still considered to be applicable. + /// + public static bool IsApplicable(OverloadResolutionErrors errors) + { + const OverloadResolutionErrors errorsThatDoNotMatterForApplicability = + OverloadResolutionErrors.AmbiguousMatch | OverloadResolutionErrors.MethodConstraintsNotSatisfied; + return (errors & ~errorsThatDoNotMatterForApplicability) == OverloadResolutionErrors.None; + } + void CheckApplicability(Candidate candidate) { // C# 4.0 spec: §7.5.3.1 Applicable function member @@ -697,6 +737,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver { if (bestCandidate == null) { bestCandidate = candidate; + bestCandidateWasValidated = false; } else { switch (BetterFunctionMember(candidate, bestCandidate)) { case 0: @@ -707,6 +748,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver break; case 1: bestCandidate = candidate; + bestCandidateWasValidated = false; bestCandidateAmbiguousWith = null; break; // case 2: best candidate stays best @@ -715,15 +757,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } #endregion + #region Output Properties public IParameterizedMember BestCandidate { get { return bestCandidate != null ? bestCandidate.Member : null; } } + /// + /// Returns the errors that apply to the best candidate. + /// This includes additional errors that do not affect applicability (e.g. AmbiguousMatch, MethodConstraintsNotSatisfied) + /// public OverloadResolutionErrors BestCandidateErrors { get { if (bestCandidate == null) return OverloadResolutionErrors.None; - OverloadResolutionErrors err = bestCandidate.Errors; + if (!bestCandidateWasValidated) { + bestCandidateValidationResult = ValidateMethodConstraints(bestCandidate); + bestCandidateWasValidated = true; + } + OverloadResolutionErrors err = bestCandidate.Errors | bestCandidateValidationResult; if (bestCandidateAmbiguousWith != null) err |= OverloadResolutionErrors.AmbiguousMatch; return err; @@ -731,7 +782,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } public bool FoundApplicableCandidate { - get { return bestCandidate != null && bestCandidate.Errors == OverloadResolutionErrors.None; } + get { return bestCandidate != null && IsApplicable(bestCandidate.Errors); } } public IParameterizedMember BestCandidateAmbiguousWith { @@ -848,21 +899,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return null; IMethod method = bestCandidate.Member as IMethod; if (method != null && method.TypeParameters.Count > 0) { - SpecializedMethod sm = method as SpecializedMethod; - if (sm != null) { - // Do not compose the substitutions, but merge them. - // This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce - return new SpecializedMethod( - (IMethod)method.MemberDefinition, - new TypeParameterSubstitution(sm.Substitution.ClassTypeArguments, bestCandidate.InferredTypes)); - } else { - return new SpecializedMethod(method, new TypeParameterSubstitution(null, bestCandidate.InferredTypes)); - } + return new SpecializedMethod((IMethod)method.MemberDefinition, GetSubstitution(bestCandidate)); } else { return bestCandidate.Member; } } + TypeParameterSubstitution GetSubstitution(Candidate candidate) + { + SpecializedMethod sm = candidate.Member as SpecializedMethod; + if (sm != null) { + // Do not compose the substitutions, but merge them. + // This is required for InvocationTests.SubstituteClassAndMethodTypeParametersAtOnce + return new TypeParameterSubstitution(sm.Substitution.ClassTypeArguments, candidate.InferredTypes); + } else { + return new TypeParameterSubstitution(null, candidate.InferredTypes); + } + } + /// /// Creates a ResolveResult representing the result of overload resolution. /// @@ -890,5 +944,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver argumentToParameterMap: this.GetArgumentToParameterMap(), initializerStatements: initializerStatements); } + #endregion } } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolutionErrors.cs b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolutionErrors.cs index 1b1ea2c91c..399f2ff091 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolutionErrors.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/OverloadResolutionErrors.cs @@ -65,10 +65,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// There is no unique best overload. /// This error does not apply to any single candidate, but only to the overall result of overload resolution. /// + /// + /// This error does not prevent a candidate from being applicable. + /// AmbiguousMatch = 0x0200, /// /// The member is not accessible. /// - Inaccessible = 0x0400 + /// + /// This error is generated by member lookup; not by overload resolution. + /// + Inaccessible = 0x0400, + /// + /// A generic method + /// + /// + /// This error does not prevent a candidate from being applicable. + /// + MethodConstraintsNotSatisfied = 0x0800 } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs index 2bc9f88760..54abb3fb5d 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs @@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser [TestFixtureSetUp] public void SetUp() { - string path = Path.GetFullPath (Path.Combine ("..", "..", "..")); + string path = Path.GetFullPath (Path.Combine ("..", "..")); if (!File.Exists(Path.Combine(path, "NRefactory.sln"))) throw new InvalidOperationException("Test cannot find the NRefactory source code in " + path); fileNames = Directory.GetFiles(path, "*.cs", SearchOption.AllDirectories); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs index 6f1946dd3a..5814490df3 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/InvocationTests.cs @@ -598,7 +598,7 @@ class Test { [Test] public void NamedArgumentInMissingMethod() { - string program = @" + string program = @" class Test { public void Test() { Missing($x: 0$); @@ -609,5 +609,31 @@ class Test { Assert.AreEqual("x", narr.ParameterName); Assert.IsNull(narr.Parameter); } + + [Test] + public void GenericMethodInvocationWithConstraintMismatch() + { + string program = @" +interface IA +{ +} +class Test +{ + void F() + { + string o = null; + $M(o)$; + } + + void M(T arg) where T : IA + { + } + void M(object arg) { + } +}"; + var rr = Resolve(program); + Assert.AreEqual(OverloadResolutionErrors.MethodConstraintsNotSatisfied, rr.OverloadResolutionErrors); + Assert.IsTrue(rr.IsError); + } } }