Browse Source

Use bool return types and early returns.

pull/2643/head
Siegfried Pammer 4 years ago
parent
commit
a4760e2d77
  1. 132
      ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs

132
ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs

@ -22,7 +22,6 @@ using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -66,7 +65,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
foreach (var member in type.Members) foreach (var member in type.Members)
{ {
visitor.Found = false; visitor.Found = false;
VisitMember(visitor, member, context, scanBodies: true); VisitMember(visitor, member, context);
if (visitor.Found) if (visitor.Found)
yield return member; yield return member;
} }
@ -108,7 +107,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
} }
} }
void VisitMember(TypeDefinitionUsedVisitor visitor, IMember member, AnalyzerContext context, bool scanBodies = false) void VisitMember(TypeDefinitionUsedVisitor visitor, IMember member, AnalyzerContext context)
{ {
member.DeclaringType.AcceptVisitor(visitor); member.DeclaringType.AcceptVisitor(visitor);
switch (member) switch (member)
@ -147,10 +146,8 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (!visitor.Found) if (!visitor.Found)
ScanAttributes(visitor, t.GetAttributes()); ScanAttributes(visitor, t.GetAttributes());
} }
if (!visitor.Found)
if (scanBodies && !visitor.Found) visitor.Found |= ScanMethodBody(visitor.TypeDefinition, method, context.GetMethodBody(method));
ScanMethodBody(visitor, method, context.GetMethodBody(method), context);
break; break;
case IProperty property: case IProperty property:
foreach (var p in property.Parameters) foreach (var p in property.Parameters)
@ -163,80 +160,77 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
property.ReturnType.AcceptVisitor(visitor); property.ReturnType.AcceptVisitor(visitor);
if (scanBodies && !visitor.Found && property.CanGet) if (!visitor.Found && property.CanGet)
{ {
if (!visitor.Found) ScanAttributes(visitor, property.Getter.GetAttributes());
ScanAttributes(visitor, property.Getter.GetAttributes());
if (!visitor.Found) if (!visitor.Found)
ScanAttributes(visitor, property.Getter.GetReturnTypeAttributes()); ScanAttributes(visitor, property.Getter.GetReturnTypeAttributes());
if (!visitor.Found)
ScanMethodBody(visitor, property.Getter, context.GetMethodBody(property.Getter), context); visitor.Found |= ScanMethodBody(visitor.TypeDefinition, property.Getter, context.GetMethodBody(property.Getter));
} }
if (scanBodies && !visitor.Found && property.CanSet) if (!visitor.Found && property.CanSet)
{ {
if (!visitor.Found) ScanAttributes(visitor, property.Setter.GetAttributes());
ScanAttributes(visitor, property.Setter.GetAttributes());
if (!visitor.Found) if (!visitor.Found)
ScanAttributes(visitor, property.Setter.GetReturnTypeAttributes()); ScanAttributes(visitor, property.Setter.GetReturnTypeAttributes());
if (!visitor.Found)
ScanMethodBody(visitor, property.Setter, context.GetMethodBody(property.Setter), context); visitor.Found |= ScanMethodBody(visitor.TypeDefinition, property.Setter, context.GetMethodBody(property.Setter));
} }
break; break;
case IEvent @event: case IEvent @event:
@event.ReturnType.AcceptVisitor(visitor); @event.ReturnType.AcceptVisitor(visitor);
if (scanBodies && !visitor.Found && @event.CanAdd) if (!visitor.Found && @event.CanAdd)
{ {
if (!visitor.Found) ScanAttributes(visitor, @event.AddAccessor.GetAttributes());
ScanAttributes(visitor, @event.AddAccessor.GetAttributes());
if (!visitor.Found) if (!visitor.Found)
ScanAttributes(visitor, @event.AddAccessor.GetReturnTypeAttributes()); ScanAttributes(visitor, @event.AddAccessor.GetReturnTypeAttributes());
if (!visitor.Found)
ScanMethodBody(visitor, @event.AddAccessor, context.GetMethodBody(@event.AddAccessor), context); visitor.Found |= ScanMethodBody(visitor.TypeDefinition, @event.AddAccessor, context.GetMethodBody(@event.AddAccessor));
} }
if (scanBodies && !visitor.Found && @event.CanRemove) if (!visitor.Found && @event.CanRemove)
{ {
if (!visitor.Found) ScanAttributes(visitor, @event.RemoveAccessor.GetAttributes());
ScanAttributes(visitor, @event.RemoveAccessor.GetAttributes());
if (!visitor.Found) if (!visitor.Found)
ScanAttributes(visitor, @event.RemoveAccessor.GetReturnTypeAttributes()); ScanAttributes(visitor, @event.RemoveAccessor.GetReturnTypeAttributes());
if (!visitor.Found)
ScanMethodBody(visitor, @event.RemoveAccessor, context.GetMethodBody(@event.RemoveAccessor), context); visitor.Found |= ScanMethodBody(visitor.TypeDefinition, @event.RemoveAccessor, context.GetMethodBody(@event.RemoveAccessor));
} }
if (scanBodies && !visitor.Found && @event.CanInvoke) if (!visitor.Found && @event.CanInvoke)
{ {
if (!visitor.Found) ScanAttributes(visitor, @event.InvokeAccessor.GetAttributes());
ScanAttributes(visitor, @event.InvokeAccessor.GetAttributes());
if (!visitor.Found) if (!visitor.Found)
ScanAttributes(visitor, @event.InvokeAccessor.GetReturnTypeAttributes()); ScanAttributes(visitor, @event.InvokeAccessor.GetReturnTypeAttributes());
if (!visitor.Found)
ScanMethodBody(visitor, @event.InvokeAccessor, context.GetMethodBody(@event.InvokeAccessor), context); visitor.Found |= ScanMethodBody(visitor.TypeDefinition, @event.InvokeAccessor, context.GetMethodBody(@event.InvokeAccessor));
} }
break; break;
} }
} }
void ScanMethodBody(TypeDefinitionUsedVisitor visitor, IMethod method, MethodBodyBlock methodBody, AnalyzerContext context) bool ScanMethodBody(ITypeDefinition analyzedType, IMethod method, MethodBodyBlock methodBody)
{ {
if (methodBody == null) if (methodBody == null)
return; return false;
var module = (MetadataModule)method.ParentModule; var module = (MetadataModule)method.ParentModule;
var metadata = module.PEFile.Metadata; var metadata = module.PEFile.Metadata;
var genericContext = new Decompiler.TypeSystem.GenericContext(); // type parameters don't matter for this analyzer var decoder = new FindTypeDecoder(module, analyzedType);
var decoder = new FindTypeDecoder(module, visitor.TypeDefinition);
if (!methodBody.LocalSignature.IsNil) if (!methodBody.LocalSignature.IsNil)
{ {
try try
{ {
var ss = metadata.GetStandaloneSignature(methodBody.LocalSignature); var ss = metadata.GetStandaloneSignature(methodBody.LocalSignature);
visitor.Found |= HandleStandaloneSignature(ss); if (HandleStandaloneSignature(ss))
{
return true;
}
} }
catch (BadImageFormatException) catch (BadImageFormatException)
{ {
@ -246,7 +240,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
var blob = methodBody.GetILReader(); var blob = methodBody.GetILReader();
while (!visitor.Found && blob.RemainingBytes > 0) while (blob.RemainingBytes > 0)
{ {
var opCode = blob.DecodeOpCode(); var opCode = blob.DecodeOpCode();
switch (opCode.GetOperandType()) switch (opCode.GetOperandType())
@ -256,9 +250,8 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
case OperandType.Sig: case OperandType.Sig:
case OperandType.Tok: case OperandType.Tok:
case OperandType.Type: case OperandType.Type:
HandleMember(MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32())); if (HandleMember(MetadataTokenHelpers.EntityHandleOrNil(blob.ReadInt32())))
if (visitor.Found) return true;
return;
break; break;
default: default:
blob.SkipOperand(opCode); blob.SkipOperand(opCode);
@ -266,75 +259,79 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
} }
} }
void HandleMember(EntityHandle member) return false;
bool HandleMember(EntityHandle member)
{ {
if (member.IsNil) if (member.IsNil)
return; return false;
switch (member.Kind) switch (member.Kind)
{ {
case HandleKind.TypeReference: case HandleKind.TypeReference:
visitor.Found |= decoder.GetTypeFromReference(metadata, (TypeReferenceHandle)member, 0); return decoder.GetTypeFromReference(metadata, (TypeReferenceHandle)member, 0);
break;
case HandleKind.TypeSpecification: case HandleKind.TypeSpecification:
visitor.Found |= decoder.GetTypeFromSpecification(metadata, default, (TypeSpecificationHandle)member, 0); return decoder.GetTypeFromSpecification(metadata, default, (TypeSpecificationHandle)member, 0);
break;
case HandleKind.TypeDefinition: case HandleKind.TypeDefinition:
visitor.Found |= decoder.GetTypeFromDefinition(metadata, (TypeDefinitionHandle)member, 0); return decoder.GetTypeFromDefinition(metadata, (TypeDefinitionHandle)member, 0);
break;
case HandleKind.FieldDefinition: case HandleKind.FieldDefinition:
var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)member); var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)member);
HandleMember(fd.GetDeclaringType()); return HandleMember(fd.GetDeclaringType()) || fd.DecodeSignature(decoder, default);
visitor.Found |= fd.DecodeSignature(decoder, default);
break;
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
var md = metadata.GetMethodDefinition((MethodDefinitionHandle)member); var md = metadata.GetMethodDefinition((MethodDefinitionHandle)member);
HandleMember(md.GetDeclaringType()); if (HandleMember(md.GetDeclaringType()))
return true;
var msig = md.DecodeSignature(decoder, default); var msig = md.DecodeSignature(decoder, default);
visitor.Found |= msig.ReturnType; if (msig.ReturnType)
return true;
foreach (var t in msig.ParameterTypes) foreach (var t in msig.ParameterTypes)
{ {
visitor.Found |= t; if (t)
return true;
} }
break; break;
case HandleKind.MemberReference: case HandleKind.MemberReference:
var mr = metadata.GetMemberReference((MemberReferenceHandle)member); var mr = metadata.GetMemberReference((MemberReferenceHandle)member);
HandleMember(mr.Parent); if (HandleMember(mr.Parent))
return true;
switch (mr.GetKind()) switch (mr.GetKind())
{ {
case MemberReferenceKind.Method: case MemberReferenceKind.Method:
msig = mr.DecodeMethodSignature(decoder, default); msig = mr.DecodeMethodSignature(decoder, default);
visitor.Found |= msig.ReturnType; if (msig.ReturnType)
return true;
foreach (var t in msig.ParameterTypes) foreach (var t in msig.ParameterTypes)
{ {
visitor.Found |= t; if (t)
return true;
} }
break; break;
case MemberReferenceKind.Field: case MemberReferenceKind.Field:
visitor.Found |= mr.DecodeFieldSignature(decoder, default); return mr.DecodeFieldSignature(decoder, default);
break;
} }
break; break;
case HandleKind.MethodSpecification: case HandleKind.MethodSpecification:
var ms = metadata.GetMethodSpecification((MethodSpecificationHandle)member); var ms = metadata.GetMethodSpecification((MethodSpecificationHandle)member);
HandleMember(ms.Method); if (HandleMember(ms.Method))
return true;
var mssig = ms.DecodeSignature(decoder, default); var mssig = ms.DecodeSignature(decoder, default);
foreach (var t in mssig) foreach (var t in mssig)
{ {
visitor.Found |= t; if (t)
return true;
} }
break; break;
case HandleKind.StandaloneSignature: case HandleKind.StandaloneSignature:
var ss = metadata.GetStandaloneSignature((StandaloneSignatureHandle)member); var ss = metadata.GetStandaloneSignature((StandaloneSignatureHandle)member);
visitor.Found |= HandleStandaloneSignature(ss); return HandleStandaloneSignature(ss);
break;
} }
return false;
} }
bool HandleStandaloneSignature(StandaloneSignature signature) bool HandleStandaloneSignature(StandaloneSignature signature)
@ -350,7 +347,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (t) if (t)
return true; return true;
} }
return false; break;
case StandaloneSignatureKind.LocalVariables: case StandaloneSignatureKind.LocalVariables:
var sig = signature.DecodeLocalSignature(decoder, default); var sig = signature.DecodeLocalSignature(decoder, default);
foreach (var t in sig) foreach (var t in sig)
@ -358,10 +355,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
if (t) if (t)
return true; return true;
} }
return false; break;
default:
return false;
} }
return false;
} }
} }

Loading…
Cancel
Save