/// <summary>
/// Parses a type definition.
/// </summary>
/// <param name="access">Type accessibility.</param>
/// <param name="typeAttributes">Type modifiers.</param>
/// <param name="elementType">Type element type.</param>
/// <returns>Type code element.</returns>
private TypeElement ParseType(
CodeAccess access,
TypeModifiers typeAttributes,
TypeElementType elementType)
{
TypeElement typeElement = new TypeElement();
EatWhiteSpace();
string className = CaptureWord();
typeElement.Name = className;
typeElement.Access = access;
typeElement.Type = elementType;
typeElement.TypeModifiers = typeAttributes;
EatWhiteSpace();
if (elementType == TypeElementType.Enum)
{
EatWhiteSpace();
if (NextChar == CSharpSymbol.TypeImplements)
{
TryReadChar();
string interfaceName = CaptureTypeName();
InterfaceReference interfaceReference =
new InterfaceReference(interfaceName, InterfaceReferenceType.None);
typeElement.AddInterface(interfaceReference);
}
string enumText = ParseBlock(true, typeElement);
// TODO: Parse enum values as fields
typeElement.BodyText = enumText;
}
else
{
bool isGeneric = TryReadChar(CSharpSymbol.BeginGeneric);
if (isGeneric)
{
string[] typeParameterNames = ParseAliasList();
foreach (string typeParameterName in typeParameterNames)
{
TypeParameter typeParameter = new TypeParameter();
typeParameter.Name = typeParameterName;
typeElement.AddTypeParameter(typeParameter);
}
EatWhiteSpace();
if (!TryReadChar(CSharpSymbol.EndGeneric))
{
this.OnParseError("Expected " + CSharpSymbol.EndGeneric);
}
}
EatWhiteSpace();
bool implements = TryReadChar(CSharpSymbol.TypeImplements);
if (implements)
{
string[] typeList = ParseAliasList();
foreach (string type in typeList)
{
InterfaceReference interfaceReference =
new InterfaceReference(type, InterfaceReferenceType.None);
typeElement.AddInterface(interfaceReference);
}
}
EatWhiteSpace();
ParseTypeParameterConstraints(typeElement);
// Associate any additional comments in the type definition with the type.
ReadOnlyCollection<ICommentElement> extraComments = ParseComments();
foreach (ICommentElement comment in extraComments)
{
typeElement.AddHeaderComment(comment);
}
EatChar(CSharpSymbol.BeginBlock);
EatWhiteSpace();
if (NextChar != CSharpSymbol.EndBlock)
{
//
// Parse child elements
//
List<ICodeElement> childElements = ParseElements(typeElement);
foreach (ICodeElement childElement in childElements)
{
typeElement.AddChild(childElement);
}
}
EatChar(CSharpSymbol.EndBlock);
}
//
// Types allow a trailing semi-colon
//
EatTrailingEndOfStatement();
return typeElement;
}