Skip to content

Instantly share code, notes, and snippets.

@chrisforbes
Created July 7, 2010 01:02
Show Gist options
  • Save chrisforbes/466154 to your computer and use it in GitHub Desktop.
Save chrisforbes/466154 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
namespace fooTest
{
class CompletionProvider
{
public CompletionProvider(string fileCompile, string fileComplete, int line, int col)
{
var psi = new ProcessStartInfo
{
CreateNoWindow = true,
FileName = "clang",
UseShellExecute = false,
Arguments = MakeCompletionArgs( fileCompile, fileComplete, line, col ),
RedirectStandardOutput = true,
RedirectStandardError = true,
StandardOutputEncoding = Encoding.ASCII,
StandardErrorEncoding = Encoding.ASCII,
};
using( var process = Process.Start(psi) )
{
RawCompletions = Encoding.ASCII.GetBytes(process.StandardOutput.ReadToEnd());
RawDiagnostics = process.StandardError.ReadToEnd();
process.WaitForExit();
}
var ms = new MemoryStream(RawCompletions);
var br = new BinaryReader(ms);
var completions = new List<Completion>();
try { for (; ; ) completions.Add(new Completion(br)); }
catch (EndOfStreamException) { }
Completions = completions.ToArray();
}
public byte[] RawCompletions;
public string RawDiagnostics;
public Completion[] Completions;
static string MakeCompletionArgs(string fileCompile, string fileComplete, int line, int col)
{
return string.Format("-Xclang -code-completion-at -Xclang {0}:{1}:{2} {3} -fsyntax-only "
+ "-Xclang -no-code-completion-debug-printer -Xclang -code-completion-macros",
fileComplete, line, col, fileCompile);
}
}
enum CompletionKind
{
UnexposedDecl = 1,
StructDecl,
UnionDecl,
ClassDecl,
EnumDecl,
FieldDecl,
EnumConstantDecl,
FunctionDecl,
VarDecl,
ParmDecl,
ObjCInterfaceDecl,
ObjCCategoryDecl,
ObjCProtcolDecl,
ObjCPropertyDecl,
ObjCIvarDecl,
ObjCInstanceMethodDecl,
ObjCClassMethodDecl,
ObjCImplementationDecl,
ObjCCategoryImplDecl,
TypedefDecl,
CxxMethod,
Namespace,
LinkageSpec,
FirstDecl = UnexposedDecl,
LastDecl = LinkageSpec,
ObjCSuperClassRef = 40,
ObjCProtocolRef,
ObjCClassRef,
TypeRef,
FirstRef = ObjCSuperClassRef,
LastRef = TypeRef,
InvalidFile = 70,
NoDeclFound,
NotImplemented,
InvalidCode,
FirstInvalid = InvalidFile,
LastInvalid = InvalidCode,
UnexposedExpr = 100,
DeclRefExpr,
MemberRefExpr,
CallExpr,
ObjCMessageExpr,
BlockExpr,
FirstExpr = UnexposedExpr,
LastExpr = BlockExpr,
UnexposedStmt = 200,
FirstStmt = UnexposedStmt,
LastStmt = UnexposedStmt,
TranslationUnit = 300,
UnexposedAttr = 400,
IBActionAttr,
IBOutletAttr,
IBOutletCollectionAttr,
FirstAttr = UnexposedAttr,
LastAttr = IBOutletCollectionAttr,
PreprocessingDirective = 500,
MacroDefinition,
MacroInstantiation,
FirstPreprocessing = PreprocessingDirective,
LastPreprocessing = MacroInstantiation
}
enum CompletionChunkKind
{
TypedText, Text, Optional, Placeholder, Informative, ResultType, CurrentParameter,
LeftParen, RightParen, LeftBracket, RightBracket, LeftBrace, RightBrace, LeftAngle, RightAngle,
Comma, Colon, SemiColon, Equal, HorizontalSpace, VerticalSpace
}
class Completion
{
public CompletionKind Kind;
public CompletionChunk[] Chunks;
public int Priority;
public Completion(BinaryReader br)
{
Kind = (CompletionKind) br.ReadInt32();
Priority = br.ReadInt32();
Chunks = CompletionChunk.ParseCompletionString(br);
}
}
class CompletionChunk
{
public CompletionChunkKind Kind;
public string Value;
public CompletionChunk[] SubChunks;
public CompletionChunk(BinaryReader br)
{
Kind = (CompletionChunkKind)br.ReadInt32();
switch (Kind)
{
case CompletionChunkKind.TypedText:
case CompletionChunkKind.Text:
case CompletionChunkKind.Placeholder:
case CompletionChunkKind.Informative:
case CompletionChunkKind.ResultType:
case CompletionChunkKind.CurrentParameter:
var valueSize = br.ReadInt32();
var valueBytes = br.ReadBytes(valueSize);
Value = Encoding.UTF8.GetString(valueBytes);
break;
case CompletionChunkKind.Optional:
SubChunks = ParseCompletionString(br);
break;
}
}
public static CompletionChunk[] ParseCompletionString(BinaryReader br)
{
var numBlocks = br.ReadInt32();
var result = new List<CompletionChunk>();
for (var i = 0; i < numBlocks; i++)
result.Add(new CompletionChunk(br));
return result.ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment