提交 9d3f7a7c 编写于 作者: C CyrusNajmabadi

Use expression bodied methods if desired.

上级 3f49a45b
......@@ -65,6 +65,7 @@
<Compile Include="Classification\Worker_Preprocesser.cs" />
<Compile Include="CodeCleanup\CSharpCodeCleanerService.cs" />
<Compile Include="CodeCleanup\CSharpCodeCleanerServiceFactory.cs" />
<Compile Include="CodeGeneration\CodeGenerationHelpers.cs" />
<Compile Include="CodeGeneration\CSharpCodeGenerationHelpers.cs" />
<Compile Include="CodeGeneration\CSharpFlagsEnumGenerator.cs" />
<Compile Include="CodeGeneration\ArgumentGenerator.cs" />
......@@ -244,4 +245,4 @@
<PublicAPI Include="PublicAPI.Unshipped.txt" />
</ItemGroup>
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -161,7 +161,8 @@ protected override TDeclarationNode AddMethod<TDeclarationNode>(TDeclarationNode
return Cast<TDeclarationNode>(OperatorGenerator.AddOperatorTo(typeDeclaration, method, options, availableIndices));
}
return Cast<TDeclarationNode>(MethodGenerator.AddMethodTo(typeDeclaration, method, options, availableIndices));
return Cast<TDeclarationNode>(MethodGenerator.AddMethodTo(
typeDeclaration, method, Workspace, options, availableIndices));
}
if (method.IsConstructor() ||
......@@ -173,11 +174,13 @@ protected override TDeclarationNode AddMethod<TDeclarationNode>(TDeclarationNode
var compilationUnit = destination as CompilationUnitSyntax;
if (compilationUnit != null)
{
return Cast<TDeclarationNode>(MethodGenerator.AddMethodTo(compilationUnit, method, options, availableIndices));
return Cast<TDeclarationNode>(
MethodGenerator.AddMethodTo(compilationUnit, method, Workspace, options, availableIndices));
}
var ns = Cast<NamespaceDeclarationSyntax>(destination);
return Cast<TDeclarationNode>(MethodGenerator.AddMethodTo(ns, method, options, availableIndices));
return Cast<TDeclarationNode>(
MethodGenerator.AddMethodTo(ns, method, Workspace, options, availableIndices));
}
protected override TDeclarationNode AddProperty<TDeclarationNode>(TDeclarationNode destination, IPropertySymbol property, CodeGenerationOptions options, IList<bool> availableIndices)
......@@ -629,7 +632,7 @@ public override SyntaxNode CreateFieldDeclaration(IFieldSymbol field, CodeGenera
}
else
{
return MethodGenerator.GenerateMethodDeclaration(method, destination, options);
return MethodGenerator.GenerateMethodDeclaration(method, destination, Workspace, options);
}
}
......
// 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 Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Microsoft.CodeAnalysis.CSharp.CodeGeneration
{
internal static class CodeGenerationHelpers
{
public static ArrowExpressionClauseSyntax TryConvertToExpressionBody(BlockSyntax block)
{
if (block != null && block.Statements.Count == 1)
{
var firstStatement = block.Statements[0];
var expression = TryGetExpression(firstStatement);
if (expression != null)
{
return SyntaxFactory.ArrowExpressionClause(expression);
}
}
return null;
}
private static ExpressionSyntax TryGetExpression(StatementSyntax firstStatement)
{
if (firstStatement.Kind() == SyntaxKind.ExpressionStatement)
{
return ((ExpressionStatementSyntax)firstStatement).Expression;
}
else if (firstStatement.Kind() == SyntaxKind.ReturnStatement)
{
var returnStatement = (ReturnStatementSyntax)firstStatement;
if (returnStatement.Expression != null)
{
return returnStatement.Expression;
}
}
else if (firstStatement.Kind() == SyntaxKind.ThrowStatement)
{
var throwStatement = (ThrowStatementSyntax)firstStatement;
if (throwStatement.Expression != null)
{
return SyntaxFactory.ThrowExpression(throwStatement.ThrowKeyword, throwStatement.Expression);
}
}
return null;
}
}
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
......@@ -17,10 +19,12 @@ internal static class MethodGenerator
internal static NamespaceDeclarationSyntax AddMethodTo(
NamespaceDeclarationSyntax destination,
IMethodSymbol method,
Workspace workspace,
CodeGenerationOptions options,
IList<bool> availableIndices)
{
var declaration = GenerateMethodDeclaration(method, CodeGenerationDestination.Namespace, options);
var declaration = GenerateMethodDeclaration(
method, CodeGenerationDestination.Namespace, workspace, options);
var members = Insert(destination.Members, declaration, options, availableIndices, after: LastMethod);
return destination.WithMembers(members.ToSyntaxList());
}
......@@ -28,10 +32,12 @@ internal static class MethodGenerator
internal static CompilationUnitSyntax AddMethodTo(
CompilationUnitSyntax destination,
IMethodSymbol method,
Workspace workspace,
CodeGenerationOptions options,
IList<bool> availableIndices)
{
var declaration = GenerateMethodDeclaration(method, CodeGenerationDestination.CompilationUnit, options);
var declaration = GenerateMethodDeclaration(
method, CodeGenerationDestination.CompilationUnit, workspace, options);
var members = Insert(destination.Members, declaration, options, availableIndices, after: LastMethod);
return destination.WithMembers(members.ToSyntaxList());
}
......@@ -39,10 +45,12 @@ internal static class MethodGenerator
internal static TypeDeclarationSyntax AddMethodTo(
TypeDeclarationSyntax destination,
IMethodSymbol method,
Workspace workspace,
CodeGenerationOptions options,
IList<bool> availableIndices)
{
var methodDeclaration = GenerateMethodDeclaration(method, GetDestination(destination), options);
var methodDeclaration = GenerateMethodDeclaration(
method, GetDestination(destination), workspace, options);
// Create a clone of the original type with the new method inserted.
var members = Insert(destination.Members, methodDeclaration, options, availableIndices, after: LastMethod);
......@@ -51,7 +59,8 @@ internal static class MethodGenerator
}
public static MethodDeclarationSyntax GenerateMethodDeclaration(
IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options)
IMethodSymbol method, CodeGenerationDestination destination,
Workspace workspace, CodeGenerationOptions options)
{
options = options ?? CodeGenerationOptions.Default;
......@@ -61,14 +70,15 @@ internal static class MethodGenerator
return reusableSyntax;
}
var declaration = GenerateMethodDeclarationWorker(method, destination, options);
var declaration = GenerateMethodDeclarationWorker(method, destination, workspace, options);
return AddAnnotationsTo(method,
ConditionallyAddDocumentationCommentTo(declaration, method, options));
}
private static MethodDeclarationSyntax GenerateMethodDeclarationWorker(
IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options)
IMethodSymbol method, CodeGenerationDestination destination,
Workspace workspace, CodeGenerationOptions options)
{
var hasNoBody = !options.GenerateMethodBodies ||
destination == CodeGenerationDestination.InterfaceType ||
......@@ -80,7 +90,7 @@ internal static class MethodGenerator
? method.ReturnType.GenerateRefTypeSyntax()
: method.ReturnType.GenerateTypeSyntax();
return AddCleanupAnnotationsTo(SyntaxFactory.MethodDeclaration(
var methodDeclaration = SyntaxFactory.MethodDeclaration(
attributeLists: GenerateAttributes(method, options, explicitInterfaceSpecifier != null),
modifiers: GenerateModifiers(method, destination, options),
returnType: returnType,
......@@ -91,7 +101,31 @@ internal static class MethodGenerator
constraintClauses: GenerateConstraintClauses(method),
body: hasNoBody ? null : StatementGenerator.GenerateBlock(method),
expressionBody: default(ArrowExpressionClauseSyntax),
semicolonToken: hasNoBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : new SyntaxToken()));
semicolonToken: hasNoBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : new SyntaxToken());
methodDeclaration = UseExpressionBodyIfDesired(workspace, methodDeclaration);
return AddCleanupAnnotationsTo(methodDeclaration);
}
private static MethodDeclarationSyntax UseExpressionBodyIfDesired(
Workspace workspace, MethodDeclarationSyntax methodDeclaration)
{
if (methodDeclaration.ExpressionBody == null)
{
var preferExpressionBody = workspace.Options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedMethods).Value;
if (preferExpressionBody)
{
var expressionBody = CodeGenerationHelpers.TryConvertToExpressionBody(methodDeclaration.Body);
if (expressionBody != null)
{
return methodDeclaration.WithBody(null)
.WithExpressionBody(expressionBody);
}
}
}
return methodDeclaration;
}
private static SyntaxList<AttributeListSyntax> GenerateAttributes(
......
......@@ -132,21 +132,24 @@ public static bool CanBeGenerated(IPropertySymbol property)
private static PropertyDeclarationSyntax UseExpressionBodyIfDesired(
Workspace workspace, PropertyDeclarationSyntax propertyDeclaration)
{
var preferExpressionBody = workspace.Options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties).Value;
if (preferExpressionBody)
if (propertyDeclaration.ExpressionBody == null)
{
if (propertyDeclaration.Initializer == null &&
propertyDeclaration.AccessorList.Accessors.Count == 1)
var preferExpressionBody = workspace.Options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties).Value;
if (preferExpressionBody)
{
var accessor = propertyDeclaration.AccessorList.Accessors[0];
if (accessor.IsKind(SyntaxKind.GetAccessorDeclaration))
if (propertyDeclaration.Initializer == null &&
propertyDeclaration.AccessorList.Accessors.Count == 1)
{
var expressionBody = TryGetExpressionBody(accessor);
if (expressionBody != null)
var accessor = propertyDeclaration.AccessorList.Accessors[0];
if (accessor.IsKind(SyntaxKind.GetAccessorDeclaration))
{
propertyDeclaration = propertyDeclaration.WithAccessorList(null)
.WithExpressionBody(expressionBody)
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
var expressionBody = TryGetExpressionBody(accessor);
if (expressionBody != null)
{
propertyDeclaration = propertyDeclaration.WithAccessorList(null)
.WithExpressionBody(expressionBody)
.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
}
}
}
}
......@@ -159,34 +162,9 @@ private static ArrowExpressionClauseSyntax TryGetExpressionBody(AccessorDeclarat
{
// If the accessor has an expression body already, then use that as the expression body
// for the property.
if (accessor.ExpressionBody != null)
{
return accessor.ExpressionBody;
}
if (accessor.Body != null)
{
if (accessor.Body.Statements.Count == 1)
{
var firstStatement = accessor.Body.Statements[0];
if (firstStatement.Kind() == SyntaxKind.ReturnStatement)
{
var returnStatement = (ReturnStatementSyntax)firstStatement;
if (returnStatement.Expression != null)
{
return SyntaxFactory.ArrowExpressionClause(returnStatement.Expression);
}
}
else if (firstStatement.Kind() == SyntaxKind.ThrowStatement)
{
var throwStatement = (ThrowStatementSyntax)firstStatement;
return SyntaxFactory.ArrowExpressionClause(
SyntaxFactory.ThrowExpression(throwStatement.ThrowKeyword, throwStatement.Expression));
}
}
}
return null;
return accessor.ExpressionBody != null
? accessor.ExpressionBody
: CodeGenerationHelpers.TryConvertToExpressionBody(accessor.Body);
}
private static AccessorListSyntax GenerateAccessorList(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册