Skip to content

Instantly share code, notes, and snippets.

@jbevain
Created August 8, 2010 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbevain/514682 to your computer and use it in GitHub Desktop.
Save jbevain/514682 to your computer and use it in GitHub Desktop.
diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay
index b718931..70051f1 100644
--- a/mcs/mcs/cs-parser.jay
+++ b/mcs/mcs/cs-parser.jay
@@ -2705,6 +2705,22 @@ delegate_declaration
}
;
+opt_enumerable_or_nullable
+ : opt_enumerable
+ | opt_nullable
+ ;
+
+opt_enumerable
+ : /* empty */
+ {
+ $$ = null;
+ }
+ | TILDE
+ {
+ $$ = ComposedTypeSpecifier.CreateIEnumerable (GetLocation ($1));
+ }
+ ;
+
opt_nullable
: /* empty */
{
@@ -2962,7 +2978,7 @@ type_expression_or_array
;
type_expression
- : namespace_or_type_name opt_nullable
+ : namespace_or_type_name opt_enumerable_or_nullable
{
MemberName name = (MemberName) $1;
@@ -2975,7 +2991,7 @@ type_expression
$$ = name.GetTypeExpression ();
}
}
- | builtin_types opt_nullable
+ | builtin_types opt_enumerable_or_nullable
{
if ($2 != null)
$$ = new ComposedCast ((FullNamedExpression) $1, (ComposedTypeSpecifier) $2);
@@ -3594,8 +3610,8 @@ opt_rank_specifier
;
opt_rank_specifier_or_nullable
- : opt_nullable
- | opt_nullable rank_specifiers
+ : opt_enumerable_or_nullable
+ | opt_enumerable_or_nullable rank_specifiers
{
if ($1 != null) {
((ComposedTypeSpecifier) $1).Next = (ComposedTypeSpecifier) $2;
diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs
index 253b1be..dd9c7bc 100644
--- a/mcs/mcs/cs-tokenizer.cs
+++ b/mcs/mcs/cs-tokenizer.cs
@@ -928,6 +928,7 @@ namespace Mono.CSharp
continue;
case Token.INTERR_NULLABLE:
+ case Token.TILDE:
case Token.STAR:
if (bracket_level == 0)
is_type = true;
@@ -1003,7 +1004,7 @@ namespace Mono.CSharp
return true;
else if (the_token == Token.COMMA || the_token == Token.DOT || the_token == Token.DOUBLE_COLON)
goto start;
- else if (the_token == Token.INTERR_NULLABLE || the_token == Token.STAR)
+ else if (the_token == Token.INTERR_NULLABLE || the_token == Token.STAR || the_token == Token.TILDE)
goto again;
else if (the_token == Token.OP_GENERICS_LT) {
if (!parse_less_than ())
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index aeb1cba..6a16fd4 100644
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -8412,6 +8412,12 @@ namespace Mono.CSharp {
}
}
+ public bool IsIEnumerable {
+ get {
+ return Dimension == -3;
+ }
+ }
+
public ComposedTypeSpecifier Next { get; set; }
#endregion
@@ -8431,6 +8437,11 @@ namespace Mono.CSharp {
return new ComposedTypeSpecifier (-2, loc);
}
+ public static ComposedTypeSpecifier CreateIEnumerable (Location loc)
+ {
+ return new ComposedTypeSpecifier (-3, loc);
+ }
+
public string GetSignatureForError ()
{
string s =
@@ -8490,6 +8501,9 @@ namespace Mono.CSharp {
type = PointerContainer.MakeType (type);
single_spec = single_spec.Next;
+ } else if (single_spec.IsIEnumerable) {
+ type = TypeManager.generic_ienumerable_type.MakeGenericType (new [] { type });
+ single_spec = single_spec.Next;
}
if (single_spec != null && single_spec.Dimension > 0) {
@txdv
Copy link

txdv commented Sep 14, 2010

Just a few lines of code and such a magnificent result.
Just beautiful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment