Last active
August 29, 2015 13:58
-
-
Save jbevain/9979462 to your computer and use it in GitHub Desktop.
Roslyn patch to add syntactic sugar to C# replacing IEnumerable<T> with T~
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Src/Compilers/CSharp/Source/Binder/Binder_Symbols.cs b/Src/Compilers/CSharp/Source/Binder/Binder_Symbols.cs | |
index ce0a903..b34b498 100644 | |
--- a/Src/Compilers/CSharp/Source/Binder/Binder_Symbols.cs | |
+++ b/Src/Compilers/CSharp/Source/Binder/Binder_Symbols.cs | |
@@ -379,6 +379,20 @@ namespace Microsoft.CodeAnalysis.CSharp | |
return new PointerTypeSymbol(elementType); | |
} | |
+ case SyntaxKind.EnumerableType: | |
+ { | |
+ NamedTypeSymbol enumerableOfT = GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T, diagnostics, syntax); | |
+ TypeSyntax typeArgumentSyntax = ((EnumerableTypeSyntax)syntax).ElementType; | |
+ TypeSymbol typeArgument = BindType(typeArgumentSyntax, diagnostics, basesBeingResolved); | |
+ NamedTypeSymbol constructedType = enumerableOfT.Construct(typeArgument); | |
+ if (ShouldCheckConstraints) | |
+ { | |
+ constructedType.CheckConstraints(this.Compilation, this.Conversions, syntax.Location, diagnostics); | |
+ } | |
+ return constructedType; | |
+ | |
+ } | |
+ | |
case SyntaxKind.OmittedTypeArgument: | |
{ | |
return BindTypeArgument((TypeSyntax)syntax, diagnostics, basesBeingResolved); | |
diff --git a/Src/Compilers/CSharp/Source/Parser/LanguageParser.cs b/Src/Compilers/CSharp/Source/Parser/LanguageParser.cs | |
index e87bc2c..bdffb2c 100644 | |
--- a/Src/Compilers/CSharp/Source/Parser/LanguageParser.cs | |
+++ b/Src/Compilers/CSharp/Source/Parser/LanguageParser.cs | |
@@ -5574,6 +5574,11 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax | |
/// Might be a pointer type or a multiplication. | |
/// </summary> | |
PointerOrMultiplication, | |
+ | |
+ /// <summary> | |
+ /// Enumerable type (ending with ~). | |
+ /// </summary> | |
+ EnumerableType, | |
} | |
private bool IsPossibleType() | |
@@ -5714,6 +5719,12 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax | |
result = ScanTypeFlags.NullableType; | |
} | |
+ if (this.CurrentToken.Kind == SyntaxKind.TildeToken) | |
+ { | |
+ this.EatToken(); | |
+ result = ScanTypeFlags.EnumerableType; | |
+ } | |
+ | |
// Now check for pointer type(s) | |
while (this.CurrentToken.Kind == SyntaxKind.AsteriskToken) | |
{ | |
@@ -5819,6 +5830,12 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax | |
} | |
} | |
+ if (this.CurrentToken.Kind == SyntaxKind.TildeToken) | |
+ { | |
+ var tilde = this.EatToken(); | |
+ type = syntaxFactory.EnumerableType(type, tilde); | |
+ } | |
+ | |
// Check for pointer types (only if pType is NOT an array type) | |
type = this.ParsePointerTypeMods(type); | |
@@ -8655,8 +8672,10 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax | |
// 2) (Foo?)bar; | |
// 3) "(int)bar" or "(int[])bar" | |
// 4) (G::Foo)bar | |
+ // 5) (Foo~)bar; | |
if (type == ScanTypeFlags.PointerOrMultiplication || | |
type == ScanTypeFlags.NullableType || | |
type == ScanTypeFlags.MustBeType || | |
- type == ScanTypeFlags.AliasQualifiedName) | |
+ type == ScanTypeFlags.AliasQualifiedName || | |
+ type == ScanTypeFlags.EnumerableType) | |
{ | |
diff --git a/Src/Compilers/CSharp/Source/Syntax/Syntax.xml b/Src/Compilers/CSharp/Source/Syntax/Syntax.xml | |
index 67ea757..6d87274 100644 | |
--- a/Src/Compilers/CSharp/Source/Syntax/Syntax.xml | |
+++ b/Src/Compilers/CSharp/Source/Syntax/Syntax.xml | |
@@ -236,7 +236,27 @@ | |
<summary>Class which represents the syntax node for a nullable type.</summary> | |
</TypeComment> | |
<FactoryComment> | |
- <summary>Creates an NullableTypeSyntax node.</summary> | |
+ <summary>Creates a NullableTypeSyntax node.</summary> | |
+ </FactoryComment> | |
+ </Node> | |
+ <Node Name="EnumerableTypeSyntax" Base="TypeSyntax"> | |
+ <Kind Name="EnumerableType"/> | |
+ <Field Name="ElementType" Type="TypeSyntax"> | |
+ <PropertyComment> | |
+ <summary>TypeSyntax node representing the type of the element.</summary> | |
+ </PropertyComment> | |
+ </Field> | |
+ <Field Name="TildeToken" Type="SyntaxToken"> | |
+ <Kind Name="TildeToken"/> | |
+ <PropertyComment> | |
+ <summary>SyntaxToken representing the tilde.</summary> | |
+ </PropertyComment> | |
+ </Field> | |
+ <TypeComment> | |
+ <summary>Class which represents the syntax node for an enumerable type.</summary> | |
+ </TypeComment> | |
+ <FactoryComment> | |
+ <summary>Creates an EnumerableTypeSyntax node.</summary> | |
</FactoryComment> | |
</Node> | |
<Node Name="OmittedTypeArgumentSyntax" Base="TypeSyntax"> | |
diff --git a/Src/Compilers/CSharp/Source/Syntax/SyntaxKind.cs b/Src/Compilers/CSharp/Source/Syntax/SyntaxKind.cs | |
index 997af9f..8d8bc8d 100644 | |
--- a/Src/Compilers/CSharp/Source/Syntax/SyntaxKind.cs | |
+++ b/Src/Compilers/CSharp/Source/Syntax/SyntaxKind.cs | |
@@ -288,6 +288,7 @@ namespace Microsoft.CodeAnalysis.CSharp | |
ArrayRankSpecifier, | |
PointerType, | |
NullableType, | |
+ EnumerableType, | |
OmittedTypeArgument, | |
// expressions |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment