// 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); } } }