Browse Source

Implemented issue provider for CS0127: A method with a void return

type cannot return a value.
This issue provider got requested - and I need to start somewhere to
implement semantic error issue providers.
pull/32/merge
Mike Krüger 13 years ago
parent
commit
40a2b81b43
  1. 2
      ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  2. 96
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CompilerErrors/CS0127ReturnMustNotBeFollowedByAnyExpression.cs
  3. 2
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SimplifyAnonymousMethodToDelegateIssue.cs
  4. 149
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CS0127ReturnMustNotBeFollowedByAnyExpressionTests.cs
  5. 1
      ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

2
ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -514,6 +514,7 @@
<Compile Include="Resolver\AliasNamespaceResolveResult.cs" /> <Compile Include="Resolver\AliasNamespaceResolveResult.cs" />
<Compile Include="Resolver\ReducedExtensionMethod.cs" /> <Compile Include="Resolver\ReducedExtensionMethod.cs" />
<Compile Include="Refactoring\CodeIssues\SimplifyAnonymousMethodToDelegateIssue.cs" /> <Compile Include="Refactoring\CodeIssues\SimplifyAnonymousMethodToDelegateIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CompilerErrors\CS0127ReturnMustNotBeFollowedByAnyExpression.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj"> <ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
@ -529,6 +530,7 @@
<Folder Include="Refactoring\CodeActions\ExtractMethod\" /> <Folder Include="Refactoring\CodeActions\ExtractMethod\" />
<Folder Include="Refactoring\CodeActions\ConvertToInitializer\" /> <Folder Include="Refactoring\CodeActions\ConvertToInitializer\" />
<Folder Include="Refactoring\CodeIssues\FormatStringIssues\" /> <Folder Include="Refactoring\CodeIssues\FormatStringIssues\" />
<Folder Include="Refactoring\CodeIssues\CompilerErrors\" />
</ItemGroup> </ItemGroup>
<ProjectExtensions> <ProjectExtensions>
<MonoDevelop> <MonoDevelop>

96
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CompilerErrors/CS0127ReturnMustNotBeFollowedByAnyExpression.cs

@ -0,0 +1,96 @@
//
// CS0127ReturnMustNotBeFollowedByAnyExpression.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
[IssueDescription("CS0127: A method with a void return type cannot return a value.",
Description = "Since 'function' returns void, a return keyword must not be followed by an object expression",
Category = IssueCategories.CompilerErrors,
Severity = Severity.Error)]
public class CS0127ReturnMustNotBeFollowedByAnyExpression : ICodeIssueProvider
{
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
{
return new GatherVisitor(context).GetIssues();
}
class GatherVisitor : GatherVisitorBase
{
MethodDeclaration currentMethod;
public GatherVisitor (BaseRefactoringContext ctx) : base (ctx)
{
}
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
var primitiveType = methodDeclaration.ReturnType as PrimitiveType;
if (primitiveType == null || primitiveType.Keyword != "void")
return;
currentMethod = methodDeclaration;
base.VisitMethodDeclaration(methodDeclaration);
}
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{
}
public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
{
}
public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)
{
}
public override void VisitLambdaExpression(LambdaExpression lambdaExpression)
{
}
public override void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)
{
}
public override void VisitReturnStatement(ReturnStatement returnStatement)
{
if (!returnStatement.Expression.IsNull) {
AddIssue(
returnStatement,
ctx.TranslateString("Remove returned expression"),
script => {
script.Remove(returnStatement.Expression);
}
);
}
}
}
}
}

2
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/SimplifyAnonymousMethodToDelegateIssue.cs

@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public GatherVisitor (BaseRefactoringContext ctx) : base (ctx) public GatherVisitor (BaseRefactoringContext ctx) : base (ctx)
{ {
} }
static Pattern pattern = new Choice { static Pattern pattern = new Choice {
new BlockStatement { new BlockStatement {
new ReturnStatement (new AnyNode ("invoke")) new ReturnStatement (new AnyNode ("invoke"))

149
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CS0127ReturnMustNotBeFollowedByAnyExpressionTests.cs

@ -0,0 +1,149 @@
//
// CS0127ReturnMustNotBeFollowedByAnyExpressionTests.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using NUnit.Framework;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.CodeActions;
namespace ICSharpCode.NRefactory.CSharp.CodeIssues
{
[TestFixture]
public class CS0127ReturnMustNotBeFollowedByAnyExpressionTests : InspectionActionTestBase
{
[Test]
public void TestSimpleCase ()
{
var input = @"class Foo
{
void Bar (string str)
{
return str;
}
}";
TestRefactoringContext context;
var issues = GetIssues (new CS0127ReturnMustNotBeFollowedByAnyExpression (), input, out context);
Assert.AreEqual (1, issues.Count);
CheckFix (context, issues, @"class Foo
{
void Bar (string str)
{
return ;
}
}");
}
[Test]
public void TestSimpleInvalidCase ()
{
var input = @"class Foo
{
string Bar (string str)
{
return str;
}
}";
TestRefactoringContext context;
var issues = GetIssues (new CS0127ReturnMustNotBeFollowedByAnyExpression (), input, out context);
Assert.AreEqual (0, issues.Count);
}
[Test]
public void TestProperty ()
{
var input = @"class Foo {
string Bar
{
get {
return ""Hello World "";
}
}
}";
TestRefactoringContext context;
var issues = GetIssues (new CS0127ReturnMustNotBeFollowedByAnyExpression (), input, out context);
Assert.AreEqual (0, issues.Count);
}
[Test]
public void TestIndexer ()
{
var input = @"class Foo {
string this [int idx]
{
get {
return ""Hello World "";
}
}
}";
TestRefactoringContext context;
var issues = GetIssues (new CS0127ReturnMustNotBeFollowedByAnyExpression (), input, out context);
Assert.AreEqual (0, issues.Count);
}
[Test]
public void TestAnonymousMethod ()
{
var input = @"class Foo
{
void Bar (string str)
{
System.Func<string> func = delegate {
return str;
};
}
}";
TestRefactoringContext context;
var issues = GetIssues (new CS0127ReturnMustNotBeFollowedByAnyExpression (), input, out context);
Assert.AreEqual (0, issues.Count);
}
[Test]
public void TestLambdaMethod ()
{
var input = @"class Foo
{
void Bar (string str)
{
System.Func<string> func = () => {
return str;
};
}
}";
TestRefactoringContext context;
var issues = GetIssues (new CS0127ReturnMustNotBeFollowedByAnyExpression (), input, out context);
Assert.AreEqual (0, issues.Count);
}
}
}

1
ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -392,6 +392,7 @@
<Compile Include="CSharp\CodeActions\CreateEnumValueTests.cs" /> <Compile Include="CSharp\CodeActions\CreateEnumValueTests.cs" />
<Compile Include="CSharp\CodeCompletion\GetCurrentParameterIndexTests.cs" /> <Compile Include="CSharp\CodeCompletion\GetCurrentParameterIndexTests.cs" />
<Compile Include="CSharp\CodeIssues\SimplifyAnonymousMethodToDelegateIssueTests.cs" /> <Compile Include="CSharp\CodeIssues\SimplifyAnonymousMethodToDelegateIssueTests.cs" />
<Compile Include="CSharp\CodeIssues\CS0127ReturnMustNotBeFollowedByAnyExpressionTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\cecil\Mono.Cecil.csproj"> <ProjectReference Include="..\..\cecil\Mono.Cecil.csproj">

Loading…
Cancel
Save