mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
93 lines
3.3 KiB
C#
93 lines
3.3 KiB
C#
using System.IO;
|
|
using Microsoft.CodeAnalysis;
|
|
|
|
namespace Semmle.Extraction.CSharp.Entities
|
|
{
|
|
internal class Assembly : Location
|
|
{
|
|
private readonly string assemblyPath;
|
|
private readonly IAssemblySymbol assembly;
|
|
private readonly bool isOutputAssembly;
|
|
|
|
private Assembly(Context cx, Microsoft.CodeAnalysis.Location? init)
|
|
: base(cx, init)
|
|
{
|
|
isOutputAssembly = init is null;
|
|
if (isOutputAssembly)
|
|
{
|
|
assemblyPath = cx.ExtractionContext.OutputPath;
|
|
assembly = cx.Compilation.Assembly;
|
|
}
|
|
else
|
|
{
|
|
assembly = init!.MetadataModule!.ContainingAssembly;
|
|
var identity = assembly.Identity;
|
|
var idString = $"{identity.Name} {identity.Version}";
|
|
assemblyPath = cx.ExtractionContext.GetAssemblyFile(idString);
|
|
}
|
|
}
|
|
|
|
public override void Populate(TextWriter trapFile)
|
|
{
|
|
if (assemblyPath is not null)
|
|
{
|
|
var isBuildlessOutputAssembly = isOutputAssembly && Context.ExtractionContext.IsStandalone;
|
|
var identifier = isBuildlessOutputAssembly
|
|
? ""
|
|
: assembly.ToString() ?? "";
|
|
var name = isBuildlessOutputAssembly ? "" : assembly.Identity.Name;
|
|
var version = isBuildlessOutputAssembly ? "" : assembly.Identity.Version.ToString();
|
|
trapFile.assemblies(this, File.Create(Context, assemblyPath), identifier, name, version);
|
|
}
|
|
}
|
|
|
|
public override bool NeedsPopulation => true;
|
|
|
|
public override int GetHashCode() =>
|
|
Symbol is null ? 91187354 : Symbol.GetHashCode();
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
if (obj is Assembly other && other.GetType() == typeof(Assembly))
|
|
return Equals(Symbol, other.Symbol);
|
|
|
|
return false;
|
|
}
|
|
|
|
public static Location Create(Context cx, Microsoft.CodeAnalysis.Location loc) => AssemblyConstructorFactory.Instance.CreateEntity(cx, loc, loc);
|
|
|
|
private class AssemblyConstructorFactory : CachedEntityFactory<Microsoft.CodeAnalysis.Location?, Assembly>
|
|
{
|
|
public static AssemblyConstructorFactory Instance { get; } = new AssemblyConstructorFactory();
|
|
|
|
public override Assembly Create(Context cx, Microsoft.CodeAnalysis.Location? init) => new Assembly(cx, init);
|
|
}
|
|
|
|
private static readonly object outputAssemblyCacheKey = new object();
|
|
|
|
public static Assembly CreateOutputAssembly(Context cx)
|
|
{
|
|
return AssemblyConstructorFactory.Instance.CreateEntity(cx, outputAssemblyCacheKey, null);
|
|
}
|
|
|
|
public override void WriteId(EscapingTextWriter trapFile)
|
|
{
|
|
if (isOutputAssembly && Context.ExtractionContext.IsStandalone)
|
|
{
|
|
trapFile.Write("buildlessOutputAssembly");
|
|
}
|
|
else
|
|
{
|
|
trapFile.Write(assembly.ToString());
|
|
}
|
|
|
|
if (assemblyPath is not null)
|
|
{
|
|
trapFile.Write("#file:///");
|
|
trapFile.Write(assemblyPath.Replace("\\", "/"));
|
|
}
|
|
trapFile.Write(";assembly");
|
|
}
|
|
}
|
|
}
|