Exemple #1
0
        void ResolveButtonClick(object sender, EventArgs e)
        {
            SimpleProjectContent     project        = new SimpleProjectContent();
            TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");

            compilationUnit.AcceptVisitor(convertVisitor, null);
            project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);

            List <ITypeResolveContext> projects = new List <ITypeResolveContext>();

            projects.Add(project);
            projects.AddRange(builtInLibs.Value);

            using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
                CSharpResolver resolver = new CSharpResolver(context);

                IResolveVisitorNavigator navigator = null;
                if (csharpTreeView.SelectedNode != null)
                {
                    navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
                }
                ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
                visitor.Scan(compilationUnit);
                csharpTreeView.BeginUpdate();
                ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
                csharpTreeView.EndUpdate();
            }
        }
Exemple #2
0
        protected Tuple <ResolveResult, CSharpResolver> ResolveExpression(CSharpParsedFile file, AstNode expr, CompilationUnit unit)
        {
            if (expr == null)
            {
                return(null);
            }
            AstNode resolveNode;

            if (expr is Expression || expr is AstType)
            {
                resolveNode = expr;
            }
            else if (expr is VariableDeclarationStatement)
            {
                resolveNode = ((VariableDeclarationStatement)expr).Type;
            }
            else
            {
                resolveNode = expr;
            }

//			var newContent = ProjectContent.UpdateProjectContent (CSharpParsedFile, file);

            var csResolver = new CSharpResolver(ctx);

            var navigator = new NodeListResolveVisitorNavigator(new[] { resolveNode });
            var visitor   = new ResolveVisitor(csResolver, CSharpParsedFile, navigator);

            visitor.Scan(unit);
            var state  = visitor.GetResolverStateBefore(resolveNode);
            var result = visitor.GetResolveResult(resolveNode);

            return(Tuple.Create(result, state));
        }
Exemple #3
0
        void FindReferencesButtonClick(object sender, EventArgs e)
        {
            if (csharpTreeView.SelectedNode == null)
            {
                return;
            }

            SimpleProjectContent project = new SimpleProjectContent();
            var parsedFile = new TypeSystemConvertVisitor(project, "dummy.cs").Convert(compilationUnit);

            project.UpdateProjectContent(null, parsedFile);

            List <ITypeResolveContext> projects = new List <ITypeResolveContext>();

            projects.Add(project);
            projects.AddRange(builtInLibs.Value);

            using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
                CSharpResolver resolver = new CSharpResolver(context);

                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;
                if (mrr != null)
                {
                    entity = mrr.Member;
                }
                else if (trr != null)
                {
                    entity = trr.Type.GetDefinition();
                }
                else
                {
                    return;
                }

                FindReferences         fr             = new FindReferences();
                int                    referenceCount = 0;
                FoundReferenceCallback callback       = delegate(AstNode matchNode, ResolveResult result) {
                    referenceCount++;
                };

                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();

                MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
            }
        }
		public static ResolveResult Resolve(ICompilation compilation, 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;
			}
			
			if (resolvableNode != null && resolvableNode.Parent is ObjectCreateExpression) {
				resolvableNode = resolvableNode.Parent;
			}
			
			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 });
			
			CSharpResolver resolver = new CSharpResolver(compilation);
			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;
		}
		string Convert(Expression expr)
		{
			ResolveVisitor rv = new ResolveVisitor(resolver, null);
			rv.Scan(expr);
			var codeExpr = (CodeExpression)convertVisitor.Convert(expr, rv);
			StringWriter writer = new StringWriter();
			writer.NewLine = " ";
			new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions { IndentString = " " });
			return Regex.Replace(writer.ToString(), @"\s+", " ");
		}
        /// <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 (resolverInitialized)
            {
                throw new InvalidOperationException("Applying a navigator is only valid as the first operation on the CSharpAstResolver.");
            }

            resolverInitialized = true;
            resolveVisitor.cancellationToken = cancellationToken;
            resolveVisitor.SetNavigator(navigator);
            try {
                resolveVisitor.Scan(rootNode);
            } finally {
                resolveVisitor.SetNavigator(null);
                resolveVisitor.cancellationToken = CancellationToken.None;
            }
        }
        string Convert(Expression expr)
        {
            ResolveVisitor rv = new ResolveVisitor(resolver, null);

            rv.Scan(expr);
            var          codeExpr = (CodeExpression)convertVisitor.Convert(expr, rv);
            StringWriter writer   = new StringWriter();

            writer.NewLine = " ";
            new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions {
                IndentString = " "
            });
            return(Regex.Replace(writer.ToString(), @"\s+", " "));
        }
Exemple #8
0
        public HlslVisitor(BlockStatement block, CustomAttribute attr, ResolveVisitor resolver, DecompilerContext ctx)
            : this()
        {
            _attr = attr;
            _resolver = resolver;
            _resolver.Scan(block);

            var trans1 = new ReplaceMethodCallsWithOperators(ctx);
            var trans2 = new RenameLocals();
            ((IAstTransform)trans1).Run(block);
            trans2.Run(block);

            Result = block.AcceptVisitor(this, 0).ToString();
            Result += Environment.NewLine;
        }
Exemple #9
0
        public HlslVisitor(BlockStatement block, CustomAttribute attr, ResolveVisitor resolver, DecompilerContext ctx)
            : this()
        {
            _attr     = attr;
            _resolver = resolver;
            _resolver.Scan(block);

            var trans1 = new ReplaceMethodCallsWithOperators(ctx);
            var trans2 = new RenameLocals();

            ((IAstTransform)trans1).Run(block);
            trans2.Run(block);

            Result  = block.AcceptVisitor(this, 0).ToString();
            Result += Environment.NewLine;
        }
Exemple #10
0
		void ResolveButtonClick(object sender, EventArgs e)
		{
			SimpleProjectContent project = new SimpleProjectContent();
			TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");
			compilationUnit.AcceptVisitor(convertVisitor, null);
			project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);
			
			List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
			projects.Add(project);
			projects.AddRange(builtInLibs.Value);
			
			using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
				CSharpResolver resolver = new CSharpResolver(context);
				
				IResolveVisitorNavigator navigator = null;
				if (csharpTreeView.SelectedNode != null) {
					navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
				}
				ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
				visitor.Scan(compilationUnit);
				csharpTreeView.BeginUpdate();
				ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
				csharpTreeView.EndUpdate();
			}
		}
Exemple #11
0
		void FindReferencesButtonClick(object sender, EventArgs e)
		{
			if (csharpTreeView.SelectedNode == null)
				return;
			
			SimpleProjectContent project = new SimpleProjectContent();
			var parsedFile = new TypeSystemConvertVisitor(project, "dummy.cs").Convert(compilationUnit);
			project.UpdateProjectContent(null, parsedFile);
			
			List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
			projects.Add(project);
			projects.AddRange(builtInLibs.Value);
			
			using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
				CSharpResolver resolver = new CSharpResolver(context);
				
				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;
				if (mrr != null) {
					entity = mrr.Member;
				} else if (trr != null) {
					entity = trr.Type.GetDefinition();
				} else {
					return;
				}
				
				FindReferences fr = new FindReferences();
				int referenceCount = 0;
				FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) {
					referenceCount++;
				};
				
				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();
				
				MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
			}
		}
Exemple #12
0
        IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace)
        {
            switch (completionChar) {
            // Magic key completion
            case ':':
            case '.':
                if (IsInsideCommentOrString ())
                    return Enumerable.Empty<ICompletionData> ();
                var expr = GetExpressionBeforeCursor ();
                if (expr == null)
                    return null;
                // do not complete <number>. (but <number>.<number>.)
                if (expr.Item2 is PrimitiveExpression) {
                    var pexpr = (PrimitiveExpression)expr.Item2;
                    if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
                        return null;
                }

                var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);

                if (resolveResult == null)
                    return null;
                if (expr.Item2 is AstType)
                    return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
                return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
            case '#':
                if (IsInsideCommentOrString ())
                    return null;
                return GetDirectiveCompletionData ();

            // XML doc completion
            case '<':
                if (IsInsideDocComment ())
                    return GetXmlDocumentationCompletionData ();
                if (controlSpace)
                    return DefaultControlSpaceItems ();
                return null;
            case '>':
                if (!IsInsideDocComment ())
                    return null;
                string lineText = document.GetText (document.GetLineByNumber (location.Line));
                int startIndex = Math.Min (location.Column - 1, lineText.Length - 1);

                while (startIndex >= 0 && lineText [startIndex] != '<') {
                    --startIndex;
                    if (lineText [startIndex] == '/') { // already closed.
                        startIndex = -1;
                        break;
                    }
                }

                if (startIndex >= 0) {
                    int endIndex = startIndex;
                    while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
                        endIndex++;
                    }
                    string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
                    if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0)
                        document.Insert (offset, "</" + tag + ">");
                }
                return null;

            // Parameter completion
            case '(':
                if (IsInsideCommentOrString ())
                    return null;
                var invoke = GetInvocationBeforeCursor (true);
                if (invoke == null)
                    return null;
                if (invoke.Item2 is TypeOfExpression)
                    return CreateTypeList ();
                var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
                if (invocationResult == null)
                    return null;
                var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
                if (methodGroup != null)
                    return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);

                if (controlSpace)
                    return DefaultControlSpaceItems (invoke);

                return null;
            case '=':
                return controlSpace ? DefaultControlSpaceItems () : null;
            case ',':
                int cpos2;
                if (!GetParameterCompletionCommandOffset (out cpos2))
                    return null;
            //	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
            //	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
            //				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);
                break;

            // Completion on space:
            case ' ':
                if (IsInsideCommentOrString ())
                    return null;

                int tokenIndex = offset;
                string token = GetPreviousToken (ref tokenIndex, false);
                // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
                //IType isAsType = null;
                var isAsExpression = GetExpressionAt (offset);
                if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
                    var parent = isAsExpression.Item2 as VariableDeclarationStatement;
                    var proposeNameList = new CompletionDataWrapper (this);

                    foreach (var possibleName in GenerateNameProposals (parent.Type)) {
                        if (possibleName.Length > 0)
                            proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
                    }

                    AutoSelect = false;
                    AutoCompleteEmptyMatch = false;
                    return proposeNameList.Result;
                }
            //				int tokenIndex = offset;
            //				string token = GetPreviousToken (ref tokenIndex, false);
            //				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
            //					resolver = CreateResolver ();
            //					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
            //					IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
            //					if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
            //						return CreateCtrlSpaceCompletionData (completionContext, result);
            //				}
                if (token == "=") {
                    int j = tokenIndex;
                    string prevToken = GetPreviousToken (ref j, false);
                    if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
                        token = prevToken + token;
                        tokenIndex = j;
                    }
                }
                switch (token) {
                case "(":
                case ",":
                    int cpos;
                    if (!GetParameterCompletionCommandOffset (out cpos))
                        break;
                    int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
                    if (currentParameter < 0)
                        return null;
                    invoke = GetInvocationBeforeCursor (token == "(");
                    if (invoke == null)
                        return null;
                    invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
                    if (invocationResult == null)
                        return null;
                    methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
                    if (methodGroup != null)
                        return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
                    return null;
                case "=":
                case "==":
                    GetPreviousToken (ref tokenIndex, false);

                    var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
                    if (expressionOrVariableDeclaration == null)
                        return null;

                    resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
                    if (resolveResult == null)
                        return null;
                    if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
                        var wrapper = new CompletionDataWrapper (this);
                        AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
                        AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
                        AutoCompleteEmptyMatch = false;
                        return wrapper.Result;
                    }
            //
            //					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
            //						CompletionDataList completionList = new ProjectDomCompletionDataList ();
            //						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
            //						completionList.AutoCompleteEmptyMatch = false;
            //						cdc.Add ("true", "md-keyword");
            //						cdc.Add ("false", "md-keyword");
            //						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
            //						return completionList;
            //					}
            //					if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
            //						CompletionDataList completionList = new ProjectDomCompletionDataList ();
            //						string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
            //						string varName = GetPreviousMemberReferenceExpression (tokenIndex);
            //						completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
            //
            //						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
            //						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
            //						foreach (var data in completionList) {
            //							if (data is MemberCompletionData)
            //								((MemberCompletionData)data).IsDelegateExpected = true;
            //						}
            //						return completionList;
            //					}
                    return null;
                case "+=":
                case "-=":
                    GetPreviousToken (ref tokenIndex, false);

                    expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
                    if (expressionOrVariableDeclaration == null)
                        return null;

                    resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
                    if (resolveResult == null)
                        return null;

                    var mrr = resolveResult.Item1 as MemberResolveResult;
                    if (mrr != null) {
                        var evt = mrr.Member as IEvent;
                        if (evt == null)
                            return null;
                        var delegateType = evt.ReturnType;
                        if (delegateType.Kind != TypeKind.Delegate)
                            return null;

                        var wrapper = new CompletionDataWrapper (this);
                        if (currentType != null) {
            //							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
                            foreach (var method in currentType.Methods) {
                                if (MatchDelegate (delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
                                    wrapper.AddMember (method);
            //									data.SetText (data.CompletionText + ";");
                                }
                            }
                        }
                        if (token == "+=") {
                            string parameterDefinition = AddDelegateHandlers (wrapper, delegateType);
                            string varName = GetPreviousMemberReferenceExpression (tokenIndex);
                            wrapper.Result.Add (factory.CreateEventCreationCompletionData (varName, delegateType, evt, parameterDefinition, currentMember, currentType));
                        }

                        return wrapper.Result;
                    }
                    return null;
                case ":":
                    if (currentMember == null) {
                        var wrapper = new CompletionDataWrapper (this);
                        AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
                        return wrapper.Result;
                    }
                    return null;
                }

                var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
                if (keywordCompletion == null && controlSpace)
                    goto default;
                return keywordCompletion;
            // Automatic completion
            default:
                if (IsInsideCommentOrString ())
                    return null;
                if (IsInLinqContext (offset)) {
                    tokenIndex = offset;
                    token = GetPreviousToken (ref tokenIndex, false); // token last typed
                    if (linqKeywords.Contains (token)) {
                        if (token == "from") // after from no auto code completion.
                            return null;
                        return DefaultControlSpaceItems ();
                    }
                    var dataList = new CompletionDataWrapper (this);
                    AddKeywords (dataList, linqKeywords);
                    return dataList.Result;
                }

                if (currentType != null && currentType.Kind == TypeKind.Enum)
                    return HandleEnumContext ();

                var contextList = new CompletionDataWrapper (this);
                var identifierStart = GetExpressionAtCursor ();
                if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration)
                    return null;

                if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) {
                    return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
                }
                if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
                    return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
                }
                char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';';
                char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' ';
                const string allowedChars = ";,[](){}+-*/%^?:&|~!<>=";
                if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
                    return null;
                if (!(Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0))
                    return null;
                // Do not pop up completion on identifier identifier (should be handled by keyword completion).
                tokenIndex = offset - 1;
                token = GetPreviousToken (ref tokenIndex, false);
                int prevTokenIndex = tokenIndex;
                var prevToken2 = GetPreviousToken (ref prevTokenIndex, false);
                if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
                    char last = token [token.Length - 1];
                    if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
                        return HandleKeywordCompletion (tokenIndex, token);
                    }
                }

                if (identifierStart == null)
                    return HandleAccessorContext () ?? DefaultControlSpaceItems ();

                CSharpResolver csResolver;
                AstNode n = identifierStart.Item2;
                // Handle foreach (type name _
                if (n is IdentifierExpression) {
                    var prev = n.GetPrevNode () as ForeachStatement;
                    if (prev != null && prev.InExpression.IsNull) {
                        if (controlSpace) {
                            contextList.AddCustom ("in");
                            return contextList.Result;
                        }
                        return null;
                    }
                }

                if (n is Identifier && n.Parent is ForeachStatement) {
                    if (controlSpace)
                        return DefaultControlSpaceItems ();
                    return null;
                }
                if (n is ArrayInitializerExpression) {
                    // check for new [] {...} expression -> no need to resolve the type there
                    var parent = n.Parent as ArrayCreateExpression;
                    if (parent != null && parent.Type.IsNull)
                        return DefaultControlSpaceItems ();

                    var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);

                    var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
                    // check if we're on the right side of an initializer expression
                    if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
                        return DefaultControlSpaceItems ();
                    }

                    if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) {

                        foreach (var property in initalizerResult.Item1.Type.GetProperties ()) {
                            if (!property.IsPublic)
                                continue;
                            contextList.AddMember (property);
                        }
                        foreach (var field in initalizerResult.Item1.Type.GetFields ()) {
                            if (!field.IsPublic)
                                continue;
                            contextList.AddMember (field);
                        }
                        return contextList.Result;
                    }
                    Console.WriteLine ("blub");
                    return DefaultControlSpaceItems ();
                }
                if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
                    csResolver = new CSharpResolver (ctx);
                    var nodes = new List<AstNode> ();
                    nodes.Add (n);
                    if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute)
                        nodes.Add (n.Parent);
                    var navigator = new NodeListResolveVisitorNavigator (nodes);
                    var visitor = new ResolveVisitor (csResolver, identifierStart.Item1, navigator);
                    visitor.Scan (identifierStart.Item3);
                    try {
                        csResolver = visitor.GetResolverStateBefore (n);
                    } catch (Exception) {
                        csResolver = GetState ();
                    }
                    // add attribute properties.
                    if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
                        var resolved = visitor.GetResolveResult (n.Parent);
                        if (resolved != null && resolved.Type != null) {
                            foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
                                contextList.AddMember (property);
                            }
                            foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
                                contextList.AddMember (field);
                            }
                        }
                    }
                } else {
                    csResolver = GetState ();
                }

                // identifier has already started with the first letter
                offset--;

                AddContextCompletion (contextList, csResolver, identifierStart.Item2);
                return contextList.Result;
            //				if (stub.Parent is BlockStatement)

            //				result = FindExpression (dom, completionContext, -1);
            //				if (result == null)
            //					return null;
            //				 else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
            //					triggerWordLength = 1;
            //					bool autoSelect = true;
            //					IType returnType = null;
            //					if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
            //						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
            //						NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
            //						if (dataProvider != null) {
            //							int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
            //							foreach (var method in dataProvider.Methods) {
            //								if (i < method.Parameters.Count) {
            //									returnType = dom.GetType (method.Parameters [i].ReturnType);
            //									autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
            //									break;
            //								}
            //							}
            //						}
            //					}
            //					// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
            //					//if (result.ExpressionContext == ExpressionContext.TypeName)
            //					//	autoSelect = false;
            //					CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
            //					AddEnumMembers (dataList, returnType);
            //					dataList.AutoSelect = autoSelect;
            //					return dataList;
            //				} else {
            //					result = FindExpression (dom, completionContext, 0);
            //					tokenIndex = offset;
            //
            //					// check foreach case, unfortunately the expression finder is too dumb to handle full type names
            //					// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
            //					var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
            //
            //					// read return types to '(' token
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
            //					if (possibleForeachToken == ">") {
            //						while (possibleForeachToken != null && possibleForeachToken != "(") {
            //							possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
            //						}
            //					} else {
            //						possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
            //						if (possibleForeachToken == ".")
            //							while (possibleForeachToken != null && possibleForeachToken != "(")
            //								possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
            //					}
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
            //
            //					if (possibleForeachToken == "foreach") {
            //						result.ExpressionContext = ExpressionContext.ForeachInToken;
            //					} else {
            //						return null;
            //						//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
            //					}
            //					result.Expression = "";
            //					result.Region = DomRegion.Empty;
            //
            //					return CreateCtrlSpaceCompletionData (completionContext, result);
            //				}
            //				break;
            }
            return null;
        }
		/// <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);
		}
		void InitResolver(AstNode firstNodeToResolve)
		{
			if (resolveVisitor == null) {
				resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, new NodeListResolveVisitorNavigator(firstNodeToResolve));
				resolveVisitor.Scan(rootNode);
			}
		}
        protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(CSharpParsedFile file, AstNode expr, CompilationUnit unit)
        {
            if (expr == null)
                return null;
            AstNode resolveNode;
            if (expr is Expression || expr is AstType) {
                resolveNode = expr;
            } else if (expr is VariableDeclarationStatement) {
                resolveNode = ((VariableDeclarationStatement)expr).Type;
            } else {
                resolveNode = expr;
            }

            //			var newContent = ProjectContent.UpdateProjectContent (CSharpParsedFile, file);

            var csResolver = new CSharpResolver (ctx);

            var navigator = new NodeListResolveVisitorNavigator (new[] { resolveNode });
            var visitor = new ResolveVisitor (csResolver, CSharpParsedFile, navigator);

            visitor.Scan (unit);
            var state = visitor.GetResolverStateBefore (resolveNode);
            var result = visitor.GetResolveResult (resolveNode);
            return Tuple.Create (result, state);
        }
Exemple #16
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);
			}
		}