提交 2933883b 编写于 作者: C Cyrus Najmabadi

Add support for generating operators in SyntaxGenerator.

上级 9e6cb00a
...@@ -149,6 +149,68 @@ private SyntaxTokenList GetParameterModifiers(RefKind refKind) ...@@ -149,6 +149,68 @@ private SyntaxTokenList GetParameterModifiers(RefKind refKind)
!hasBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : default(SyntaxToken)); !hasBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : default(SyntaxToken));
} }
public override SyntaxNode OperatorDeclaration(OperatorKind kind, IEnumerable<SyntaxNode> parameters = null, SyntaxNode returnType = null, Accessibility accessibility = Accessibility.NotApplicable, DeclarationModifiers modifiers = default(DeclarationModifiers), IEnumerable<SyntaxNode> statements = null)
{
var hasBody = !modifiers.IsAbstract && (!modifiers.IsPartial || statements != null);
var returnTypeNode = returnType != null ? (TypeSyntax)returnType : SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword));
var parameterList = AsParameterList(parameters);
var body = hasBody ? CreateBlock(statements) : null;
var semicolon = !hasBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : default(SyntaxToken);
var modifierList = AsModifierList(accessibility, modifiers, SyntaxKind.OperatorDeclaration);
var attributes = default(SyntaxList<AttributeListSyntax>);
if (kind == OperatorKind.ImplicitConversion || kind == OperatorKind.ExplicitConversion)
{
return SyntaxFactory.ConversionOperatorDeclaration(
attributes, modifierList, SyntaxFactory.Token(GetTokenKind(kind)),
SyntaxFactory.Token(SyntaxKind.OperatorKeyword),
returnTypeNode, parameterList, body, semicolon);
}
else
{
return SyntaxFactory.OperatorDeclaration(
attributes, modifierList, returnTypeNode,
SyntaxFactory.Token(SyntaxKind.OperatorKeyword),
SyntaxFactory.Token(GetTokenKind(kind)),
parameterList, body, semicolon);
}
}
private SyntaxKind GetTokenKind(OperatorKind kind)
{
switch (kind)
{
case OperatorKind.ImplicitConversion: return SyntaxKind.ImplicitKeyword;
case OperatorKind.ExplicitConversion: return SyntaxKind.ExplicitKeyword;
case OperatorKind.Addition: return SyntaxKind.PlusToken;
case OperatorKind.BitwiseAnd: return SyntaxKind.AmpersandToken;
case OperatorKind.BitwiseOr:return SyntaxKind.BarToken;
case OperatorKind.Decrement: return SyntaxKind.MinusMinusToken;
case OperatorKind.Division: return SyntaxKind.SlashToken;
case OperatorKind.Equality: return SyntaxKind.EqualsEqualsToken;
case OperatorKind.ExclusiveOr: return SyntaxKind.CaretToken;
case OperatorKind.False: return SyntaxKind.FalseKeyword;
case OperatorKind.GreaterThan: return SyntaxKind.GreaterThanToken;
case OperatorKind.GreaterThanOrEqual: return SyntaxKind.GreaterThanEqualsToken;
case OperatorKind.Increment: return SyntaxKind.PlusPlusToken;
case OperatorKind.Inequality: return SyntaxKind.ExclamationEqualsToken;
case OperatorKind.LeftShift: return SyntaxKind.LessThanLessThanToken;
case OperatorKind.LessThan: return SyntaxKind.LessThanToken;
case OperatorKind.LessThanOrEqual: return SyntaxKind.LessThanEqualsToken;
case OperatorKind.LogicalNot: return SyntaxKind.ExclamationToken;
case OperatorKind.Modulus:return SyntaxKind.PercentToken;
case OperatorKind.Multiply:return SyntaxKind.AsteriskToken;
case OperatorKind.OnesComplement:return SyntaxKind.TildeToken;
case OperatorKind.RightShift:return SyntaxKind.GreaterThanGreaterThanToken;
case OperatorKind.Subtraction: return SyntaxKind.MinusToken;
case OperatorKind.True: return SyntaxKind.TrueKeyword;
case OperatorKind.UnaryNegation: return SyntaxKind.MinusToken;
case OperatorKind.UnaryPlus: return SyntaxKind.PlusToken;
default:
throw new ArgumentException("Unknown operator kind.");
}
}
private ParameterListSyntax AsParameterList(IEnumerable<SyntaxNode> parameters) private ParameterListSyntax AsParameterList(IEnumerable<SyntaxNode> parameters)
{ {
return parameters != null return parameters != null
......
...@@ -724,6 +724,124 @@ public void TestMethodDeclarations() ...@@ -724,6 +724,124 @@ public void TestMethodDeclarations()
"partial void m()\r\n{\r\n y;\r\n}"); "partial void m()\r\n{\r\n y;\r\n}");
} }
[Fact]
public void TestOperatorDeclaration()
{
var parameterTypes = new[]
{
_emptyCompilation.GetSpecialType(SpecialType.System_Int32),
_emptyCompilation.GetSpecialType(SpecialType.System_String)
};
var parameters = parameterTypes.Select((t, i) => _g.ParameterDeclaration("p" + i, _g.TypeExpression(t))).ToList();
var returnType = _g.TypeExpression(SpecialType.System_Boolean);
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Addition, parameters, returnType),
"bool operator +(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.BitwiseAnd, parameters, returnType),
"bool operator &(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.BitwiseOr, parameters, returnType),
"bool operator |(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Decrement, parameters, returnType),
"bool operator --(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Division, parameters, returnType),
"bool operator /(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Equality, parameters, returnType),
"bool operator ==(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.ExclusiveOr, parameters, returnType),
"bool operator ^(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.False, parameters, returnType),
"bool operator false (System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.GreaterThan, parameters, returnType),
"bool operator>(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.GreaterThanOrEqual, parameters, returnType),
"bool operator >=(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Increment, parameters, returnType),
"bool operator ++(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Inequality, parameters, returnType),
"bool operator !=(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LeftShift, parameters, returnType),
"bool operator <<(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LessThan, parameters, returnType),
"bool operator <(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LessThanOrEqual, parameters, returnType),
"bool operator <=(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.LogicalNot, parameters, returnType),
"bool operator !(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Modulus, parameters, returnType),
"bool operator %(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Multiply, parameters, returnType),
"bool operator *(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.OnesComplement, parameters, returnType),
"bool operator ~(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.RightShift, parameters, returnType),
"bool operator >>(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.Subtraction, parameters, returnType),
"bool operator -(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.True, parameters, returnType),
"bool operator true (System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.UnaryNegation, parameters, returnType),
"bool operator -(System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<OperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.UnaryPlus, parameters, returnType),
"bool operator +(System.Int32 p0, System.String p1)\r\n{\r\n}");
// Conversion operators
VerifySyntax<ConversionOperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.ImplicitConversion, parameters, returnType),
"implicit operator bool (System.Int32 p0, System.String p1)\r\n{\r\n}");
VerifySyntax<ConversionOperatorDeclarationSyntax>(
_g.OperatorDeclaration(OperatorKind.ExplicitConversion, parameters, returnType),
"explicit operator bool (System.Int32 p0, System.String p1)\r\n{\r\n}");
}
[Fact] [Fact]
public void TestConstructorDeclaration() public void TestConstructorDeclaration()
{ {
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Editing
{
public enum OperatorKind
{
/// <summary>
/// The name assigned to an implicit (widening) conversion.
/// </summary>
ImplicitConversion,
/// <summary>
/// The name assigned to an explicit (narrowing) conversion.
/// </summary>
ExplicitConversion,
/// <summary>
/// The name assigned to the Addition operator.
/// </summary>
Addition,
/// <summary>
/// The name assigned to the BitwiseAnd operator.
/// </summary>
BitwiseAnd,
/// <summary>
/// The name assigned to the BitwiseOr operator.
/// </summary>
BitwiseOr,
/// <summary>
/// The name assigned to the Decrement operator.
/// </summary>
Decrement,
/// <summary>
/// The name assigned to the Division operator.
/// </summary>
Division,
/// <summary>
/// The name assigned to the Equality operator.
/// </summary>
Equality,
/// <summary>
/// The name assigned to the ExclusiveOr operator.
/// </summary>
ExclusiveOr,
/// <summary>
/// The name assigned to the False operator.
/// </summary>
False,
/// <summary>
/// The name assigned to the GreaterThan operator.
/// </summary>
GreaterThan,
/// <summary>
/// The name assigned to the GreaterThanOrEqual operator.
/// </summary>
GreaterThanOrEqual,
/// <summary>
/// The name assigned to the Increment operator.
/// </summary>
Increment,
/// <summary>
/// The name assigned to the Inequality operator.
/// </summary>
Inequality,
/// <summary>
/// The name assigned to the LeftShift operator.
/// </summary>
LeftShift,
/// <summary>
/// The name assigned to the LessThan operator.
/// </summary>
LessThan,
/// <summary>
/// The name assigned to the LessThanOrEqual operator.
/// </summary>
LessThanOrEqual,
/// <summary>
/// The name assigned to the LogicalNot operator.
/// </summary>
LogicalNot,
/// <summary>
/// The name assigned to the Modulus operator.
/// </summary>
Modulus,
/// <summary>
/// The name assigned to the Multiply operator.
/// </summary>
Multiply,
/// <summary>
/// The name assigned to the OnesComplement operator.
/// </summary>
OnesComplement,
/// <summary>
/// The name assigned to the RightShift operator.
/// </summary>
RightShift,
/// <summary>
/// The name assigned to the Subtraction operator.
/// </summary>
Subtraction,
/// <summary>
/// The name assigned to the True operator.
/// </summary>
True,
/// <summary>
/// The name assigned to the UnaryNegation operator.
/// </summary>
UnaryNegation,
/// <summary>
/// The name assigned to the UnaryPlus operator.
/// </summary>
UnaryPlus,
}
}
\ No newline at end of file
...@@ -154,6 +154,73 @@ public SyntaxNode MethodDeclaration(IMethodSymbol method, IEnumerable<SyntaxNode ...@@ -154,6 +154,73 @@ public SyntaxNode MethodDeclaration(IMethodSymbol method, IEnumerable<SyntaxNode
return decl; return decl;
} }
/// <summary>
/// Creates a method declaration.
/// </summary>
public abstract SyntaxNode OperatorDeclaration(
OperatorKind kind,
IEnumerable<SyntaxNode> parameters = null,
SyntaxNode returnType = null,
Accessibility accessibility = Accessibility.NotApplicable,
DeclarationModifiers modifiers = default(DeclarationModifiers),
IEnumerable<SyntaxNode> statements = null);
/// <summary>
/// Creates a method declaration matching an existing method symbol.
/// </summary>
public SyntaxNode OperatorDeclaration(IMethodSymbol method, IEnumerable<SyntaxNode> statements = null)
{
if (method.MethodKind != MethodKind.UserDefinedOperator)
{
throw new ArgumentException("Method is not an operator.");
}
var decl = OperatorDeclaration(
GetOperatorKind(method),
parameters: method.Parameters.Select(p => ParameterDeclaration(p)),
returnType: method.ReturnType.IsSystemVoid() ? null : TypeExpression(method.ReturnType),
accessibility: method.DeclaredAccessibility,
modifiers: DeclarationModifiers.From(method),
statements: statements);
return decl;
}
private OperatorKind GetOperatorKind(IMethodSymbol method)
{
switch (method.Name)
{
case WellKnownMemberNames.ImplicitConversionName: return OperatorKind.ImplicitConversion;
case WellKnownMemberNames.ExplicitConversionName: return OperatorKind.ExplicitConversion;
case WellKnownMemberNames.AdditionOperatorName: return OperatorKind.Addition;
case WellKnownMemberNames.BitwiseAndOperatorName: return OperatorKind.BitwiseAnd;
case WellKnownMemberNames.BitwiseOrOperatorName: return OperatorKind.BitwiseOr;
case WellKnownMemberNames.DecrementOperatorName: return OperatorKind.Decrement;
case WellKnownMemberNames.DivisionOperatorName: return OperatorKind.Division;
case WellKnownMemberNames.EqualityOperatorName: return OperatorKind.Equality;
case WellKnownMemberNames.ExclusiveOrOperatorName: return OperatorKind.ExclusiveOr;
case WellKnownMemberNames.FalseOperatorName: return OperatorKind.False;
case WellKnownMemberNames.GreaterThanOperatorName: return OperatorKind.GreaterThan;
case WellKnownMemberNames.GreaterThanOrEqualOperatorName: return OperatorKind.GreaterThanOrEqual;
case WellKnownMemberNames.IncrementOperatorName: return OperatorKind.Increment;
case WellKnownMemberNames.InequalityOperatorName: return OperatorKind.Inequality;
case WellKnownMemberNames.LeftShiftOperatorName: return OperatorKind.LeftShift;
case WellKnownMemberNames.LessThanOperatorName: return OperatorKind.LessThan;
case WellKnownMemberNames.LessThanOrEqualOperatorName: return OperatorKind.LessThanOrEqual;
case WellKnownMemberNames.LogicalNotOperatorName: return OperatorKind.LogicalNot;
case WellKnownMemberNames.ModulusOperatorName: return OperatorKind.Modulus;
case WellKnownMemberNames.MultiplyOperatorName: return OperatorKind.Multiply;
case WellKnownMemberNames.OnesComplementOperatorName: return OperatorKind.OnesComplement;
case WellKnownMemberNames.RightShiftOperatorName: return OperatorKind.RightShift;
case WellKnownMemberNames.SubtractionOperatorName: return OperatorKind.Subtraction;
case WellKnownMemberNames.TrueOperatorName: return OperatorKind.True;
case WellKnownMemberNames.UnaryNegationOperatorName: return OperatorKind.UnaryNegation;
case WellKnownMemberNames.UnaryPlusOperatorName: return OperatorKind.UnaryPlus;
default:
throw new ArgumentException("Unknown operator kind.");
}
}
/// <summary> /// <summary>
/// Creates a parameter declaration. /// Creates a parameter declaration.
/// </summary> /// </summary>
...@@ -436,6 +503,9 @@ public SyntaxNode Declaration(ISymbol symbol) ...@@ -436,6 +503,9 @@ public SyntaxNode Declaration(ISymbol symbol)
case MethodKind.Ordinary: case MethodKind.Ordinary:
return MethodDeclaration(method); return MethodDeclaration(method);
case MethodKind.UserDefinedOperator:
return OperatorDeclaration(method);
} }
break; break;
......
Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Addition = 2 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.BitwiseAnd = 3 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.BitwiseOr = 4 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Decrement = 5 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Division = 6 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Equality = 7 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.ExclusiveOr = 8 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.ExplicitConversion = 1 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.False = 9 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.GreaterThan = 10 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.GreaterThanOrEqual = 11 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.ImplicitConversion = 0 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Increment = 12 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Inequality = 13 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.LeftShift = 14 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.LessThan = 15 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.LessThanOrEqual = 16 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.LogicalNot = 17 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Modulus = 18 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Multiply = 19 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.OnesComplement = 20 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.RightShift = 21 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.Subtraction = 22 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.True = 23 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.UnaryNegation = 24 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.OperatorKind.UnaryPlus = 25 -> Microsoft.CodeAnalysis.Editing.OperatorKind
Microsoft.CodeAnalysis.Editing.SyntaxEditor.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> void Microsoft.CodeAnalysis.Editing.SyntaxEditor.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> void
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.OperatorDeclaration(Microsoft.CodeAnalysis.IMethodSymbol method, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> statements = null) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Project.IsSubmission.get -> bool Microsoft.CodeAnalysis.Project.IsSubmission.get -> bool
Microsoft.CodeAnalysis.Workspace.UpdateReferencesAfterAdd() -> void Microsoft.CodeAnalysis.Workspace.UpdateReferencesAfterAdd() -> void
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ArrayCreationExpression(Microsoft.CodeAnalysis.SyntaxNode elementType, Microsoft.CodeAnalysis.SyntaxNode size) -> Microsoft.CodeAnalysis.SyntaxNode abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ArrayCreationExpression(Microsoft.CodeAnalysis.SyntaxNode elementType, Microsoft.CodeAnalysis.SyntaxNode size) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ArrayCreationExpression(Microsoft.CodeAnalysis.SyntaxNode elementType, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> elements) -> Microsoft.CodeAnalysis.SyntaxNode abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ArrayCreationExpression(Microsoft.CodeAnalysis.SyntaxNode elementType, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> elements) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.OperatorDeclaration(Microsoft.CodeAnalysis.Editing.OperatorKind kind, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> parameters = null, Microsoft.CodeAnalysis.SyntaxNode returnType = null, Microsoft.CodeAnalysis.Accessibility accessibility = Microsoft.CodeAnalysis.Accessibility.NotApplicable, Microsoft.CodeAnalysis.Editing.DeclarationModifiers modifiers = default(Microsoft.CodeAnalysis.Editing.DeclarationModifiers), System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> statements = null) -> Microsoft.CodeAnalysis.SyntaxNode
static Microsoft.CodeAnalysis.Editing.SyntaxGenerator.GetGenerator(Microsoft.CodeAnalysis.Project project) -> Microsoft.CodeAnalysis.Editing.SyntaxGenerator static Microsoft.CodeAnalysis.Editing.SyntaxGenerator.GetGenerator(Microsoft.CodeAnalysis.Project project) -> Microsoft.CodeAnalysis.Editing.SyntaxGenerator
virtual Microsoft.CodeAnalysis.Editing.SyntaxGenerator.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode root, Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> Microsoft.CodeAnalysis.SyntaxNode virtual Microsoft.CodeAnalysis.Editing.SyntaxGenerator.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode root, Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> Microsoft.CodeAnalysis.SyntaxNode
\ No newline at end of file
...@@ -340,6 +340,7 @@ ...@@ -340,6 +340,7 @@
<Compile Include="Editing\GenerationOptionsProvider.cs" /> <Compile Include="Editing\GenerationOptionsProvider.cs" />
<Compile Include="Editing\ImportAdder.cs" /> <Compile Include="Editing\ImportAdder.cs" />
<Compile Include="Editing\ImportAdderService.cs" /> <Compile Include="Editing\ImportAdderService.cs" />
<Compile Include="Editing\OperatorKind.cs" />
<Compile Include="Editing\SolutionEditor.cs" /> <Compile Include="Editing\SolutionEditor.cs" />
<Compile Include="Editing\SymbolEditor.cs" /> <Compile Include="Editing\SymbolEditor.cs" />
<Compile Include="Editing\SymbolEditorExtensions.cs" /> <Compile Include="Editing\SymbolEditorExtensions.cs" />
......
...@@ -652,6 +652,95 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -652,6 +652,95 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
End If End If
End Function End Function
Public Overrides Function OperatorDeclaration(kind As OperatorKind,
Optional parameters As IEnumerable(Of SyntaxNode) = Nothing,
Optional returnType As SyntaxNode = Nothing,
Optional accessibility As Accessibility = Accessibility.NotApplicable,
Optional modifiers As DeclarationModifiers = Nothing,
Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode
Dim statement As OperatorStatementSyntax
Dim asClause = If(returnType IsNot Nothing, SyntaxFactory.SimpleAsClause(DirectCast(returnType, TypeSyntax)), Nothing)
Dim parameterList = GetParameterList(parameters)
Dim operatorToken = SyntaxFactory.Token(GetTokenKind(kind))
Dim modifierList As SyntaxTokenList = GetModifierList(accessibility, modifiers And s_methodModifiers)
If kind = OperatorKind.ImplicitConversion OrElse kind = OperatorKind.ExplicitConversion Then
modifierList = modifierList.Add(SyntaxFactory.Token(
If(kind = OperatorKind.ImplicitConversion, SyntaxKind.WideningKeyword, SyntaxKind.NarrowingKeyword)))
statement = SyntaxFactory.OperatorStatement(
attributeLists:=Nothing, modifiers:=modifierList, operatorToken:=operatorToken,
parameterList:=parameterList, asClause:=asClause)
Else
statement = SyntaxFactory.OperatorStatement(
attributeLists:=Nothing, modifiers:=modifierList,
operatorToken:=operatorToken, parameterList:=parameterList,
asClause:=asClause)
End If
If modifiers.IsAbstract Then
Return statement
Else
Return SyntaxFactory.OperatorBlock(
operatorStatement:=statement,
statements:=GetStatementList(statements),
endOperatorStatement:=SyntaxFactory.EndOperatorStatement())
End If
End Function
Private Function GetTokenKind(kind As OperatorKind) As SyntaxKind
Select Case kind
Case OperatorKind.ImplicitConversion,
OperatorKind.ExplicitConversion
Return SyntaxKind.CTypeKeyword
Case OperatorKind.Addition
Return SyntaxKind.PlusToken
Case OperatorKind.BitwiseAnd
Return SyntaxKind.AndKeyword
Case OperatorKind.BitwiseOr
Return SyntaxKind.OrKeyword
Case OperatorKind.Division
Return SyntaxKind.SlashToken
Case OperatorKind.Equality
Return SyntaxKind.EqualsToken
Case OperatorKind.ExclusiveOr
Return SyntaxKind.XorKeyword
Case OperatorKind.False
Return SyntaxKind.IsFalseKeyword
Case OperatorKind.GreaterThan
Return SyntaxKind.GreaterThanToken
Case OperatorKind.GreaterThanOrEqual
Return SyntaxKind.GreaterThanEqualsToken
Case OperatorKind.Inequality
Return SyntaxKind.LessThanGreaterThanToken
Case OperatorKind.LeftShift
Return SyntaxKind.LessThanLessThanToken
Case OperatorKind.LessThan
Return SyntaxKind.LessThanToken
Case OperatorKind.LessThanOrEqual
Return SyntaxKind.LessThanEqualsToken
Case OperatorKind.LogicalNot
Return SyntaxKind.NotKeyword
Case OperatorKind.Modulus
Return SyntaxKind.ModKeyword
Case OperatorKind.Multiply
Return SyntaxKind.AsteriskToken
Case OperatorKind.RightShift
Return SyntaxKind.GreaterThanGreaterThanToken
Case OperatorKind.Subtraction
Return SyntaxKind.MinusToken
Case OperatorKind.True
Return SyntaxKind.IsTrueKeyword
Case OperatorKind.UnaryNegation
Return SyntaxKind.MinusToken
Case OperatorKind.UnaryPlus
Return SyntaxKind.PlusToken
Case Else
Throw New ArgumentException($"Operator {kind} cannot be generated in Visual Basic.")
End Select
End Function
Private Function GetParameterList(parameters As IEnumerable(Of SyntaxNode)) As ParameterListSyntax Private Function GetParameterList(parameters As IEnumerable(Of SyntaxNode)) As ParameterListSyntax
Return If(parameters IsNot Nothing, SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters.Cast(Of ParameterSyntax)())), SyntaxFactory.ParameterList()) Return If(parameters IsNot Nothing, SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters.Cast(Of ParameterSyntax)())), SyntaxFactory.ParameterList())
End Function End Function
...@@ -3203,7 +3292,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -3203,7 +3292,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
If accessor IsNot Nothing Then If accessor IsNot Nothing Then
accessor = DirectCast(Me.WithStatements(accessor, statements), AccessorBlockSyntax) accessor = DirectCast(Me.WithStatements(accessor, statements), AccessorBlockSyntax)
Return Me.WithAccessorBlock(declaration, kind, accessor) Return Me.WithAccessorBlock(declaration, kind, accessor)
ElseIf Me.CanHaveAccessors(declaration.Kind) ElseIf Me.CanHaveAccessors(declaration.Kind) Then
accessor = Me.AccessorBlock(kind, statements, Me.ClearTrivia(Me.GetType(declaration))) accessor = Me.AccessorBlock(kind, statements, Me.ClearTrivia(Me.GetType(declaration)))
Return Me.WithAccessorBlock(declaration, kind, accessor) Return Me.WithAccessorBlock(declaration, kind, accessor)
Else Else
...@@ -3226,7 +3315,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ...@@ -3226,7 +3315,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Dim currentAccessor = Me.GetAccessorBlock(declaration, kind) Dim currentAccessor = Me.GetAccessorBlock(declaration, kind)
If currentAccessor IsNot Nothing Then If currentAccessor IsNot Nothing Then
Return Me.ReplaceNode(declaration, currentAccessor, accessor) Return Me.ReplaceNode(declaration, currentAccessor, accessor)
ElseIf accessor IsNot Nothing ElseIf accessor IsNot Nothing Then
Select Case declaration.Kind Select Case declaration.Kind
Case SyntaxKind.PropertyBlock Case SyntaxKind.PropertyBlock
Dim pb = DirectCast(declaration, PropertyBlockSyntax) Dim pb = DirectCast(declaration, PropertyBlockSyntax)
......
...@@ -812,6 +812,134 @@ End Function</x>.Value) ...@@ -812,6 +812,134 @@ End Function</x>.Value)
End Sub</x>.Value) End Sub</x>.Value)
End Sub End Sub
<Fact>
Public Sub TestOperatorDeclaration()
Dim parameterTypes = {
_emptyCompilation.GetSpecialType(SpecialType.System_Int32),
_emptyCompilation.GetSpecialType(SpecialType.System_String)
}
Dim parameters = parameterTypes.Select(Function(t, i) _g.ParameterDeclaration("p" & i, _g.TypeExpression(t))).ToList()
Dim returnType = _g.TypeExpression(SpecialType.System_Boolean)
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Addition, parameters, returnType),
"Operator +(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.BitwiseAnd, parameters, returnType),
"Operator And(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.BitwiseOr, parameters, returnType),
"Operator Or(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Division, parameters, returnType),
"Operator /(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Equality, parameters, returnType),
"Operator =(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.ExclusiveOr, parameters, returnType),
"Operator Xor(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.False, parameters, returnType),
"Operator IsFalse(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.GreaterThan, parameters, returnType),
"Operator>(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.GreaterThanOrEqual, parameters, returnType),
"Operator >=(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Inequality, parameters, returnType),
"Operator <>(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.LeftShift, parameters, returnType),
"Operator <<(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.LessThan, parameters, returnType),
"Operator <(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.LessThanOrEqual, parameters, returnType),
"Operator <=(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.LogicalNot, parameters, returnType),
"Operator Not(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Modulus, parameters, returnType),
"Operator Mod(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Multiply, parameters, returnType),
"Operator *(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.RightShift, parameters, returnType),
"Operator >>(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.Subtraction, parameters, returnType),
"Operator -(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.True, parameters, returnType),
"Operator IsTrue(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.UnaryNegation, parameters, returnType),
"Operator -(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.UnaryPlus, parameters, returnType),
"Operator +(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
' Conversion operators
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.ImplicitConversion, parameters, returnType),
"Widening Operator CType(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
VerifySyntax(Of OperatorBlockSyntax)(
_g.OperatorDeclaration(OperatorKind.ExplicitConversion, parameters, returnType),
"Narrowing Operator CType(p0 As System.Int32, p1 As System.String) As Boolean
End Operator")
End Sub
<Fact> <Fact>
Public Sub MethodDeclarationCanRoundTrip() Public Sub MethodDeclarationCanRoundTrip()
Dim tree = VisualBasicSyntaxTree.ParseText( Dim tree = VisualBasicSyntaxTree.ParseText(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册