2
// InconsistentNamingIssue.cs
5
// Mike KrĆ¼ger <mkrueger@xamarin.com>
7
// Copyright (c) 2012 Xamarin <http://xamarin.com>
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:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
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
27
using System.Collections.Generic;
29
using ICSharpCode.NRefactory.Semantics;
30
using ICSharpCode.NRefactory.TypeSystem;
32
namespace ICSharpCode.NRefactory.CSharp.Refactoring
34
[IssueDescription("Inconsistent Naming",
35
Description = "Name doesn't match the defined style for this entity.",
36
Category = IssueCategories.ConstraintViolations,
37
Severity = Severity.Warning)]
38
public class InconsistentNamingIssue : ICodeIssueProvider
40
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
42
var visitor = new GatherVisitor(context, this);
43
context.RootNode.AcceptVisitor(visitor);
44
return visitor.FoundIssues;
47
class GatherVisitor : GatherVisitorBase
49
readonly InconsistentNamingIssue inspector;
50
readonly NamingConventionService service;
52
public GatherVisitor (BaseRefactoringContext ctx, InconsistentNamingIssue inspector) : base (ctx)
54
this.inspector = inspector;
55
service = (NamingConventionService)ctx.GetService (typeof (NamingConventionService));
58
void CheckName(AstNode node, AffectedEntity entity, Identifier identifier, Modifiers accessibilty)
60
ResolveResult resolveResult = null;
62
resolveResult = ctx.Resolve(node);
64
if (resolveResult is TypeResolveResult) {
65
var type = ((TypeResolveResult)resolveResult).Type;
66
if (type.DirectBaseTypes.Any(t => t.FullName == "System.Attribute")) {
67
if (CheckNamedResolveResult(resolveResult, AffectedEntity.CustomAttributes, identifier, accessibilty)) {
70
} else if (type.DirectBaseTypes.Any(t => t.FullName == "System.EventArgs")) {
71
if (CheckNamedResolveResult(resolveResult, AffectedEntity.CustomEventArgs, identifier, accessibilty)) {
74
} else if (type.DirectBaseTypes.Any(t => t.FullName == "System.Exception")) {
75
if (CheckNamedResolveResult(resolveResult, AffectedEntity.CustomExceptions, identifier, accessibilty)) {
80
var typeDef = type.GetDefinition();
81
if (typeDef != null && typeDef.Attributes.Any(attr => attr.AttributeType.FullName == "NUnit.Framework.TestFixtureAttribute")) {
82
if (CheckNamedResolveResult(resolveResult, AffectedEntity.TestType, identifier, accessibilty)) {
86
} else if (resolveResult is MemberResolveResult) {
87
var member = ((MemberResolveResult)resolveResult).Member;
88
if (member.EntityType == EntityType.Method && member.Attributes.Any(attr => attr.AttributeType.FullName == "NUnit.Framework.TestAttribute")) {
89
if (CheckNamedResolveResult(resolveResult, AffectedEntity.TestMethod, identifier, accessibilty)) {
94
CheckNamedResolveResult(resolveResult, entity, identifier, accessibilty);
97
bool CheckNamedResolveResult(ResolveResult resolveResult, AffectedEntity entity, Identifier identifier, Modifiers accessibilty)
99
bool wasHandled = false;
100
foreach (var rule in service.Rules) {
101
if (!rule.AffectedEntity.HasFlag(entity)) {
104
if (!rule.VisibilityMask.HasFlag(accessibilty)) {
107
if (!rule.IncludeInstanceMembers || !rule.IncludeStaticEntities) {
108
IEntity typeSystemEntity = null;
109
if (resolveResult is MemberResolveResult) {
110
typeSystemEntity = ((MemberResolveResult)resolveResult).Member;
111
} else if (resolveResult is TypeResolveResult) {
112
typeSystemEntity = ((TypeResolveResult)resolveResult).Type.GetDefinition();
114
if (!rule.IncludeInstanceMembers) {
115
if (typeSystemEntity == null || !typeSystemEntity.IsStatic) {
119
if (!rule.IncludeStaticEntities) {
120
if (typeSystemEntity == null || typeSystemEntity.IsStatic) {
126
if (!rule.IsValid(identifier.Name)) {
127
IList<string> suggestedNames;
128
var msg = rule.GetErrorMessage(ctx, identifier.Name, out suggestedNames);
129
var actions = new List<CodeAction>(suggestedNames.Select(n => new CodeAction(string.Format(ctx.TranslateString("Rename to '{0}'"), n), (Script script) => {
130
if (resolveResult is MemberResolveResult) {
131
script.Rename(((MemberResolveResult)resolveResult).Member, n);
132
} else if (resolveResult is TypeResolveResult) {
133
var def = ((TypeResolveResult)resolveResult).Type.GetDefinition();
135
script.Rename(def, n);
137
script.RenameTypeParameter(((TypeResolveResult)resolveResult).Type, n);
139
} else if (resolveResult is LocalResolveResult) {
140
script.Rename(((LocalResolveResult)resolveResult).Variable, n);
142
script.Replace(identifier, Identifier.Create(n));
147
if (resolveResult is MemberResolveResult || resolveResult is TypeResolveResult || resolveResult is LocalResolveResult) {
148
actions.Add(new CodeAction(string.Format(ctx.TranslateString("Rename '{0}'..."), identifier.Name), (Script script) => {
149
if (resolveResult is MemberResolveResult) {
150
script.Rename(((MemberResolveResult)resolveResult).Member);
151
} else if (resolveResult is TypeResolveResult) {
152
var def = ((TypeResolveResult)resolveResult).Type.GetDefinition();
156
script.RenameTypeParameter(((TypeResolveResult)resolveResult).Type);
158
} else if (resolveResult is LocalResolveResult) {
159
script.Rename(((LocalResolveResult)resolveResult).Variable);
164
AddIssue(identifier, msg, actions);
170
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
172
base.VisitNamespaceDeclaration(namespaceDeclaration);
173
foreach (var id in namespaceDeclaration.Identifiers) {
174
CheckName(null, AffectedEntity.Namespace, id, Modifiers.None);
178
Modifiers GetAccessibiltiy(EntityDeclaration decl, Modifiers defaultModifier)
180
var accessibility = (decl.Modifiers & Modifiers.VisibilityMask);
181
if (accessibility == Modifiers.None) {
182
return defaultModifier;
184
return accessibility;
187
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
189
base.VisitTypeDeclaration(typeDeclaration);
190
AffectedEntity entity;
191
switch (typeDeclaration.ClassType) {
192
case ClassType.Class:
193
entity = AffectedEntity.Class;
195
case ClassType.Struct:
196
entity = AffectedEntity.Struct;
198
case ClassType.Interface:
199
entity = AffectedEntity.Interface;
202
entity = AffectedEntity.Enum;
205
throw new System.ArgumentOutOfRangeException();
207
CheckName(typeDeclaration, entity, typeDeclaration.NameToken, GetAccessibiltiy(typeDeclaration, typeDeclaration.Parent is TypeDeclaration ? Modifiers.Private : Modifiers.Internal));
210
public override void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
212
base.VisitDelegateDeclaration(delegateDeclaration);
213
CheckName(delegateDeclaration, AffectedEntity.Delegate, delegateDeclaration.NameToken, GetAccessibiltiy(delegateDeclaration, delegateDeclaration.Parent is TypeDeclaration ? Modifiers.Private : Modifiers.Internal));
216
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
218
base.VisitPropertyDeclaration(propertyDeclaration);
219
CheckName(propertyDeclaration, AffectedEntity.Property, propertyDeclaration.NameToken, GetAccessibiltiy(propertyDeclaration, Modifiers.Private));
222
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
224
base.VisitMethodDeclaration(methodDeclaration);
226
CheckName(methodDeclaration, methodDeclaration.Modifiers.HasFlag(Modifiers.Async) ? AffectedEntity.AsyncMethod : AffectedEntity.Method, methodDeclaration.NameToken, GetAccessibiltiy(methodDeclaration, Modifiers.Private));
229
public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
231
base.VisitFieldDeclaration(fieldDeclaration);
232
var entity = AffectedEntity.Field;
233
if (fieldDeclaration.Modifiers.HasFlag(Modifiers.Const)) {
234
entity = AffectedEntity.ConstantField;
235
} else if (fieldDeclaration.Modifiers.HasFlag(Modifiers.Readonly)) {
236
entity = AffectedEntity.ReadonlyField;
238
foreach (var init in fieldDeclaration.Variables) {
239
CheckName(init, entity, init.NameToken, GetAccessibiltiy(fieldDeclaration, Modifiers.Private));
243
public override void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
245
base.VisitFixedFieldDeclaration(fixedFieldDeclaration);
246
var entity = AffectedEntity.Field;
247
if (fixedFieldDeclaration.Modifiers.HasFlag(Modifiers.Const)) {
248
entity = AffectedEntity.ConstantField;
249
} else if (fixedFieldDeclaration.Modifiers.HasFlag(Modifiers.Readonly)) {
250
entity = AffectedEntity.ReadonlyField;
252
CheckName(fixedFieldDeclaration, entity, fixedFieldDeclaration.NameToken, GetAccessibiltiy(fixedFieldDeclaration, Modifiers.Private));
255
public override void VisitEventDeclaration(EventDeclaration eventDeclaration)
257
base.VisitEventDeclaration(eventDeclaration);
258
foreach (var init in eventDeclaration.Variables) {
259
CheckName(init, AffectedEntity.Event, init.NameToken, GetAccessibiltiy(eventDeclaration, Modifiers.Private));
263
public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)
265
base.VisitCustomEventDeclaration(eventDeclaration);
266
CheckName(eventDeclaration, AffectedEntity.Event, eventDeclaration.NameToken, GetAccessibiltiy(eventDeclaration, Modifiers.Private));
269
public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
271
base.VisitEnumMemberDeclaration(enumMemberDeclaration);
272
CheckName(enumMemberDeclaration, AffectedEntity.EnumMember, enumMemberDeclaration.NameToken, GetAccessibiltiy(enumMemberDeclaration, Modifiers.Private));
275
public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration)
277
base.VisitParameterDeclaration(parameterDeclaration);
278
CheckName(parameterDeclaration, parameterDeclaration.Parent is LambdaExpression ? AffectedEntity.LambdaParameter : AffectedEntity.Parameter, parameterDeclaration.NameToken, Modifiers.None);
281
public override void VisitTypeParameterDeclaration(TypeParameterDeclaration typeParameterDeclaration)
283
base.VisitTypeParameterDeclaration(typeParameterDeclaration);
284
CheckName(typeParameterDeclaration, AffectedEntity.TypeParameter, typeParameterDeclaration.NameToken, Modifiers.None);
287
public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)
289
base.VisitVariableDeclarationStatement(variableDeclarationStatement);
290
var entity = variableDeclarationStatement.Modifiers.HasFlag(Modifiers.Const) ? AffectedEntity.LocalConstant : AffectedEntity.LocalVariable;
291
foreach (var init in variableDeclarationStatement.Variables) {
292
CheckName(init, entity, init.NameToken, Modifiers.None);
296
public override void VisitLabelStatement(LabelStatement labelStatement)
298
base.VisitLabelStatement(labelStatement);
299
CheckName(null, AffectedEntity.Label, labelStatement.LabelToken, Modifiers.None);