mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
98 lines
3.7 KiB
C#
98 lines
3.7 KiB
C#
using Semmle.Util;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
namespace Semmle.Extraction.Entities
|
|
{
|
|
public class File : CachedEntity<string>
|
|
{
|
|
File(Context cx, string path)
|
|
: base(cx, path)
|
|
{
|
|
OriginalPath = path;
|
|
TransformedPathLazy = new Lazy<PathTransformer.ITransformedPath>(() => Context.Extractor.PathTransformer.Transform(OriginalPath));
|
|
}
|
|
|
|
readonly string OriginalPath;
|
|
readonly Lazy<PathTransformer.ITransformedPath> TransformedPathLazy;
|
|
PathTransformer.ITransformedPath TransformedPath => TransformedPathLazy.Value;
|
|
|
|
public override bool NeedsPopulation => Context.DefinesFile(OriginalPath) || OriginalPath == Context.Extractor.OutputPath;
|
|
|
|
public override void Populate(TextWriter trapFile)
|
|
{
|
|
trapFile.files(this, TransformedPath.Value, TransformedPath.NameWithoutExtension, TransformedPath.Extension);
|
|
|
|
if (TransformedPath.ParentDirectory is PathTransformer.ITransformedPath dir)
|
|
trapFile.containerparent(Folder.Create(Context, dir), this);
|
|
|
|
var fromSource = TransformedPath.Extension.ToLowerInvariant().Equals("cs");
|
|
if (fromSource)
|
|
{
|
|
foreach (var text in Context.Compilation.SyntaxTrees.
|
|
Where(t => t.FilePath == OriginalPath).
|
|
Select(tree => tree.GetText()))
|
|
{
|
|
var rawText = text.ToString() ?? "";
|
|
var lineCounts = LineCounter.ComputeLineCounts(rawText);
|
|
if (rawText.Length > 0 && rawText[rawText.Length - 1] != '\n') lineCounts.Total++;
|
|
|
|
trapFile.numlines(this, lineCounts);
|
|
Context.TrapWriter.Archive(OriginalPath, TransformedPath, text.Encoding ?? System.Text.Encoding.Default);
|
|
}
|
|
}
|
|
|
|
trapFile.file_extraction_mode(this, Context.Extractor.Standalone ? 1 : 0);
|
|
}
|
|
|
|
public override void WriteId(System.IO.TextWriter trapFile)
|
|
{
|
|
trapFile.Write(TransformedPath.DatabaseId);
|
|
trapFile.Write(";sourcefile");
|
|
}
|
|
|
|
public static File Create(Context cx, string path) => FileFactory.Instance.CreateEntity(cx, (typeof(File), path), path);
|
|
|
|
public static File CreateGenerated(Context cx) => GeneratedFile.Create(cx);
|
|
|
|
class GeneratedFile : File
|
|
{
|
|
GeneratedFile(Context cx) : base(cx, "") { }
|
|
|
|
public override bool NeedsPopulation => true;
|
|
|
|
public override void Populate(TextWriter trapFile)
|
|
{
|
|
trapFile.files(this, "", "", "");
|
|
}
|
|
|
|
public override void WriteId(TextWriter trapFile)
|
|
{
|
|
trapFile.Write("GENERATED;sourcefile");
|
|
}
|
|
|
|
public static GeneratedFile Create(Context cx) =>
|
|
GeneratedFileFactory.Instance.CreateEntity(cx, typeof(GeneratedFile), null);
|
|
|
|
class GeneratedFileFactory : ICachedEntityFactory<string?, GeneratedFile>
|
|
{
|
|
public static readonly GeneratedFileFactory Instance = new GeneratedFileFactory();
|
|
|
|
public GeneratedFile Create(Context cx, string? init) => new GeneratedFile(cx);
|
|
}
|
|
}
|
|
|
|
public override Microsoft.CodeAnalysis.Location? ReportingLocation => null;
|
|
|
|
class FileFactory : ICachedEntityFactory<string, File>
|
|
{
|
|
public static readonly FileFactory Instance = new FileFactory();
|
|
|
|
public File Create(Context cx, string init) => new File(cx, init);
|
|
}
|
|
|
|
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
|
|
}
|
|
}
|