Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 69ce7df

Browse files
committed
Update to NRefactory version aa289c2.
aa289c2 Fix potential NullReferenceException in OperatorIsCanBeUsedIssue. 9db72dc Fix icsharpcode/NRefactory#377 - NullReferenceException in NullAnalysisVisitor db2c7b6 Add IAstVisitor.VisitNullNode(). 95141c8 Fix ICompilation.Import(ISymbol) for namespaces in extern alias. c05dbd0 Handle errors if the XML file changes between the XmlDocumentationProvider ctor call and the GetDocumentation call. e763376 Fixed bug in FunctionNeverReturnsIssue. 168b76f Formatting options change: blank lines are now >minimum< blank lines. TODO: Add options for maximum blank lines to preserve. fde2a06 Fixed bug in 'XmlDocIssue'. 1403af7 Added 'CS1105ExtensionMethodMustBeDeclaredStaticAction'. acca096 Merge pull request icsharpcode/NRefactory#381 from mono-soc-2013/MateY-IndentEngine 505c974 Issue with preprocessor directives. 4730eca Added some indenting unit tests. 412b324 Fixed possible parser bug. 989abdd Fixed completion bug. 3582f57 Fixed bug in StaticEventSubscriptionIssue bbe2d12 Merge pull request icsharpcode/NRefactory#380 from Therzok/patch-2 43b42c5 Merge pull request icsharpcode/NRefactory#379 from Therzok/patch-1 02278d8 Fix typo in documentation f08bcdb Add StaticEventSubscription static check test 084d2de StaticEventSubscriptionIssue - Check if static b7ab0b1 Implemented StaticEventSubscriptionIssue aa291c5 Fixed construct fixer tests. dd6db96 Fixed unit test bug. 6899688 Fixed constructfixer tests on windows. 3d42715 Improved display location for 'RedundantBoolCompareIssue'. c1b8ab5 Removed IndentStateFactory. (Creating the classes direcly is a magnitude faster) e7b490e Optimized IsNewLine method. d95fdc2 Added some optimizations to the indent engine. 313235e Speed up indentation engine 540af30 Fixed indentation bug. 7db77a4 Added some more construct fix cases. Unfortunately the parser error recovery isn't good enough for implementing that feature. bd6d6f1 Added c# ConstructFixer.
1 parent 4e35d33 commit 69ce7df

62 files changed

Lines changed: 2549 additions & 514 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@
339339
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.SimplifyConditionalTernaryExpressionIssue" />
340340
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.SimplifyLinqExpressionIssue" />
341341
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.StaticConstructorParameterIssue" />
342+
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.StaticEventSubscriptionIssue" />
342343
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.StaticFieldInGenericTypeIssue" />
343344
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.StringCompareIsCultureSpecificIssue" />
344345
<Class class = "ICSharpCode.NRefactory.CSharp.Refactoring.StringCompareToIsCultureSpecificIssue" />
@@ -428,6 +429,7 @@
428429
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateOverloadWithoutParameterAction" />
429430
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreatePropertyAction" />
430431
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS1520MethodMustHaveAReturnTypeAction" />
432+
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.CS1105ExtensionMethodMustBeDeclaredStaticAction" />
431433
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.DeclareLocalVariableAction" />
432434
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.ExtensionMethodInvocationToStaticMethodInvocationAction" />
433435
<CSharpCodeActionProvider class = "ICSharpCode.NRefactory.CSharp.Refactoring.ExtractAnonymousMethodAction" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// CS1105ExtensionMethodMustBeDeclaredStaticAction.cs
3+
//
4+
// Author:
5+
// Mike Krüger <mkrueger@xamarin.com>
6+
//
7+
// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
using System;
27+
using ICSharpCode.NRefactory.TypeSystem;
28+
using System.Threading;
29+
using System.Collections.Generic;
30+
using System.Linq;
31+
32+
namespace ICSharpCode.NRefactory.CSharp.Refactoring
33+
{
34+
[ContextAction("Extension methods must be declared static")]
35+
public class CS1105ExtensionMethodMustBeDeclaredStaticAction : CodeActionProvider
36+
{
37+
public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
38+
{
39+
var method = context.GetNode<MethodDeclaration>();
40+
if (method == null || !method.NameToken.Contains(context.Location))
41+
yield break;
42+
43+
if (method.HasModifier(Modifiers.Static))
44+
yield break;
45+
var param = method.Parameters.FirstOrDefault();
46+
if (param == null || param.ParameterModifier != ParameterModifier.This)
47+
yield break;
48+
yield return new CodeAction(
49+
context.TranslateString("Convert method to static"),
50+
script => script.ChangeModifier(method, method.Modifiers | Modifiers.Static),
51+
method) {
52+
Severity = ICSharpCode.NRefactory.Refactoring.Severity.Error
53+
};
54+
}
55+
}
56+
}
57+
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//
2+
// StaticEventSubscriptionIssue.cs
3+
//
4+
// Author:
5+
// Mike Krüger <mkrueger@xamarin.com>
6+
//
7+
// Copyright (c) 2014 Xamarin Inc. (http://xamarin.com)
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
using System;
27+
using ICSharpCode.NRefactory.PatternMatching;
28+
using System.Collections.Generic;
29+
using ICSharpCode.NRefactory.TypeSystem;
30+
using ICSharpCode.NRefactory.Refactoring;
31+
using Mono.CSharp;
32+
using ICSharpCode.NRefactory.Semantics;
33+
using ICSharpCode.NRefactory.CSharp.Resolver;
34+
using System.Linq;
35+
36+
namespace ICSharpCode.NRefactory.CSharp.Refactoring
37+
{
38+
[IssueDescription("Static event removal check",
39+
Description = "Checks if static events are removed",
40+
Category = IssueCategories.CodeQualityIssues,
41+
Severity = Severity.Warning)]
42+
public class StaticEventSubscriptionIssue : GatherVisitorCodeIssueProvider
43+
{
44+
protected override IGatherVisitor CreateVisitor(BaseRefactoringContext context)
45+
{
46+
return new GatherVisitor(context);
47+
}
48+
49+
class GatherVisitor : GatherVisitorBase<StaticEventSubscriptionIssue>
50+
{
51+
public GatherVisitor (BaseRefactoringContext ctx) : base (ctx)
52+
{
53+
}
54+
55+
public override void VisitSyntaxTree(SyntaxTree syntaxTree)
56+
{
57+
base.VisitSyntaxTree(syntaxTree);
58+
59+
foreach (var assignedEvent in assignedEvents) {
60+
addedEvents.Remove(assignedEvent);
61+
}
62+
63+
foreach (var hs in removedEvents) {
64+
HashSet<Tuple<IMember, AssignmentExpression>> h;
65+
if (!addedEvents.TryGetValue(hs.Key, out h))
66+
continue;
67+
foreach (var evt in hs.Value) {
68+
restart:
69+
foreach (var m in h) {
70+
if (m.Item1 == evt) {
71+
h.Remove(m);
72+
goto restart;
73+
}
74+
}
75+
}
76+
}
77+
78+
foreach (var added in addedEvents) {
79+
foreach (var usage in added.Value) {
80+
AddIssue(new CodeIssue(usage.Item2.OperatorToken,
81+
ctx.TranslateString("Subscription to static events without unsubscription may cause memory leaks.")));
82+
}
83+
}
84+
}
85+
86+
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
87+
{
88+
if (methodDeclaration.HasModifier(Modifiers.Static))
89+
return;
90+
91+
base.VisitMethodDeclaration(methodDeclaration);
92+
}
93+
94+
public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
95+
{
96+
if (constructorDeclaration.HasModifier(Modifiers.Static))
97+
return;
98+
base.VisitConstructorDeclaration(constructorDeclaration);
99+
}
100+
readonly Dictionary<IMember, HashSet<Tuple<IMember, AssignmentExpression>>> addedEvents = new Dictionary<IMember, HashSet<Tuple<IMember, AssignmentExpression>>>();
101+
readonly Dictionary<IMember, HashSet<IMember>> removedEvents = new Dictionary<IMember, HashSet<IMember>>();
102+
readonly HashSet<IMember> assignedEvents = new HashSet<IMember> ();
103+
104+
public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression)
105+
{
106+
base.VisitAssignmentExpression(assignmentExpression);
107+
108+
if (assignmentExpression.Operator == AssignmentOperatorType.Add) {
109+
var left = ctx.Resolve(assignmentExpression.Left) as MemberResolveResult;
110+
if (left == null || left.Member.SymbolKind != SymbolKind.Event || !left.Member.IsStatic)
111+
return;
112+
113+
if (assignmentExpression.Right is AnonymousMethodExpression || assignmentExpression.Right is LambdaExpression) {
114+
AddIssue(new CodeIssue(assignmentExpression.OperatorToken,
115+
ctx.TranslateString("Subscription to static events with an anonymous method may cause memory leaks.")));
116+
}
117+
118+
119+
var right = ctx.Resolve(assignmentExpression.Right) as MethodGroupResolveResult;
120+
if (right == null || right.Methods.Count() != 1)
121+
return;
122+
HashSet<Tuple<IMember, AssignmentExpression>> hs;
123+
if (!addedEvents.TryGetValue(left.Member, out hs))
124+
addedEvents[left.Member] = hs = new HashSet<Tuple<IMember, AssignmentExpression>>();
125+
hs.Add(Tuple.Create((IMember)right.Methods.First(), assignmentExpression));
126+
} else if (assignmentExpression.Operator == AssignmentOperatorType.Subtract) {
127+
var left = ctx.Resolve(assignmentExpression.Left) as MemberResolveResult;
128+
if (left == null || left.Member.SymbolKind != SymbolKind.Event || !left.Member.IsStatic)
129+
return;
130+
var right = ctx.Resolve(assignmentExpression.Right) as MethodGroupResolveResult;
131+
if (right == null || right.Methods.Count() != 1)
132+
return;
133+
HashSet<IMember> hs;
134+
if (!removedEvents.TryGetValue(left.Member, out hs))
135+
removedEvents[left.Member] = hs = new HashSet<IMember>();
136+
hs.Add(right.Methods.First());
137+
} else if (assignmentExpression.Operator == AssignmentOperatorType.Assign) {
138+
var left = ctx.Resolve(assignmentExpression.Left) as MemberResolveResult;
139+
if (left == null || left.Member.SymbolKind != SymbolKind.Event || !left.Member.IsStatic)
140+
return;
141+
assignedEvents.Add(left.Member);
142+
}
143+
}
144+
}
145+
}
146+
}
147+

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp.Refactoring/CodeIssues/Custom/XmlDocIssue.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ void CheckXmlDoc(AstNode node)
183183
var m = member as IParameterizedMember;
184184
if (m != null && m.Parameters.Any(p => p.Name == name.Value))
185185
break;
186+
if (name.Value == "value" && (member.SymbolKind == SymbolKind.Property || member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Event) && el.Name == "paramref")
187+
break;
186188
AddXmlIssue(name.ValueSegment.Offset - firstline.Length + 1, name.ValueSegment.Length - 2, string.Format(ctx.TranslateString("Parameter '{0}' not found"), name.Value));
187189
break;
188190
case "exception":

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp.Refactoring/CodeIssues/Synced/CodeQuality/FunctionNeverReturnsIssue.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,16 @@ public override bool VisitAssignmentExpression(AssignmentExpression assignmentEx
152152
return base.VisitAssignmentExpression(assignmentExpression);
153153
}
154154

155+
public override bool VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)
156+
{
157+
return false;
158+
}
159+
160+
public override bool VisitLambdaExpression(LambdaExpression lambdaExpression)
161+
{
162+
return false;
163+
}
164+
155165
public override bool VisitIdentifierExpression(IdentifierExpression identifierExpression)
156166
{
157167
return CheckRecursion(identifierExpression);

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp.Refactoring/CodeIssues/Synced/CodeQuality/OperatorIsCanBeUsedIssue.cs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2525
// THE SOFTWARE.using System;
2626

27+
using System.Linq;
2728
using ICSharpCode.NRefactory.PatternMatching;
2829
using ICSharpCode.NRefactory.TypeSystem;
2930
using ICSharpCode.NRefactory.Semantics;
@@ -64,25 +65,13 @@ public override void VisitBinaryOperatorExpression(BinaryOperatorExpression bina
6465
if (!m.Success)
6566
return;
6667

67-
Expression identifier = null;
68-
AstType type = null;
69-
70-
if (binaryOperatorExpression.Left is TypeOfExpression && binaryOperatorExpression.Right is InvocationExpression) {
71-
type = (binaryOperatorExpression.Left as TypeOfExpression).Type;
72-
var right = binaryOperatorExpression.Right as InvocationExpression;
73-
identifier = (right.Target as MemberReferenceExpression).Target;
74-
} else if (binaryOperatorExpression.Right is TypeOfExpression && binaryOperatorExpression.Left is InvocationExpression) {
75-
type = (binaryOperatorExpression.Right as TypeOfExpression).Type;
76-
var left = binaryOperatorExpression.Left as InvocationExpression;
77-
identifier = (left.Target as MemberReferenceExpression).Target;
78-
} else
79-
return;
80-
81-
if (identifier == null || type == null)
68+
Expression identifier = m.Get<Expression>("a").Single();
69+
AstType type = m.Get<AstType>("b").Single();
70+
71+
var typeResolved = ctx.Resolve(type) as TypeResolveResult;
72+
if (typeResolved == null)
8273
return;
8374

84-
var typeResolved = ctx.Resolve(type) as TypeResolveResult;
85-
8675
if (typeResolved.Type.Kind == TypeKind.Class) {
8776
if (!typeResolved.Type.GetDefinition().IsSealed) {
8877
return;

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp.Refactoring/CodeIssues/Synced/RedundanciesInCode/RedundantBoolCompareIssue.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,20 @@ public override void VisitBinaryOperatorExpression (BinaryOperatorExpression bin
7777
if (exprType == null || exprType.KnownTypeCode != KnownTypeCode.Boolean)
7878
return;
7979

80-
var boolConstant = (bool)match.Get<PrimitiveExpression> ("const").First ().Value;
80+
var boolExpr = match.Get<PrimitiveExpression>("const").First();
81+
var boolConstant = (bool)boolExpr.Value;
82+
83+
TextLocation start, end;
84+
if (boolExpr == binaryOperatorExpression.Left) {
85+
start = binaryOperatorExpression.StartLocation;
86+
end = binaryOperatorExpression.OperatorToken.EndLocation;
87+
} else {
88+
start = binaryOperatorExpression.OperatorToken.StartLocation;
89+
end = binaryOperatorExpression.EndLocation;
90+
}
91+
8192
AddIssue (new CodeIssue(
82-
binaryOperatorExpression,
93+
start, end,
8394
boolConstant ? ctx.TranslateString ("Comparison with 'true' is redundant") : ctx.TranslateString ("Comparison with 'false' is redundant"),
8495
ctx.TranslateString ("Remove redundant comparison"),
8596
script => {

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp.Refactoring/ICSharpCode.NRefactory.CSharp.Refactoring.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@
426426
<Compile Include="CodeIssues\Uncategorized\RedundantNotNullAttributeInNonNullableTypeIssue.cs" />
427427
<Compile Include="CodeIssues\Custom\CompilerErrors\CS0618UsageOfObsoleteMemberIssue.cs" />
428428
<Compile Include="CodeIssues\Custom\CompilerErrors\CS0169FieldIsNeverUsedIssue.cs" />
429+
<Compile Include="CodeIssues\Custom\StaticEventSubscriptionIssue.cs" />
430+
<Compile Include="CodeActions\CS1105ExtensionMethodMustBeDeclaredStaticAction.cs" />
429431
</ItemGroup>
430432
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
431433
<ItemGroup>

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/NullValueAnalysis.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,18 @@ public NullAnalysisVisitor(NullValueAnalysis analysis) {
776776
this.analysis = analysis;
777777
}
778778

779+
protected override VisitorResult VisitChildren(AstNode node, VariableStatusInfo data)
780+
{
781+
Debug.Fail("Missing override for " + node.GetType().Name);
782+
return VisitorResult.ForValue(data, NullValueStatus.Unknown);
783+
}
784+
785+
public override VisitorResult VisitNullNode(AstNode nullNode, VariableStatusInfo data)
786+
{
787+
// can occur due to syntax errors
788+
return VisitorResult.ForValue(data, NullValueStatus.Unknown);
789+
}
790+
779791
public override VisitorResult VisitEmptyStatement(EmptyStatement emptyStatement, VariableStatusInfo data)
780792
{
781793
return VisitorResult.ForValue(data, NullValueStatus.Unknown);

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ public override bool IsNull {
5959

6060
public override void AcceptVisitor (IAstVisitor visitor)
6161
{
62+
visitor.VisitNullNode(this);
6263
}
6364

6465
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
6566
{
66-
return default (T);
67+
return visitor.VisitNullNode(this);
6768
}
6869

6970
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
7071
{
71-
return default (S);
72+
return visitor.VisitNullNode(this, data);
7273
}
7374

7475
protected internal override bool DoMatch (AstNode other, PatternMatching.Match match)

0 commit comments

Comments
 (0)