Skip to content

Commit c4ac18a

Browse files
committed
Update to lostmsu's fork
1 parent 721db45 commit c4ac18a

File tree

2 files changed

+43
-28
lines changed

2 files changed

+43
-28
lines changed

src/noncopyable_analyzer/NonCopyableAnalyzer.cs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ public override void Initialize(AnalysisContext context)
5757
CheckCopyability(oc, op.Value, ArgumentRule);
5858
}, OperationKind.Argument);
5959

60-
// csc.RegisterOperationAction(oc =>
61-
// {
62-
// var op = (IReturnOperation)oc.Operation;
63-
// if (op.ReturnedValue == null) return;
64-
// CheckCopyability(oc, op.ReturnedValue, ReturnRule);
65-
// }, OperationKind.Return,
66-
// OperationKind.YieldReturn);
60+
csc.RegisterOperationAction(oc =>
61+
{
62+
var op = (IReturnOperation)oc.Operation;
63+
if (op.ReturnedValue == null) return;
64+
CheckCopyability(oc, op.ReturnedValue, ReturnRule);
65+
}, OperationKind.Return,
66+
OperationKind.YieldReturn);
6767

6868
csc.RegisterOperationAction(oc =>
6969
{
@@ -83,10 +83,10 @@ public override void Initialize(AnalysisContext context)
8383
op == ((IForEachLoopOperation)op.Parent).Collection &&
8484
op.Conversion.IsIdentity)
8585
{
86-
return;
86+
return;
8787
}
8888

89-
oc.ReportDiagnostic(Diagnostic.Create(ConversionRule, v.Syntax.GetLocation(), t.Name));
89+
oc.ReportDiagnostic(Error(v.Syntax, ConversionRule, t.Name));
9090
}, OperationKind.Conversion);
9191

9292
csc.RegisterOperationAction(oc =>
@@ -101,24 +101,12 @@ public override void Initialize(AnalysisContext context)
101101
}
102102
}, OperationKind.ArrayInitializer);
103103

104-
csc.RegisterOperationAction(oc =>
105-
{
106-
var op = (ICollectionElementInitializerOperation)oc.Operation;
107-
108-
if (!HasNonCopyableParameter(op.AddMethod)) return;
109-
110-
foreach (var a in op.Arguments)
111-
{
112-
CheckCopyability(oc, a, InitializerRule);
113-
}
114-
}, OperationKind.CollectionElementInitializer);
115-
116104
csc.RegisterOperationAction(oc =>
117105
{
118106
var op = (IDeclarationPatternOperation)oc.Operation;
119107
var t = ((ILocalSymbol)op.DeclaredSymbol).Type;
120108
if (!t.IsNonCopyable()) return;
121-
oc.ReportDiagnostic(Diagnostic.Create(PatternRule, op.Syntax.GetLocation(), t.Name));
109+
oc.ReportDiagnostic(Error(op.Syntax, PatternRule, t.Name));
122110
}, OperationKind.DeclarationPattern);
123111

124112
csc.RegisterOperationAction(oc =>
@@ -152,13 +140,24 @@ public override void Initialize(AnalysisContext context)
152140

153141
}, OperationKind.Invocation);
154142

143+
csc.RegisterOperationAction(oc => {
144+
var op = (IDynamicInvocationOperation)oc.Operation;
145+
146+
foreach(var arg in op.Arguments) {
147+
if (!arg.Type.IsNonCopyable()) continue;
148+
149+
oc.ReportDiagnostic(Error(arg.Syntax, GenericConstraintRule));
150+
}
151+
152+
}, OperationKind.DynamicInvocation);
153+
155154
csc.RegisterOperationAction(oc =>
156155
{
157156
// delagate creation
158157
var op = (IMemberReferenceOperation)oc.Operation;
159158
if (op.Instance == null) return;
160159
if (!op.Instance.Type.IsNonCopyable()) return;
161-
oc.ReportDiagnostic(Diagnostic.Create(DelegateRule, op.Instance.Syntax.GetLocation(), op.Instance.Type.Name));
160+
oc.ReportDiagnostic(Error(op.Instance.Syntax, DelegateRule, op.Instance.Type.Name));
162161
}, OperationKind.MethodReference);
163162

164163
csc.RegisterSymbolAction(sac =>
@@ -168,7 +167,7 @@ public override void Initialize(AnalysisContext context)
168167
if (!f.Type.IsNonCopyable()) return;
169168
if (f.ContainingType.IsReferenceType) return;
170169
if (f.ContainingType.IsNonCopyable()) return;
171-
sac.ReportDiagnostic(Diagnostic.Create(FieldDeclarationRule, f.DeclaringSyntaxReferences[0].GetSyntax().GetLocation(), f.Type.Name));
170+
sac.ReportDiagnostic(Error(f.DeclaringSyntaxReferences[0].GetSyntax(), FieldDeclarationRule, f.Type.Name));
172171
}, SymbolKind.Field);
173172
});
174173

@@ -192,7 +191,7 @@ private static void CheckGenericConstraints(in OperationAnalysisContext oc, IInv
192191
var a = arguments[i];
193192

194193
if (a.IsNonCopyable() && !p.IsNonCopyable())
195-
oc.ReportDiagnostic(Diagnostic.Create(rule, op.Syntax.GetLocation(), a.Name));
194+
oc.ReportDiagnostic(Error(op.Syntax, rule, a.Name));
196195
}
197196
}
198197
}
@@ -206,10 +205,15 @@ private static void CheckInstanceReadonly(in OperationAnalysisContext oc, IOpera
206205

207206
if (IsInstanceReadonly(instance))
208207
{
209-
oc.ReportDiagnostic(Diagnostic.Create(rule, instance.Syntax.GetLocation(), t.Name));
208+
oc.ReportDiagnostic(Error(instance.Syntax, rule, t.Name));
210209
}
211210
}
212211

212+
private static Diagnostic Error(SyntaxNode at, DiagnosticDescriptor rule, string name = null)
213+
=> name is null
214+
? Diagnostic.Create(rule, at.GetLocation())
215+
: Diagnostic.Create(rule, at.GetLocation(), name);
216+
213217
private static bool IsInstanceReadonly(IOperation instance)
214218
{
215219
bool isReadOnly = false;
@@ -246,7 +250,7 @@ private static void CheckCopyability(in OperationAnalysisContext oc, IOperation
246250
var t = v.Type;
247251
if (!t.IsNonCopyable()) return;
248252
if (v.CanCopy()) return;
249-
oc.ReportDiagnostic(Diagnostic.Create(rule, v.Syntax.GetLocation(), t.Name));
253+
oc.ReportDiagnostic(Error(v.Syntax, rule, t.Name));
250254
}
251255
}
252256
}

src/noncopyable_analyzer/TypeExtensions.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,24 @@ public static bool CanCopy(this IOperation op)
7878
if (parent == SyntaxKind.RefExpression) return true;
7979
}
8080

81+
if (k == OperationKind.Conditional)
82+
{
83+
var cond = (IConditionalOperation)op;
84+
return cond.WhenFalse.CanCopy() && cond.WhenFalse.CanCopy();
85+
}
86+
8187
return k == OperationKind.ObjectCreation
8288
|| k == OperationKind.DefaultValue
8389
|| k == OperationKind.Literal
84-
|| k == OperationKind.Invocation;
90+
|| k == OperationKind.Invocation
91+
// workaround for https://github.com/dotnet/roslyn/issues/49751
92+
|| !IsValid(k) && op.Syntax is InvocationExpressionSyntax;
8593

8694
//todo: should return value be OK?
8795
//todo: move semantics
8896
}
97+
98+
static bool IsValid(OperationKind kind)
99+
=> kind != OperationKind.None && kind != OperationKind.Invalid;
89100
}
90101
}

0 commit comments

Comments
 (0)