ExpressionContext FindExactContextForNewCompletion(ITextEditor editor, string documentToCursor, IDocumentLine currentLine, int pos) { CSharpExpressionFinder ef = CreateExpressionFinder(editor.Document.Text); // find expression on left hand side of the assignment ExpressionResult lhsExpr = ef.FindExpression(documentToCursor, currentLine.Offset + pos); if (lhsExpr.Expression != null) { ResolveResult rr = ParserService.Resolve(lhsExpr, currentLine.LineNumber, pos, editor.Document.Text, editor.Document.Text, ProjectContent); if (rr != null && rr.ResolvedType != null) { ExpressionContext context; IClass c; if (rr.ResolvedType.IsArrayReturnType) { // when creating an array, all classes deriving from the array's element type are allowed IReturnType elementType = rr.ResolvedType.CastToArrayReturnType().ArrayElementType; c = elementType != null?elementType.GetUnderlyingClass() : null; context = ExpressionContext.TypeDerivingFrom(elementType, false); } else { // when creating a normal instance, all non-abstract classes deriving from the type // are allowed c = rr.ResolvedType.GetUnderlyingClass(); context = ExpressionContext.TypeDerivingFrom(rr.ResolvedType, true); } if (c != null && context.ShowEntry(c)) { // Try to suggest an entry (List<int> a = new => suggest List<int>). string suggestedClassName = LanguageProperties.CSharp.CodeGenerator.GenerateCode( CodeGenerator.ConvertType( rr.ResolvedType, new ClassFinder(ParserService.GetParseInformation(editor.Document.Text, ProjectContent), editor.Caret.Line, editor.Caret.Column) ), ""); context.SuggestedItem = suggestedClassName != c.Name ? new SuggestedCodeCompletionItem(c, suggestedClassName, ProjectContent) : new CodeCompletionItem(c, ProjectContent); } return(context); } } return(null); }
CSharpExpressionFinder CreateExpressionFinder(string fileName) { return(new CSharpExpressionFinder(ParserService.GetParseInformation(fileName, ProjectContent))); }
public override bool HandleKeyword(ITextEditor editor, string word) { switch (word) { case "using": if (IsInComment(editor)) { return(false); } ParseInformation parseInfo = ParserService.GetParseInformation(editor.Document.Text, ProjectContent); if (parseInfo != null) { IClass innerMostClass = parseInfo.CompilationUnit.GetInnermostClass(editor.Caret.Line, editor.Caret.Column); if (innerMostClass == null) { ShowCompletion(CompletionItemProviderFactory.Create(LanguageProperties.CSharp, ExpressionContext.Namespace, ProjectContent), editor, ProjectContent); return(true); } } break; case "as": case "is": if (IsInComment(editor)) { return(false); } ShowCompletion(CompletionItemProviderFactory.Create(LanguageProperties.CSharp, ExpressionContext.Type, ProjectContent), editor, ProjectContent); return(true); case "override": if (IsInComment(editor)) { return(false); } ShowCompletion(new OverrideCompletionItemProvider(ProjectContent), editor, ProjectContent); return(true); case "new": return(ShowNewCompletion(editor)); case "case": if (IsInComment(editor)) { return(false); } return(DoCaseCompletion(editor)); case "return": if (IsInComment(editor)) { return(false); } IMember m = GetCurrentMember(editor); if (m != null) { return(ProvideContextCompletion(editor, m.ReturnType, ' ')); } break; } return(false); }
public bool InsightRefreshOnComma(ITextEditor editor, char ch, out IInsightWindow insightWindow, IProjectContent projectContent) { // Show MethodInsightWindow or IndexerInsightWindow NRefactoryResolver r = new NRefactoryResolver(languageProperties); Location cursorLocation = editor.Caret.Position; if (r.Initialize(ParserService.GetParseInformation(editor.Document.Text, projectContent), cursorLocation.Y, cursorLocation.X)) { TextReader currentMethod = r.ExtractCurrentMethod(editor.Document.Text); if (currentMethod != null) { ILexer lexer = ParserFactory.CreateLexer(language, currentMethod); Token token; InspectedCall call = new InspectedCall(Location.Empty, null); call.parent = call; // HACK MINI PARSER // The following code tries to find the current nested call until the caret position (= cursorLocation) is // reached. call.commas contains all commas up to the caret position. // DOES NOT HANDLE GENERICS CORRECTLY! This is sufficient for overload "search", because if we miss one // overload it does not matter. But if we highlight the wrong parameter (see below) it DOES MATTER! while ((token = lexer.NextToken()) != null && token.Kind != eofToken && token.Location < cursorLocation) { if (token.Kind == commaToken) { call.commas.Add(token.Location); } else if (token.Kind == openParensToken || token.Kind == openBracketToken || token.Kind == openBracesToken) { call = new InspectedCall(token.Location, call); } else if (token.Kind == closeParensToken || token.Kind == closeBracketToken || token.Kind == closeBracesToken) { call = call.parent; } } int offset = LocationToOffset(editor, call.start); if (offset >= 0 && offset < editor.Document.TextLength) { char c = editor.Document.GetCharAt(offset); if (c == '(' || c == '[') { var insightProvider = new MethodInsightProvider(projectContent) { LookupOffset = offset }; var insightItems = insightProvider.ProvideInsight(editor); // find highlighted parameter // see mini parser description above; the number of recognized parameters is the index // of the current parameter! var parameters = ResolveCallParameters(editor, call); highlightedParameter = parameters.Count; insightWindow = ShowInsight(editor, insightItems, parameters, ch); return(insightWindow != null); } else { } } } } insightWindow = null; return(false); }