public void VisitEnd(EndMethods end) { string details = string.Empty; if (m_disposeMethod != null && !m_hasBaseCall) { MethodDefinition pmethod = m_disposeMethod.GetBasestMethod(Cache); if (pmethod != null && pmethod != m_disposeMethod && !pmethod.IsAbstract) { details += "Dispose(bool) does not call base.Dispose(bool)" + Environment.NewLine; } } if (m_hasFinalizer) { details += "Type has a finalizer" + Environment.NewLine; } // if (m_disposable && end.Type.TypeImplements("System.IDisposable")) // details += "Type re-implements IDisposable" + Environment.NewLine; if (m_hasDispose) { details += "Type has a Dispose() method" + Environment.NewLine; } details = details.Trim(); if (details.Length > 0) { Log.DebugLine(this, "Details: {0}", details); Reporter.TypeFailed(end.Type, CheckID, details); } }
public void VisitEnd(EndMethods end) { string details = string.Empty; foreach (Property prop in m_properties) { if (prop.HasTrivialGetter && prop.HasTrivialSetter) { foreach (EqualityMethod method in m_equalities) { if (method.ChecksSomething) { if (!method.ChecksField(prop.Field) && !method.ChecksProp(prop.Name)) { details += string.Format("{0} does not check {1}", method.Name, prop.Name) + Environment.NewLine; } } } } } details = details.Trim(); if (details.Length > 0) { Log.DebugLine(this, "Details: {0}", details); Reporter.TypeFailed(end.Type, CheckID, details); } }
public void VisitEnd(EndMethods end) { if (m_notSerializable && m_hasMethod) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
public void VisitEnd(EndMethods end) { if (m_fields.Count > 0) { string details = "Fields: " + string.Join(" ", m_fields.ToArray()); Log.DebugLine(this, "{0}", details); Reporter.TypeFailed(end.Type, CheckID, details); } }
public void VisitEnd(EndMethods end) { if (m_names.Count >= 5) { m_names.Sort(); string details = "Names: " + string.Join(" ", m_names.ToArray()); Log.DebugLine(this, details); Reporter.TypeFailed(end.Type, CheckID, details); } }
public void VisitEnd(EndMethods end) { Log.DebugLine(this, " {0} types", m_types.Count); if (m_types.Count >= m_maxTypes) { Log.TraceLine(this, "{0} references {1} types:", m_type.FullName, m_types.Count); foreach (string type in m_types) { Log.TraceLine(this, " {0}", type); } string details = string.Format("references {0} types", m_types.Count); Reporter.TypeFailed(end.Type, CheckID, details); } }
public void VisitEnd(EndMethods end) { if (m_needsCheck) { Log.DebugLine(this, "Initial partition:"); foreach (Partition p in m_partitions) { Log.DebugLine(this, "{0}", p); } Log.DebugLine(this, " "); DoCoalesce(); DoClean(); Log.DebugLine(this, "Final partition:"); foreach (Partition p in m_partitions) { Log.DebugLine(this, "{0}", p); } List <Partition> bad = new List <Partition>(); foreach (Partition p in m_partitions) { if (p.Fields.Count >= 3 && p.Methods.Count >= 3 && !p.HasVirtual()) { bad.Add(p); } } if (bad.Count >= 2) { StringBuilder b = new StringBuilder(); foreach (Partition p in bad) { if (p == bad[bad.Count - 1]) { b.Append(p.ToString()); } else { b.AppendLine(p.ToString()); } } Reporter.TypeFailed(end.Type, CheckID, b.ToString()); } } }
public void VisitEnd(EndMethods end) { if (m_foundEquals) { // for (int i = 0; i < end.Type.Interfaces.Count; ++i) // { // TypeReference t = end.Type.Interfaces[i]; // Log.DebugLine(this, "implements: {0}", t.FullName); // } if (!end.Type.TypeImplements("System.IEquatable")) { Log.DebugLine(this, "doesn't implement IEquatable"); Reporter.TypeFailed(end.Type, CheckID, string.Empty); } } }
public void VisitEnd(EndMethods end) { if (m_disposable) { string details = string.Empty; if (!m_hasUnaryDispose) // DisposableRule will verify protected and virtual { details += "The type is unsealed, but does not have Dispose(bool)." + Environment.NewLine; } details = details.Trim(); if (details.Length > 0) { Log.DebugLine(this, "Details: {0}", details); Reporter.TypeFailed(end.Type, CheckID, details); } } }
public void VisitEnd(EndMethods end) { string details = string.Empty; foreach (FieldDefinition field in m_fields) { Entry entry = m_table[field]; if (entry.FoundAdd && !entry.FoundRemove) { details = details + field.Name + " "; } } if (details.Length > 0) { details = "Fields: " + details; Log.DebugLine(this, "{0}", details); Reporter.TypeFailed(end.Type, CheckID, details); } }
public void VisitEnd(EndMethods end) { Unused.Value = end; foreach (KeyValuePair <int, List <CodeBlock> > entry in m_table) { Log.DebugLine(this, "there are {0} blocks of length {1}", entry.Value.Count, entry.Key); while (entry.Value.Count > 1) { string details = string.Empty; CodeBlock block = entry.Value[0]; for (int i = 1; i < entry.Value.Count;) { if (DoMatch(entry.Value[0], entry.Value[i], entry.Key)) { details += entry.Value[i].Method.ToString() + " "; DoSanitize(entry.Value[i].Method); } else { ++i; } } if (details.Length > 0) { details = "Match: " + details; Log.DebugLine(this, details); int offset = block.Instructions[block.Index].Untyped.Offset; Reporter.MethodFailed(block.Method, CheckID, offset, details); } DoSanitize(block.Method); } } }
private void DoCheckMethods(AssemblyCache cache, string[] onlyType) { Profile.Start("CheckMethods"); foreach (KeyValuePair <TypeDefinition, List <MethodInfo> > entry in cache.TypeMethods) { if (DoNameNeedsCheck(entry.Key.FullName, onlyType)) { BeginMethods begin = new BeginMethods(entry.Key); m_checker.Dispatcher.Dispatch(begin); foreach (MethodInfo method in entry.Value) { m_checker.Check(method); } EndMethods end = new EndMethods(entry.Key); m_checker.Dispatcher.Dispatch(end); } } Profile.Stop("CheckMethods"); }
public void VisitEnds(EndMethods end) { m_table.Add(end.Type, m_current); m_current = null; }
public void VisitEnd(EndMethods end) { if (m_disposable) { string details = string.Empty; if (m_noThrowMethods.Length > 0) { details += "Methods which don't throw ObjectDisposedException: " + Environment.NewLine; details += m_noThrowMethods; } if (m_badDisposeNames.Count > 0) { details += "Unusual Dispose methods: "; details += string.Join(" ", m_badDisposeNames.ToArray()); details += Environment.NewLine; } if (m_illegalDisposeNames.Count > 0) { details += "Bad method names: "; details += string.Join(" ", m_illegalDisposeNames.ToArray()); details += Environment.NewLine; } if (m_hasVirtualDispose) { details += "Dispose() is virtual" + Environment.NewLine; } if (m_hasPublicDispose) { details += "Dispose(bool) is public." + Environment.NewLine; } if (m_hasNonProtectedDispose) { details += "The type is unsealed, but Dispose(bool) is not protected." + Environment.NewLine; } if (m_hasNonVirtualDispose) { details += "The type is unsealed, but Dispose(bool) is not virtual." + Environment.NewLine; } if (m_disposeThrows) { details += "A Dispose methods throws, but does not catch." + Environment.NewLine; } if (m_disposableFields.Count > 0) { StringBuilder builder = new StringBuilder(); builder.Append("Fields which are not disposed: "); foreach (string field in m_disposableFields) { int i = field.LastIndexOf(':'); if (i >= 0) { builder.Append(field.Substring(i + 1)); } else { builder.Append(field); } builder.Append(' '); } details += builder.ToString() + Environment.NewLine; } if (m_hasFinalizer && !m_supressWasCalled) { details += "GC.SuppressFinalize was not called" + Environment.NewLine; } if (m_hasNativeFields && m_type.IsValueType) { details += "The type is a value type, but has native fields." + Environment.NewLine; } if (m_hasNullCall) { details += "Dispose calls a method on a field which may be null (because the constructor may have thrown)." + Environment.NewLine; } details = details.Trim(); if (details.Length > 0) { Log.DebugLine(this, "Details: {0}", details); Reporter.TypeFailed(end.Type, CheckID, details); } } }