mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
126 lines
4.2 KiB
C#
126 lines
4.2 KiB
C#
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Semmle.Extraction.CSharp.Entities;
|
|
using Semmle.Extraction.Entities;
|
|
using Semmle.Util.Logging;
|
|
|
|
namespace Semmle.Extraction.CSharp.Populators
|
|
{
|
|
public class TypeContainerVisitor : CSharpSyntaxVisitor
|
|
{
|
|
protected readonly Context cx;
|
|
protected readonly IEntity parent;
|
|
|
|
public TypeContainerVisitor(Context cx, IEntity parent)
|
|
{
|
|
this.cx = cx;
|
|
this.parent = parent;
|
|
}
|
|
|
|
public override void DefaultVisit(SyntaxNode node)
|
|
{
|
|
throw new InternalError(node, "Unhandled top-level syntax node");
|
|
}
|
|
|
|
public override void VisitDelegateDeclaration(DelegateDeclarationSyntax node)
|
|
{
|
|
Entities.NamedType.Create(cx, cx.Model(node).GetDeclaredSymbol(node)).ExtractRecursive(parent);
|
|
}
|
|
|
|
public override void VisitClassDeclaration(ClassDeclarationSyntax classDecl)
|
|
{
|
|
Entities.Type.Create(cx, cx.Model(classDecl).GetDeclaredSymbol(classDecl)).ExtractRecursive(parent);
|
|
}
|
|
|
|
public override void VisitStructDeclaration(StructDeclarationSyntax node)
|
|
{
|
|
Entities.Type.Create(cx, cx.Model(node).GetDeclaredSymbol(node)).ExtractRecursive(parent);
|
|
}
|
|
|
|
public override void VisitEnumDeclaration(EnumDeclarationSyntax node)
|
|
{
|
|
Entities.Type.Create(cx, cx.Model(node).GetDeclaredSymbol(node)).ExtractRecursive(parent);
|
|
}
|
|
|
|
public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node)
|
|
{
|
|
Entities.Type.Create(cx, cx.Model(node).GetDeclaredSymbol(node)).ExtractRecursive(parent);
|
|
}
|
|
|
|
public override void VisitAttributeList(AttributeListSyntax node)
|
|
{
|
|
if (cx.Extractor.Standalone) return;
|
|
|
|
var outputAssembly = Assembly.CreateOutputAssembly(cx);
|
|
foreach (var attribute in node.Attributes)
|
|
{
|
|
var ae = new Attribute(cx, attribute, outputAssembly);
|
|
cx.BindComments(ae, attribute.GetLocation());
|
|
}
|
|
}
|
|
}
|
|
|
|
class TypeOrNamespaceVisitor : TypeContainerVisitor
|
|
{
|
|
public TypeOrNamespaceVisitor(Context cx, IEntity parent)
|
|
: base(cx, parent) { }
|
|
|
|
public override void VisitUsingDirective(UsingDirectiveSyntax usingDirective)
|
|
{
|
|
// Only deal with "using namespace" not "using X = Y"
|
|
if (usingDirective.Alias == null)
|
|
new UsingDirective(cx, usingDirective, (NamespaceDeclaration)parent);
|
|
}
|
|
|
|
public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node)
|
|
{
|
|
NamespaceDeclaration.Create(cx, node, (NamespaceDeclaration)parent);
|
|
}
|
|
}
|
|
|
|
class CompilationUnitVisitor : TypeOrNamespaceVisitor
|
|
{
|
|
public CompilationUnitVisitor(Context cx)
|
|
: base(cx, null) { }
|
|
|
|
public override void VisitExternAliasDirective(ExternAliasDirectiveSyntax node)
|
|
{
|
|
// This information is not yet extracted.
|
|
cx.Extractor.Message(new Message { severity = Severity.Info, message = "Ignoring extern alias directive" });
|
|
}
|
|
|
|
public override void VisitCompilationUnit(CompilationUnitSyntax compilationUnit)
|
|
{
|
|
foreach (var m in compilationUnit.ChildNodes())
|
|
{
|
|
cx.Try(m, null, () => ((CSharpSyntaxNode)m).Accept(this));
|
|
}
|
|
|
|
// Gather comments:
|
|
foreach (SyntaxTrivia trivia in compilationUnit.DescendantTrivia(compilationUnit.Span))
|
|
{
|
|
CommentLine.Extract(cx, trivia);
|
|
}
|
|
|
|
foreach (var trivia in compilationUnit.GetLeadingTrivia())
|
|
{
|
|
CommentLine.Extract(cx, trivia);
|
|
}
|
|
|
|
foreach (var trivia in compilationUnit.GetTrailingTrivia())
|
|
{
|
|
CommentLine.Extract(cx, trivia);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CompilationUnit
|
|
{
|
|
public static void Extract(Context cx, SyntaxNode unit)
|
|
{
|
|
((CSharpSyntaxNode)unit).Accept(new CompilationUnitVisitor(cx));
|
|
}
|
|
}
|
|
}
|