private OffsetSyntaxHighlightingData CreateOffsetData(NClang.ClangCursor cursor, NClang.ClangCursor parent)
{
HighlightType highlightKind = HighlightType.Literal;
bool useSpellingLocation = false;
switch (cursor.Kind)
{
case NClang.CursorKind.StringLiteral:
case NClang.CursorKind.CharacterLiteral:
break;
case NClang.CursorKind.IntegerLiteral:
case NClang.CursorKind.FloatingLiteral:
case NClang.CursorKind.ImaginaryLiteral:
highlightKind = HighlightType.NumericLiteral;
break;
case NClang.CursorKind.Constructor:
case NClang.CursorKind.Destructor:
case NClang.CursorKind.TypedefDeclaration:
case NClang.CursorKind.ClassDeclaration:
case NClang.CursorKind.TemplateReference:
useSpellingLocation = true;
highlightKind = HighlightType.ClassName;
break;
case NClang.CursorKind.EnumDeclaration:
case NClang.CursorKind.UnionDeclaration:
useSpellingLocation = true;
highlightKind = HighlightType.EnumTypeName;
break;
case NClang.CursorKind.TemplateTypeParameter:
useSpellingLocation = true;
highlightKind = HighlightType.InterfaceName;
break;
case NClang.CursorKind.TypeReference:
if (parent.Kind == NClang.CursorKind.CXXBaseSpecifier)
{
highlightKind = HighlightType.ClassName;
useSpellingLocation = true;
}
else if (cursor.CursorType.Kind == NClang.TypeKind.Enum)
{
highlightKind = HighlightType.EnumTypeName;
}
else if (cursor.CursorType.Kind == NClang.TypeKind.Record && cursor.Spelling.StartsWith("union"))
{
highlightKind = HighlightType.EnumTypeName;
}
else
{
highlightKind = HighlightType.ClassName;
}
break;
case NClang.CursorKind.CXXMethod:
case NClang.CursorKind.FunctionDeclaration:
useSpellingLocation = true;
highlightKind = HighlightType.CallExpression;
break;
case NClang.CursorKind.FirstExpression:
if (parent.Kind == NClang.CursorKind.CallExpression && cursor.CursorType.Kind == NClang.TypeKind.Pointer && cursor.CursorType.PointeeType.Kind == NClang.TypeKind.FunctionProto)
{
useSpellingLocation = true;
highlightKind = HighlightType.CallExpression;
}
else
{
return null;
}
break;
case NClang.CursorKind.MemberReferenceExpression:
if (parent.Kind == NClang.CursorKind.CallExpression && cursor.CursorType.Kind == NClang.TypeKind.Pointer && cursor.CursorType.PointeeType.Kind == NClang.TypeKind.FunctionProto)
{
useSpellingLocation = true;
highlightKind = HighlightType.CallExpression;
}
else if (parent.Kind == NClang.CursorKind.CallExpression && cursor.CursorType.Kind == NClang.TypeKind.Unexposed)
{
useSpellingLocation = true;
highlightKind = HighlightType.CallExpression;
}
else
{
return null;
}
break;
default:
return null;
}
if (highlightKind == HighlightType.ClassName)
{
string spelling = cursor.Spelling;
if (cursor.Kind == NClang.CursorKind.TypeReference && parent.Kind == NClang.CursorKind.CXXBaseSpecifier)
{
spelling = cursor.Spelling.Replace("class ", string.Empty);
}
if (spelling.Length > 1 && spelling.StartsWith("I") && char.IsUpper(spelling[1]))
{
highlightKind = HighlightType.InterfaceName;
}
}
if (useSpellingLocation)
{
if (cursor.Kind == NClang.CursorKind.TypeReference && parent.Kind == NClang.CursorKind.CXXBaseSpecifier && cursor.Spelling.StartsWith("class"))
{
return new OffsetSyntaxHighlightingData()
{
Start = cursor.Location.SpellingLocation.Offset,
Length = cursor.Spelling.Length - 5, // Because spelling includes keyword "class"
Type = highlightKind
};
}
else if ((cursor.Kind == NClang.CursorKind.Destructor || cursor.Kind == NClang.CursorKind.Constructor) && parent.Kind == NClang.CursorKind.ClassTemplate)
{
return new OffsetSyntaxHighlightingData()
{
Start = cursor.Location.SpellingLocation.Offset,
Length = cursor.Spelling.Length, // TODO select only the name...
Type = highlightKind
};
}
else
{
return new OffsetSyntaxHighlightingData()
{
Start = cursor.Location.SpellingLocation.Offset,
Length = cursor.Spelling.Length,
Type = highlightKind
};
}
}
else
{
return new OffsetSyntaxHighlightingData()
{
Start = cursor.CursorExtent.Start.FileLocation.Offset,
Length = cursor.CursorExtent.End.FileLocation.Offset - cursor.CursorExtent.Start.FileLocation.Offset,
Type = highlightKind
};
}
}