diff --git a/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs index 4026263c3843e..7ee3be2112286 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/CodeAnalysisExtensions/SymbolExtensions.cs @@ -648,5 +648,17 @@ public static IEnumerable GetAnnotatedTypeArguments(this IN /// public static bool IsPublicOrProtected(this ISymbol symbol) => symbol.DeclaredAccessibility == Accessibility.Public || symbol.DeclaredAccessibility == Accessibility.Protected; + + /// + /// Returns true if the given symbol should be extracted in this context. + /// + public static bool ShouldExtractSymbol(this ISymbol symbol) => + symbol.Locations.Any(x => !x.IsInMetadata) || symbol.IsPublicOrProtected(); + + /// + /// Returns the symbols that should be extracted in the given context. + /// + public static IEnumerable ToExtract(this IEnumerable symbols) where T : ISymbol => + symbols.Where(symbol => symbol.ShouldExtractSymbol()); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs index 6890ca4908476..6ba5cca01cf62 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Method.cs @@ -101,7 +101,7 @@ public void Overrides(TextWriter trapFile) } } - if (Symbol.OverriddenMethod is not null) + if (Symbol.OverriddenMethod is not null && Symbol.OverriddenMethod.ShouldExtractSymbol()) { trapFile.overrides(this, Method.Create(Context, Symbol.OverriddenMethod)); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs index ac860b2e3e156..4a7677d6aa44e 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Types/Type.cs @@ -228,24 +228,20 @@ private void ExtractParametersForDelegateLikeType(TextWriter trapFile, IMethodSy /// Called to extract members and nested types. /// This is called on each member of a namespace, /// in either source code or an assembly. - /// If true, only extract members that are effectively public otherwise extract all members. /// - public void ExtractRecursive(bool onlyEffectivelyPublic = false) + public void ExtractRecursive() { foreach (var l in Symbol.DeclaringSyntaxReferences.Select(s => s.GetSyntax().GetLocation())) { Context.BindComments(this, l); } - foreach (var member in Symbol.GetMembers()) + foreach (var member in Symbol.GetMembers().ToExtract()) { - if (onlyEffectivelyPublic && !member.IsPublicOrProtected()) - continue; - switch (member.Kind) { case SymbolKind.NamedType: - Create(Context, (ITypeSymbol)member).ExtractRecursive(onlyEffectivelyPublic); + Create(Context, (ITypeSymbol)member).ExtractRecursive(); break; default: Context.CreateEntity(member); @@ -266,16 +262,16 @@ public void PopulateGenerics() var members = new List(); - foreach (var member in Symbol.GetMembers()) + foreach (var member in Symbol.GetMembers().ToExtract()) members.Add(member); - foreach (var member in Symbol.GetTypeMembers()) + foreach (var member in Symbol.GetTypeMembers().ToExtract()) members.Add(member); // Mono extractor puts all BASE interface members as members of the current interface. if (Symbol.TypeKind == TypeKind.Interface) { - foreach (var baseInterface in Symbol.Interfaces) + foreach (var baseInterface in Symbol.Interfaces.ToExtract()) { foreach (var member in baseInterface.GetMembers()) members.Add(member); @@ -289,10 +285,10 @@ public void PopulateGenerics() Context.CreateEntity(member); } - if (Symbol.BaseType is not null) + if (Symbol.BaseType is not null && Symbol.BaseType.ShouldExtractSymbol()) Create(Context, Symbol.BaseType).PopulateGenerics(); - foreach (var i in Symbol.Interfaces) + foreach (var i in Symbol.Interfaces.ToExtract()) { Create(Context, i).PopulateGenerics(); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs index 7e82a76ac42b7..8b8f4613c43e3 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Analyser.cs @@ -271,9 +271,9 @@ private static void AnalyseNamespace(Context cx, INamespaceSymbol ns) foreach (var memberType in ns.GetTypeMembers()) { - if (memberType.IsPublicOrProtected()) + if (memberType.ShouldExtractSymbol()) { - Entities.Type.Create(cx, memberType).ExtractRecursive(onlyEffectivelyPublic: true); + Entities.Type.Create(cx, memberType).ExtractRecursive(); } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs index 67bb2808ae620..2408d3a7cdbf7 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Extractor/Context.cs @@ -550,6 +550,7 @@ public bool Defines(ISymbol symbol) => !SymbolEqualityComparer.Default.Equals(symbol, symbol.OriginalDefinition) || scope.InScope(symbol); + /// /// Runs the given action , guarding for trap duplication /// based on key .