Beispiel #1
0
        private void WalkMethod(MetadataReader mdReader, MethodDefinitionHandle handle, MutableSymbol parent)
        {
            MethodDefinition method     = mdReader.GetMethodDefinition(handle);
            MethodAttributes attributes = method.Attributes;
            string           name       = mdReader.GetString(method.Name);

            MutableSymbol result = new MutableSymbol(name, GetMethodType(attributes, name));

            AddModifiers(attributes, result);
            AddLocation(handle, result);
            AddParameters(mdReader, method, result);

            // Make Constructor/Destructors use the type name as the method name [like Ctrl+, search]
            if (result.Type == SymbolType.Constructor || result.Type == SymbolType.StaticConstructor || result.Type == SymbolType.Destructor)
            {
                result.Name = parent.Name.ToString();
            }

            if (IsExcluded(result))
            {
                return;
            }

            parent.AddChild(result);

            // TODO: Identify Extension Methods. Issue: Requires a lot of Blob reading. See http://source.roslyn.io/#q=PEMethodSymbol.IsExtensionMethod, http://source.roslyn.io/#q=PEModule.HasExtensionAttribute
        }
Beispiel #2
0
        private void WalkMethod(IMethodSymbol method, MutableSymbol parent)
        {
            MutableSymbol result = new MutableSymbol(method.AdjustedName(), GetMethodType(method));

            AddModifiers(method, result);
            AddLocation(method, result);

            if (this.IncludeSignatures)
            {
                result.Parameters = method.MinimalParameters();
            }

            if (IsExcluded(method, result))
            {
                return;
            }

            parent.AddChild(result);

            // Add the extended type under Extension Methods
            if (result.Type == SymbolType.ExtensionMethod && method.Parameters.Length > 0)
            {
                IParameterSymbol thisParameter = method.Parameters[0];
                ITypeSymbol      thisType      = thisParameter.Type;
                MutableSymbol    extendedType  = new MutableSymbol(thisType.NamespaceAndName(), SymbolType.ExtendedType);
                extendedType.Modifiers = result.Modifiers;
                result.AddChild(extendedType);
            }
        }
Beispiel #3
0
        private void WalkIncremental(string filePath, MutableSymbol parent)
        {
            // Copy the old database for this binary if it is older than the old index and we find it
            if (this.Previous != null)
            {
                DateTime binaryModifiedUtc = File.GetLastWriteTimeUtc(filePath);
                if (binaryModifiedUtc <= this.PreviousWriteUtc)
                {
                    Symbol oldAssembly;
                    if (TryFindAssembly(Path.GetFileName(filePath), out oldAssembly))
                    {
                        parent.AddTree(oldAssembly);
                        return;
                    }
                    else if (TryFindAssembly(Path.GetFileNameWithoutExtension(filePath), out oldAssembly))
                    {
                        parent.AddTree(oldAssembly);
                        return;
                    }
                }
            }

            // Otherwise, recrawl
            InnerCrawler.Walk(filePath, parent);
        }
Beispiel #4
0
        internal static void AddSampleMembers(PackageDatabase db)
        {
            MutableSymbol packageRoot = db.MutableRoot.AddChild(new MutableSymbol(db.Identity.PackageName, SymbolType.Package));

            AddSampleTypes(packageRoot, NET20, addMemoryType: false);
            AddSampleTypes(packageRoot, NET35, addMemoryType: true);
        }
Beispiel #5
0
        public void Walk(string walkPath, MutableSymbol parent)
        {
            string encodedFrameworkNames = null;

            string[] walkPathTokens = walkPath.Split('\t');

            Debug.Assert(walkPathTokens.Length == 1 || walkPathTokens.Length == 2);

            walkPath = walkPathTokens[0];
            if (walkPathTokens.Length > 1)
            {
                encodedFrameworkNames = walkPathTokens[1];
            }

            // Index the directory|file list|solution|project|binary
            string extension = Path.GetExtension(walkPath).ToLowerInvariant();

            if (FileIO.IsManagedBinary(walkPath))
            {
                WalkBinary(walkPath, parent, encodedFrameworkNames);
            }
            else if (extension.Equals(".sln"))
            {
                WalkSolution(walkPath, parent);
            }
            else if (extension.EndsWith("proj"))
            {
                WalkProject(walkPath, parent);
            }
            else
            {
                throw new ArgumentException(String.Format("RoslynCompilationCrawler doesn't know how to walk item with extension '{0}'", extension));
            }
        }
Beispiel #6
0
 private void WalkProject(string projectPath, MutableSymbol parent)
 {
     using (MSBuildWorkspace workspace = BuildWorkspace())
     {
         // Open Project with Roslyn
         var project = workspace.OpenProjectAsync(projectPath).Result;
         WalkProject(project, parent);
     }
 }
Beispiel #7
0
        private void WalkProject(Project project, MutableSymbol parent)
        {
            // Get the consolidated assembly symbols and walk them
            Compilation     rootCompilation = project.GetCompilationAsync().Result;
            IAssemblySymbol assembly        = rootCompilation.Assembly;

            MutableSymbol assemblyRoot = parent.AddChild(new MutableSymbol(Path.GetFileName(project.OutputFilePath), SymbolType.Assembly));

            WalkNamespace(assembly.GlobalNamespace, assemblyRoot);
        }
Beispiel #8
0
        private void WalkField(IFieldSymbol field, MutableSymbol parent)
        {
            MutableSymbol result = new MutableSymbol(field.Name, GetFieldType(field));

            AddModifiers(field, result);
            AddLocation(field, result);

            if (!IsExcluded(field, result))
            {
                parent.AddChild(result);
            }
        }
Beispiel #9
0
        private static void AddSampleTypes(MutableSymbol packageRoot, string frameworkTargets, bool addMemoryType)
        {
            string fx = frameworkTargets.ToFrameworkNames().First();

            MutableSymbol assembly        = packageRoot.AddChild(new MutableSymbol(DLL_NAME, SymbolType.Assembly));
            MutableSymbol frameworkTarget = assembly.AddChild(new MutableSymbol(frameworkTargets, SymbolType.FrameworkTarget));
            MutableSymbol sample          = frameworkTarget.AddChild(new MutableSymbol(NS_SAMPLE, SymbolType.Namespace));
            MutableSymbol diagnostics     = sample.AddChild(new MutableSymbol(NS_DIAGNOSTICS, SymbolType.Namespace));
            MutableSymbol logger          = diagnostics.AddChild(new MutableSymbol(TYPE_LOGGER, SymbolType.Class)
            {
                Modifiers = SymbolModifier.Public, FilePath = @"src\" + fx + @"\Diagnostics\Logger.cs", Line = 8, CharInLine = 18
            });

            logger.AddChild(new MutableSymbol(TYPE_LOGGER, SymbolType.Constructor)
            {
                Modifiers = SymbolModifier.Public, Parameters = "string", FilePath = @"src\" + fx + @"\Diagnostics\Logger.cs", Line = 22, CharInLine = 16
            });
            logger.AddChild(new MutableSymbol("LogUse", SymbolType.Method)
            {
                Modifiers = SymbolModifier.Public, FilePath = @"src\" + fx + @"\Diagnostics\Logger.cs", Line = 32, CharInLine = 21
            });
            logger.AddChild(new MutableSymbol("LogException", SymbolType.Method)
            {
                Modifiers = SymbolModifier.Public, Parameters = "Exception", FilePath = @"src\" + fx + @"\Diagnostics\Logger.cs", Line = 37, CharInLine = 21
            });
            logger.AddChild(new MutableSymbol("TryLog", SymbolType.Method)
            {
                Modifiers = SymbolModifier.Private, Parameters = "string, string", FilePath = @"src\" + fx + @"\Diagnostics\Logger.cs", Line = 44, CharInLine = 22
            });

            // Nested public types should appear in the IDX but not the ARDB
            logger.AddChild(new MutableSymbol("NestedPublicType", SymbolType.Class)
            {
                Modifiers = SymbolModifier.Public, FilePath = @"src\" + fx + @"\Diagnostics\Logger.cs", Line = 22, CharInLine = 16
            });

            if (addMemoryType)
            {
                MutableSymbol memory = diagnostics.AddChild(new MutableSymbol(TYPE_MEMORY, SymbolType.Class)
                {
                    Modifiers = SymbolModifier.Public | SymbolModifier.Static, FilePath = @"src\" + fx + @"\Diagnostics\Memory.cs", Line = 5, CharInLine = 25
                });
                memory.AddChild(new MutableSymbol("MeasureObjectSize", SymbolType.Method)
                {
                    Modifiers = SymbolModifier.Public | SymbolModifier.Static, Parameters = "Func<object>", FilePath = @"src\" + fx + @"\Diagnostics\Memory.cs", Line = 13, CharInLine = 28
                });
                memory.AddChild(new MutableSymbol("FromGigabytes", SymbolType.Method)
                {
                    Modifiers = SymbolModifier.Public | SymbolModifier.Static, Parameters = "double", FilePath = @"src\" + fx + @"\Diagnostics\Memory.cs", Line = 32, CharInLine = 28
                });
            }
        }
Beispiel #10
0
        private bool IsExcluded(MutableSymbol symbolToAdd)
        {
            // Exclude members we don't want indexed (backing fields, property get/set methods)
            if (symbolToAdd.Type == SymbolType.Excluded)
            {
                return(true);
            }

            // Exclude types which are generated under the covers (IEnumerable worker classes)
            if (symbolToAdd.Name.StartsWith("<"))
            {
                return(true);
            }

            // Exclude weird value__ fields appearing on enum types
            if (symbolToAdd.Name.Equals("value__"))
            {
                return(true);
            }

            // Exclude constructors for enums [TODO]
            //if (symbolToAdd.Type == SymbolType.Constructor)
            //{
            //    INamedTypeSymbol parentType = symbol.ContainingType.BaseType;
            //    if (parentType != null && parentType.Name.Equals("Enum"))
            //    {
            //        return true;
            //    }
            //}

            // Exclude Event add_ and remove_ methods [rolled up in Event]
            if (symbolToAdd.Type == SymbolType.Method && (symbolToAdd.Name.StartsWith("add_") || symbolToAdd.Name.StartsWith("remove_")))
            {
                if (!this.IncludeSignatures || symbolToAdd.Parameters.Equals("EventHandler"))
                {
                    return(true);
                }
            }

            // Exclude non-public members *if configured to*
            if (this.IncludeNonPublicMembers == false)
            {
                if (!symbolToAdd.Modifiers.HasFlag(SymbolModifier.Public))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #11
0
        private void WalkSolution(string solutionPath, MutableSymbol parent)
        {
            using (MSBuildWorkspace workspace = BuildWorkspace())
            {
                // Open Solution with Roslyn
                var solution = workspace.OpenSolutionAsync(solutionPath).Result;

                // Build assembly symbols for each project in a shared tree
                foreach (Project project in solution.Projects)
                {
                    WalkProject(project, parent);
                }
            }
        }
Beispiel #12
0
        private void WalkField(MetadataReader mdReader, FieldDefinitionHandle handle, MutableSymbol parent)
        {
            FieldDefinition field = mdReader.GetFieldDefinition(handle);

            MutableSymbol result = new MutableSymbol(mdReader.GetString(field.Name), SymbolType.Field);

            AddModifiers(field.Attributes, result);
            AddLocation(handle, result);

            if (IsExcluded(result))
            {
                return;
            }
            parent.AddChild(result);
        }
Beispiel #13
0
        private bool IsExcluded(ISymbol MutableSymbol, MutableSymbol symbolToAdd)
        {
            //// Debugging: Uncomment to stop at MutableSymbol causing trouble
            //if (MutableSymbol.Name.EndsWith("BackingField"))
            //{
            //    Debugger.Break();
            //}

            // Exclude members we don't want indexed (backing fields, property get/set methods)
            if (symbolToAdd.Type == SymbolType.Excluded)
            {
                return(true);
            }

            // Exclude types which are generated under the covers (IEnumerable worker classes)
            if (MutableSymbol.CanBeReferencedByName == false && MutableSymbol is INamedTypeSymbol)
            {
                return(true);
            }

            // Exclude weird value__ fields appearing on enum types
            if (MutableSymbol.Name.Equals("value__"))
            {
                return(true);
            }

            // Exclude constructors for enums
            if (symbolToAdd.Type == SymbolType.Constructor)
            {
                INamedTypeSymbol parentType = MutableSymbol.ContainingType.BaseType;
                if (parentType != null && parentType.Name.Equals("Enum"))
                {
                    return(true);
                }
            }

            // Exclude non-public members *if configured to*
            if (this.IncludeNonPublicMembers == false)
            {
                if (!symbolToAdd.Modifiers.HasFlag(SymbolModifier.Public))
                {
                    return(true);
                }
            }

            // Include everything else
            return(false);
        }
Beispiel #14
0
        private void WalkType(INamedTypeSymbol symbol, MutableSymbol parent)
        {
            // Build this type
            MutableSymbol result = new MutableSymbol(symbol.Name, GetNamedTypeType(symbol));

            AddModifiers(symbol, result);
            AddLocation(symbol, result);

            // Stop if it should be excluded
            if (IsExcluded(symbol, result))
            {
                return;
            }

            // Add the type itself
            MutableSymbol thisSymbol = parent.AddChild(result);

            // Recurse on members
            foreach (ISymbol child in symbol.GetMembers())
            {
                if (child is INamedTypeSymbol)
                {
                    WalkType((INamedTypeSymbol)child, thisSymbol);
                }
                else
                {
                    if (this.IncludeMembers)
                    {
                        if (child is IMethodSymbol)
                        {
                            WalkMethod((IMethodSymbol)child, thisSymbol);
                        }
                        else if (child is IPropertySymbol)
                        {
                            WalkProperty((IPropertySymbol)child, thisSymbol);
                        }
                        else if (child is IFieldSymbol)
                        {
                            WalkField((IFieldSymbol)child, thisSymbol);
                        }
                        else
                        {
                            // Other contents excluded
                        }
                    }
                }
            }
        }
Beispiel #15
0
        private void AddModifiers(ISymbol MutableSymbol, MutableSymbol result)
        {
            SymbolModifier modifiers = SymbolModifier.None;

            // Convert individual properties
            if (MutableSymbol.IsStatic)
            {
                modifiers |= SymbolModifier.Static;
            }

            // Not needed for scenarios.
            //if (MutableSymbol.IsAbstract) modifiers |= SymbolModifier.Abstract;
            //if (MutableSymbol.IsExtern) modifiers |= SymbolModifier.Extern;
            //if (MutableSymbol.IsOverride) modifiers |= SymbolModifier.Override;
            //if (MutableSymbol.IsSealed) modifiers |= SymbolModifier.Sealed;
            //if (MutableSymbol.IsVirtual) modifiers |= SymbolModifier.Virtual;

            // Convert accessibility
            switch (MutableSymbol.DeclaredAccessibility)
            {
            case Accessibility.Public:
                modifiers |= SymbolModifier.Public;
                break;

            case Accessibility.Protected:
                modifiers |= SymbolModifier.Protected;
                break;

            case Accessibility.Private:
                modifiers |= SymbolModifier.Private;
                break;

            case Accessibility.Internal:
                modifiers |= SymbolModifier.Internal;
                break;

            case Accessibility.ProtectedAndInternal:
            case Accessibility.ProtectedOrInternal:
                modifiers |= SymbolModifier.Protected | SymbolModifier.Internal;
                break;

            default:
                throw new ArgumentException("Accessibility unhandled: " + MutableSymbol.DeclaredAccessibility.ToString());
            }

            result.Modifiers = modifiers;
        }
Beispiel #16
0
        private void WalkType(MetadataReader mdReader, TypeDefinitionHandle handle, MutableSymbol parent)
        {
            TypeDefinition type       = mdReader.GetTypeDefinition(handle);
            var            attributes = type.Attributes;

            // Get the name and remove generic suffix (List`1 => List)
            string metadataName           = mdReader.GetString(type.Name);
            int    genericNameSuffixIndex = metadataName.IndexOf('`');
            string baseName = (genericNameSuffixIndex < 0 ? metadataName : metadataName.Substring(0, genericNameSuffixIndex));

            MutableSymbol result = new MutableSymbol(baseName, GetTypeType(mdReader, type));

            AddModifiers(attributes, result);
            AddLocation(handle, result);

            if (IsExcluded(result))
            {
                return;
            }
            parent.AddChild(result);

            foreach (TypeDefinitionHandle nestedTypeHandle in type.GetNestedTypes())
            {
                WalkType(mdReader, nestedTypeHandle, result);
            }

            if (this.IncludeMembers)
            {
                foreach (MethodDefinitionHandle methodHandle in type.GetMethods())
                {
                    WalkMethod(mdReader, methodHandle, result);
                }

                foreach (FieldDefinitionHandle fieldHandle in type.GetFields())
                {
                    WalkField(mdReader, fieldHandle, result);
                }

                foreach (PropertyDefinitionHandle propertyHandle in type.GetProperties())
                {
                    WalkProperty(mdReader, propertyHandle, result);
                }

                // NOTE: type.GetEvents, type.GetInterfaceImplementations are not converted.
            }
        }
Beispiel #17
0
        private void WalkProperty(IPropertySymbol property, MutableSymbol parent)
        {
            MutableSymbol result = new MutableSymbol(property.Name, GetPropertyType(property));

            AddModifiers(property, result);
            AddLocation(property, result);

            if (this.IncludeSignatures)
            {
                result.Parameters = property.MinimalParameters();
            }

            if (!IsExcluded(property, result))
            {
                parent.AddChild(result);
            }
        }
Beispiel #18
0
        public PackageDatabase Walk(string walkPath, PackageIdentity identity = null)
        {
            // Normalize WalkPath to ensure we can get a name for it
            walkPath = Path.GetFullPath(walkPath);

            if (identity == null)
            {
                identity = new PackageIdentity(Path.GetFileName(walkPath));
            }
            if (String.IsNullOrEmpty(identity.IndexFileName))
            {
                throw new ArgumentException(String.Format("ERROR: Unable to compute database name for path \"{0}\"", walkPath));
            }

            PackageDatabase db          = new PackageDatabase(identity);
            MutableSymbol   packageRoot = db.MutableRoot.AddChild(new MutableSymbol(identity.PackageName, SymbolType.Package));

            // Index the directory|file list|solution|project|binary
            string extension = Path.GetExtension(walkPath).ToLowerInvariant();

            if (Directory.Exists(walkPath))
            {
                if (this.IncludeSymbolCacheIndices)
                {
                    WalkEverythingAndSymbolCache(walkPath, packageRoot);
                }
                else
                {
                    WalkJustMyCode(walkPath, packageRoot);
                }
            }
            else if (extension.Equals(".txt"))
            {
                foreach (string itemPath in File.ReadAllLines(walkPath))
                {
                    WalkIncremental(itemPath, packageRoot);
                }
            }
            else
            {
                InnerCrawler.Walk(walkPath, packageRoot);
            }

            return(db);
        }
Beispiel #19
0
        private void AddModifiers(TypeAttributes attributes, MutableSymbol symbolToAdd)
        {
            SymbolModifier modifiers = symbolToAdd.Modifiers;

            // Same as Roslyn PENamedTypeSymbol.DeclaredAccessibility
            switch (attributes & TypeAttributes.VisibilityMask)
            {
            case TypeAttributes.NestedAssembly:
                modifiers = SymbolModifier.Internal;
                break;

            case TypeAttributes.NestedFamORAssem:
            case TypeAttributes.NestedFamANDAssem:
                modifiers = SymbolModifier.Protected | SymbolModifier.Internal;
                break;

            case TypeAttributes.NestedPrivate:
                modifiers = SymbolModifier.Private;
                break;

            case TypeAttributes.Public:
            case TypeAttributes.NestedPublic:
                modifiers = SymbolModifier.Public;
                break;

            case TypeAttributes.NestedFamily:
                modifiers = SymbolModifier.Protected;
                break;

            case TypeAttributes.NotPublic:
                modifiers = SymbolModifier.Internal;
                break;
            }


            // Same as Roslyn PENamedTypeSymbol.IsStatic
            if (attributes.HasFlag(TypeAttributes.Sealed) && attributes.HasFlag(TypeAttributes.Abstract))
            {
                modifiers |= SymbolModifier.Static;
            }

            symbolToAdd.Modifiers = modifiers;
        }
Beispiel #20
0
        private void WalkProperty(MetadataReader mdReader, PropertyDefinitionHandle handle, MutableSymbol parent)
        {
            PropertyDefinition prop = mdReader.GetPropertyDefinition(handle);

            MutableSymbol result = new MutableSymbol(mdReader.GetString(prop.Name), SymbolType.Property);

            // Use the accessibility and location of the getter [or setter, if write only property]
            // Not identical to Roslyn PEPropertyDeclaration but much simpler
            MethodDefinitionHandle getterOrSetterHandle = prop.GetAccessors().Getter;

            if (getterOrSetterHandle.IsNil)
            {
                getterOrSetterHandle = prop.GetAccessors().Setter;
            }

            // If we couldn't retrieve a getter or setter, exclude this property
            if (getterOrSetterHandle.IsNil)
            {
                return;
            }

            MethodDefinition getterOrSetter = mdReader.GetMethodDefinition(getterOrSetterHandle);

            AddModifiers(getterOrSetter.Attributes, result);
            AddLocation(getterOrSetterHandle, result);
            AddParameters(mdReader, getterOrSetter, result);

            // If this is an Indexer, rename it and retype it
            // Roslyn PEPropertySymbol.IsIndexer is also just based on the name.
            if (result.Name == "Item")
            {
                result.Name = "this[]";
                result.Type = SymbolType.Indexer;
            }

            if (IsExcluded(result))
            {
                return;
            }
            parent.AddChild(result);
        }
Beispiel #21
0
        public void Walk(string binaryPath, MutableSymbol parent)
        {
            if (!FileIO.IsManagedBinary(binaryPath))
            {
                throw new ArgumentException(String.Format("SrmCrawler doesn't know how to walk file with extension '{0}'", Path.GetExtension(binaryPath)));
            }

            FileStream stream = new FileStream(binaryPath, FileMode.Open, FileAccess.Read);

            // NOTE: Need to keep PEReader alive through crawl to avoid AV in looking up signatures
            using (PEReader peReader = new PEReader(stream))
            {
                if (peReader.HasMetadata == false)
                {
                    return;
                }

                Trace.WriteLine("\t" + binaryPath);

                using (PdbSymbolProvider pdbProvider = PdbSymbolProvider.TryBuildProvider(binaryPath))
                {
                    PDB = pdbProvider;

                    MutableSymbol assemblyRoot = parent.AddChild(new MutableSymbol(Path.GetFileName(binaryPath), SymbolType.Assembly));

                    // Walk all non-nested types. Namespaces are derived as found. Nested types will be found during crawl of containing type.
                    MetadataReader mdReader = peReader.GetMetadataReader();
                    foreach (TypeDefinitionHandle typeHandle in mdReader.TypeDefinitions)
                    {
                        TypeDefinition type            = mdReader.GetTypeDefinition(typeHandle);
                        string         namespaceString = mdReader.GetString(type.Namespace);

                        if (!type.Attributes.IsNested())
                        {
                            MutableSymbol ns = assemblyRoot.FindOrAddPath(namespaceString, '.', SymbolType.Namespace);
                            WalkType(mdReader, typeHandle, ns);
                        }
                    }
                }
            }
        }
Beispiel #22
0
        private void WalkNamespace(INamespaceSymbol ns, MutableSymbol parent)
        {
            // Build a MutableSymbol for this namespace; collapse the global namespace right under the binary
            MutableSymbol thisSymbol = parent;

            if (!ns.IsGlobalNamespace)
            {
                thisSymbol = parent.AddChild(new MutableSymbol(ns.Name, SymbolType.Namespace));
            }

            // Enumerate child namespaces
            foreach (INamespaceSymbol childNamespace in ns.GetNamespaceMembers())
            {
                WalkNamespace(childNamespace, thisSymbol);
            }

            // Enumerate types
            foreach (INamedTypeSymbol childType in ns.GetTypeMembers())
            {
                WalkType(childType, thisSymbol);
            }
        }
Beispiel #23
0
        private void WalkJustMyCode(string rootPath, MutableSymbol parent)
        {
            List <string> justMyCodeBinaries = new List <string>();

            // Find each PDB for which we can find the binary and find the first referenced source file
            using (new TraceWatch("Finding 'Just My Code' binaries..."))
            {
                justMyCodeBinaries = JustMyCodeBinaryFinder.FindJustMyCodeUnder(rootPath);
            }

            // Index each binary
            ProgressWriter p = new ProgressWriter(justMyCodeBinaries.Count);

            using (new TraceWatch("Indexing {0:n0} binaries...", justMyCodeBinaries.Count))
            {
                foreach (string binaryPath in justMyCodeBinaries)
                {
                    WalkIncremental(binaryPath, parent);
                    p.IncrementProgress();
                }
            }
        }
Beispiel #24
0
        private void AddLocation(Handle handle, MutableSymbol symbolToAdd)
        {
            if (!this.IncludeCodeLocations)
            {
                return;
            }

            if (PDB != null)
            {
                int token = MetadataTokens.GetToken(handle);

                // If found, associate the member with the first location found
                IEnumerable <ILSequencePoint> locations = PDB.GetSequencePointsForMethod(token);
                foreach (ILSequencePoint location in locations)
                {
                    symbolToAdd.FilePath   = location.Document;
                    symbolToAdd.Line       = location.StartLine.TrimToUShort();
                    symbolToAdd.CharInLine = location.StartCharInLine.TrimToUShort();
                    return;
                }
            }
        }
Beispiel #25
0
        private void AddLocation(ISymbol symbol, MutableSymbol symbolToAdd)
        {
            if (this.IncludeCodeLocations)
            {
                // Get MutableSymbol declaration location from Roslyn, if available
                if (symbol.Locations.Length != 0)
                {
                    if (symbol.Locations[0].IsInSource)
                    {
                        // Roslyn locations are zero-based. Correct to normal positions.
                        FileLinePositionSpan location = symbol.Locations[0].GetLineSpan();
                        symbolToAdd.FilePath   = location.Path;
                        symbolToAdd.Line       = (location.StartLinePosition.Line + 1).TrimToUShort();
                        symbolToAdd.CharInLine = (location.StartLinePosition.Character + 1).TrimToUShort();
                        return;
                    }
                }

                // Get MutableSymbol declaration location from the PDB, if available
                if (PDB != null)
                {
                    MethodDefinitionHandle handle = symbol.GetMethodDefinitionHandle();
                    if (!handle.IsNil)
                    {
                        int token = MetadataTokens.GetToken(handle);

                        // If found, associate the member with the first location found
                        ILSequencePoint location;
                        if (PDB.TryGetFirstPointForMethod(token, out location))
                        {
                            symbolToAdd.FilePath   = location.Document;
                            symbolToAdd.Line       = location.StartLine.TrimToUShort();
                            symbolToAdd.CharInLine = location.StartCharInLine.TrimToUShort();
                        }
                    }
                }
            }
        }
Beispiel #26
0
        private void AddModifiers(FieldAttributes attributes, MutableSymbol symbolToAdd)
        {
            SymbolModifier modifiers = symbolToAdd.Modifiers;

            // Same as Roslyn PEFieldSymbol.DeclaredAccessibility
            switch (attributes & FieldAttributes.FieldAccessMask)
            {
            case FieldAttributes.Assembly:
                modifiers = SymbolModifier.Internal;
                break;

            case FieldAttributes.FamORAssem:
            case FieldAttributes.FamANDAssem:
                modifiers = SymbolModifier.Protected | SymbolModifier.Internal;
                break;

            case FieldAttributes.Private:
            case FieldAttributes.PrivateScope:
                modifiers = SymbolModifier.Private;
                break;

            case FieldAttributes.Public:
                modifiers = SymbolModifier.Public;
                break;

            case FieldAttributes.Family:
                modifiers = SymbolModifier.Protected;
                break;
            }

            if (attributes.HasFlag(FieldAttributes.Static))
            {
                modifiers |= SymbolModifier.Static;
            }

            symbolToAdd.Modifiers = modifiers;
        }
Beispiel #27
0
        private void AddParameters(MetadataReader mdReader, MethodDefinition method, MutableSymbol result)
        {
            if (!this.IncludeSignatures)
            {
                return;
            }

            StringBuilder parameterString = new StringBuilder();

            StringSignatureProvider provider = new StringSignatureProvider(mdReader, mdReader.GetTypeDefinition(method.GetDeclaringType()), method);

            MethodSignature <string> signature = method.DecodeSignature <string, DisassemblingGenericContext>(provider, null);

            foreach (string value in signature.ParameterTypes)
            {
                if (parameterString.Length > 0)
                {
                    parameterString.Append(", ");
                }
                parameterString.Append(value);
            }

            result.Parameters = parameterString.ToString();
        }
 public void Walk(string filePath, MutableSymbol parent)
 {
     this.Count++;
     this.InnerCrawler.Walk(filePath, parent);
 }
Beispiel #29
0
        private void WalkBinary(string binaryPath, MutableSymbol parent, string encodedFrameworkNames)
        {
            // Add the binary as a reference to resolve symbols in it
            MetadataReference reference = MetadataReference.CreateFromFile(binaryPath);

            CSharpCompilationOptions compilationOptions = new CSharpCompilationOptions(
                outputKind: OutputKind.ConsoleApplication,
                reportSuppressedDiagnostics: false);

            compilationOptions.SetMetadataImportOptions(MetadataImportOptions.All);

            // Create an empty binary to 'host' the reference
            CSharpCompilation emptyCompilation = CSharpCompilation.Create("Empty.exe", references: new[] { reference }, options: compilationOptions);

            // Get the root of the reference specifically
            ISymbol referenceRootSymbol = emptyCompilation.GetAssemblyOrModuleSymbol(reference);

            // If this wasn't a managed assembly, don't add anything
            if (referenceRootSymbol == null)
            {
                return;
            }

            string           assemblyName    = null;
            INamespaceSymbol globalNamespace = null;

            if (referenceRootSymbol is IAssemblySymbol)
            {
                // NOTE: Use the Assembly.Identity.Name specifically as the root to allow VS to identify binaries (potentially) already referenced safely.
                assemblyName    = ((IAssemblySymbol)referenceRootSymbol).Identity.Name;
                globalNamespace = ((IAssemblySymbol)referenceRootSymbol).GlobalNamespace;
            }
            else if (referenceRootSymbol is IModuleSymbol)
            {
                assemblyName    = Path.GetFileName(binaryPath);
                globalNamespace = ((IModuleSymbol)referenceRootSymbol).GlobalNamespace;
            }
            else
            {
                // Unable to crawl if we didn't find an assembly or module
                Trace.WriteLine(String.Format("ERROR: Unable to crawl binary with root symbol type '{0}'", referenceRootSymbol.GetType().Name));
                return;
            }

            // Walk the binary
            MutableSymbol addUnderRoot = parent.AddChild(new MutableSymbol(assemblyName, SymbolType.Assembly));

            // Add the target framework [if requested and identifiable]
            if (this.IncludeFrameworkTargets)
            {
                if (!String.IsNullOrEmpty(encodedFrameworkNames))
                {
                    addUnderRoot = addUnderRoot.AddChild(new MutableSymbol(encodedFrameworkNames, SymbolType.FrameworkTarget));
                }
            }

            // PRIVATE ROSLYN: Attempt to build a PDB reader for the binary
            using (PdbSymbolProvider pdbProvider = PdbSymbolProvider.TryBuildProvider(binaryPath))
            {
                PDB = pdbProvider;

                WalkNamespace(globalNamespace, addUnderRoot);

                // Remove the PdbSymbolProvider
                PDB = null;
            }
        }
Beispiel #30
0
        public void MergedMembersDatabase_Merging()
        {
            MergedMembersDatabase db = new MergedMembersDatabase();
            DatabaseAddResult     result;
            string lastAddResult;

            PackageDatabase source = PackageDatabaseTests.BuildDefaultSample();

            source.Identity.PackageName = "V1";
            result        = db.Add(source, ArdbVersion.Current);
            lastAddResult = Write.ToString(result.WriteMemberResults);
            Trace.WriteLine("First Sample Import:\r\n" + lastAddResult);
            Trace.WriteLine(Write.ToString(result.WriteDuplicateComponents));

            // Sample has at least one unique thing
            Assert.IsTrue(result.WasMemberAdded[0].Value);

            // Memory class is included
            Assert.IsTrue(result.WasMemberAdded[ItemTreeTests.FindByPath(source.DeclaredMembers, source.StringStore, DIAGNOSTICS_NAMESPACE_REF35 + "|Memory", PackageDatabaseTests.SEPARATOR_CHAR)].Value);

            // FromGigabytes member is ignored (not a type)
            Assert.IsFalse(result.WasMemberAdded[ItemTreeTests.FindByPath(source.DeclaredMembers, source.StringStore, DIAGNOSTICS_NAMESPACE_REF35 + "|Memory|FromGigabytes", PackageDatabaseTests.SEPARATOR_CHAR)].HasValue);

            // Add the source again (a complete duplicate)
            source.Identity.PackageName = "V2";
            result        = db.Add(source, ArdbVersion.Current);
            lastAddResult = Write.ToString(result.WriteMemberResults);
            Trace.WriteLine("Duplicate Sample Import:\r\n" + lastAddResult);
            Trace.WriteLine(Write.ToString(result.WriteDuplicateComponents));

            // Verify nothing is unique this time
            Assert.IsFalse(result.WasMemberAdded[0].Value);

            // Add a new public class to the sample (should be added)
            MutableSymbol diagnostics = source.MutableRoot.FindByFullName(DIAGNOSTICS_NAMESPACE_LIB20, PackageDatabaseTests.SEPARATOR_CHAR);

            diagnostics.AddChild(new MutableSymbol("TraceWatch", SymbolType.Class)
            {
                Modifiers = SymbolModifier.Public | SymbolModifier.Static
            });

            // Add a new method to Logger (no effect)
            MutableSymbol logger = source.MutableRoot.FindByFullName(DIAGNOSTICS_NAMESPACE_LIB20 + "|Logger", PackageDatabaseTests.SEPARATOR_CHAR);

            logger.AddChild(new MutableSymbol("LogTime", SymbolType.Method)
            {
                Modifiers = SymbolModifier.Public
            });

            // Add the source with additions, verify something is new
            source.Identity.PackageName = "V3";
            result        = db.Add(source, ArdbVersion.Current);
            lastAddResult = Write.ToString(result.WriteMemberResults);
            Trace.WriteLine("Sample with additions Import:\r\n" + lastAddResult);
            Trace.WriteLine(Write.ToString(result.WriteDuplicateComponents));
            Assert.IsTrue(result.WasMemberAdded[0].Value);

            // Verify Diagnostics contains changes
            Assert.IsTrue(result.WasMemberAdded[ItemTreeTests.FindByPath(source.DeclaredMembers, source.StringStore, DIAGNOSTICS_NAMESPACE_LIB20, PackageDatabaseTests.SEPARATOR_CHAR)].Value);

            // Verify Logger wasn't considered changed
            Assert.IsFalse(result.WasMemberAdded[ItemTreeTests.FindByPath(source.DeclaredMembers, source.StringStore, TYPE_LOGGER, PackageDatabaseTests.SEPARATOR_CHAR)].Value);

            // Add a new private class to the sample (should not be added)
            diagnostics.AddChild(new MutableSymbol("SmartTimer", SymbolType.Class)
            {
                Modifiers = SymbolModifier.Internal
            });

            // Add the source again, verify nothing is new
            source.Identity.PackageName = "V4";
            result        = db.Add(source, ArdbVersion.Current);
            lastAddResult = Write.ToString(result.WriteMemberResults);
            Trace.WriteLine("Sample with private class Import:\r\n" + lastAddResult);
            Trace.WriteLine(Write.ToString(result.WriteDuplicateComponents));
            Assert.IsFalse(result.WasMemberAdded[0].Value);

            Trace.WriteLine(Write.ToString((w) => db.WriteMergedTree(w)));
        }