using System.IO; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Semmle.Extraction.CSharp.Entities { internal class UsingDirective : FreshEntity { private readonly UsingDirectiveSyntax node; private readonly NamespaceDeclaration parent; public UsingDirective(Context cx, UsingDirectiveSyntax usingDirective, NamespaceDeclaration parent) : base(cx) { node = usingDirective; this.parent = parent; TryPopulate(); } protected override void Populate(TextWriter trapFile) { if (Context.OnlyScaffold) { return; } // This is guaranteed to be non-null as we only deal with "using namespace" not "using X = Y" var name = node.Name!; var info = Context.GetModel(node).GetSymbolInfo(name); if (node.StaticKeyword.IsKind(SyntaxKind.None)) { // A normal using if (info.Symbol is INamespaceSymbol namespaceSymbol) { var ns = Namespace.Create(Context, namespaceSymbol); trapFile.using_namespace_directives(this, ns); trapFile.using_directive_location(this, Context.CreateLocation(ReportingLocation)); } else { Context.ExtractionContext.MissingNamespace(name.ToFullString(), Context.FromSource); Context.ModelError(node, "Namespace not found"); return; } } else { // A "using static" var m = Type.Create(Context, (ITypeSymbol?)info.Symbol); trapFile.using_static_directives(this, m.TypeRef); trapFile.using_directive_location(this, Context.CreateLocation(ReportingLocation)); } if (node.GlobalKeyword.IsKind(SyntaxKind.GlobalKeyword)) { trapFile.using_global(this); } if (parent is not null) { trapFile.parent_namespace_declaration(this, parent); } } public sealed override Microsoft.CodeAnalysis.Location ReportingLocation => node.GetLocation(); } }