/// <summary>
        /// Builds an overload candidate for parameter hinting.
        /// </summary>
        /// <returns>Overload candidate which contains return type, function name.</returns>
        /// <param name="resultItem">Result item. resultItem.CursorKind must be CXCursorKind.OverloadCandidate. </param>
        OverloadCandidate GetOverloadCandidate(CXCompletionResult resultItem)
        {
            var  completionString   = new CXCompletionString(resultItem.CompletionString);
            uint completionchunknum = clang.getNumCompletionChunks(completionString.Pointer);

            string ret        = String.Empty;
            string nam        = String.Empty;
            var    parameters = new List <string> ();

            for (uint j = 0; j < completionchunknum; j++)
            {
                switch (clang.getCompletionChunkKind(completionString.Pointer, j))
                {
                case CXCompletionChunkKind.ResultType:
                    ret = clang.getCompletionChunkText(completionString.Pointer, j).ToString();
                    break;

                case CXCompletionChunkKind.Text:
                    nam = clang.getCompletionChunkText(completionString.Pointer, j).ToString();
                    break;

                case CXCompletionChunkKind.CurrentParameter:
                case CXCompletionChunkKind.Placeholder:
                    parameters.Add(clang.getCompletionChunkText(completionString.Pointer, j).ToString());
                    break;
                }
            }
            return(new OverloadCandidate(ret, nam, parameters));
        }
        // modified code of Michael Hutchinson from https://github.com/mhutch/cbinding/pull/1#discussion_r34485216
        IEnumerable <ClangCompletionUnit> GetCompletionUnits(CXCompletionResult resultItem, Regex operatorFilter, bool fieldOrMethodMode)
        {
            var  completionString   = new CXCompletionString(resultItem.CompletionString);
            uint completionchunknum = clang.getNumCompletionChunks(completionString.Pointer);

            for (uint j = 0; j < completionchunknum; j++)
            {
                if (clang.getCompletionChunkKind(completionString.Pointer, j) != CXCompletionChunkKind.TypedText)
                {
                    continue;
                }
                switch (resultItem.CursorKind)
                {
                case CXCursorKind.Destructor:
                case CXCursorKind.UnaryOperator:
                case CXCursorKind.BinaryOperator:
                case CXCursorKind.CompoundAssignOperator:
                    continue;
                }
                if (fieldOrMethodMode)
                {
                    switch (resultItem.CursorKind)
                    {
                    case CXCursorKind.ClassDecl:
                    case CXCursorKind.StructDecl:
                        continue;
                    }
                }
                string realstring = clang.getCompletionChunkText(completionString.Pointer, j).ToString();
                if (operatorFilter.IsMatch(realstring))
                {
                    continue;
                }
                uint priority = clang.getCompletionPriority(completionString.Pointer);
                yield return(new ClangCompletionUnit(resultItem, realstring, priority));
            }
        }
        public override Task <ICompletionDataList> HandleCodeCompletionAsync(CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, CancellationToken token = default(CancellationToken))
        {
            var project = (CProject)DocumentContext.Project;

            if (project == null || !project.HasLibClang)
            {
                return(Task.FromResult((ICompletionDataList)null));
            }

            return(Task.Run(() => {
                var completionChar = triggerInfo.TriggerCharacter ?? ' ';
                ICompletionDataList list = new CompletionDataList();
                if (ShouldCompleteOn(completionChar))
                {
                    unsavedFiles = project.UnsavedFiles.Get();
                    bool fieldOrMethodMode = completionChar == '.' || completionChar == '>' ? true : false;
                    IntPtr pResults = project.ClangManager.CodeComplete(completionContext, unsavedFiles.ToArray(), DocumentContext.Name);
                    if (pResults.ToInt64() != 0)
                    {
                        CXCodeCompleteResults results = Marshal.PtrToStructure <CXCodeCompleteResults> (pResults);
                        for (int i = 0; i < results.NumResults; i++)
                        {
                            IntPtr iteratingPointer = results.Results + i * Marshal.SizeOf <CXCompletionResult> ();
                            CXCompletionResult resultItem = Marshal.PtrToStructure <CXCompletionResult> (iteratingPointer);
                            foreach (var cd in GetCompletionUnits(resultItem, operatorFilter, fieldOrMethodMode))
                            {
                                list.Add(cd);
                            }
                        }
                    }
                    clang.disposeCodeCompleteResults(pResults);
                }
                previous = completionChar;
                list.Sort((x, y) => x.CompareTo(y));
                return list;
            }, token));
        }
Beispiel #4
0
        public CompletionData(CXCompletionResult item, string dataString)
        {
            switch (item.CursorKind)
            {
            case CXCursorKind.ClassDecl:
                image = Stock.Class;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.ClassCategory);
                break;

            case CXCursorKind.ClassTemplate:
                image = Stock.Class;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.ClassTemplateCategory);
                break;

            case CXCursorKind.ClassTemplatePartialSpecialization:
                image = Stock.Class;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.ClassTemplatePartialCategory);
                break;

            case CXCursorKind.StructDecl:
                image = Stock.Struct;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.StructCategory);
                break;

            case CXCursorKind.UnionDecl:
                image = "md-union";
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.UnionCategory);
                break;

            case CXCursorKind.EnumDecl:
                image = Stock.Enum;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.EnumerationCategory);
                break;

            case CXCursorKind.EnumConstantDecl:
                image = Stock.Literal;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.EnumeratorCategory);
                break;

            case CXCursorKind.FunctionDecl:
                image = Stock.Method;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.FunctionCategory);
                break;

            case CXCursorKind.FunctionTemplate:
                image = Stock.Method;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.FunctionTemplateCategory);
                break;

            case CXCursorKind.Namespace:
                image = Stock.NameSpace;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.NamespaceCategory);
                break;

            case CXCursorKind.TypedefDecl:
                image = Stock.Interface;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.TypedefCategory);
                break;

            case CXCursorKind.CXXMethod:
                image = Stock.Field;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.MethodCategory);
                break;

            case CXCursorKind.FieldDecl:
                image = Stock.Field;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.FieldCategory);
                break;

            case CXCursorKind.VarDecl:
                image = Stock.Field;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.VariablesCategory);
                break;

            case CXCursorKind.MacroDefinition:
                image = Stock.Literal;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.MacroCategory);
                break;

            case CXCursorKind.ParmDecl:
                image = Stock.Field;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.ParameterCategory);
                break;

            default:
                image = Stock.Literal;
                CompletionCategory = new ClangCompletionCategory(ClangCompletionCategory.OtherCategory);
                break;
            }
            text             = dataString;
            completionString = dataString;
            description      = string.Empty;
        }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CompletionResult"/> class.
 /// </summary>
 /// <param name="completionResult">The completionResult<see cref="CXCompletionResult"/></param>
 /// <param name="fixIts">The fixIts<see cref="FixIt[]"/></param>
 internal CompletionResult(CXCompletionResult completionResult, FixIt[] fixIts)
 {
     this.m_value    = completionResult;
     this.FixIts     = fixIts;
     this.CursorKind = completionResult.CursorKind;
 }
        /// <summary>
        /// Handles the parameter completion async. Invoked automatically on every keypress.
        /// Contains scenarios for veeery perverted codes like: classInstancePointer    ->
        /// classmethod  ( (	new tempClass<int>{ 1 , 2 , 3 }  ) , (new int[1]{})) , but might be not ready for everything.
        /// </summary>
        /// <returns>The parameter completion async.</returns>
        /// <param name="completionContext">Completion context.</param>
        /// <param name="completionChar">Completion char.</param>
        /// <param name="token">Token.</param>s
        public override Task <ParameterHintingResult> HandleParameterCompletionAsync(
            CodeCompletionContext completionContext,
            char completionChar,
            CancellationToken token = default(CancellationToken))
        {
            if (completionChar != '(' && completionChar != ',')
            {
                return(Task.FromResult((ParameterHintingResult)null));
            }

            var project = (CProject)DocumentContext.Project;

            if (project == null || !project.HasLibClang)
            {
                return(Task.FromResult((ParameterHintingResult)null));
            }

            return(Task.Run(() => {
                #region NEEDED_FOR_STARTOFFSET_:(

                int inParenthesis = 0;
                int nameEnd = completionContext.TriggerOffset - 1;
                char endChar = Editor.GetCharAt(nameEnd);
                char prevChar = Editor.GetCharAt(nameEnd - 1);
                while (!(prevChar != '(' && endChar == '(' && inParenthesis <= 0) &&             //multiple '('
                       nameEnd > 1)
                {
                    switch (endChar)
                    {
                    case ')':
                        inParenthesis++;
                        break;

                    case '(':
                        inParenthesis--;
                        break;
                    }
                    endChar = Editor.GetCharAt(--nameEnd);
                    prevChar = Editor.GetCharAt(nameEnd - 1);
                }

                WorkaroundWhitespaces(ref prevChar, ref nameEnd);
                WorkaroundTemplateSpecifier(ref prevChar, ref nameEnd);
                WorkaroundWhitespaces(ref prevChar, ref nameEnd);

                int nameStart = nameEnd - 1;
                //the actual name getting, march backwards while not a ., ->, space etc.
                while (!allowedChars.Contains(prevChar) && nameStart > 1)
                {
                    nameStart--;
                    prevChar = Editor.GetCharAt(nameStart - 1);
                }
                string functionName = Editor.Text.Substring(nameStart, nameEnd - nameStart);

                #endregion

                if (string.IsNullOrEmpty(functionName))
                {
                    return (ParameterHintingResult)null;
                }
                unsavedFiles = project.UnsavedFiles.Get();

                IntPtr pResults = project.ClangManager.CodeComplete(completionContext, unsavedFiles.ToArray(), DocumentContext.Name);
                CXCodeCompleteResults results = Marshal.PtrToStructure <CXCodeCompleteResults> (pResults);

                if (results.Results.ToInt64() != 0)
                {
                    var parameterInformation = new List <OverloadCandidate> ();
                    for (int i = 0; i < results.NumResults; i++)
                    {
                        IntPtr iteratingPointer = results.Results + i * Marshal.SizeOf <CXCompletionResult> ();
                        CXCompletionResult resultItem = Marshal.PtrToStructure <CXCompletionResult> (iteratingPointer);

                        if (resultItem.CursorKind == CXCursorKind.@OverloadCandidate)
                        {
                            parameterInformation.Add(GetOverloadCandidate(resultItem));
                        }
                    }
                    clang.disposeCodeCompleteResults(pResults);
                    return (ParameterHintingResult) new ParameterDataProvider(nameStart, parameterInformation);
                }
                return (ParameterHintingResult)null;
            }, token));
        }
Beispiel #7
0
 public ClangCompletionUnit(CXCompletionResult item, string dataString, uint prio) : base(item, dataString)
 {
     priority = prio;
 }