diff --git a/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs b/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs index e16fee1909..d5463020f5 100644 --- a/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs +++ b/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs @@ -169,7 +169,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis throw new NotImplementedException(); } - public IList BuildControlFlowGraph(Statement statement, ResolveVisitor resolveVisitor) + internal IList BuildControlFlowGraph(Statement statement, ResolveVisitor resolveVisitor) { if (statement == null) throw new ArgumentNullException("statement"); diff --git a/ICSharpCode.NRefactory.CSharp/Ast/CompilationUnit.cs b/ICSharpCode.NRefactory.CSharp/Ast/CompilationUnit.cs index 92a0df4cd6..3f3f0d08e7 100644 --- a/ICSharpCode.NRefactory.CSharp/Ast/CompilationUnit.cs +++ b/ICSharpCode.NRefactory.CSharp/Ast/CompilationUnit.cs @@ -1,6 +1,6 @@ // // CompilationUnit.cs -// +// // Author: // Mike Krüger // @@ -25,12 +25,13 @@ // THE SOFTWARE. using System; using System.Collections.Generic; +using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.TypeSystem; namespace ICSharpCode.NRefactory.CSharp { - public class CompilationUnit : AstNode + public class CompilationUnit : AstNode { public static readonly Role MemberRole = new Role("Member", AstNode.Null); @@ -40,6 +41,11 @@ namespace ICSharpCode.NRefactory.CSharp } } + /// + /// Gets/Sets the file name of this compilation unit. + /// + public string FileName { get; set; } + List errors = new List (); public List Errors { @@ -72,7 +78,7 @@ namespace ICSharpCode.NRefactory.CSharp yield return (TypeDeclaration)curNode; foreach (var child in curNode.Children) { if (!(child is Statement || child is Expression) && - (child.Role != TypeDeclaration.MemberRole || (child is TypeDeclaration && includeInnerTypes))) + (child.Role != TypeDeclaration.MemberRole || (child is TypeDeclaration && includeInnerTypes))) nodeStack.Push (child); } } @@ -92,9 +98,13 @@ namespace ICSharpCode.NRefactory.CSharp /// /// Converts this compilation unit into a parsed file that can be stored in the type system. /// - public CSharpParsedFile ToTypeSystem(string fileName) + public CSharpParsedFile ToTypeSystem() { - return new TypeSystemConvertVisitor(fileName).Convert(this); + if (string.IsNullOrEmpty(this.FileName)) + throw new InvalidOperationException("Cannot use ToTypeSystem() on a compilation unit without file name."); + var v = new TypeSystemConvertVisitor(this.FileName); + v.VisitCompilationUnit(this, null); + return v.ParsedFile; } } } diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj index e0df2fb60a..2d07941aa5 100644 --- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj +++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj @@ -273,6 +273,7 @@ + diff --git a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs index 98e7d887f8..eae983b0a6 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs @@ -3379,7 +3379,7 @@ namespace ICSharpCode.NRefactory.CSharp } } - public CompilationUnit Parse (TextReader reader, int line = 0) + public CompilationUnit Parse (TextReader reader, string fileName, int lineModifier = 0) { // TODO: can we optimize this to avoid the text->stream->text roundtrip? using (MemoryStream stream = new MemoryStream ()) { @@ -3390,21 +3390,21 @@ namespace ICSharpCode.NRefactory.CSharp w.Write (buffer, 0, read); w.Flush (); // we can't close the StreamWriter because that would also close the MemoryStream stream.Position = 0; - return Parse (stream, line); + return Parse (stream, fileName, lineModifier); } } - public static void AdjustLineLocations (AstNode node, int line) + public static void AdjustLineLocations (AstNode node, int lineModifier) { if (node is IRelocatable) { - ((IRelocatable)node).SetStartLocation (new TextLocation (node.StartLocation.Line + line, node.StartLocation.Column)); + ((IRelocatable)node).SetStartLocation (new TextLocation (node.StartLocation.Line + lineModifier, node.StartLocation.Column)); } foreach (var child in node.Children) { - AdjustLineLocations (child, line); + AdjustLineLocations (child, lineModifier); } } - public CompilationUnit Parse (CompilerCompilationUnit top, int line) + public CompilationUnit Parse (CompilerCompilationUnit top, string fileName, int lineModifier = 0) { if (top == null) return null; @@ -3414,10 +3414,11 @@ namespace ICSharpCode.NRefactory.CSharp InsertComments (top, conversionVisitor); if (CompilationUnitCallback != null) CompilationUnitCallback (top); - if (line != 0) - AdjustLineLocations (conversionVisitor.Unit, line); + if (lineModifier != 0) + AdjustLineLocations (conversionVisitor.Unit, lineModifier); if (top.LastYYValue is Mono.CSharp.Expression) conversionVisitor.Unit.TopExpression = ((Mono.CSharp.Expression)top.LastYYValue).Accept (conversionVisitor) as AstNode; + conversionVisitor.Unit.FileName = fileName; return conversionVisitor.Unit; } @@ -3436,17 +3437,17 @@ namespace ICSharpCode.NRefactory.CSharp set; } - public CompilationUnit Parse (string program) + public CompilationUnit Parse (string program, string fileName) { - return Parse (new StringReader (program)); + return Parse (new StringReader (program), fileName); } - public CompilationUnit Parse (Stream stream, int line = 0) + public CompilationUnit Parse (Stream stream, string fileName, int lineModifier = 0) { lock (CompilerCallableEntryPoint.parseLock) { errorReportPrinter = new ErrorReportPrinter (""); - CompilerCompilationUnit top = CompilerCallableEntryPoint.ParseFile (CompilerArguments, stream, "parsed.cs", errorReportPrinter); - var unit = Parse (top, line); + CompilerCompilationUnit top = CompilerCallableEntryPoint.ParseFile (CompilerArguments, stream, fileName, errorReportPrinter); + var unit = Parse (top, fileName, lineModifier); unit.Errors.AddRange (errorReportPrinter.Errors); return unit; } @@ -3455,7 +3456,7 @@ namespace ICSharpCode.NRefactory.CSharp public IEnumerable ParseTypeMembers (TextReader reader, int lineModifier = 0) { string code = "unsafe partial class MyClass { " + Environment.NewLine + reader.ReadToEnd () + "}"; - var cu = Parse (new StringReader (code), -1 + lineModifier); + var cu = Parse (new StringReader (code), "parsed.cs", lineModifier - 1); if (cu == null) return Enumerable.Empty (); var td = cu.Children.FirstOrDefault () as TypeDeclaration; diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs new file mode 100644 index 0000000000..94cb773c89 --- /dev/null +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs @@ -0,0 +1,128 @@ +// 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 ICSharpCode.NRefactory.CSharp.TypeSystem; +using ICSharpCode.NRefactory.Semantics; +using ICSharpCode.NRefactory.TypeSystem; + +namespace ICSharpCode.NRefactory.CSharp.Resolver +{ + /// + /// Resolves C# AST nodes. + /// + public class CSharpAstResolver + { + readonly CSharpResolver initialResolverState; + readonly AstNode rootNode; + readonly CSharpParsedFile parsedFile; + ResolveVisitor resolveVisitor; + + /// + /// Creates a new C# AST resolver. + /// + /// The current compilation. + /// + /// Result of the for the file being passed. This is used for setting up the context on the resolver. The parsed file must be registered in the compilation. + /// + /// The compilation unit corresponding to the specified parsed file. + public CSharpAstResolver(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile) + { + if (compilation == null) + throw new ArgumentNullException("compilation"); + if (parsedFile == null) + throw new ArgumentNullException("parsedFile"); + if (compilationUnit == null) + throw new ArgumentNullException("compilationUnit"); + this.initialResolverState = new CSharpResolver(compilation); + this.rootNode = compilationUnit; + this.parsedFile = parsedFile; + } + + /// + /// Creates a new C# AST resolver. + /// + /// The resolver state at the root node. + /// The root node of the resolved tree. + /// The parsed file for the nodes being resolved. This parameter is used only + /// when the root node is on the type level; it is not necessary when an expression is passed. + /// This parameter may be null. + public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpParsedFile parsedFile = null) + { + if (resolver == null) + throw new ArgumentNullException("resolver"); + if (rootNode == null) + throw new ArgumentNullException("rootNode"); + this.initialResolverState = resolver.Clone(); + this.rootNode = rootNode; + this.parsedFile = parsedFile; + } + + /// + /// Applies a resolver navigator. This will resolve the nodes requested by the navigator, and will inform the + /// navigator of the results. + /// This method must be called as the first operation on the CSharpAstResolver, it is invalid to apply a navigator + /// after a portion of the file was already resolved. + /// + public void ApplyNavigator(IResolveVisitorNavigator navigator) + { + if (resolveVisitor != null) + throw new InvalidOperationException("Applying a navigator is only valid as the first operation on the CSharpAstResolver."); + resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, navigator); + lock (resolveVisitor) + resolveVisitor.Scan(rootNode); + } + + /// + /// Resolves the specified node. + /// + public ResolveResult Resolve(AstNode node) + { + if (resolveVisitor == null) { + resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile); + resolveVisitor.Scan(rootNode); + } + lock (resolveVisitor) + return resolveVisitor.GetResolveResult(node); + } + + /// + /// Gets the expected type for the specified node. This is the type being that a node is being converted to. + /// + public IType GetExpectedType(Expression expr) + { + throw new NotImplementedException(); + } + + /// + /// Gets the conversion that is being applied to the specified expression. + /// + public Conversion GetConversion(Expression expr) + { + throw new NotImplementedException(); + } + + /// + /// Gets whether the specified node is unresolvable. + /// + public static bool IsUnresolvableNode(AstNode node) + { + return (node.NodeType == NodeType.Whitespace || node is ArraySpecifier || node is NamedArgumentExpression); + } + } +} diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/CompositeResolveVisitorNavigator.cs b/ICSharpCode.NRefactory.CSharp/Resolver/CompositeResolveVisitorNavigator.cs index e810c435a7..8a0111ffb7 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/CompositeResolveVisitorNavigator.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/CompositeResolveVisitorNavigator.cs @@ -31,6 +31,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver if (navigators == null) throw new ArgumentNullException("navigators"); this.navigators = navigators; + foreach (var n in navigators) { + if (n == null) + throw new ArgumentException("Array must not contain nulls."); + } } public ResolveVisitorNavigationMode Scan(AstNode node) diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs index 80cc8d7934..3629035320 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferenceSearchScope.cs @@ -26,6 +26,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// public interface IFindReferenceSearchScope { + /// + /// Gets the parent compilation for this search scope. + /// + ICompilation Compilation { get; } + /// /// Gets the search term. Only files that contain this identifier need to be parsed. /// Can return null if all files need to be parsed. diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs index 99b6e6e867..11b45e98d8 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs @@ -96,11 +96,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver abstract class SearchScope : IResolveVisitorNavigator, IFindReferenceSearchScope { protected string searchTerm; + internal ICompilation compilation; internal Accessibility accessibility; internal ITypeDefinition topLevelTypeDefinition; FoundReferenceCallback callback; + ICompilation IFindReferenceSearchScope.Compilation { + get { return compilation; } + } + IResolveVisitorNavigator IFindReferenceSearchScope.GetNavigator(FoundReferenceCallback callback) { SearchScope n = (SearchScope)MemberwiseClone(); @@ -203,10 +208,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } if (scope.accessibility == Accessibility.None) scope.accessibility = effectiveAccessibility; + scope.compilation = entity.Compilation; scope.topLevelTypeDefinition = topLevelTypeDefinition; if (additionalScope != null) { if (additionalScope.accessibility == Accessibility.None) additionalScope.accessibility = effectiveAccessibility; + additionalScope.compilation = entity.Compilation; additionalScope.topLevelTypeDefinition = topLevelTypeDefinition; return new[] { scope, additionalScope }; } else { @@ -277,7 +284,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// The type resolve context to use for resolving the file. /// Callback used to report the references that were found. public void FindReferencesInFile(IFindReferenceSearchScope searchScope, CSharpParsedFile parsedFile, CompilationUnit compilationUnit, - FoundReferenceCallback callback, CancellationToken cancellationToken) + FoundReferenceCallback callback, CancellationToken cancellationToken) { if (searchScope == null) throw new ArgumentNullException("searchScope"); @@ -290,8 +297,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// The search scopes for which to look. /// The type system representation of the file being searched. /// The compilation unit of the file being searched. - /// The type resolve context to use for resolving the file. /// Callback used to report the references that were found. + /// Cancellation token. public void FindReferencesInFile(IList searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit, FoundReferenceCallback callback, CancellationToken cancellationToken) { @@ -301,24 +308,26 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver throw new ArgumentNullException("parsedFile"); if (compilationUnit == null) throw new ArgumentNullException("compilationUnit"); - throw new NotImplementedException(); - /* - if (context == null) - throw new ArgumentNullException("context"); if (searchScopes.Count == 0) return; - using (var ctx = context.Synchronize()) { - IResolveVisitorNavigator navigator; - if (searchScopes.Count == 1) - navigator = searchScopes[0].GetNavigator(callback); - else - navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray()); - navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit); - CSharpResolver resolver = new CSharpResolver(ctx, this.CancellationToken); - ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator); - v.Scan(compilationUnit); - }*/ + ICompilation compilation = searchScopes[0].Compilation; + IResolveVisitorNavigator navigator; + if (searchScopes.Count == 1) { + navigator = searchScopes[0].GetNavigator(callback); + } else { + IResolveVisitorNavigator[] navigators = new IResolveVisitorNavigator[searchScopes.Count]; + for (int i = 0; i < navigators.Length; i++) { + if (searchScopes[i].Compilation != compilation) + throw new InvalidOperationException("All search scopes must belong to the same compilation"); + navigators[i] = searchScopes[i].GetNavigator(callback); + } + navigator = new CompositeResolveVisitorNavigator(navigators); + } + + navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile); + resolver.ApplyNavigator(navigator); } #endregion diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/IResolveVisitorNavigator.cs b/ICSharpCode.NRefactory.CSharp/Resolver/IResolveVisitorNavigator.cs index 7a568cc41f..4c455faba7 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/IResolveVisitorNavigator.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/IResolveVisitorNavigator.cs @@ -83,7 +83,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver this.targetForResolveCalls = targetForResolveCalls; } - ResolveVisitorNavigationMode IResolveVisitorNavigator.Scan(AstNode node) { return mode; diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/NodeListResolveVisitorNavigator.cs b/ICSharpCode.NRefactory.CSharp/Resolver/NodeListResolveVisitorNavigator.cs index 6737c10649..0a1b684c35 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/NodeListResolveVisitorNavigator.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/NodeListResolveVisitorNavigator.cs @@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// implementation that resolves a list of nodes. /// We will skip all nodes which are not the target nodes or ancestors of the target nodes. /// - public sealed class NodeListResolveVisitorNavigator : IResolveVisitorNavigator + public class NodeListResolveVisitorNavigator : IResolveVisitorNavigator { readonly Dictionary dict = new Dictionary(); @@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } /// - public ResolveVisitorNavigationMode Scan(AstNode node) + public virtual ResolveVisitorNavigationMode Scan(AstNode node) { ResolveVisitorNavigationMode mode; if (dict.TryGetValue(node, out mode)) { @@ -65,11 +65,11 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver } } - void IResolveVisitorNavigator.Resolved(AstNode node, ResolveResult result) + public virtual void Resolved(AstNode node, ResolveResult result) { } - void IResolveVisitorNavigator.ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) + public virtual void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) { } } diff --git a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs index a81d3dd83a..0ddcbbe87e 100644 --- a/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs @@ -53,7 +53,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// Moreover, there is the ResolveAll mode - it works similar to resolving mode, but will not switch back to scanning mode. /// The whole subtree will be resolved without notifying the navigator. /// - public sealed class ResolveVisitor : IAstVisitor + sealed class ResolveVisitor : IAstVisitor { // The ResolveVisitor is also responsible for handling lambda expressions. @@ -359,7 +359,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// public ResolveResult GetResolveResult(AstNode node) { - if (IsUnresolvableNode(node)) + if (CSharpAstResolver.IsUnresolvableNode(node)) return null; MergeUndecidedLambdas(); @@ -397,14 +397,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver return null; } - /// - /// Gets whether the specified node is unresolvable. - /// - public static bool IsUnresolvableNode(AstNode node) - { - return (node.NodeType == NodeType.Whitespace || node is ArraySpecifier || node is NamedArgumentExpression); - } - /// /// Gets the resolve result for the specified node. /// If the node was not resolved by the navigator, this method will return null. diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs index c302734cba..379ebe2eeb 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpAssembly.cs @@ -194,6 +194,12 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem } } + public IEnumerable TopLevelTypeDefinitions { + get { + return GetTypes().Values; + } + } + sealed class NS : INamespace { readonly CSharpAssembly assembly; diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/ResolvedUsingScope.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/ResolvedUsingScope.cs index 5aa606309e..120369de19 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/ResolvedUsingScope.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/ResolvedUsingScope.cs @@ -35,7 +35,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem { readonly CSharpTypeResolveContext parentContext; readonly UsingScope usingScope; - readonly CSharpResolver resolver; internal readonly ConcurrentDictionary ResolveCache = new ConcurrentDictionary(); internal List> AllExtensionMethods; diff --git a/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs b/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs index 8bafe65e91..642c1b2d88 100644 --- a/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs @@ -78,12 +78,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem this.currentTypeDefinition = currentTypeDefinition; } - public CSharpParsedFile Convert(AstNode node) - { - node.AcceptVisitor(this, null); - return parsedFile; - } - public CSharpParsedFile ParsedFile { get { return parsedFile; } } diff --git a/ICSharpCode.NRefactory.Demo/CSDemo.cs b/ICSharpCode.NRefactory.Demo/CSDemo.cs index 08a1d720af..37b6334b19 100644 --- a/ICSharpCode.NRefactory.Demo/CSDemo.cs +++ b/ICSharpCode.NRefactory.Demo/CSDemo.cs @@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.Demo void CSharpParseButtonClick(object sender, EventArgs e) { CSharpParser parser = new CSharpParser(); - compilationUnit = parser.Parse(new StringReader(csharpCodeTextBox.Text)); + compilationUnit = parser.Parse(new StringReader(csharpCodeTextBox.Text), "dummy.cs"); csharpTreeView.Nodes.Clear(); foreach (var element in compilationUnit.Children) { csharpTreeView.Nodes.Add(MakeTreeNode(element)); @@ -200,36 +200,73 @@ namespace ICSharpCode.NRefactory.Demo void ResolveButtonClick(object sender, EventArgs e) { IProjectContent project = new CSharpProjectContent(); - var parsedFile = compilationUnit.ToTypeSystem("dummy.cs"); + var parsedFile = compilationUnit.ToTypeSystem(); project = project.UpdateProjectContent(null, parsedFile); project = project.AddAssemblyReferences(builtInLibs.Value); ICompilation compilation = project.CreateCompilation(); - CSharpResolver resolver = new CSharpResolver(compilation); - IResolveVisitorNavigator navigator = null; + StoreInDictionaryNavigator navigator; if (csharpTreeView.SelectedNode != null) { - navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag }); + navigator = new StoreInDictionaryNavigator((AstNode)csharpTreeView.SelectedNode.Tag); + } else { + navigator = new StoreInDictionaryNavigator(); } - ResolveVisitor visitor = new ResolveVisitor(resolver, parsedFile, navigator); - visitor.Scan(compilationUnit); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile); + resolver.ApplyNavigator(navigator); csharpTreeView.BeginUpdate(); - ShowResolveResultsInTree(csharpTreeView.Nodes, visitor); + ShowResolveResultsInTree(csharpTreeView.Nodes, navigator); csharpTreeView.EndUpdate(); } - void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v) + sealed class StoreInDictionaryNavigator : NodeListResolveVisitorNavigator + { + internal Dictionary resolveResults = new Dictionary(); + internal Dictionary conversions = new Dictionary(); + internal Dictionary conversionTargetTypes = new Dictionary(); + bool resolveAll; + + public StoreInDictionaryNavigator(params AstNode[] nodes) + : base(nodes) + { + resolveAll = (nodes.Length == 0); + } + + public override ResolveVisitorNavigationMode Scan(AstNode node) + { + if (resolveAll) + return ResolveVisitorNavigationMode.Resolve; + else + return base.Scan(node); + } + + public override void Resolved(AstNode node, ResolveResult result) + { + resolveResults.Add(node, result); + } + + public override void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType) + { + conversions.Add(expression, conversion); + conversionTargetTypes.Add(expression, targetType); + } + } + + void ShowResolveResultsInTree(TreeNodeCollection c, StoreInDictionaryNavigator n) { foreach (TreeNode t in c) { AstNode node = t.Tag as AstNode; if (node != null) { - ResolveResult rr = v.GetResolveResultIfResolved(node); - if (rr != null) - t.Text = GetNodeTitle(node) + " " + rr.ToString(); - else - t.Text = GetNodeTitle(node); + ResolveResult rr; + string text = GetNodeTitle(node); + if (n.resolveResults.TryGetValue(node, out rr)) + text += " " + rr.ToString(); + if (n.conversions.ContainsKey(node)) { + text += " [" + n.conversions[node] + " to " + n.conversionTargetTypes[node] + "]"; + } + t.Text = text; } - ShowResolveResultsInTree(t.Nodes, v); + ShowResolveResultsInTree(t.Nodes, n); } } @@ -253,20 +290,17 @@ namespace ICSharpCode.NRefactory.Demo return; IProjectContent project = new CSharpProjectContent(); - var parsedFile = compilationUnit.ToTypeSystem("dummy.cs"); + var parsedFile = compilationUnit.ToTypeSystem(); project = project.UpdateProjectContent(null, parsedFile); project = project.AddAssemblyReferences(builtInLibs.Value); ICompilation compilation = project.CreateCompilation(); - CSharpResolver resolver = new CSharpResolver(compilation); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile); AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag; - IResolveVisitorNavigator navigator = new NodeListResolveVisitorNavigator(new[] { node }); - ResolveVisitor visitor = new ResolveVisitor(resolver, parsedFile, navigator); - visitor.Scan(compilationUnit); IEntity entity; - MemberResolveResult mrr = visitor.GetResolveResult(node) as MemberResolveResult; - TypeResolveResult trr = visitor.GetResolveResult(node) as TypeResolveResult; + MemberResolveResult mrr = resolver.Resolve(node) as MemberResolveResult; + TypeResolveResult trr = resolver.Resolve(node) as TypeResolveResult; if (mrr != null) { entity = mrr.Member; } else if (trr != null) { @@ -282,13 +316,7 @@ namespace ICSharpCode.NRefactory.Demo }; var searchScopes = fr.GetSearchScopes(entity); - navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray()); - visitor = new ResolveVisitor(resolver, parsedFile, navigator); - visitor.Scan(compilationUnit); - - csharpTreeView.BeginUpdate(); - ShowResolveResultsInTree(csharpTreeView.Nodes, visitor); - csharpTreeView.EndUpdate(); + fr.FindReferencesInFile(searchScopes, parsedFile, compilationUnit, callback, CancellationToken.None); MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs index c43489ee72..966b5867d3 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/UsingDeclarationTests.cs @@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope { string program = "using\n"; CSharpParser parser = new CSharpParser(); - CompilationUnit cu = parser.Parse (program); + CompilationUnit cu = parser.Parse (program, "parsed.cs"); Assert.AreEqual(0, cu.Children.Count()); Assert.IsTrue(parser.HasErrors); } @@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope string program = "using System;\n" + "using My.Name.Space;\n"; CSharpParser parser = new CSharpParser(); - CompilationUnit cu = parser.Parse(new StringReader(program)); + CompilationUnit cu = parser.Parse(new StringReader(program), "parsed.cs"); Assert.IsFalse(parser.HasErrors); Assert.AreEqual(2, cu.Children.Count()); @@ -64,7 +64,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope "using myAlias=My.Name.Space;\n" + "using StringCollection = System.Collections.Generic.List;\n"; CSharpParser parser = new CSharpParser(); - CompilationUnit cu = parser.Parse(new StringReader(program)); + CompilationUnit cu = parser.Parse(new StringReader(program), "parsed.cs"); Assert.IsFalse(parser.HasErrors); Assert.AreEqual(3, cu.Children.Count()); @@ -92,7 +92,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope "using myAlias=global::My.Name.Space;\n" + "using a::b.c;\n"; CSharpParser parser = new CSharpParser(); - CompilationUnit cu = parser.Parse(new StringReader(program)); + CompilationUnit cu = parser.Parse(new StringReader(program), "parsed.cs"); Assert.IsFalse(parser.HasErrors); Assert.AreEqual(3, cu.Children.Count()); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs index bb720e07c3..77f4fdd732 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseSelfTests.cs @@ -52,9 +52,9 @@ namespace ICSharpCode.NRefactory.CSharp.Parser foreach (string fileName in fileNames) { CompilationUnit cu; using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan)) { - cu = parser.Parse(fs); + cu = parser.Parse(fs, fileName); } - var parsedFile = cu.ToTypeSystem(fileName); + var parsedFile = cu.ToTypeSystem(); foreach (var td in parsedFile.GetAllTypeDefinitions()) { Assert.AreSame(parsedFile, td.ParsedFile); foreach (var member in td.Members) { @@ -76,7 +76,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser CSharpParser parser = new CSharpParser(); foreach (string fileName in fileNames) { this.currentDocument = new ReadOnlyDocument(File.ReadAllText(fileName)); - CompilationUnit cu = parser.Parse(currentDocument.CreateReader()); + CompilationUnit cu = parser.Parse(currentDocument.CreateReader(), fileName); if (parser.HasErrors) continue; this.currentFileName = fileName; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs index 2e9c6b6ece..e4527d3a00 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/ParseUtil.cs @@ -33,7 +33,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser public static T ParseGlobal(string code, bool expectErrors = false) where T : AstNode { CSharpParser parser = new CSharpParser(); - CompilationUnit cu = parser.Parse(new StringReader(code)); + CompilationUnit cu = parser.Parse(new StringReader(code), "parsed.cs"); if (parser.HasErrors) parser.ErrorPrinter.Errors.ForEach (err => Console.WriteLine (err.Message)); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs index bb9ce196b4..32591e010a 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeMembers/PropertyDeclarationTests.cs @@ -72,7 +72,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.TypeMembers int line4Pos = code.IndexOf("\t\tset"); CSharpParser parser = new CSharpParser(); - CompilationUnit cu = parser.Parse(new StringReader(code)); + CompilationUnit cu = parser.Parse(new StringReader(code), "parsed.cs"); PropertyDeclaration pd = (PropertyDeclaration)cu.Children.Single().GetChildByRole(TypeDeclaration.MemberRole); Assert.AreEqual(new TextLocation(2, code.IndexOf("{\n\t\tget") - line2Pos + 1), pd.GetChildByRole(AstNode.Roles.LBrace).StartLocation); Assert.AreEqual(new TextLocation(5, 3), pd.EndLocation); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs index 4621f97bef..178aa4e333 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs @@ -41,10 +41,10 @@ namespace ICSharpCode.NRefactory.CSharp.Parser CSharpParser parser = new CSharpParser(); CompilationUnit cu; using (Stream s = typeof(TypeSystemTests).Assembly.GetManifestResourceStream(typeof(TypeSystemTests), fileName)) { - cu = parser.Parse(s); + cu = parser.Parse(s, fileName); } - var parsedFile = cu.ToTypeSystem(fileName); + var parsedFile = cu.ToTypeSystem(); return new CSharpProjectContent() .UpdateProjectContent(null, parsedFile) .AddAssemblyReferences(new[] { CecilLoaderTests.Mscorlib }) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs index a8ad261a9e..4288448785 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs @@ -63,7 +63,7 @@ namespace OtherNS { { pc = new CSharpProjectContent(); pc = pc.SetAssemblyName("MyAssembly"); - parsedFile = new CSharpParser().Parse(new StringReader(program)).ToTypeSystem("program.cs"); + parsedFile = new CSharpParser().Parse(new StringReader(program), "program.cs").ToTypeSystem(); pc = pc.UpdateProjectContent(null, parsedFile); pc = pc.AddAssemblyReferences(new [] { CecilLoaderTests.Mscorlib }); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs index 59d531af44..d0187510a6 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs @@ -40,8 +40,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver CSharpParsedFile Parse(string program) { - CompilationUnit cu = new CSharpParser().Parse(new StringReader(program)); - CSharpParsedFile parsedFile = cu.ToTypeSystem("test.cs"); + CompilationUnit cu = new CSharpParser().Parse(new StringReader(program), "test.cs"); + CSharpParsedFile parsedFile = cu.ToTypeSystem(); project = project.UpdateProjectContent(null, parsedFile); compilation = project.CreateCompilation(); return parsedFile; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs index 7ef89de6db..49f282b1a1 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ResolverTestBase.cs @@ -151,14 +151,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver protected ResolveResult Resolve(string code) { - CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", ""))); + CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", "")), "code.cs"); TextLocation[] dollars = FindDollarSigns(code).ToArray(); Assert.AreEqual(2, dollars.Length, "Expected 2 dollar signs marking start+end of desired node"); SetUp(); - CSharpParsedFile parsedFile = cu.ToTypeSystem("code.cs"); + CSharpParsedFile parsedFile = cu.ToTypeSystem(); project = project.UpdateProjectContent(null, parsedFile); compilation = project.CreateCompilation(); @@ -169,10 +169,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver Debug.WriteLine(new string('=', 70)); Debug.WriteLine("Starting new resolver for " + fnv.ResultNode); - var navigator = new NodeListResolveVisitorNavigator(new[] { fnv.ResultNode }); - ResolveVisitor rv = new ResolveVisitor(new CSharpResolver(compilation), parsedFile, navigator); - rv.Scan(cu); - ResolveResult rr = rv.GetResolveResult(fnv.ResultNode); + CSharpAstResolver resolver = new CSharpAstResolver(compilation, cu, parsedFile); + ResolveResult rr = resolver.Resolve(fnv.ResultNode); Assert.IsNotNull(rr, "ResolveResult is null - did something go wrong while navigating to the target node?"); Debug.WriteLine("ResolveResult is " + rr); return rr; @@ -212,14 +210,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver protected ResolveResult ResolveAtLocation(string code) { - CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", ""))); + CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", "")), "test.cs"); TextLocation[] dollars = FindDollarSigns(code).ToArray(); Assert.AreEqual(1, dollars.Length, "Expected 1 dollar signs marking the location"); SetUp(); - CSharpParsedFile parsedFile = cu.ToTypeSystem("test.cs"); + CSharpParsedFile parsedFile = cu.ToTypeSystem(); project = project.UpdateProjectContent(null, parsedFile); compilation = project.CreateCompilation(); diff --git a/ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs b/ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs index b127d10529..af3e0f2194 100644 --- a/ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs +++ b/ICSharpCode.NRefactory.Tests/FormattingTests/TextEditorTestAdapter.cs @@ -54,7 +54,7 @@ namespace ICSharpCode.NRefactory.FormattingTests var adapter = new ReadOnlyDocument (input); var visitor = new AstFormattingVisitor (policy, adapter, factory); - var compilationUnit = new CSharpParser ().Parse (new StringReader (input)); + var compilationUnit = new CSharpParser ().Parse (new StringReader (input), "test.cs"); compilationUnit.AcceptVisitor (visitor, null); return new ReadOnlyDocument(ApplyChanges (input, visitor.Changes)); @@ -74,7 +74,7 @@ namespace ICSharpCode.NRefactory.FormattingTests { var visitior = new AstFormattingVisitor (policy, document, factory); - var compilationUnit = new CSharpParser ().Parse (new StringReader (document.Text)); + var compilationUnit = new CSharpParser ().Parse (new StringReader (document.Text), "test.cs"); compilationUnit.AcceptVisitor (visitior, null); string newText = ApplyChanges (document.Text, visitior.Changes); if (expectedOutput != newText) { diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs index c764cdc01a..651fbe78cb 100644 --- a/ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs +++ b/ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs @@ -58,37 +58,6 @@ namespace ICSharpCode.NRefactory.TypeSystem Assert.AreEqual(1, resolvedC.GetMethods(m => m.Name == "ToString").Count()); } - [Test, Ignore] - public void ArrayType() - { - IType arrayType = compilation.FindType(typeof(string[])); - // Array inherits ToString() from System.Object - Assert.AreEqual("System.Object.ToString", arrayType.GetMethods(m => m.Name == "ToString").Single().FullName); - Assert.AreEqual("System.Array.GetLowerBound", arrayType.GetMethods(m => m.Name == "GetLowerBound").Single().FullName); - Assert.AreEqual("System.Array.Length", arrayType.GetProperties(p => p.Name == "Length").Single().FullName); - - // test indexer - IProperty indexer = arrayType.GetProperties(p => p.IsIndexer).Single(); - Assert.AreEqual("System.Array.Items", indexer.FullName); - Assert.AreEqual("System.String", indexer.ReturnType.ReflectionName); - Assert.AreEqual(1, indexer.Parameters.Count); - Assert.AreEqual("System.Int32", indexer.Parameters[0].Type.ReflectionName); - } - - [Test, Ignore] - public void MultidimensionalArrayType() - { - IType arrayType = compilation.FindType(typeof(string[,][])); - - // test indexer - IProperty indexer = arrayType.GetProperties(p => p.IsIndexer).Single(); - Assert.AreEqual("System.Array.Items", indexer.FullName); - Assert.AreEqual("System.String[]", indexer.ReturnType.ReflectionName); - Assert.AreEqual(2, indexer.Parameters.Count); - Assert.AreEqual("System.Int32", indexer.Parameters[0].Type.ReflectionName); - Assert.AreEqual("System.Int32", indexer.Parameters[1].Type.ReflectionName); - } - [Test] public void GetNestedTypesOfUnboundGenericClass() { diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index df02ee53c8..7c3473ddf4 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -20,12 +20,14 @@ ..\ICSharpCode.NRefactory.snk False File + bin\Release\ICSharpCode.NRefactory.xml AnyCPU False Auto 465371136 + 4096 bin\Debug\ @@ -33,23 +35,22 @@ False DEBUG;TRACE True - true bin\Release\ - true PdbOnly True TRACE False - false 4 + true 4 - full + Full + true @@ -98,6 +99,7 @@ + @@ -125,7 +127,6 @@ - diff --git a/ICSharpCode.NRefactory/PatternMatching/INode.cs b/ICSharpCode.NRefactory/PatternMatching/INode.cs index 7dc0a7dc36..f382e7bb45 100644 --- a/ICSharpCode.NRefactory/PatternMatching/INode.cs +++ b/ICSharpCode.NRefactory/PatternMatching/INode.cs @@ -41,7 +41,7 @@ namespace ICSharpCode.NRefactory.PatternMatching /// this is the pattern, is the AST that is being matched. /// /// - /// A match object. Check to see whether the match was successful. + /// A match object. Check to see whether the match was successful. /// /// /// Patterns are ASTs that contain special pattern nodes (from the PatternMatching namespace). diff --git a/ICSharpCode.NRefactory/TextLocation.cs b/ICSharpCode.NRefactory/TextLocation.cs index 4bc7a81e00..6580cd2f13 100644 --- a/ICSharpCode.NRefactory/TextLocation.cs +++ b/ICSharpCode.NRefactory/TextLocation.cs @@ -26,8 +26,8 @@ namespace ICSharpCode.NRefactory /// Text editor lines/columns are counted started from one. /// /// - /// The document provides the methods and - /// to convert between offsets and TextLocations. + /// The document provides the methods and + /// to convert between offsets and TextLocations. /// [Serializable] public struct TextLocation : IComparable, IEquatable diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AnonymousType.cs b/ICSharpCode.NRefactory/TypeSystem/AnonymousType.cs similarity index 97% rename from ICSharpCode.NRefactory/TypeSystem/Implementation/AnonymousType.cs rename to ICSharpCode.NRefactory/TypeSystem/AnonymousType.cs index 3d3c9f9934..1109eea0f9 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AnonymousType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/AnonymousType.cs @@ -19,9 +19,10 @@ using System; using System.Collections.Generic; using System.Linq; +using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.Utils; -namespace ICSharpCode.NRefactory.TypeSystem.Implementation +namespace ICSharpCode.NRefactory.TypeSystem { /// /// Anonymous type. diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs index 75be3778cb..f65ecd7724 100644 --- a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs +++ b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs @@ -152,7 +152,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Loads a type from Cecil. /// /// The Cecil TypeDefinition. - /// The project content used as parent for the new type. /// ITypeDefinition representing the Cecil type. [CLSCompliant(false)] public IUnresolvedTypeDefinition LoadType(TypeDefinition typeDefinition) @@ -234,8 +233,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// a type system type reference. /// Attributes associated with the Cecil type reference. /// This is used to support the 'dynamic' type. - /// The entity that owns this type reference. - /// Used for generic type references. [CLSCompliant(false)] public ITypeReference ReadTypeReference(TypeReference type, ICustomAttributeProvider typeAttributes = null) { diff --git a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs index 7c091f40c3..27e4016cdb 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ExtensionMethods.cs @@ -34,7 +34,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Gets all base types. /// - /// This is the reflexive and transitive closure of . + /// This is the reflexive and transitive closure of . /// Note that this method does not return all supertypes - doing so is impossible due to contravariance /// (and undesirable for covariance as the list could become very large). /// @@ -183,6 +183,17 @@ namespace ICSharpCode.NRefactory.TypeSystem return TreeTraversal.PreOrder(file.TopLevelTypeDefinitions, t => t.NestedTypes); } + public static IEnumerable GetAllTypeDefinitions (this IAssembly assembly) + { + return TreeTraversal.PreOrder(assembly.TopLevelTypeDefinitions, t => t.NestedTypes); + } + + public static IEnumerable GetAllTypeDefinitions (this ICompilation compilation) + { + return compilation.MainAssembly.GetAllTypeDefinitions() + .Concat(compilation.ReferencedAssemblies.SelectMany(a => a.GetAllTypeDefinitions())); + } + /// /// Gets the type (potentially a nested type) defined at the specified location. /// Returns null if no type is defined at that location. diff --git a/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs b/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs index 8e78180ec6..89677612f2 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IAssembly.cs @@ -105,5 +105,10 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets the type definition for the specified unresolved type. /// ITypeDefinition GetTypeDefinition(IUnresolvedTypeDefinition unresolved); + + /// + /// Gets all non-nested types in the assembly. + /// + IEnumerable TopLevelTypeDefinitions { get; } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/ICompilation.cs b/ICSharpCode.NRefactory/TypeSystem/ICompilation.cs index ee14da90fb..23d92889ae 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ICompilation.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ICompilation.cs @@ -50,11 +50,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// INamespace GetNamespaceForExternAlias(string alias); - /// - /// Gets all type defininitions in this compilation, including nested types. - /// - IEnumerable GetAllTypeDefinitions(); - IType FindType(KnownTypeCode typeCode); /// diff --git a/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs b/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs index 106f3f2334..d8db45147d 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs @@ -30,8 +30,9 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Resolves the value of this constant. /// - /// Compilation context where the constant value will be used. - /// Resolve result representing the constant value. + /// Context where the constant value will be used. + /// Resolve result representing the constant value. + /// This method never returns null; in case of errors, an ErrorResolveResult will be returned. ResolveResult Resolve(ITypeResolveContext context); } } diff --git a/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs b/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs index c53a12e8cb..fef4721fc9 100644 --- a/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs +++ b/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs @@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// /// For types, the reflection name can be parsed back into a ITypeReference by using - /// . + /// . /// /// /// "System.Int32[]" for int[]
diff --git a/ICSharpCode.NRefactory/TypeSystem/IParameter.cs b/ICSharpCode.NRefactory/TypeSystem/IParameter.cs index 676b70ba33..1084d9ba87 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IParameter.cs @@ -91,7 +91,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// Gets whether this parameter is optional. - /// The default value is given by the property. + /// The default value is given by the property. /// bool IsOptional { get; } } diff --git a/ICSharpCode.NRefactory/TypeSystem/IType.cs b/ICSharpCode.NRefactory/TypeSystem/IType.cs index 0758c7eaa5..e5e821432c 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IType.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IType.cs @@ -28,23 +28,23 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// /// A type is potentially - /// - a type definition (, i.e. a class, struct, interface, delegate, or built-in primitive type) + /// - a type definition (, i.e. a class, struct, interface, delegate, or built-in primitive type) /// - a parameterized type (, e.g. List<int>) /// - a type parameter (, e.g. T) /// - an array () /// - a pointer () /// - a managed reference () - /// - one of the special types (, , - /// , ) + /// - one of the special types (, , + /// , ) /// /// The property can be used to switch on the kind of a type. /// /// - /// IType uses the null object pattern: serves as the null object. + /// IType uses the null object pattern: serves as the null object. /// Methods or properties returning IType never return null unless documented otherwise. /// /// - /// Types should be compared for equality using the method. + /// Types should be compared for equality using the method. /// Identical types do not necessarily use the same object reference. /// /// @@ -117,10 +117,11 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which types to return. /// The filter is tested on the original type definitions (before parameterization). + /// Specified additional options for the GetMembers() operation. /// /// /// If the nested type is generic, this method will return a parameterized type, - /// where the additional type parameters are set to . + /// where the additional type parameters are set to . /// /// /// Type parameters belonging to the outer class will have the value copied from the outer type @@ -160,6 +161,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// The type arguments passed to the inner class /// The filter used to select which types to return. /// The filter is tested on the original type definitions (before parameterization). + /// Specified additional options for the GetMembers() operation. /// /// Type parameters belonging to the outer class will have the value copied from the outer type /// if it is a parameterized type. Otherwise, those existing type parameters will be self-parameterized, @@ -173,11 +175,12 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which constructors to return. /// The filter is tested on the original method definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// The result does not include constructors in base classes or static constructors. /// /// For methods on parameterized types, type substitution will be performed on the method signature, - /// and the appropriate will be returned. + /// and the appropriate will be returned. /// /// IEnumerable GetConstructors(Predicate filter = null, GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers); @@ -187,13 +190,14 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which methods to return. /// The filter is tested on the original method definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// /// The result does not include constructors. /// /// /// For methods on parameterized types, type substitution will be performed on the method signature, - /// and the appropriate will be returned. + /// and the appropriate will be returned. /// /// /// If the method being returned is generic, and this type is a parameterized type where the type @@ -214,10 +218,11 @@ namespace ICSharpCode.NRefactory.TypeSystem /// The type arguments used for the method call. /// The filter used to select which methods to return. /// The filter is tested on the original method definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// The result does not include constructors. /// - /// Type substitution will be performed on the method signature, creating a + /// Type substitution will be performed on the method signature, creating a /// with the specified type arguments. /// /// @@ -233,9 +238,10 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which properties to return. /// The filter is tested on the original property definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// For properties on parameterized types, type substitution will be performed on the property signature, - /// and the appropriate will be returned. + /// and the appropriate will be returned. /// IEnumerable GetProperties(Predicate filter = null, GetMemberOptions options = GetMemberOptions.None); @@ -244,9 +250,10 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which constructors to return. /// The filter is tested on the original field definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// For fields on parameterized types, type substitution will be performed on the field's return type, - /// and the appropriate will be returned. + /// and the appropriate will be returned. /// IEnumerable GetFields(Predicate filter = null, GetMemberOptions options = GetMemberOptions.None); @@ -255,9 +262,10 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which events to return. /// The filter is tested on the original event definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// For fields on parameterized types, type substitution will be performed on the event's return type, - /// and the appropriate will be returned. + /// and the appropriate will be returned. /// IEnumerable GetEvents(Predicate filter = null, GetMemberOptions options = GetMemberOptions.None); @@ -266,6 +274,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// The filter used to select which members to return. /// The filter is tested on the original member definitions (before specialization). + /// Specified additional options for the GetMembers() operation. /// /// /// The resulting list is the union of GetFields(), GetProperties(), GetMethods() and GetEvents(). @@ -274,7 +283,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// /// For generic methods, the remarks about ambiguous signatures from the - /// method apply here as well. + /// method apply here as well. /// /// IEnumerable GetMembers(Predicate filter = null, GetMemberOptions options = GetMemberOptions.None); diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs index 6184768d89..4d58020b98 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs @@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// /// Returns the resolved type. - /// In case of an error, returns . + /// In case of an error, returns . /// Never returns null. /// IType Resolve(ITypeResolveContext context); diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs index 3a0eb37a22..b08334973d 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs @@ -249,7 +249,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public bool InternalsVisibleTo(IAssembly assembly) { - throw new NotImplementedException(); + return assembly == this; } public ITypeDefinition GetTypeDefinition(string ns, string name, int typeParameterCount) @@ -276,6 +276,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } } + public IEnumerable TopLevelTypeDefinitions { + get { + return unresolved.TopLevelTypeDefinitions.Select(t => GetTypeDefinition(t)); + } + } + sealed class NS : INamespace { readonly DefaultResolvedAssembly assembly; diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/MergedNamespace.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/MergedNamespace.cs index 349ebbf850..493f0e582a 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/MergedNamespace.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/MergedNamespace.cs @@ -38,6 +38,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation /// /// Creates a new merged root namespace. /// + /// The main compilation. /// The individual namespaces being merged. /// The extern alias for this namespace. public MergedNamespace(ICompilation compilation, INamespace[] namespaces, string externAlias = null) diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs index 4e0a7fece5..3cf2e8a9c1 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/SimpleCompilation.cs @@ -107,13 +107,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation { return null; } - - public IEnumerable GetAllTypeDefinitions() - { - return TreeTraversal.PreOrder(this.RootNamespace, ns => ns.ChildNamespaces) - .SelectMany(ns => TreeTraversal.PreOrder(ns.Types, t => t.NestedTypes)); - } - public IType FindType(KnownTypeCode typeCode) { return knownTypeCache.FindType(typeCode); diff --git a/ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs b/ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs index ece064cc15..bf25911126 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ReflectionHelper.cs @@ -68,7 +68,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Creates a reference to the specified type. /// /// The type to be converted. - /// The parent entity, used to fetch the ITypeParameter for generic types. /// Returns the type reference. public static ITypeReference ToTypeReference(this Type type) { @@ -195,8 +194,6 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Parses a reflection name into a type reference. /// /// The reflection name of the type. - /// Parent entity, used to find the type parameters for open types. - /// If no entity is provided, type parameters are converted to . /// The syntax of the reflection type name is invalid /// A type reference that represents the reflection name. public static ITypeReference ParseReflectionName(string reflectionTypeName) diff --git a/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs b/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs index dae398ddf4..98362b6688 100644 --- a/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs +++ b/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs @@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.TypeSystem /// /// A type used for unbound type arguments in partially parameterized types. /// - /// + /// public readonly static SpecialType UnboundTypeArgument = new SpecialType(TypeKind.UnboundTypeArgument, "", isReferenceType: null); readonly TypeKind kind; diff --git a/ICSharpCode.NRefactory/TypeSystem/TypeKind.cs b/ICSharpCode.NRefactory/TypeSystem/TypeKind.cs index 9fd32f8516..05f852991b 100644 --- a/ICSharpCode.NRefactory/TypeSystem/TypeKind.cs +++ b/ICSharpCode.NRefactory/TypeSystem/TypeKind.cs @@ -47,17 +47,17 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Void, - /// + /// Unknown, /// The type of the null literal. - /// + /// Null, /// Type representing the C# 'dynamic' type. - /// + /// Dynamic, /// Represents missing type arguments in partially parameterized types. - /// - /// + /// + /// UnboundTypeArgument, /// The type is a type parameter.