Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

Commit

Permalink
Support tuples for type directive tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
ajaybhargavb committed Aug 14, 2017
1 parent 655a693 commit 8d2a9e5
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
Expand Up @@ -957,7 +957,34 @@ protected bool QualifiedIdentifier(out int identifierLength)

protected bool NamespaceOrTypeName()
{
if (Optional(CSharpSymbolType.Identifier) || Optional(CSharpSymbolType.Keyword))
if (Optional(CSharpSymbolType.LeftParenthesis))
{
while (!Optional(CSharpSymbolType.RightParenthesis) && !EndOfFile)
{
Optional(CSharpSymbolType.WhiteSpace);

if (!NamespaceOrTypeName())
{
return false;
}

Optional(CSharpSymbolType.WhiteSpace);
Optional(CSharpSymbolType.Identifier);
Optional(CSharpSymbolType.WhiteSpace);
Optional(CSharpSymbolType.Comma);
}

if (At(CSharpSymbolType.WhiteSpace) && NextIs(CSharpSymbolType.QuestionMark))
{
// Only accept the whitespace if we are going to consume the next token.
AcceptAndMoveNext();
}

Optional(CSharpSymbolType.QuestionMark); // Nullable

return true;
}
else if (Optional(CSharpSymbolType.Identifier) || Optional(CSharpSymbolType.Keyword))
{
if (Optional(CSharpSymbolType.DoubleColon))
{
Expand All @@ -975,8 +1002,20 @@ protected bool NamespaceOrTypeName()
NamespaceOrTypeName();
}

if (At(CSharpSymbolType.WhiteSpace) && NextIs(CSharpSymbolType.QuestionMark))
{
// Only accept the whitespace if we are going to consume the next token.
AcceptAndMoveNext();
}

Optional(CSharpSymbolType.QuestionMark); // Nullable

if (At(CSharpSymbolType.WhiteSpace) && NextIs(CSharpSymbolType.LeftBracket))
{
// Only accept the whitespace if we are going to consume the next token.
AcceptAndMoveNext();
}

while (At(CSharpSymbolType.LeftBracket))
{
Balance(BalancingModes.None);
Expand Down
Expand Up @@ -811,6 +811,55 @@ public void DirectiveDescriptor_AllowsNullableTypes(string expectedType)
Factory.Span(SpanKindInternal.Code, expectedType, markup: false).AsDirectiveToken(descriptor.Tokens[0])));
}

[Theory]
[InlineData("(bool, int)")]
[InlineData("(int aa, string bb)?")]
[InlineData("( int? q , bool w )")]
[InlineData("( int ? q, bool ?w ,(long ? [])) ?")]
[InlineData("(List<(int, string)?> aa, string bb)")]
[InlineData("(string ss, (int u, List<(string, int)> k, (Char c, bool b, List<int> l)), global::System.Int32[] a)")]
public void DirectiveDescriptor_AllowsTupleTypes(string expectedType)
{
// Arrange
var descriptor = DirectiveDescriptor.CreateDirective(
"custom",
DirectiveKind.SingleLine,
b => b.AddTypeToken());

// Act & Assert
ParseCodeBlockTest(
$"@custom {expectedType}",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
Factory.Span(SpanKindInternal.Code, expectedType, markup: false).AsDirectiveToken(descriptor.Tokens[0])));
}

[Fact]
public void DirectiveDescriptor_AllowsTupleTypes_IgnoresTrailingWhitespace()
{
// Arrange
var descriptor = DirectiveDescriptor.CreateDirective(
"custom",
DirectiveKind.SingleLine,
b => b.AddTypeToken());

// Act & Assert
ParseCodeBlockTest(
$"@custom (bool, int?) ",
new[] { descriptor },
new DirectiveBlock(
new DirectiveChunkGenerator(descriptor),
Factory.CodeTransition(),
Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
Factory.Span(SpanKindInternal.Code, "(bool, int?)", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
Factory.MetaCode(" ").Accepts(AcceptedCharactersInternal.WhiteSpace)));
}

[Fact]
public void DirectiveDescriptor_ErrorsExtraContentAfterDirective()
{
Expand Down

0 comments on commit 8d2a9e5

Please sign in to comment.