Beispiel #1
0
        private bool DoLeftHidesRight(MethodReference left, MethodReference right)
        {
            DBC.Assert(left.Name == right.Name, "names don't match");

            bool hides = false;

            if (left.Parameters.Count == right.Parameters.Count)
            {
                int count = 0;
                for (int i = 0; i < left.Parameters.Count && count >= 0; ++i)
                {
                    TypeReference leftType  = left.Parameters[i].ParameterType;
                    TypeReference rightType = right.Parameters[i].ParameterType;

                    if (leftType.MetadataToken != rightType.MetadataToken)
                    {
                        if (rightType.IsSubclassOf(leftType, Cache))
                        {
                            ++count;
                        }
                        else
                        {
                            count = -1;                                                                 // left types have to all be equal or a base class of right
                        }
                    }
                }

                hides = count > 0;
            }

            return(hides);
        }
        public void VisitBegin(BeginType begin)
        {
            DBC.Assert(!m_checkingCalls, "VisitBegin was called after we started visiting calls");

            // If the class is internal,
            if (begin.Type.IsNotPublic || begin.Type.IsNestedAssembly || begin.Type.IsNestedFamilyAndAssembly)
            {
                Log.DebugLine(this, "-----------------------------------");
                Log.DebugLine(this, "{0}", begin.Type);

                // and it directly implements one or more public interfaces,
                int count = DoCountInterfaces(begin.Type);
                if (count > 0)
                {
                    // then build a list of all the non-private/protected methods
                    // in the class that were not declared in an interface.
                    foreach (MethodDefinition method in begin.Type.Methods)
                    {
                        if (!method.IsPrivate && !method.IsFamily)
                        {
                            if (!method.IsConstructor)
                            {
                                TypeReference t = method.GetDeclaredIn(Cache);
                                if (t == begin.Type)
                                {
                                    Log.DebugLine(this, "   adding {0}", method.Name);
                                    m_candidates.Add(method, new Info(begin.Type));
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        public static string ColorizeCode(string code)
        {
            string result = ms_codeRE.Replace(code, match =>
            {
                if (match.Groups[1].Length > 0)
                {
                    return("<span class = \"comment\">" + match.Groups[1].Value + "</span>");
                }

                else if (match.Groups[2].Length > 0)
                {
                    return("<span class = \"string\">" + match.Groups[2].Value + "</span>");
                }

                DBC.Assert(match.Groups[3].Length > 0, "expected a keyword match");
                if (Array.IndexOf(ms_keywords, match.Groups[3].Value) >= 0)
                {
                    return("<span class = \"keyword\">" + match.Groups[3].Value + "</span>");
                }
                else
                {
                    return(match.Groups[3].Value);
                }
            });

            return(result);
        }
Beispiel #4
0
        private bool DoMatches(int base1, int base2, int count)
        {
            DBC.Assert(count >= 0, "count is negative ({0})", count);

            bool match = true;

            Log.DebugLine(this, "checking {0} instructions at {1:X2} and {2:X2}", count, m_info.Instructions[base1].Untyped.Offset, m_info.Instructions[base2].Untyped.Offset);

            for (int i = 0; i < count && match; ++i)
            {
                Instruction i1 = m_info.Instructions[base1 + i].Untyped;
                Instruction i2 = m_info.Instructions[base2 + i].Untyped;

                if (!i1.Matches(i2))
                {
                    match = false;
                    Log.DebugLine(this, "   {0} != {1}", m_info.Instructions[base1 + i], m_info.Instructions[base2 + i]);
                }
            }

            if (match)
            {
                Log.DebugLine(this, "   matches");
            }

            return(match);
        }
Beispiel #5
0
        /// <summary>Check an assembly and return an array of violations.</summary>
        /// <remarks>OnlyType is used to check only the types that contain a string in the array which may be null.
        /// Severity is the minimum rule severity to use. IgnoreBreaks is true if we want to
        /// ignore rules that break binary compatibility. Note that this should only be called once:
        /// if you want to smoke multiple assemblies create a new AnalyzeAssembly object.</remarks>
        public Error[] Analyze(string imagePath, string[] onlyType, Severity severity, bool ignoreBreaks)
        {
            DBC.Assert(!m_analyzed, "Analyze can only be called once");                 // TODO: would be nice to relax this, maybe add an overload to allow another assembly to be checked with the same settings
            m_analyzed = true;

            Profile.Start("AssemblyFactory");
            AssemblyDefinition assemblyDef = AssemblyFactory.GetAssembly(imagePath);

            Profile.Stop("AssemblyFactory");

            string path = Path.GetFullPath(imagePath);                  // need to add a cecil search directory so that it finds assemblies in the same directory as the assembly we're checking
            string dir  = Path.GetDirectoryName(path);
            BaseAssemblyResolver resolver = assemblyDef.Resolver as BaseAssemblyResolver;

            DBC.Assert(resolver != null, "assemblyDef.Resolver isn't a BaseAssemblyResolver");
            resolver.AddSearchDirectory(dir);

            m_symbols = new SymbolTable();
            AssemblyCache cache = new AssemblyCache(m_symbols, assemblyDef, m_callback);

            var assembly = System.Reflection.Assembly.GetExecutingAssembly();

            m_checker.LoadRules(assembly, cache, severity, ignoreBreaks);

            Error[] errors = DoCheckAssembly(assemblyDef, cache, onlyType);

            return(errors);
        }
Beispiel #6
0
        private TypeReference DoConsolidateTypes(List <TypeReference> types)
        {
            DBC.Assert(types.Count > 1, "can only consolidate multiple types");

            TypeReference current = types[0];

            return(DoConsolidateTypes(types, current, 1));
        }
Beispiel #7
0
        public void Init(AssemblyCache cache, List <Error> errors)
        {
            DBC.Assert(cache != null, "cache is null");
            DBC.Assert(errors != null, "errors is null");

            m_cache  = cache;
            m_errors = errors;
        }
Beispiel #8
0
        public void VisitInitObj(InitObj init)
        {
            DBC.Assert(m_state == State.Calls, "state is {0}", m_state);

            if (m_types.Count > 0)
            {
                DoRemoveTypes(init.Type);
            }
        }
Beispiel #9
0
        public void VisitNewObj(NewObj newobj)
        {
            DBC.Assert(m_state == State.Calls, "state is {0}", m_state);

            if (m_types.Count > 0)
            {
                DoRemoveTypes(newobj.Ctor.DeclaringType);
            }
        }
Beispiel #10
0
 private void DoSanityTest()
 {
     foreach (Option option in m_options.Values)
     {
         foreach (string name in option.Names)
         {
             Option result = DoFind(name);                       // make sure no two options are ambiguous
             DBC.Assert(result != null, "expected to find {0}", name);
         }
     }
 }
Beispiel #11
0
        public void LoadRules(System.Reflection.Assembly assembly, AssemblyCache cache, Severity severity, bool ignoreBreaks)
        {
            DBC.Assert(cache != null, "cache is null");

            Profile.Start("LoadRules");
            int count = DoLoadRules(assembly, cache, severity, ignoreBreaks);

            DoCheckXml();
            count += DoLoadCustomRules(cache, severity, ignoreBreaks);
            Profile.Stop("LoadRules");

            Log.InfoLine(this, "loaded {0} rules (although not all may be used)", count);
        }
Beispiel #12
0
        // call  System.Void Smokey.Tests.NotInstantiatedTest/Tuple2`2<T0,T1>::.ctor(T0,T1)
        public void VisitCall(Call call)
        {
            DBC.Assert(m_state == State.Calls, "state is {0}", m_state);

            if (m_types.Count > 0)
            {
                MethodInfo info = Cache.FindMethod(call.Target);
                if (info != null && info.Method.IsConstructor)
                {
                    DoRemoveTypes(info.Method.DeclaringType);
                }
            }
        }
Beispiel #13
0
        public void VisitEndTypes(EndTypes end)
        {
            Unused.Value = end;

            DBC.Assert(m_state == State.Types, "state is {0}", m_state);

            Log.DebugLine(this, "-------------");
            Log.DebugLine(this, "VisitEndTypes");

            m_types.AddRange(m_keys.Select(k => k.Type.FullName));
            m_types.Sort();
            m_state = State.Calls;
        }
Beispiel #14
0
                private static long?[] DoMeetVars(long?[] lhs, long?[] rhs)
                {
                    DBC.Assert(lhs.Length == rhs.Length, "lengths don't match");

                    long?[] result = new long?[lhs.Length];

                    for (int i = 0; i < lhs.Length; ++i)
                    {
                        result[i] = DoMeet(lhs[i], rhs[i]);
                    }

                    return(result);
                }
Beispiel #15
0
        private void DoGetMethods(AssemblyDefinition assembly, List <MethodInfo> methods, string[] names, bool allowEmpty)
        {
            string testName = GetType().FullName;

            DBC.Assert(names.Distinct().Count() == names.Length, "duplicate name in " + string.Join(", ", names));

            foreach (string name in names)
            {
                string[] parts = name.Split('.');
                DBC.Assert(parts.Length == 2, "{0} should be of the form 'test.method'", name);

                string         caseType = parts[0];
                string         fullName = string.Format("{0}/{1}", testName, caseType);
                TypeDefinition type     = assembly.MainModule.Types[fullName];
                DBC.Assert(type != null, "null type from {0}", fullName);

                string caseMethod = parts[1];
                if (caseMethod.Length > 0)
                {
                    if (caseMethod == caseType)
                    {
                        DBC.Assert(type.Constructors.Count > 0, "expected a ctor, but {0} has no ctors", caseType);

                        foreach (MethodDefinition method in type.Constructors)
                        {
                            methods.Add(new MethodInfo(type, method));
                        }
                    }
                    else
                    {
                        MethodDefinition[] defs = type.Methods.GetMethod(caseMethod);
                        DBC.Assert(defs.Length == 1, "expected 1 method, but {0} has {1} methods", caseType + "::" + caseMethod, defs.Length);
                        methods.Add(new MethodInfo(type, defs[0]));
                    }
                }
                else
                {
                    DBC.Assert(allowEmpty, "{0} needs a method name", name);

                    foreach (MethodDefinition method in type.Constructors)
                    {
                        methods.Add(new MethodInfo(type, method));
                    }

                    foreach (MethodDefinition method in type.Methods)
                    {
                        methods.Add(new MethodInfo(type, method));
                    }
                }
            }
        }
Beispiel #16
0
        private TypeReference DoConsolidateTypes(List <TypeReference> types, TypeReference current, int i)
        {
            DBC.Assert(i > 0, "can't have current with zero index");
            DBC.Assert(i < types.Count, "i is out of range");

            TypeReference result = current.CommonClass(types[i], Cache);

            if (i + 1 < types.Count && result != null)
            {
                result = DoConsolidateTypes(types, result, i + 1);
            }

            return(result);
        }
Beispiel #17
0
        // This is visited after methods.
        public void VisitFini(EndTesting end)
        {
            Unused.Value = end;

            DBC.Assert(m_state == State.Calls, "state is {0}", m_state);
            m_state = State.End;

            if (m_types.Count > 0)
            {
                string details = "Unused: " + string.Join(Environment.NewLine, m_types.ToArray());
                Log.DebugLine(this, details);

                Reporter.AssemblyFailed(Cache.Assembly, CheckID, details);
            }
        }
Beispiel #18
0
        private void DoGetUsed(AssemblyDefinition assembly, List <TypeDefinition> types, string[] names)
        {
            string testName = GetType().FullName;

            foreach (string name in names)
            {
                DBC.Assert(name.IndexOf('.') < 0, "{0} has a method", name);

                string         fullName = string.Format("{0}/{1}", testName, name);
                TypeDefinition type     = assembly.MainModule.Types[fullName];
                DBC.Assert(type != null, "Couldn't find {0}", fullName);

                types.Add(type);
            }
        }
Beispiel #19
0
        // Returns the smallest number k such that the instructions in
        // [offset - k, offset] push a single value onto the stack.
        private int DoGetPushRange(MethodInfo info, int offset)
        {
            int delta = DoGetStackDelta(info.Instructions[offset]);

            int k = 0;

            while (delta <= 0 && offset - k >= 0)
            {
                ++k;
                delta += DoGetStackDelta(info.Instructions[offset - k]);
            }

            DBC.Assert(offset - k >= 0, "couldn't find the range");

            return(k);
        }
Beispiel #20
0
        // Note that using reflection is roughly 6x faster than using a thunk.
        // It'd be slicker to register the methods via attributes but that would
        // be quite a bit slower...
        public void Register <T>(T rule, string method) where T : Rule
        {
#if DEBUG
            Rule r;
            if (m_registered.TryGetValue(rule.CheckID, out r))
            {
                DBC.Assert(rule.Equals(r), "multiple rules have id {0}", rule.CheckID);
            }
            else
            {
                m_registered.Add(rule.CheckID, rule);
            }
#endif

            Register(rule, method, rule.GetType().Name, rule.CheckID);
        }
Beispiel #21
0
        public void VisitType(TypeDefinition type)
        {
            DBC.Assert(m_state == State.Types, "state is {0}", m_state);
            Log.DebugLine(this, "{0}", type.FullName);

            if (!type.ExternallyVisible(Cache) && DoInstantiable(type) && DoValidType(type))
            {
                if (!type.IsCompilerGenerated())
                {
                    var key = new AssemblyCache.TypeKey(type);
                    DBC.Assert(m_keys.IndexOf(key) < 0, "{0} is already in types", type.FullName);
                    Log.DebugLine(this, "adding {0}", type.FullName);

                    m_keys.Add(key);
                }
            }
        }
Beispiel #22
0
        public void TypeFailed(TypeDefinition type, string checkID, string details)
        {
            if (!type.CustomAttributes.HasDisableRule(checkID))
            {
                DBC.Assert(m_cache != null, "m_cache is null");
                DBC.Assert(m_cache.Symbols != null, "m_cache.Symbols is null");
                DBC.Assert(type != null, "type is null");
                DBC.Assert(details != null, "details is null");

                Location  location  = m_cache.Symbols.Location(type, details);
                Violation violation = ViolationDatabase.Get(checkID);
                DBC.Assert(violation != null, "violation is null");
                DBC.Assert(m_errors != null, "m_errors is null");

                m_errors.Add(new Error(location, violation));
            }
        }
Beispiel #23
0
        private static void DoViolation(XmlNode violation)
        {
            string   checkID  = violation.Attributes["checkID"].Value;
            Severity severity = (Severity)Enum.Parse(typeof(Severity), violation.Attributes["severity"].Value);
            bool     breaking = violation.Attributes["breaking"].Value.ToLower() == "true";

            foreach (XmlNode child in violation.ChildNodes)
            {
                if (child.Name == "Translation")
                {
                    // Get the next translation.
                    Entry entry = DoTranslation(child, checkID, severity, breaking);

#if DEBUG
                    // Make sure it's not a duplicate of one we've seen already.
                    string key = string.Format("{0}/{1}", checkID, entry.Lang);

                    int i = ms_checkIDs.BinarySearch(key);
                    if (i < 0)
                    {
                        ms_checkIDs.Insert(~i, key);
                    }
                    else
                    {
                        DBC.Assert(false, "{0} is already defined", key);
                    }
#endif

                    // If the checkID is new, or the language is better than
                    // our current translation use the new translation.
                    int index = ms_entries.BinarySearch(entry);
                    if (index < 0)
                    {
                        Log.DebugLine(true, "adding {0}", checkID);
                        ms_entries.Insert(~index, entry);
                    }
                    else if (DoLeftIsBetter(entry, ms_entries[index]))
                    {
                        Log.DebugLine(true, "overriding {0} ({1} is better than {2})", checkID, entry.Lang, ms_entries[index].Lang);
                        ms_entries[index] = entry;
                    }
                }
            }
        }
Beispiel #24
0
        /// <summary>Split the string based on capitalization changes.</summary>
        /// <remarks>So, "inName" becomes ["in", "Name"].</remarks>
        public static string[] CapsSplit(this string str)
        {
            DBC.Pre(str != null, "str is null");

            List <string> parts = new List <string>();

            int index = 0;

            while (index < str.Length)
            {
                int count = DoFindCapsRun(str, index);
                DBC.Assert(count > 0, "count is {0}", count);

                parts.Add(str.Substring(index, count));
                index += count;
            }

            return(parts.ToArray());
        }
Beispiel #25
0
        private Option DoFind(string arg)
        {
            DBC.Assert(!string.IsNullOrEmpty(arg), "null or empty arg");

            Option        result  = null;
            int           best    = -1;
            List <string> matches = new List <string>();

            foreach (Option option in m_options.Values)
            {
                string alias;
                int    num = option.Match(arg, out alias);

                if (num > 0 && num >= best)
                {
                    if (num > best)
                    {
                        best = num;
                        matches.Clear();
                    }

                    result = option;
                    matches.Add(alias);
                }
            }

            if (result == null)
            {
                throw new MalformedCommandLineException(arg + " is not a valid option");
            }

            if (matches.Count > 1)
            {
                string mesg = string.Format("{0} matches the {1} options", arg, string.Join(", ", matches.ToArray()));
                throw new MalformedCommandLineException(mesg);
            }

            return(result);
        }
Beispiel #26
0
        private Dictionary <int, BasicBlock> DoGetUnwiredBlocks(TypedInstructionCollection instructions)
        {
            // First get a list of all the instructions which start a block.
            List <int> leaders = DoGetLeaders(instructions);

            // Sort them so we can efficiently pop them off the list.
            leaders.Sort();
            Log.TraceLine(this, "Leaders: {0}", DoTargetsToString(instructions, leaders));
            leaders.Reverse();

            // And form the basic blocks by starting at the first leader and
            // accumulating instructions until we hit another leader.
            Dictionary <int, BasicBlock> blocks = new Dictionary <int, BasicBlock>();

            while (leaders.Count > 0)
            {
                int first = leaders[leaders.Count - 1];
                leaders.RemoveAt(leaders.Count - 1);

                BasicBlock block;
                if (leaders.Count > 0)
                {
                    int last = leaders[leaders.Count - 1];
                    DBC.Assert(first < last, "Leader {0} should be before {1}", first, last);

                    block = new BasicBlock(instructions[first], instructions[last - 1]);
                }
                else
                {
                    block = new BasicBlock(instructions[first], instructions[instructions.Length - 1]);
                }

                blocks.Add(first, block);
                Log.DebugLine(this, "Added block: {0}", block);
            }

            return(blocks);
        }
Beispiel #27
0
        private void DoGetTypes(List <List <TypeDefinition> > types, string[] names)
        {
            DBC.Assert(names.Distinct().Count() == names.Length, "duplicate name in " + string.Join(", ", names));

            string testName = GetType().FullName;

            foreach (string composed in names)
            {
                string[] compose = composed.Split('+');

                List <TypeDefinition> inner = new List <TypeDefinition>();
                foreach (string name in compose)
                {
                    string         fullName = string.Format("{0}/{1}", testName, name);
                    TypeDefinition type     = Assembly.MainModule.Types[fullName];
                    DBC.Assert(type != null, "Couldn't find {0}", fullName);

                    inner.Add(type);
                }

                types.Add(inner);
            }
        }
Beispiel #28
0
        private void DoGetEvents(AssemblyDefinition assembly, List <EventDefinition> events, string[] names)
        {
            string testName = GetType().FullName;

            foreach (string name in names)
            {
                string[] parts = name.Split('.');
                DBC.Assert(parts.Length == 2, "{0} should be of the form 'test.event'", name);

                string         caseType = parts[0];
                string         fullName = string.Format("{0}/{1}", testName, caseType);
                TypeDefinition type     = assembly.MainModule.Types[fullName];
                DBC.Assert(type != null, "null type from {0}", fullName);

                string caseEvent = parts[1];
                DBC.Assert(caseEvent.Length > 0, "{0} has no event part", name);

                EventDefinition evt = type.Events.GetEvent(caseEvent);
                DBC.Assert(evt != null, "couldn't find an event for {0}", caseType + "::" + caseEvent);

                events.Add(evt);
            }
        }
Beispiel #29
0
        public void VisitField(FieldDefinition field)
        {
            if (m_needsCheck && field.IsAssembly && m_type.IsClass)
//			if (m_needsCheck && field.IsAssembly && m_type.IsClass && !m_type.FullName.Contains("PrivateImplementationDetails"))
            {
                if (!m_type.CustomAttributes.HasDisableRule("D1050"))
                {
                    TypeAttributes attrs = m_type.Attributes;
                    if (!m_type.IsValueType || (attrs & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout)
                    {
                        if (m_fields.ContainsKey(field))
                        {
                            DBC.Assert(m_fields[field] == State.Referenced, "state is {0}", m_fields[field]);
                            m_fields[field] = State.Used;
                        }
                        else
                        {
                            m_fields.Add(field, State.Defined);
                        }
                    }
                }
            }
        }
Beispiel #30
0
        [DisableRule("D1042", "IdenticalMethods")]              // TODO: should have a base class for progress and watchdog
        public void Shutdown()
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            lock (m_lock)
            {
                if (m_running)
                {
                    m_running = false;
                    Monitor.PulseAll(m_lock);
                }
            }

            if (m_thread != null)
            {
                bool terminated = m_thread.Join(1000);
                DBC.Assert(terminated, "thread didn't terminate");

                m_thread = null;
            }
        }