/// <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)); }
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; }
/// <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)); }
public ClangCompletionUnit(CXCompletionResult item, string dataString, uint prio) : base(item, dataString) { priority = prio; }