コード例 #1
0
        public override ICompletionDataList HandleCodeCompletion(CodeCompletionContext completionContext, char completionChar, ref int triggerWordLength)
        {
            //		IDisposable timer = null;
            try {
            if (dom == null /*|| Document.CompilationUnit == null*/)
                return null;
            if (completionChar != '#' && stateTracker.Engine.IsInsidePreprocessorDirective)
                return null;
            //	timer = Counters.ResolveTime.BeginTiming ();
            DomLocation location = new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset - 1);
            stateTracker.UpdateEngine ();
            ExpressionResult result;
            int cursor, newCursorOffset = 0;
            switch (completionChar) {
            case ':':
            case '.':
                if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
                    return null;
                result = FindExpression (dom, completionContext);
                if (result == null || result.Expression == null)
                    return null;
                int idx = result.Expression.LastIndexOf ('.');
                if (idx > 0)
                    result.Expression = result.Expression.Substring (0, idx);
                NRefactoryResolver resolver = new NRefactoryResolver (dom, Document.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, Editor, Document.FileName);
                ResolveResult resolveResult = resolver.Resolve (result, location);
                if (resolver.ResolvedExpression is ICSharpCode.NRefactory.Ast.PrimitiveExpression) {
                    ICSharpCode.NRefactory.Ast.PrimitiveExpression pex = (ICSharpCode.NRefactory.Ast.PrimitiveExpression)resolver.ResolvedExpression;
                    if (!tryToForceCompletion && !(pex.Value is string || pex.Value is char || pex.Value is bool))
                        return null;
                }

                return CreateCompletionData (location, resolveResult, result, resolver);
            case '#':
                if (stateTracker.Engine.IsInsidePreprocessorDirective)
                    return GetDirectiveCompletionData ();
                return null;
            case '>':
                cursor = Editor.SelectionStartPosition;

                if (stateTracker.Engine.IsInsideDocLineComment) {
                    string lineText = Editor.GetLineText (completionContext.TriggerLine);
                    int startIndex = Math.Min (completionContext.TriggerLineOffset - 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 <= completionContext.TriggerLineOffset && 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) {
                            Editor.InsertText (cursor, "</" + tag + ">");
                            Editor.CursorPosition = cursor;
                            return null;
                        }
                    }
                }
                return null;
            /* Disabled because it gives problems when declaring arrays - for example string [] should not pop up code completion.
             			case '[':
                if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
                    return null;
                result = FindExpression (dom, completionContext);
                if (result.ExpressionContext == ExpressionContext.Attribute)
                    return CreateCtrlSpaceCompletionData (completionContext, result);
                return null;*/
            case '<':
                if (stateTracker.Engine.IsInsideDocLineComment)
                    return GetXmlDocumentationCompletionData ();
                return null;
            case '(':
                if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
                    return null;
                result = FindExpression (dom, completionContext, -1);
                if (result == null || result.Expression == null)
                    return null;
                resolver = new NRefactoryResolver (dom, Document.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, Editor, Document.FileName);
                resolveResult = resolver.Resolve (result, new DomLocation (completionContext.TriggerLine, completionContext.TriggerLineOffset - 2));

                if (resolveResult != null && resolver.ResolvedExpression is ICSharpCode.NRefactory.Ast.TypeOfExpression) {
                    CompletionDataList completionList = new ProjectDomCompletionDataList ();

                    CompletionDataCollector col = new CompletionDataCollector (completionList, Document.CompilationUnit, location);
                    AddPrimitiveTypes (col);
                    foreach (object o in dom.GetNamespaceContents (GetUsedNamespaces (), true, true)) {
                        col.Add (o);
                    }
                    return completionList;
                }
                return null;
            case '/':
                cursor = Editor.SelectionStartPosition;
                if (cursor < 2)
                    break;

                if (stateTracker.Engine.IsInsideDocLineComment) {
                    string lineText = Editor.GetLineText (completionContext.TriggerLine);
                    bool startsDocComment = true;
                    int slashes = 0;
                    for (int i = 0; i < completionContext.TriggerLineOffset && i < lineText.Length; i++) {
                        if (lineText[i] == '/') {
                            slashes++;
                            continue;
                        }
                        if (!Char.IsWhiteSpace (lineText[i])) {
                            startsDocComment = false;
                            break;
                        }
                    }
                    // check if lines above already start a doc comment
                    for (int i = completionContext.TriggerLine - 1; i >= 0; i--) {
                        string text = Editor.GetLineText (i).Trim ();
                        if (text.Length == 0)
                            continue;
                        if (text.StartsWith ("///")) {
                            startsDocComment = false;
                            break;
                        }
                        break;
                    }

                    // check if following lines start a doc comment
                    for (int i = completionContext.TriggerLine + 1; i < Editor.LineCount; i++) {
                        string text = Editor.GetLineText (i);
                        if (text == null)
                            break;
                        text = text.Trim ();
                        if (text.Length == 0)
                            continue;
                        if (text.StartsWith ("///")) {
                            startsDocComment = false;
                            break;
                        }
                        break;
                    }

                    if (!startsDocComment || slashes != 3)
                        break;
                    StringBuilder generatedComment = new StringBuilder ();
                    bool generateStandardComment = true;
                    ParsedDocument currentParsedDocument = Document.UpdateParseDocument ();
                    IType insideClass = NRefactoryResolver.GetTypeAtCursor (currentParsedDocument.CompilationUnit, Document.FileName, location);
                    if (insideClass != null) {
                        string indent = GetLineWhiteSpace (lineText);
                        if (insideClass.ClassType == ClassType.Delegate) {
                            AppendSummary (generatedComment, indent, out newCursorOffset);
                            IMethod m = null;
                            foreach (IMethod method in insideClass.Methods)
                                m = method;
                            AppendMethodComment (generatedComment, indent, m);
                            generateStandardComment = false;
                        } else {
                            if (!IsInsideClassBody (insideClass, completionContext.TriggerLine, completionContext.TriggerLineOffset))
                                break;
                            string body = GenerateBody (insideClass, completionContext.TriggerLine, indent, out newCursorOffset);
                            if (!String.IsNullOrEmpty (body)) {
                                generatedComment.Append (body);
                                generateStandardComment = false;
                            }
                        }
                    }
                    if (generateStandardComment) {
                        string indent = GetLineWhiteSpace (Editor.GetLineText (completionContext.TriggerLine));
                        AppendSummary (generatedComment, indent, out newCursorOffset);
                    }
                    Editor.EndAtomicUndo ();
                    Editor.BeginAtomicUndo ();
                    Editor.InsertText (cursor, generatedComment.ToString ());
                    Editor.CursorPosition = cursor + newCursorOffset;
                    return null;
                }
                return null;
            case ' ':
                if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
                    return null;
                result = FindExpression (dom, completionContext);
                if (result == null)
                    return null;

                int tokenIndex = completionContext.TriggerOffset;
                string token = GetPreviousToken (ref tokenIndex, false);
                if (token == "=") {
                    int j = tokenIndex;
                    string prevToken = GetPreviousToken (ref j, false);
                    if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
                        token = prevToken + token;
                        tokenIndex = j;
                    }
                }
                switch (token) {
                case "=":
                case "==":
                    result = FindExpression (dom, completionContext, tokenIndex - completionContext.TriggerOffset - 1);
                    resolver = new NRefactoryResolver (dom, Document.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, Editor, Document.FileName);
                    resolveResult = resolver.Resolve (result, location);
                    if (resolveResult != null) {
                        IType resolvedType = dom.GetType (resolveResult.ResolvedType);
                        if (resolvedType != null && resolvedType.ClassType == ClassType.Enum) {
                            CompletionDataList completionList = new ProjectDomCompletionDataList ();
                            CompletionDataCollector cdc = new CompletionDataCollector (completionList, Document.CompilationUnit, location);
                            IReturnType returnType = new DomReturnType (resolvedType);
                            bool added = false;
                            foreach (IUsing u in Document.CompilationUnit.Usings) {
                                foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
                                    if (alias.Value.ToInvariantString () == returnType.ToInvariantString ()) {
                                        cdc.Add (alias.Key, "md-class");
                                        added = true;
                                    }
                                }
                            }
                            if (!added)
                                cdc.Add (returnType);
                            foreach (object o in CreateCtrlSpaceCompletionData (completionContext, result)) {
                                MemberCompletionData memberData = o as MemberCompletionData;
                                if (memberData == null || memberData.Member == null)
                                    continue;
                                if (memberData.Member is IMember) {
                                    returnType = ((IMember)memberData.Member).ReturnType;
                                } else if (memberData.Member is IParameter) {
                                    returnType = ((IParameter)memberData.Member).ReturnType;
                                } else {
                                    returnType = ((LocalVariable)memberData.Member).ReturnType;
                                }
                                if (returnType != null && returnType.FullName == resolvedType.FullName)
                                    completionList.Add (memberData);
                            }
                            completionList.AutoCompleteEmptyMatch = false;
                            return completionList;
                        }
                    }
                    return null;
                case "+=":
                case "-=":
                    if (stateTracker.Engine.IsInsideDocLineComment || stateTracker.Engine.IsInsideOrdinaryCommentOrString)
                        return null;
                    result = FindExpression (dom, completionContext, tokenIndex - completionContext.TriggerOffset);
                    resolver = new NRefactoryResolver (dom, Document.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, Editor, Document.FileName);
                    resolveResult = resolver.Resolve (result, location);

                    if (resolveResult is MemberResolveResult) {
                        MemberResolveResult mrr = resolveResult as MemberResolveResult;
                        IEvent evt = mrr.ResolvedMember as IEvent;

                        if (evt == null)
                            return null;
                        IType delegateType = dom.GetType (evt.ReturnType);
                        if (delegateType == null || delegateType.ClassType != ClassType.Delegate)
                            return null;
                        CompletionDataList completionList = new ProjectDomCompletionDataList ();
                        CompletionDataCollector cdc = new CompletionDataCollector (completionList, Document.CompilationUnit, location);

                        IType declaringType = resolver.CallingType;
                        if (Document.LastErrorFreeParsedDocument != null) {
                            declaringType = Document.LastErrorFreeParsedDocument.CompilationUnit.GetType (declaringType.FullName, declaringType.TypeParameters.Count);
                        }
                        IType typeFromDatabase = dom.GetType (declaringType.FullName, new DomReturnType (declaringType).GenericArguments) ?? declaringType;
                        bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
                        foreach (IType type in dom.GetInheritanceTree (typeFromDatabase)) {
                            foreach (IMethod method in type.Methods) {
                                if (method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) && MatchDelegate (delegateType, method)) {
                                    ICompletionData data = cdc.Add (method);
                                    data.SetText (data.CompletionText + ";");
                                }
                            }
                        }
                        if (token == "+=") {
                            IMethod delegateMethod = delegateType.Methods.First ();
                            completionList.Add ("delegate", "md-keyword", GettextCatalog.GetString ("Creates anonymous delegate."), "delegate {\n" + stateTracker.Engine.ThisLineIndent  + TextEditorProperties.IndentString + "|\n" + stateTracker.Engine.ThisLineIndent +"};");
                            StringBuilder sb = new StringBuilder ("(");
                            for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
                                if (k > 0)
                                    sb.Append (", ");
                                sb.Append (CompletionDataCollector.ambience.GetString (Document.CompilationUnit.ShortenTypeName (delegateMethod.Parameters[k].ReturnType, Document.TextEditor.CursorLine, Document.TextEditor.CursorColumn), OutputFlags.ClassBrowserEntries | OutputFlags.UseFullName));
                                sb.Append (" ");
                                sb.Append (delegateMethod.Parameters[k].Name);
                            }
                            sb.Append (")");
                            completionList.Add ("delegate" + sb, "md-keyword", GettextCatalog.GetString ("Creates anonymous delegate."), "delegate" + sb + " {\n" + stateTracker.Engine.ThisLineIndent  + TextEditorProperties.IndentString + "|\n" + stateTracker.Engine.ThisLineIndent +"};");
                            string varName = GetPreviousToken (ref tokenIndex, false);
                            varName = GetPreviousToken (ref tokenIndex, false);
                            if (varName != ".") {
                                varName = null;
                            } else {
                                List<string> names = new List<string> ();
                                while (varName == ".") {
                                    varName = GetPreviousToken (ref tokenIndex, false);
                                    if (varName == "this") {
                                        names.Add ("handle");
                                    } else if (varName != null) {
                                        string trimmedName = varName.Trim ();
                                        if (trimmedName.Length == 0)
                                            break;
                                        names.Insert (0, trimmedName);
                                    }
                                    varName = GetPreviousToken (ref tokenIndex, false);
                                }
                                varName = String.Join ("", names.ToArray ());
                            }

                            completionList.Add (new EventCreationCompletionData (((Mono.TextEditor.ITextEditorDataProvider)Document.GetContent<Mono.TextEditor.ITextEditorDataProvider> ()).GetTextEditorData (), varName, delegateType, evt, sb.ToString (), resolver.CallingMember, typeFromDatabase));
                        }
                        return completionList;
                    }
                    return null;
                }
                return HandleKeywordCompletion (completionContext, result, tokenIndex, token);
            default:
                if ((Char.IsLetter (completionChar) || completionChar == '_') && TextEditorProperties.EnableAutoCodeCompletion
                        && !stateTracker.Engine.IsInsideDocLineComment
                        && !stateTracker.Engine.IsInsideOrdinaryCommentOrString)
                {
                    char prevCh = completionContext.TriggerOffset > 2
                            ? Editor.GetCharAt (completionContext.TriggerOffset - 2)
                            : '\0';

                    char nextCh = completionContext.TriggerOffset < Editor.TextLength
                            ? Editor.GetCharAt (completionContext.TriggerOffset)
                            : ' ';
                    const string allowedChars = ";[(){}+-*/%^?:&|~!<>=";
                    if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
                        return null;
                    if (Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0)
                    {
                        result = FindExpression (dom, completionContext, -1);
                        if (result == null)
                            return null;

                        if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
                            triggerWordLength = 1;
                            bool autoSelect = true;
                            int cpos;
                            if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
                                CodeCompletionContext ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
                                NRefactoryParameterDataProvider provider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
                                if (provider != null) {
                                    int i = provider.GetCurrentParameterIndex (ctx) - 1;
                                    if (i < provider.Methods[0].Parameters.Count) {
                                        IType returnType = dom.GetType (provider.Methods[0].Parameters[i].ReturnType);
                                        autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
                                    }
                                }
                            }
                            CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
                            dataList.AutoSelect = autoSelect;
                            return dataList;
                        }
                    }
                }
                break;
            }
            } catch (Exception e) {
                System.Console.WriteLine("cce: " +e);
            } finally {
            //			if (timer != null)
            //				timer.Dispose ();
            }
            return null;
        }
コード例 #2
0
        CompletionDataList GetDefineCompletionData()
        {
            if (Document.Project == null)
                return null;

            Dictionary<string, string> symbols = new Dictionary<string, string> ();
            CompletionDataList cp = new ProjectDomCompletionDataList ();
            foreach (DotNetProjectConfiguration conf in Document.Project.Configurations) {
                FSharpCompilerParameters cparams = conf.CompilationParameters as FSharpCompilerParameters;
                if (cparams != null) {
                    string[] syms = cparams.DefineSymbols.Split (';');
                    foreach (string s in syms) {
                        string ss = s.Trim ();
                        if (ss.Length > 0 && !symbols.ContainsKey (ss)) {
                            symbols [ss] = ss;
                            cp.Add (ss, "md-literal");
                        }
                    }
                }
            }
            return cp;
        }
コード例 #3
0
        CompletionDataList GetPartialCompletionData(CodeCompletionContext ctx, IType type, string modifiers)
        {
            CompletionDataList result = new ProjectDomCompletionDataList ();

            CompoundType partialType = dom.GetType (type.FullName) as CompoundType;
            if (partialType != null) {
                List<IMethod> methods = new List<IMethod> ();
                // gather all partial methods without implementation
                foreach (IType part in partialType.Parts) {
                    if (part.Location == type.Location && part.CompilationUnit.FileName == type.CompilationUnit.FileName)
                        continue;
                    foreach (IMethod method in part.Methods) {
                        if (method.IsPartial && method.BodyRegion.End.Line == 0 && !ContainsDeclaration (type, method)) {
                            methods.Add (method);
                        }
                    }
                }

                // now filter all methods that are implemented in the compound class
                foreach (IType part in partialType.Parts) {
                    if (part.Location == type.Location && part.CompilationUnit.FileName == type.CompilationUnit.FileName)
                        continue;
                    for (int i = 0; i < methods.Count; i++) {
                        IMethod curMethod = methods[i];
                        IMethod method = GetDeclaration (part, curMethod);
                        if (method != null && method.BodyRegion.End.Line != 0) {
                            methods.RemoveAt (i);
                            i--;
                            continue;
                        }
                    }
                }

                foreach (IMethod method in methods) {
                    NewOverrideCompletionData data = new NewOverrideCompletionData (dom, Editor, ctx.TriggerOffset, type, method);
                    data.GenerateBody = false;
                    result.Add (data);
                }

            }
            return result;
        }
コード例 #4
0
        CompletionDataList CreateTypeCompletionData(DomLocation location, IType callingType, ExpressionContext context, IReturnType returnType, IReturnType returnTypeUnresolved)
        {
            CompletionDataList result = new ProjectDomCompletionDataList ();
            // "var o = new " needs special treatment.
            if (returnType == null && returnTypeUnresolved != null && returnTypeUnresolved.FullName == "var")
                returnType = returnTypeUnresolved = DomReturnType.Object;

            //	ExpressionContext.TypeExpressionContext tce = context as ExpressionContext.TypeExpressionContext;

            CompletionDataCollector col = new CompletionDataCollector (result, Document.CompilationUnit, location);
            IType type = null;
            if (returnType != null)
                type = dom.GetType (returnType);
            if (type == null)
                type = dom.SearchType (new SearchTypeRequest (Document.CompilationUnit, returnTypeUnresolved, null));

            if (type == null || !(type.IsAbstract || type.ClassType == ClassType.Interface)) {
                if (type == null || type.ConstructorCount == 0 || type.Methods.Any (c => c.IsConstructor && c.IsAccessibleFrom (dom, callingType, type, callingType != null && dom.GetInheritanceTree (callingType).Any (x => x.FullName == type.FullName)))) {
                    if (returnTypeUnresolved != null) {
                        col.FullyQualify = true;
                        ICompletionData unresovedCompletionData = col.Add (returnTypeUnresolved);
                        col.FullyQualify = false;
                        result.DefaultCompletionString = StripGenerics (unresovedCompletionData.CompletionText);
                    } else {
                        ICompletionData unresovedCompletionData = col.Add (returnType);
                        result.DefaultCompletionString = StripGenerics (unresovedCompletionData.CompletionText);
                    }
                }
            }
            //				if (tce != null && tce.Type != null) {
            //					result.DefaultCompletionString = StripGenerics (col.AddCompletionData (result, tce.Type).CompletionString);
            //				}
            //			else {
            //			}

            if (type == null)
                return result;
            HashSet<string> usedNamespaces = new HashSet<string> (GetUsedNamespaces ());
            if (type.FullName == DomReturnType.Object.FullName)
                AddPrimitiveTypes (col);
            foreach (IType curType in dom.GetSubclasses (type)) {
                if (context != null && context.FilterEntry (curType))
                    continue;
                if ((curType.TypeModifier & TypeModifier.HasOnlyHiddenConstructors) == TypeModifier.HasOnlyHiddenConstructors)
                    continue;
                if (usedNamespaces.Contains (curType.Namespace)) {
                    if (curType.ConstructorCount > 0) {
                        if (!(curType.Methods.Any (c => c.IsConstructor && c.IsAccessibleFrom (dom, curType, callingType, callingType != null && dom.GetInheritanceTree (callingType).Any (x => x.FullName == curType.FullName)))))
                            continue;
                    }
                    col.Add (curType);
                } else {
                    string nsName = curType.Namespace;
                    int idx = nsName.IndexOf ('.');
                    if (idx >= 0)
                        nsName = nsName.Substring (0, idx);
                    col.Add (new Namespace (nsName));
                }
            }

            // add aliases
            if (returnType != null) {
                foreach (IUsing u in Document.CompilationUnit.Usings) {
                    foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
                        if (alias.Value.ToInvariantString () == returnType.ToInvariantString ())
                            result.Add (alias.Key, "md-class");
                    }
                }
            }
            return result;
        }