예제 #1
0
        protected ResolveResult Resolve(string code)
        {
            CompilationUnit cu = new CSharpParser().Parse(new StringReader(code.Replace("$", "")));

            TextLocation[] dollars = FindDollarSigns(code).ToArray();
            Assert.AreEqual(2, dollars.Length, "Expected 2 dollar signs marking start+end of desired node");

            SetUp();

            CSharpParsedFile         parsedFile     = new CSharpParsedFile("test.cs", resolver.CurrentUsingScope);
            TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(parsedFile, resolver.CurrentUsingScope, null);

            cu.AcceptVisitor(convertVisitor, null);
            project.UpdateProjectContent(null, convertVisitor.ParsedFile);

            FindNodeVisitor fnv = new FindNodeVisitor(dollars[0], dollars[1]);

            cu.AcceptVisitor(fnv, null);
            Assert.IsNotNull(fnv.ResultNode, "Did not find DOM node at the specified location");

            Debug.WriteLine(new string('=', 70));
            Debug.WriteLine("Starting new resolver for " + fnv.ResultNode);

            var           navigator = new NodeListResolveVisitorNavigator(new[] { fnv.ResultNode });
            ResolveResult rr;

            using (var context = this.context.Synchronize()) {
                ResolveVisitor rv = new ResolveVisitor(new CSharpResolver(context), convertVisitor.ParsedFile, navigator);
                rv.Scan(cu);
                rr = rv.GetResolveResult(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);
        }
예제 #2
0
 void InitResolver(AstNode firstNodeToResolve)
 {
     if (resolveVisitor == null)
     {
         resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, new NodeListResolveVisitorNavigator(firstNodeToResolve));
         resolveVisitor.Scan(rootNode);
     }
 }
예제 #3
0
 /// <summary>
 /// 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.
 /// </summary>
 public void ApplyNavigator(IResolveVisitorNavigator navigator, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (navigator == null)
     {
         throw new ArgumentNullException("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);
 }
예제 #4
0
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving code snippets (not necessarily complete files).
 /// </summary>
 /// <param name="resolver">The resolver state at the root node (to be more precise: outside the root node).</param>
 /// <param name="rootNode">The root node of the resolved tree.</param>
 /// <param name="parsedFile">
 /// Optional: Result of the <see cref="TypeSystemConvertVisitor"/> for the file being resolved.
 /// <para>
 /// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
 /// </para>
 /// <para>
 /// When a parsedFile 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 (<c>null</c> value for this parameter), the resolver will instead compare the
 /// member's signature in the AST with the signature in the type system.
 /// </para>
 /// </param>
 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;
     this.rootNode             = rootNode;
     this.parsedFile           = parsedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, parsedFile);
 }
예제 #5
0
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving within a complete C# file.
 /// </summary>
 /// <param name="compilation">The current compilation.</param>
 /// <param name="compilationUnit">The compilation unit corresponding to the specified parsed file.</param>
 /// <param name="parsedFile">
 /// Optional: Result of the <see cref="TypeSystemConvertVisitor"/> for the file being resolved.
 /// <para>
 /// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
 /// </para>
 /// <para>
 /// When a parsedFile 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 (<c>null</c> value for this parameter), the resolver will instead compare the
 /// member's signature in the AST with the signature in the type system.
 /// </para>
 /// </param>
 public CSharpAstResolver(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile = null)
 {
     if (compilation == null)
     {
         throw new ArgumentNullException("compilation");
     }
     if (compilationUnit == null)
     {
         throw new ArgumentNullException("compilationUnit");
     }
     this.initialResolverState = new CSharpResolver(compilation);
     this.rootNode             = compilationUnit;
     this.parsedFile           = parsedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, parsedFile);
 }
예제 #6
0
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving within a complete C# file.
 /// </summary>
 /// <param name="compilation">The current compilation.</param>
 /// <param name="syntaxTree">The syntax tree to be resolved.</param>
 /// <param name="unresolvedFile">
 /// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
 /// <para>
 /// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
 /// </para>
 /// <para>
 /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
 /// member declarations in the AST with members in the type system.
 /// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
 /// member's signature in the AST with the signature in the type system.
 /// </para>
 /// </param>
 public CSharpAstResolver(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile = null)
 {
     if (compilation == null)
     {
         throw new ArgumentNullException("compilation");
     }
     if (syntaxTree == null)
     {
         throw new ArgumentNullException("syntaxTree");
     }
     this.initialResolverState = new CSharpResolver(compilation);
     this.rootNode             = syntaxTree;
     this.unresolvedFile       = unresolvedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, unresolvedFile);
 }
예제 #7
0
 /// <summary>
 /// Finds all references in the given file.
 /// </summary>
 /// <param name="searchScopes">The search scopes for which to look.</param>
 /// <param name="parsedFile">The type system representation of the file being searched.</param>
 /// <param name="compilationUnit">The compilation unit of the file being searched.</param>
 /// <param name="context">The type resolve context to use for resolving the file.</param>
 /// <param name="callback">Callback used to report the references that were found.</param>
 public void FindReferencesInFile(IList <IFindReferenceSearchScope> searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit,
                                  ITypeResolveContext context, FoundReferenceCallback callback)
 {
     if (searchScopes == null)
     {
         throw new ArgumentNullException("searchScopes");
     }
     if (parsedFile == null)
     {
         throw new ArgumentNullException("parsedFile");
     }
     if (compilationUnit == null)
     {
         throw new ArgumentNullException("compilationUnit");
     }
     if (context == null)
     {
         throw new ArgumentNullException("context");
     }
     this.CancellationToken.ThrowIfCancellationRequested();
     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);
     }
 }
예제 #8
0
            internal override bool CanMatch(AstNode node)
            {
                InvocationExpression ie = node as InvocationExpression;

                if (ie != null)
                {
                    Expression target = ResolveVisitor.UnpackParenthesizedExpression(ie.Target);

                    IdentifierExpression ident = target as IdentifierExpression;
                    if (ident != null)
                    {
                        return(ident.Identifier == method.Name);
                    }

                    MemberReferenceExpression mre = target as MemberReferenceExpression;
                    if (mre != null)
                    {
                        return(mre.MemberName == method.Name);
                    }

                    PointerReferenceExpression pre = target as PointerReferenceExpression;
                    if (pre != null)
                    {
                        return(pre.MemberName == method.Name);
                    }
                }
                if (node is MethodDeclaration)
                {
                    return(true);
                }
                if (specialNodeType != null)
                {
                    return(specialNodeType.IsInstanceOfType(node));
                }
                else
                {
                    return(false);
                }
            }
예제 #9
0
        public void Resolved(AstNode node, ResolveResult result)
        {
            if (ResolveVisitor.ActsAsParenthesizedExpression(node))
            {
                return;
            }

            MemberResolveResult mrr = result as MemberResolveResult;

            if (mrr != null)
            {
                referenceFound(node, mrr.Member.MemberDefinition);
            }
            TypeResolveResult trr = result as TypeResolveResult;

            if (trr != null)
            {
                ITypeDefinition typeDef = trr.Type.GetDefinition();
                if (typeDef != null)
                {
                    referenceFound(node, typeDef);
                }
            }
        }
예제 #10
0
        public static ResolveResult Resolve(ITypeResolveContext context, CSharpParsedFile parsedFile, CompilationUnit cu, TextLocation location,
                                            CancellationToken cancellationToken = default(CancellationToken))
        {
            AstNode node = cu.GetNodeAt(location);

            if (node == null)
            {
                return(null);
            }
            AstNode resolvableNode;

            if (node is AstType)
            {
                resolvableNode = node;
                if (resolvableNode.Parent is ComposedType)
                {
                    while (resolvableNode.Parent is ComposedType)
                    {
                        resolvableNode = resolvableNode.Parent;
                    }
                    //node is preffered over the resolvable node. Which shouldn't be done in the case of nullables, arrays etc.
                    node = resolvableNode;
                }
            }
            else if (node is Identifier)
            {
                resolvableNode = node.Parent;
            }
            else if (node.NodeType == NodeType.Token)
            {
                if (node.Parent is ConstructorInitializer)
                {
                    resolvableNode = node.Parent;
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                // don't resolve arbitrary nodes - we don't want to show tooltips for everything
                return(null);
            }

            InvocationExpression parentInvocation = null;

            if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression))
            {
                // we also need to resolve the invocation
                parentInvocation = resolvableNode.Parent as InvocationExpression;
            }

            IResolveVisitorNavigator navigator;

            if (parentInvocation != null)
            {
                navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode, parentInvocation });
            }
            else
            {
                navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode });
            }

            using (var ctx = context.Synchronize()) {
                CSharpResolver resolver = new CSharpResolver(ctx, cancellationToken);
                ResolveVisitor v        = new ResolveVisitor(resolver, parsedFile, navigator);
                v.Scan(cu);

                // Prefer the RR from the token itself, if it was assigned a ResolveResult
                // (this can happen with the identifiers in various nodes such as catch clauses or foreach statements)
                ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode);
                if (rr is MethodGroupResolveResult && parentInvocation != null)
                {
                    return(v.GetResolveResult(parentInvocation));
                }
                else
                {
                    return(rr);
                }
            }
        }
예제 #11
0
		public override IEnumerable<ICSharpCode.NRefactory.TypeSystem.IMember> ResolveMember (Expression expression)
		{
			var pf = ParsedFile;
			var csResolver = new CSharpResolver (TypeResolveContext, System.Threading.CancellationToken.None);
			var navigator = new NodeListResolveVisitorNavigator (new[] { expression });
			
			var visitor = new ICSharpCode.NRefactory.CSharp.Resolver.ResolveVisitor (csResolver, pf, navigator);
		
			visitor.VisitCompilationUnit (Unit, null);
			var resolveResult = visitor.Resolve (expression);
			if (resolveResult == null)
				yield break;
			if (resolveResult is MemberResolveResult) {
				yield return ((MemberResolveResult)resolveResult).Member;
			} else if (resolveResult is MethodGroupResolveResult) {
				var mgg = (MethodGroupResolveResult)resolveResult;
				foreach (var m in mgg.Methods)
					yield return m;
			}
		}