зеркало из https://github.com/github/codeql.git
Make derived 'Context' classes internal and adjust visibility of members in base 'Context'
This commit is contained in:
Родитель
539fdf952a
Коммит
841ef9a4ae
|
@ -24,7 +24,7 @@ namespace Semmle.Extraction.CIL.Driver
|
||||||
{
|
{
|
||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
Entities.Assembly.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, trapCompression, out _, out _);
|
Analyser.ExtractCIL(layout, assemblyPath, logger, nocache, extractPdbs, trapCompression, out _, out _);
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed);
|
logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
using Semmle.Util.Logging;
|
||||||
|
using System;
|
||||||
|
using Semmle.Util;
|
||||||
|
using Semmle.Extraction.CIL.Entities;
|
||||||
|
|
||||||
|
namespace Semmle.Extraction.CIL
|
||||||
|
{
|
||||||
|
public static class Analyser
|
||||||
|
{
|
||||||
|
private static void ExtractCIL(Extractor extractor, TrapWriter trapWriter, bool extractPdbs)
|
||||||
|
{
|
||||||
|
using var cilContext = new Context(extractor, trapWriter, extractor.OutputPath, extractPdbs);
|
||||||
|
cilContext.Populate(new Assembly(cilContext));
|
||||||
|
cilContext.PopulateAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Main entry point to the CIL extractor.
|
||||||
|
/// Call this to extract a given assembly.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="layout">The trap layout.</param>
|
||||||
|
/// <param name="assemblyPath">The full path of the assembly to extract.</param>
|
||||||
|
/// <param name="logger">The logger.</param>
|
||||||
|
/// <param name="nocache">True to overwrite existing trap file.</param>
|
||||||
|
/// <param name="extractPdbs">Whether to extract PDBs.</param>
|
||||||
|
/// <param name="trapFile">The path of the trap file.</param>
|
||||||
|
/// <param name="extracted">Whether the file was extracted (false=cached).</param>
|
||||||
|
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, TrapWriter.CompressionMode trapCompression, out string trapFile, out bool extracted)
|
||||||
|
{
|
||||||
|
trapFile = "";
|
||||||
|
extracted = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
|
||||||
|
var pathTransformer = new PathTransformer(canonicalPathCache);
|
||||||
|
var extractor = new Extractor(false, assemblyPath, logger, pathTransformer);
|
||||||
|
var transformedAssemblyPath = pathTransformer.Transform(assemblyPath);
|
||||||
|
var project = layout.LookupProjectOrDefault(transformedAssemblyPath);
|
||||||
|
using var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), trapCompression, discardDuplicates: true);
|
||||||
|
trapFile = trapWriter.TrapFile;
|
||||||
|
if (nocache || !System.IO.File.Exists(trapFile))
|
||||||
|
{
|
||||||
|
ExtractCIL(extractor, trapWriter, extractPdbs);
|
||||||
|
extracted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||||
|
{
|
||||||
|
logger.Log(Severity.Error, string.Format("Exception extracting {0}: {1}", assemblyPath, ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,11 +9,11 @@ namespace Semmle.Extraction.CIL
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides methods for creating and caching various entities.
|
/// Provides methods for creating and caching various entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Context
|
internal sealed partial class Context
|
||||||
{
|
{
|
||||||
private readonly Dictionary<object, Label> ids = new Dictionary<object, Label>();
|
private readonly Dictionary<object, Label> ids = new Dictionary<object, Label>();
|
||||||
|
|
||||||
public T Populate<T>(T e) where T : IExtractedEntity
|
internal T Populate<T>(T e) where T : IExtractedEntity
|
||||||
{
|
{
|
||||||
if (e.Label.Valid)
|
if (e.Label.Valid)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace Semmle.Extraction.CIL
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
e.Label = GetNewLabel();
|
e.Label = GetNewLabel();
|
||||||
DefineLabel(e, TrapWriter.Writer, Extractor);
|
DefineLabel(e);
|
||||||
ids.Add(e, e.Label);
|
ids.Add(e, e.Label);
|
||||||
PopulateLater(() =>
|
PopulateLater(() =>
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ namespace Semmle.Extraction.CIL
|
||||||
{
|
{
|
||||||
Label = GetNewLabel()
|
Label = GetNewLabel()
|
||||||
};
|
};
|
||||||
DefineLabel(e, TrapWriter.Writer, Extractor);
|
DefineLabel(e);
|
||||||
primitiveTypes[(int)code] = e;
|
primitiveTypes[(int)code] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// Adds additional context that is specific for CIL extraction.
|
/// Adds additional context that is specific for CIL extraction.
|
||||||
/// One context = one DLL/EXE.
|
/// One context = one DLL/EXE.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class Context : Extraction.Context, IDisposable
|
internal sealed partial class Context : Extraction.Context, IDisposable
|
||||||
{
|
{
|
||||||
private readonly FileStream stream;
|
private readonly FileStream stream;
|
||||||
private Entities.Assembly? assemblyNull;
|
private Entities.Assembly? assemblyNull;
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A generic context which does not contain any type parameters.
|
/// A generic context which does not contain any type parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EmptyContext : IGenericContext
|
internal class EmptyContext : IGenericContext
|
||||||
{
|
{
|
||||||
public EmptyContext(Context cx)
|
public EmptyContext(Context cx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Semmle.Util.Logging;
|
|
||||||
using System;
|
|
||||||
using Semmle.Extraction.Entities;
|
using Semmle.Extraction.Entities;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Semmle.Util;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An assembly to extract.
|
/// An assembly to extract.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Assembly : LabelledEntity, ILocation
|
internal class Assembly : LabelledEntity, ILocation
|
||||||
{
|
{
|
||||||
private readonly File file;
|
private readonly File file;
|
||||||
private readonly AssemblyName assemblyName;
|
private readonly AssemblyName assemblyName;
|
||||||
|
@ -101,48 +98,5 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ExtractCIL(Extractor extractor, TrapWriter trapWriter, bool extractPdbs)
|
|
||||||
{
|
|
||||||
using var cilContext = new Context(extractor, trapWriter, extractor.OutputPath, extractPdbs);
|
|
||||||
cilContext.Populate(new Assembly(cilContext));
|
|
||||||
cilContext.PopulateAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Main entry point to the CIL extractor.
|
|
||||||
/// Call this to extract a given assembly.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="layout">The trap layout.</param>
|
|
||||||
/// <param name="assemblyPath">The full path of the assembly to extract.</param>
|
|
||||||
/// <param name="logger">The logger.</param>
|
|
||||||
/// <param name="nocache">True to overwrite existing trap file.</param>
|
|
||||||
/// <param name="extractPdbs">Whether to extract PDBs.</param>
|
|
||||||
/// <param name="trapFile">The path of the trap file.</param>
|
|
||||||
/// <param name="extracted">Whether the file was extracted (false=cached).</param>
|
|
||||||
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, bool nocache, bool extractPdbs, TrapWriter.CompressionMode trapCompression, out string trapFile, out bool extracted)
|
|
||||||
{
|
|
||||||
trapFile = "";
|
|
||||||
extracted = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var canonicalPathCache = CanonicalPathCache.Create(logger, 1000);
|
|
||||||
var pathTransformer = new PathTransformer(canonicalPathCache);
|
|
||||||
var extractor = new Extractor(false, assemblyPath, logger, pathTransformer);
|
|
||||||
var transformedAssemblyPath = pathTransformer.Transform(assemblyPath);
|
|
||||||
var project = layout.LookupProjectOrDefault(transformedAssemblyPath);
|
|
||||||
using var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), trapCompression, discardDuplicates: true);
|
|
||||||
trapFile = trapWriter.TrapFile;
|
|
||||||
if (nocache || !System.IO.File.Exists(trapFile))
|
|
||||||
{
|
|
||||||
ExtractCIL(extractor, trapWriter, extractPdbs);
|
|
||||||
extracted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
|
||||||
{
|
|
||||||
logger.Log(Severity.Error, string.Format("Exception extracting {0}: {1}", assemblyPath, ex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A CIL entity which has been extracted.
|
/// A CIL entity which has been extracted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IExtractedEntity : IExtractionProduct, IEntity
|
internal interface IExtractedEntity : IExtractionProduct, IEntity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The contents of the entity.
|
/// The contents of the entity.
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// - Enumerate Contents to produce more extraction products
|
/// - Enumerate Contents to produce more extraction products
|
||||||
/// - Extract these until there is nothing left to extract
|
/// - Extract these until there is nothing left to extract
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public interface IExtractionProduct
|
internal interface IExtractionProduct
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform further extraction/population of this item as necessary.
|
/// Perform further extraction/population of this item as necessary.
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// When we decode a type/method signature, we need access to
|
/// When we decode a type/method signature, we need access to
|
||||||
/// generic parameters.
|
/// generic parameters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IGenericContext
|
internal interface IGenericContext
|
||||||
{
|
{
|
||||||
Context Cx { get; }
|
Context Cx { get; }
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// An entity that needs to be populated during extraction.
|
/// An entity that needs to be populated during extraction.
|
||||||
/// This assigns a key and optionally extracts its contents.
|
/// This assigns a key and optionally extracts its contents.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LabelledEntity : Extraction.LabelledEntity, IExtractedEntity
|
internal abstract class LabelledEntity : Extraction.LabelledEntity, IExtractedEntity
|
||||||
{
|
{
|
||||||
// todo: with .NET 5 this can override the base context, and change the return type.
|
// todo: with .NET 5 this can override the base context, and change the return type.
|
||||||
public Context Cx => (Context)base.Context;
|
public Context Cx => (Context)base.Context;
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Semmle.Extraction.CIL
|
||||||
/// An entity that has contents to extract. There is no need to populate
|
/// An entity that has contents to extract. There is no need to populate
|
||||||
/// a key as it's done in the contructor.
|
/// a key as it's done in the contructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class UnlabelledEntity : Extraction.UnlabelledEntity, IExtractedEntity
|
internal abstract class UnlabelledEntity : Extraction.UnlabelledEntity, IExtractedEntity
|
||||||
{
|
{
|
||||||
// todo: with .NET 5 this can override the base context, and change the return type.
|
// todo: with .NET 5 this can override the base context, and change the return type.
|
||||||
public Context Cx => (Context)base.Context;
|
public Context Cx => (Context)base.Context;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A constructed type.
|
/// A constructed type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ConstructedType : Type
|
internal sealed class ConstructedType : Type
|
||||||
{
|
{
|
||||||
private readonly Type unboundGenericType;
|
private readonly Type unboundGenericType;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
public class File : LabelledEntity, IFileOrFolder
|
internal class File : LabelledEntity, IFileOrFolder
|
||||||
{
|
{
|
||||||
protected string OriginalPath { get; }
|
protected string OriginalPath { get; }
|
||||||
protected PathTransformer.ITransformedPath TransformedPath { get; }
|
protected PathTransformer.ITransformedPath TransformedPath { get; }
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
public sealed class Folder : LabelledEntity, IFileOrFolder
|
internal sealed class Folder : LabelledEntity, IFileOrFolder
|
||||||
{
|
{
|
||||||
private readonly PathTransformer.ITransformedPath transformedPath;
|
private readonly PathTransformer.ITransformedPath transformedPath;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A namespace.
|
/// A namespace.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class Namespace : TypeContainer
|
internal sealed class Namespace : TypeContainer
|
||||||
{
|
{
|
||||||
public Namespace? ParentNamespace { get; }
|
public Namespace? ParentNamespace { get; }
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
public class PdbSourceFile : File
|
internal class PdbSourceFile : File
|
||||||
{
|
{
|
||||||
private readonly PDB.ISourceFile file;
|
private readonly PDB.ISourceFile file;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
public sealed class PrimitiveType : Type
|
internal sealed class PrimitiveType : Type
|
||||||
{
|
{
|
||||||
private readonly PrimitiveTypeCode typeCode;
|
private readonly PrimitiveTypeCode typeCode;
|
||||||
public PrimitiveType(Context cx, PrimitiveTypeCode tc) : base(cx)
|
public PrimitiveType(Context cx, PrimitiveTypeCode tc) : base(cx)
|
||||||
|
|
|
@ -4,7 +4,7 @@ using Semmle.Extraction.PDB;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
public sealed class PdbSourceLocation : LabelledEntity, ILocation
|
internal sealed class PdbSourceLocation : LabelledEntity, ILocation
|
||||||
{
|
{
|
||||||
private readonly Location location;
|
private readonly Location location;
|
||||||
private readonly PdbSourceFile file;
|
private readonly PdbSourceFile file;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A type.
|
/// A type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Type : TypeContainer, IMember
|
internal abstract class Type : TypeContainer, IMember
|
||||||
{
|
{
|
||||||
internal const string AssemblyTypeNameSeparator = "::";
|
internal const string AssemblyTypeNameSeparator = "::";
|
||||||
internal const string PrimitiveTypePrefix = "builtin" + AssemblyTypeNameSeparator + "System.";
|
internal const string PrimitiveTypePrefix = "builtin" + AssemblyTypeNameSeparator + "System.";
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for all type containers (namespaces, types, methods).
|
/// Base class for all type containers (namespaces, types, methods).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class TypeContainer : LabelledEntity, IGenericContext
|
internal abstract class TypeContainer : LabelledEntity, IGenericContext
|
||||||
{
|
{
|
||||||
protected TypeContainer(Context cx) : base(cx)
|
protected TypeContainer(Context cx) : base(cx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A type defined in the current assembly.
|
/// A type defined in the current assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class TypeDefinitionType : Type
|
internal sealed class TypeDefinitionType : Type
|
||||||
{
|
{
|
||||||
private readonly TypeDefinitionHandle handle;
|
private readonly TypeDefinitionHandle handle;
|
||||||
private readonly TypeDefinition td;
|
private readonly TypeDefinition td;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A type reference, to a type in a referenced assembly.
|
/// A type reference, to a type in a referenced assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class TypeReferenceType : Type
|
internal sealed class TypeReferenceType : Type
|
||||||
{
|
{
|
||||||
private readonly TypeReferenceHandle handle;
|
private readonly TypeReferenceHandle handle;
|
||||||
private readonly TypeReference tr;
|
private readonly TypeReference tr;
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes a type signature and produces a Type, for use by DecodeSignature() and friends.
|
/// Decodes a type signature and produces a Type, for use by DecodeSignature() and friends.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TypeSignatureDecoder : ISignatureTypeProvider<Type, IGenericContext>
|
internal class TypeSignatureDecoder : ISignatureTypeProvider<Type, IGenericContext>
|
||||||
{
|
{
|
||||||
private readonly Context cx;
|
private readonly Context cx;
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ namespace Semmle.Extraction.CSharp
|
||||||
{
|
{
|
||||||
var stopwatch = new Stopwatch();
|
var stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
CIL.Entities.Assembly.ExtractCIL(layout, r.FilePath, Logger, !options.Cache, options.PDB, options.TrapCompression, out var trapFile, out var extracted);
|
CIL.Analyser.ExtractCIL(layout, r.FilePath, Logger, !options.Cache, options.PDB, options.TrapCompression, out var trapFile, out var extracted);
|
||||||
stopwatch.Stop();
|
stopwatch.Stop();
|
||||||
ReportProgress(r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
ReportProgress(r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp
|
namespace Semmle.Extraction.CSharp
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A factory for creating cached entities.
|
/// A factory for creating cached entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class CachedEntityFactory<TInit, TEntity>
|
internal abstract class CachedEntityFactory<TInit, TEntity>
|
||||||
: Extraction.CachedEntityFactory<TInit, TEntity> where TEntity : CachedEntity
|
: Extraction.CachedEntityFactory<TInit, TEntity> where TEntity : CachedEntity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Semmle.Extraction.Entities;
|
using Semmle.Extraction.Entities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp
|
namespace Semmle.Extraction.CSharp
|
||||||
{
|
{
|
||||||
|
@ -9,7 +10,7 @@ namespace Semmle.Extraction.CSharp
|
||||||
/// State that needs to be available throughout the extraction process.
|
/// State that needs to be available throughout the extraction process.
|
||||||
/// There is one Context object per trap output file.
|
/// There is one Context object per trap output file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Context : Extraction.Context
|
internal class Context : Extraction.Context
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The program database provided by Roslyn.
|
/// The program database provided by Roslyn.
|
||||||
|
@ -50,7 +51,7 @@ namespace Semmle.Extraction.CSharp
|
||||||
|
|
||||||
public bool IsAssemblyScope => scope is AssemblyScope;
|
public bool IsAssemblyScope => scope is AssemblyScope;
|
||||||
|
|
||||||
public SyntaxTree SourceTree => scope is SourceScope sc ? sc.SourceTree : null;
|
private SyntaxTree SourceTree => scope is SourceScope sc ? sc.SourceTree : null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the given symbol needs to be defined in this context.
|
/// Whether the given symbol needs to be defined in this context.
|
||||||
|
@ -116,5 +117,28 @@ namespace Semmle.Extraction.CSharp
|
||||||
loc = null;
|
loc = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly HashSet<Label> extractedGenerics = new HashSet<Label>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the given entity be extracted?
|
||||||
|
/// A second call to this method will always return false,
|
||||||
|
/// on the assumption that it would have been extracted on the first call.
|
||||||
|
///
|
||||||
|
/// This is used to track the extraction of generics, which cannot be extracted
|
||||||
|
/// in a top-down manner.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">The entity to extract.</param>
|
||||||
|
/// <returns>True only on the first call for a particular entity.</returns>
|
||||||
|
internal bool ExtractGenerics(CachedEntity entity)
|
||||||
|
{
|
||||||
|
if (extractedGenerics.Contains(entity.Label))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
extractedGenerics.Add(entity.Label);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public class Assembly : Extraction.Entities.Location
|
internal class Assembly : Extraction.Entities.Location
|
||||||
{
|
{
|
||||||
// todo: this can be changed to an override after the .NET 5 upgrade
|
// todo: this can be changed to an override after the .NET 5 upgrade
|
||||||
private new Context Context => (Context)base.Context;
|
private new Context Context => (Context)base.Context;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public abstract class CachedEntity<T> : Extraction.CachedEntity<T>
|
internal abstract class CachedEntity<T> : Extraction.CachedEntity<T>
|
||||||
{
|
{
|
||||||
// todo: this can be changed to an override after the .NET 5 upgrade
|
// todo: this can be changed to an override after the .NET 5 upgrade
|
||||||
protected new Context Context => (Context)base.Context;
|
protected new Context Context => (Context)base.Context;
|
||||||
|
|
|
@ -9,7 +9,7 @@ using System.Reflection.Metadata.Ecma335;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public abstract class CachedSymbol<T> : CachedEntity<T> where T : ISymbol
|
internal abstract class CachedSymbol<T> : CachedEntity<T> where T : ISymbol
|
||||||
{
|
{
|
||||||
// todo: this can be changed to an override after the .NET 5 upgrade
|
// todo: this can be changed to an override after the .NET 5 upgrade
|
||||||
protected new Context Context => (Context)base.Context;
|
protected new Context Context => (Context)base.Context;
|
||||||
|
|
|
@ -6,7 +6,7 @@ using Semmle.Util;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public class Compilation : CachedEntity<object>
|
internal class Compilation : CachedEntity<object>
|
||||||
{
|
{
|
||||||
private static (string Cwd, string[] Args) settings;
|
private static (string Cwd, string[] Args) settings;
|
||||||
private static int hashCode;
|
private static int hashCode;
|
||||||
|
|
|
@ -8,7 +8,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public class Constructor : Method
|
internal class Constructor : Method
|
||||||
{
|
{
|
||||||
private Constructor(Context cx, IMethodSymbol init)
|
private Constructor(Context cx, IMethodSymbol init)
|
||||||
: base(cx, init) { }
|
: base(cx, init) { }
|
||||||
|
|
|
@ -23,12 +23,13 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||||
|
|
||||||
private static ExprKind GetKind(Context cx, BinaryExpressionSyntax node)
|
private static ExprKind GetKind(Context cx, BinaryExpressionSyntax node)
|
||||||
{
|
{
|
||||||
var k = GetBinaryTokenKind(cx, node.OperatorToken.Kind());
|
var k = GetBinaryTokenKind(cx, node);
|
||||||
return GetCallType(cx, node).AdjustKind(k);
|
return GetCallType(cx, node).AdjustKind(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ExprKind GetBinaryTokenKind(Context cx, SyntaxKind kind)
|
private static ExprKind GetBinaryTokenKind(Context cx, BinaryExpressionSyntax node)
|
||||||
{
|
{
|
||||||
|
var kind = node.OperatorToken.Kind();
|
||||||
switch (kind)
|
switch (kind)
|
||||||
{
|
{
|
||||||
case SyntaxKind.LessThanToken: return ExprKind.LT;
|
case SyntaxKind.LessThanToken: return ExprKind.LT;
|
||||||
|
@ -54,7 +55,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||||
case SyntaxKind.QuestionQuestionToken: return ExprKind.NULL_COALESCING;
|
case SyntaxKind.QuestionQuestionToken: return ExprKind.NULL_COALESCING;
|
||||||
// !! And the rest
|
// !! And the rest
|
||||||
default:
|
default:
|
||||||
cx.ModelError($"Unhandled operator type {kind}");
|
cx.ModelError(node, $"Unhandled operator type {kind}");
|
||||||
return ExprKind.UNKNOWN;
|
return ExprKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||||
ObjectInitializer.Create(new ExpressionNodeInfo(Context, Syntax.Initializer, this, -1).SetType(Type));
|
ObjectInitializer.Create(new ExpressionNodeInfo(Context, Syntax.Initializer, this, -1).SetType(Type));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Context.ModelError("Unhandled initializer in object creation");
|
Context.ModelError(Syntax.Initializer, "Unhandled initializer in object creation");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public class File : Extraction.Entities.File
|
internal class File : Extraction.Entities.File
|
||||||
{
|
{
|
||||||
// todo: this can be changed to an override after the .NET 5 upgrade
|
// todo: this can be changed to an override after the .NET 5 upgrade
|
||||||
private new Context Context => (Context)base.Context;
|
private new Context Context => (Context)base.Context;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public abstract class FreshEntity : Extraction.FreshEntity
|
internal abstract class FreshEntity : Extraction.FreshEntity
|
||||||
{
|
{
|
||||||
// todo: this can be changed to an override after the .NET 5 upgrade
|
// todo: this can be changed to an override after the .NET 5 upgrade
|
||||||
protected new Context Context => (Context)base.Context;
|
protected new Context Context => (Context)base.Context;
|
||||||
|
|
|
@ -8,7 +8,7 @@ using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public abstract class Method : CachedSymbol<IMethodSymbol>, IExpressionParentEntity, IStatementParentEntity
|
internal abstract class Method : CachedSymbol<IMethodSymbol>, IExpressionParentEntity, IStatementParentEntity
|
||||||
{
|
{
|
||||||
protected Method(Context cx, IMethodSymbol init)
|
protected Method(Context cx, IMethodSymbol init)
|
||||||
: base(cx, init) { }
|
: base(cx, init) { }
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public class NonGeneratedSourceLocation : Extraction.Entities.SourceLocation
|
internal class NonGeneratedSourceLocation : Extraction.Entities.SourceLocation
|
||||||
{
|
{
|
||||||
// todo: this can be changed to an override after the .NET 5 upgrade
|
// todo: this can be changed to an override after the .NET 5 upgrade
|
||||||
private new Context Context => (Context)base.Context;
|
private new Context Context => (Context)base.Context;
|
||||||
|
|
|
@ -7,7 +7,7 @@ using System.IO;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public class Parameter : CachedSymbol<IParameterSymbol>, IExpressionParentEntity
|
internal class Parameter : CachedSymbol<IParameterSymbol>, IExpressionParentEntity
|
||||||
{
|
{
|
||||||
protected IEntity Parent { get; set; }
|
protected IEntity Parent { get; set; }
|
||||||
protected Parameter Original { get; }
|
protected Parameter Original { get; }
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public sealed class Nullability
|
internal sealed class Nullability
|
||||||
{
|
{
|
||||||
public int Annotation { get; }
|
public int Annotation { get; }
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NullabilityEntity : CachedEntity<Nullability>
|
internal class NullabilityEntity : CachedEntity<Nullability>
|
||||||
{
|
{
|
||||||
public NullabilityEntity(Context cx, Nullability init) : base(cx, init)
|
public NullabilityEntity(Context cx, Nullability init) : base(cx, init)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
{
|
{
|
||||||
public abstract class Type : CachedSymbol<ITypeSymbol>
|
internal abstract class Type : CachedSymbol<ITypeSymbol>
|
||||||
{
|
{
|
||||||
protected Type(Context cx, ITypeSymbol init)
|
protected Type(Context cx, ITypeSymbol init)
|
||||||
: base(cx, init) { }
|
: base(cx, init) { }
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||||
var returnType = Type.Create(Context, Symbol.ReturnType);
|
var returnType = Type.Create(Context, Symbol.ReturnType);
|
||||||
trapFile.operators(this,
|
trapFile.operators(this,
|
||||||
Symbol.Name,
|
Symbol.Name,
|
||||||
OperatorSymbol(Context, Symbol.Name),
|
OperatorSymbol(Context, Symbol),
|
||||||
ContainingType,
|
ContainingType,
|
||||||
returnType.TypeRef,
|
returnType.TypeRef,
|
||||||
(UserOperator)OriginalDefinition);
|
(UserOperator)OriginalDefinition);
|
||||||
|
@ -176,10 +176,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||||
/// <param name="cx">Extractor context.</param>
|
/// <param name="cx">Extractor context.</param>
|
||||||
/// <param name="methodName">The method name.</param>
|
/// <param name="methodName">The method name.</param>
|
||||||
/// <returns>The converted name.</returns>
|
/// <returns>The converted name.</returns>
|
||||||
public static string OperatorSymbol(Context cx, string methodName)
|
private static string OperatorSymbol(Context cx, IMethodSymbol method)
|
||||||
{
|
{
|
||||||
|
var methodName = method.Name;
|
||||||
if (!OperatorSymbol(methodName, out var result))
|
if (!OperatorSymbol(methodName, out var result))
|
||||||
cx.ModelError($"Unhandled operator name in OperatorSymbol(): '{methodName}'");
|
cx.ModelError(method, $"Unhandled operator name in OperatorSymbol(): '{methodName}'");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Populators
|
namespace Semmle.Extraction.CSharp.Populators
|
||||||
{
|
{
|
||||||
public class TypeContainerVisitor : CSharpSyntaxVisitor
|
internal class TypeContainerVisitor : CSharpSyntaxVisitor
|
||||||
{
|
{
|
||||||
protected Context Cx { get; }
|
protected Context Cx { get; }
|
||||||
protected IEntity Parent { get; }
|
protected IEntity Parent { get; }
|
||||||
|
|
|
@ -35,19 +35,19 @@ namespace Semmle.Extraction
|
||||||
// A recursion guard against writing to the trap file whilst writing an id to the trap file.
|
// A recursion guard against writing to the trap file whilst writing an id to the trap file.
|
||||||
private bool writingLabel = false;
|
private bool writingLabel = false;
|
||||||
|
|
||||||
public void DefineLabel(IEntity entity, TextWriter trapFile, Extractor extractor)
|
protected void DefineLabel(IEntity entity)
|
||||||
{
|
{
|
||||||
if (writingLabel)
|
if (writingLabel)
|
||||||
{
|
{
|
||||||
// Don't define a label whilst writing a label.
|
// Don't define a label whilst writing a label.
|
||||||
PopulateLater(() => DefineLabel(entity, trapFile, extractor));
|
PopulateLater(() => DefineLabel(entity));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
writingLabel = true;
|
writingLabel = true;
|
||||||
entity.DefineLabel(trapFile, extractor);
|
entity.DefineLabel(TrapWriter.Writer, Extractor);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -70,13 +70,13 @@ namespace Semmle.Extraction
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public Label GetNewLabel() => new Label(GetNewId());
|
protected Label GetNewLabel() => new Label(GetNewId());
|
||||||
|
|
||||||
public TEntity CreateEntity<TInit, TEntity>(CachedEntityFactory<TInit, TEntity> factory, object cacheKey, TInit init)
|
internal TEntity CreateEntity<TInit, TEntity>(CachedEntityFactory<TInit, TEntity> factory, object cacheKey, TInit init)
|
||||||
where TEntity : CachedEntity =>
|
where TEntity : CachedEntity =>
|
||||||
cacheKey is ISymbol s ? CreateEntity(factory, s, init, symbolEntityCache) : CreateEntity(factory, cacheKey, init, objectEntityCache);
|
cacheKey is ISymbol s ? CreateEntity(factory, s, init, symbolEntityCache) : CreateEntity(factory, cacheKey, init, objectEntityCache);
|
||||||
|
|
||||||
public TEntity CreateEntityFromSymbol<TSymbol, TEntity>(CachedEntityFactory<TSymbol, TEntity> factory, TSymbol init)
|
internal TEntity CreateEntityFromSymbol<TSymbol, TEntity>(CachedEntityFactory<TSymbol, TEntity> factory, TSymbol init)
|
||||||
where TSymbol : ISymbol
|
where TSymbol : ISymbol
|
||||||
where TEntity : CachedEntity => CreateEntity(factory, init, init, symbolEntityCache);
|
where TEntity : CachedEntity => CreateEntity(factory, init, init, symbolEntityCache);
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ namespace Semmle.Extraction
|
||||||
|
|
||||||
dictionary[cacheKey] = entity;
|
dictionary[cacheKey] = entity;
|
||||||
|
|
||||||
DefineLabel(entity, TrapWriter.Writer, Extractor);
|
DefineLabel(entity);
|
||||||
if (entity.NeedsPopulation)
|
if (entity.NeedsPopulation)
|
||||||
Populate(init as ISymbol, entity);
|
Populate(init as ISymbol, entity);
|
||||||
|
|
||||||
|
@ -117,32 +117,11 @@ namespace Semmle.Extraction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should the given entity be extracted?
|
|
||||||
/// A second call to this method will always return false,
|
|
||||||
/// on the assumption that it would have been extracted on the first call.
|
|
||||||
///
|
|
||||||
/// This is used to track the extraction of generics, which cannot be extracted
|
|
||||||
/// in a top-down manner.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity">The entity to extract.</param>
|
|
||||||
/// <returns>True only on the first call for a particular entity.</returns>
|
|
||||||
public bool ExtractGenerics(CachedEntity entity)
|
|
||||||
{
|
|
||||||
if (extractedGenerics.Contains(entity.Label))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
extractedGenerics.Add(entity.Label);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a fresh label with ID "*", and set it on the
|
/// Creates a fresh label with ID "*", and set it on the
|
||||||
/// supplied <paramref name="entity"/> object.
|
/// supplied <paramref name="entity"/> object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void AddFreshLabel(Entity entity)
|
internal void AddFreshLabel(Entity entity)
|
||||||
{
|
{
|
||||||
entity.Label = GetNewLabel();
|
entity.Label = GetNewLabel();
|
||||||
entity.DefineFreshLabel(TrapWriter.Writer);
|
entity.DefineFreshLabel(TrapWriter.Writer);
|
||||||
|
@ -154,7 +133,6 @@ namespace Semmle.Extraction
|
||||||
|
|
||||||
private readonly IDictionary<object, CachedEntity> objectEntityCache = new Dictionary<object, CachedEntity>();
|
private readonly IDictionary<object, CachedEntity> objectEntityCache = new Dictionary<object, CachedEntity>();
|
||||||
private readonly IDictionary<ISymbol, CachedEntity> symbolEntityCache = new Dictionary<ISymbol, CachedEntity>(10000, SymbolEqualityComparer.Default);
|
private readonly IDictionary<ISymbol, CachedEntity> symbolEntityCache = new Dictionary<ISymbol, CachedEntity>(10000, SymbolEqualityComparer.Default);
|
||||||
private readonly HashSet<Label> extractedGenerics = new HashSet<Label>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queue of items to populate later.
|
/// Queue of items to populate later.
|
||||||
|
@ -204,11 +182,11 @@ namespace Semmle.Extraction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context(Extractor e, TrapWriter trapWriter, bool addAssemblyTrapPrefix = false)
|
protected Context(Extractor extractor, TrapWriter trapWriter, bool shouldAddAssemblyTrapPrefix = false)
|
||||||
{
|
{
|
||||||
Extractor = e;
|
Extractor = extractor;
|
||||||
TrapWriter = trapWriter;
|
TrapWriter = trapWriter;
|
||||||
ShouldAddAssemblyTrapPrefix = addAssemblyTrapPrefix;
|
ShouldAddAssemblyTrapPrefix = shouldAddAssemblyTrapPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int currentRecursiveDepth = 0;
|
private int currentRecursiveDepth = 0;
|
||||||
|
@ -277,7 +255,7 @@ namespace Semmle.Extraction
|
||||||
/// <param name="optionalSymbol">Symbol for reporting errors.</param>
|
/// <param name="optionalSymbol">Symbol for reporting errors.</param>
|
||||||
/// <param name="entity">The entity to populate.</param>
|
/// <param name="entity">The entity to populate.</param>
|
||||||
/// <exception cref="InternalError">Thrown on invalid trap stack behaviour.</exception>
|
/// <exception cref="InternalError">Thrown on invalid trap stack behaviour.</exception>
|
||||||
public void Populate(ISymbol? optionalSymbol, CachedEntity entity)
|
private void Populate(ISymbol? optionalSymbol, CachedEntity entity)
|
||||||
{
|
{
|
||||||
if (writingLabel)
|
if (writingLabel)
|
||||||
{
|
{
|
||||||
|
@ -372,7 +350,7 @@ namespace Semmle.Extraction
|
||||||
/// <param name="message">The text of the message.</param>
|
/// <param name="message">The text of the message.</param>
|
||||||
/// <param name="optionalSymbol">The symbol of the error, or null.</param>
|
/// <param name="optionalSymbol">The symbol of the error, or null.</param>
|
||||||
/// <param name="optionalEntity">The entity of the error, or null.</param>
|
/// <param name="optionalEntity">The entity of the error, or null.</param>
|
||||||
public void ExtractionError(string message, ISymbol? optionalSymbol, Entity optionalEntity)
|
private void ExtractionError(string message, ISymbol? optionalSymbol, Entity optionalEntity)
|
||||||
{
|
{
|
||||||
if (!(optionalSymbol is null))
|
if (!(optionalSymbol is null))
|
||||||
{
|
{
|
||||||
|
@ -392,9 +370,9 @@ namespace Semmle.Extraction
|
||||||
/// Log an extraction message.
|
/// Log an extraction message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="msg">The message to log.</param>
|
/// <param name="msg">The message to log.</param>
|
||||||
public void ExtractionError(Message msg)
|
private void ExtractionError(Message msg)
|
||||||
{
|
{
|
||||||
new Entities.ExtractionMessage(this, msg);
|
new ExtractionMessage(this, msg);
|
||||||
Extractor.Message(msg);
|
Extractor.Message(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +390,7 @@ namespace Semmle.Extraction
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signal an error in the program model.
|
/// Signal an error in the program model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="node">Symbol causing the error.</param>
|
/// <param name="symbol">Symbol causing the error.</param>
|
||||||
/// <param name="msg">The error message.</param>
|
/// <param name="msg">The error message.</param>
|
||||||
public void ModelError(ISymbol symbol, string msg)
|
public void ModelError(ISymbol symbol, string msg)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче