mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
C#: Fix up test output
C#: Fix a qltest whereby a tuple type having multiple underlying types was causing an issue with the IR sanity checks. C#: Revert more changes. C#: Fix tests and remove dead code.
This commit is contained in:
@@ -204,7 +204,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (type.ContainsTypeParameters(cx, method))
|
||||
type.BuildTypeId(cx, trapFile, (cx0, tb0, type0) => AddSignatureTypeToId(cx, tb0, method, type0));
|
||||
else
|
||||
trapFile.WriteSubId(Type.Create(cx, type).TypeRef);
|
||||
trapFile.WriteSubId(Type.Create(cx, type));
|
||||
}
|
||||
|
||||
protected static void AddParametersToId(Context cx, TextWriter trapFile, IMethodSymbol method)
|
||||
|
||||
@@ -86,8 +86,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.Write(";parameter");
|
||||
}
|
||||
|
||||
// If we don't have the type of the parameter, do not populate it.
|
||||
public override bool NeedsPopulation => symbol.Type.TypeKind != TypeKind.Error;
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
string Name
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
trapFile.typeref_type((TypeRef)TypeRef, this);
|
||||
trapFile.typeref_type((NamedTypeRef)TypeRef, this);
|
||||
|
||||
if (symbol.IsGenericType)
|
||||
{
|
||||
@@ -151,39 +151,34 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init);
|
||||
}
|
||||
|
||||
public override Type TypeRef => Entities.TypeRef.Create(Context, this, symbol);
|
||||
public override Type TypeRef => NamedTypeRef.Create(Context, symbol);
|
||||
}
|
||||
|
||||
class TypeRef : Type<ITypeSymbol>
|
||||
class NamedTypeRef : Type<INamedTypeSymbol>
|
||||
{
|
||||
readonly Type referencedType;
|
||||
|
||||
public TypeRef(Context cx, Type type, ITypeSymbol symbol) : base(cx, symbol)
|
||||
public NamedTypeRef(Context cx, INamedTypeSymbol symbol) : base(cx, symbol)
|
||||
{
|
||||
referencedType = type;
|
||||
referencedType = Type.Create(cx, symbol);
|
||||
}
|
||||
|
||||
public static TypeRef Create(Context cx, Type referencedType, ITypeSymbol type) =>
|
||||
NamedTypeRefFactory.Instance.CreateEntity2(cx, (referencedType, type));
|
||||
public static NamedTypeRef Create(Context cx, INamedTypeSymbol type) =>
|
||||
NamedTypeRefFactory.Instance.CreateEntity2(cx, type);
|
||||
|
||||
class NamedTypeRefFactory : ICachedEntityFactory<(Type, ITypeSymbol), TypeRef>
|
||||
class NamedTypeRefFactory : ICachedEntityFactory<INamedTypeSymbol, NamedTypeRef>
|
||||
{
|
||||
public static readonly NamedTypeRefFactory Instance = new NamedTypeRefFactory();
|
||||
|
||||
public TypeRef Create(Context cx, (Type, ITypeSymbol) init) => new TypeRef(cx, init.Item1, init.Item2);
|
||||
public NamedTypeRef Create(Context cx, INamedTypeSymbol init) => new NamedTypeRef(cx, init);
|
||||
}
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void WriteId(TextWriter trapFile)
|
||||
{
|
||||
void ExpandType(Context cx0, TextWriter tb0, ITypeSymbol sub)
|
||||
{
|
||||
sub.BuildTypeId(cx0, tb0, ExpandType);
|
||||
}
|
||||
|
||||
symbol.BuildTypeId(Context, trapFile, ExpandType);
|
||||
trapFile.Write(";typeref");
|
||||
trapFile.WriteSubId(referencedType);
|
||||
trapFile.Write(";typeRef");
|
||||
}
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
PopulateGenerics();
|
||||
|
||||
var underlyingType = NamedType.Create(Context, symbol.TupleUnderlyingType);
|
||||
trapFile.tuple_underlying_type(this, underlyingType.TypeRef);
|
||||
trapFile.tuple_underlying_type(this, underlyingType);
|
||||
|
||||
int index = 0;
|
||||
foreach (var element in TupleElements)
|
||||
|
||||
@@ -95,7 +95,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var baseTypes = new List<Type>();
|
||||
if (symbol.BaseType != null)
|
||||
{
|
||||
// !! Do not extend "object" if the base type is missing :-(
|
||||
Type baseKey = Create(Context, symbol.BaseType);
|
||||
trapFile.extend(this, baseKey.TypeRef);
|
||||
if (symbol.TypeKind != TypeKind.Struct)
|
||||
@@ -269,7 +268,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public static Type Create(Context cx, ITypeSymbol type)
|
||||
{
|
||||
type = type.DisambiguateType();
|
||||
|
||||
const bool errorTypeIsNull = false;
|
||||
return type == null || (errorTypeIsNull && type.TypeKind == TypeKind.Error) ?
|
||||
NullType.Create(cx).Type : (Type)cx.CreateEntity(type);
|
||||
|
||||
@@ -120,8 +120,7 @@ namespace Semmle.Extraction.CSharp
|
||||
var syntaxTrees = new List<SyntaxTree>();
|
||||
var syntaxTreeTasks = ReadSyntaxTrees(
|
||||
compilerArguments.SourceFiles.
|
||||
Select(src => canonicalPathCache.GetCanonicalPath(src.Path)).
|
||||
Where(f => !f.EndsWith(".dll")),
|
||||
Select(src => canonicalPathCache.GetCanonicalPath(src.Path)),
|
||||
analyser,
|
||||
compilerArguments.ParseOptions,
|
||||
compilerArguments.Encoding,
|
||||
|
||||
@@ -4,8 +4,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
@@ -135,34 +133,15 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="subTermAction">The action to apply to syntactic sub terms of this type.</param>
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
||||
{
|
||||
switch(type.SpecialType)
|
||||
if (type.SpecialType != SpecialType.None)
|
||||
{
|
||||
case SpecialType.System_Object:
|
||||
case SpecialType.System_Void:
|
||||
case SpecialType.System_Boolean:
|
||||
case SpecialType.System_Char:
|
||||
case SpecialType.System_SByte:
|
||||
case SpecialType.System_Byte:
|
||||
case SpecialType.System_Int16:
|
||||
case SpecialType.System_UInt16:
|
||||
case SpecialType.System_Int32:
|
||||
case SpecialType.System_UInt32:
|
||||
case SpecialType.System_Int64:
|
||||
case SpecialType.System_UInt64:
|
||||
case SpecialType.System_Decimal:
|
||||
case SpecialType.System_Single:
|
||||
case SpecialType.System_Double:
|
||||
case SpecialType.System_String:
|
||||
case SpecialType.System_IntPtr:
|
||||
case SpecialType.System_UIntPtr:
|
||||
|
||||
/*
|
||||
* Use the keyword ("int" etc) for the built-in types.
|
||||
* This makes the IDs shorter and means that all built-in types map to
|
||||
* the same entities (even when using multiple versions of mscorlib).
|
||||
*/
|
||||
trapFile.Write(type.ToDisplayString());
|
||||
return;
|
||||
/*
|
||||
* Use the keyword ("int" etc) for the built-in types.
|
||||
* This makes the IDs shorter and means that all built-in types map to
|
||||
* the same entities (even when using multiple versions of mscorlib).
|
||||
*/
|
||||
trapFile.Write(type.ToDisplayString());
|
||||
return;
|
||||
}
|
||||
|
||||
using (cx.StackGuard)
|
||||
@@ -186,7 +165,7 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Pointer:
|
||||
var ptr = (IPointerTypeSymbol)type;
|
||||
subTermAction(cx, trapFile, ptr.PointedAtType);
|
||||
trapFile.Write("*");
|
||||
trapFile.Write('*');
|
||||
return;
|
||||
case TypeKind.TypeParameter:
|
||||
var tp = (ITypeParameterSymbol)type;
|
||||
@@ -214,28 +193,8 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write(']');
|
||||
}
|
||||
|
||||
private static void BuildAssembly(IAssemblySymbol asm, TextWriter trapFile, bool extraPrecise = false)
|
||||
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
||||
{
|
||||
var assembly = asm.Identity;
|
||||
trapFile.Write(assembly.Name);
|
||||
trapFile.Write('_');
|
||||
trapFile.Write(assembly.Version.Major);
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(assembly.Version.Minor);
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(assembly.Version.Build);
|
||||
if (extraPrecise)
|
||||
{
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(assembly.Version.Revision);
|
||||
}
|
||||
trapFile.Write("::");
|
||||
}
|
||||
|
||||
public static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
||||
{
|
||||
bool prefixAssembly = !(named.ContainingAssembly is null);
|
||||
|
||||
if (named.IsTupleType)
|
||||
{
|
||||
trapFile.Write('(');
|
||||
@@ -258,8 +217,6 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
else if (named.ContainingNamespace != null)
|
||||
{
|
||||
if (prefixAssembly)
|
||||
BuildAssembly(named.ContainingAssembly, trapFile);
|
||||
named.ContainingNamespace.BuildNamespace(cx, trapFile);
|
||||
}
|
||||
|
||||
@@ -290,6 +247,26 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter trapFile)
|
||||
{
|
||||
// Only include the assembly information in each type ID
|
||||
// for normal extractions. This is because standalone extractions
|
||||
// lack assembly information or may be ambiguous.
|
||||
bool prependAssemblyToTypeId = !cx.Extractor.Standalone && ns.ContainingAssembly != null;
|
||||
|
||||
if (prependAssemblyToTypeId)
|
||||
{
|
||||
// Note that we exclude the revision number as this has
|
||||
// been observed to be unstable.
|
||||
var assembly = ns.ContainingAssembly.Identity;
|
||||
trapFile.Write(assembly.Name);
|
||||
trapFile.Write('_');
|
||||
trapFile.Write(assembly.Version.Major);
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(assembly.Version.Minor);
|
||||
trapFile.Write('.');
|
||||
trapFile.Write(assembly.Version.Build);
|
||||
trapFile.Write("::");
|
||||
}
|
||||
|
||||
trapFile.WriteSubId(Namespace.Create(cx, ns));
|
||||
trapFile.Write('.');
|
||||
}
|
||||
@@ -379,7 +356,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
|
||||
trapFile.Write(namedType.Name);
|
||||
if (namedType.IsGenericType && namedType.TypeArguments.Any())
|
||||
if (namedType.IsGenericType && namedType.TypeKind != TypeKind.Error && namedType.TypeArguments.Any())
|
||||
{
|
||||
trapFile.Write('<');
|
||||
trapFile.BuildList(",", namedType.TypeArguments, (p, tb0) =>
|
||||
@@ -478,30 +455,6 @@ namespace Semmle.Extraction.CSharp
|
||||
public static SymbolInfo GetSymbolInfo(this Context cx, Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node) =>
|
||||
cx.GetModel(node).GetSymbolInfo(node);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the symbol for a particular syntax node.
|
||||
/// Throws an exception if the symbol is not found.
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// This gives a nicer message than a "null pointer exception",
|
||||
/// and should be used where we require a symbol to be resolved.
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="cx">The extraction context.</param>
|
||||
/// <param name="node">The syntax node.</param>
|
||||
/// <returns>The resolved symbol.</returns>
|
||||
public static ISymbol GetSymbol(this Context cx, Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode node)
|
||||
{
|
||||
var info = GetSymbolInfo(cx, node);
|
||||
if (info.Symbol == null)
|
||||
{
|
||||
throw new InternalError(node, "Could not resolve symbol");
|
||||
}
|
||||
|
||||
return info.Symbol;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the type of a node, or default
|
||||
/// if the type could not be determined.
|
||||
@@ -515,84 +468,11 @@ namespace Semmle.Extraction.CSharp
|
||||
return new AnnotatedTypeSymbol(info.Type.DisambiguateType(), info.Nullability.Annotation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated type of an IPropertySymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static AnnotatedTypeSymbol GetAnnotatedType(this IPropertySymbol symbol) => new AnnotatedTypeSymbol(symbol.Type, symbol.NullableAnnotation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated type of an IFieldSymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static AnnotatedTypeSymbol GetAnnotatedType(this IFieldSymbol symbol) => new AnnotatedTypeSymbol(symbol.Type, symbol.NullableAnnotation);
|
||||
private static bool IsSpecialized(this IMethodSymbol method) =>
|
||||
method.IsGenericMethod &&
|
||||
!ReferenceEquals(method, method.OriginalDefinition) &&
|
||||
method.TypeParameters.Zip(method.TypeArguments, (a, b) => !ReferenceEquals(a, b)).Any(b => b);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated return type of an IMethodSymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static AnnotatedTypeSymbol GetAnnotatedReturnType(this IMethodSymbol symbol) => new AnnotatedTypeSymbol(symbol.ReturnType, symbol.ReturnNullableAnnotation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type annotation for a NullableAnnotation.
|
||||
/// </summary>
|
||||
public static Kinds.TypeAnnotation GetTypeAnnotation(this NullableAnnotation na)
|
||||
{
|
||||
switch(na)
|
||||
{
|
||||
case NullableAnnotation.Annotated:
|
||||
return Kinds.TypeAnnotation.Annotated;
|
||||
case NullableAnnotation.NotAnnotated:
|
||||
return Kinds.TypeAnnotation.NotAnnotated;
|
||||
default:
|
||||
return Kinds.TypeAnnotation.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated element type of an IArrayTypeSymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static AnnotatedTypeSymbol GetAnnotatedElementType(this IArrayTypeSymbol symbol) =>
|
||||
new AnnotatedTypeSymbol(symbol.ElementType, symbol.ElementNullableAnnotation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated type arguments of an INamedTypeSymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static IEnumerable<AnnotatedTypeSymbol> GetAnnotatedTypeArguments(this INamedTypeSymbol symbol) =>
|
||||
symbol.TypeArguments.Zip(symbol.TypeArgumentsNullableAnnotations, (t, a) => new AnnotatedTypeSymbol(t, a));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated type arguments of an IMethodSymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static IEnumerable<AnnotatedTypeSymbol> GetAnnotatedTypeArguments(this IMethodSymbol symbol) =>
|
||||
symbol.TypeArguments.Zip(symbol.TypeArgumentsNullableAnnotations, (t, a) => new AnnotatedTypeSymbol(t, a));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the annotated type constraints of an ITypeParameterSymbol.
|
||||
/// This has not yet been exposed on the public API.
|
||||
/// </summary>
|
||||
public static IEnumerable<AnnotatedTypeSymbol> GetAnnotatedTypeConstraints(this ITypeParameterSymbol symbol) =>
|
||||
symbol.ConstraintTypes.Zip(symbol.ConstraintNullableAnnotations, (t, a) => new AnnotatedTypeSymbol(t, a));
|
||||
|
||||
/// <summary>
|
||||
/// Creates an AnnotatedTypeSymbol from an ITypeSymbol.
|
||||
/// Note: not currently used but might be useful.
|
||||
/// </summary>
|
||||
public static AnnotatedTypeSymbol WithAnnotation(this ITypeSymbol symbol, NullableAnnotation annotation) =>
|
||||
new AnnotatedTypeSymbol(symbol, annotation);
|
||||
|
||||
/// <summary>
|
||||
/// Holds if this type looks like an "anonymous" type. Names of anonymous types
|
||||
/// sometimes collide so they need to be handled separately.
|
||||
/// </summary>
|
||||
public static bool IsAnonymous(this INamedTypeSymbol type) =>
|
||||
type.IsAnonymousType || type.Name.StartsWith("<>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
internal static void nullability_member(this TextWriter trapFile, NullabilityEntity nullability, int index, NullabilityEntity child)
|
||||
{
|
||||
trapFile.WriteTuple(nameof(nullability_member), nullability, index, child);
|
||||
trapFile.WriteTuple("nullability_member", nullability, index, child);
|
||||
}
|
||||
|
||||
internal static void numlines(this TextWriter trapFile, IEntity label, LineCounts lineCounts)
|
||||
@@ -481,7 +481,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.WriteTuple("tuple_element", type, index, field);
|
||||
}
|
||||
|
||||
internal static void tuple_underlying_type(this TextWriter trapFile, TupleType type, Type underlying)
|
||||
internal static void tuple_underlying_type(this TextWriter trapFile, TupleType type, NamedType underlying)
|
||||
{
|
||||
trapFile.WriteTuple("tuple_underlying_type", type, underlying);
|
||||
}
|
||||
@@ -526,12 +526,12 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.WriteTuple("type_parameters", param, child, typeOrMethod, (int)param.Variance);
|
||||
}
|
||||
|
||||
internal static void typeref_type(this TextWriter trapFile, TypeRef typeref, Type type)
|
||||
internal static void typeref_type(this TextWriter trapFile, NamedTypeRef typeref, Type type)
|
||||
{
|
||||
trapFile.WriteTuple("typeref_type", typeref, type);
|
||||
}
|
||||
|
||||
internal static void typerefs(this TextWriter trapFile, TypeRef type, string name)
|
||||
internal static void typerefs(this TextWriter trapFile, NamedTypeRef type, string name)
|
||||
{
|
||||
trapFile.WriteTuple("typerefs", type, name);
|
||||
}
|
||||
|
||||
@@ -87,22 +87,6 @@ namespace Semmle.Extraction
|
||||
/// <param name="scope">The extraction scope (what to include in this trap file).</param>
|
||||
/// <returns></returns>
|
||||
Context CreateContext(Compilation c, TrapWriter trapWriter, IExtractionScope scope);
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the algorithm used to generate identifiers in trap files.
|
||||
/// </summary>
|
||||
TrapIdenfierMode TrapIdentifiers { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures how to generate identifiers in trap files.
|
||||
/// </summary>
|
||||
public enum TrapIdenfierMode
|
||||
{
|
||||
Imprecise, // Names are not qualified by assembly version
|
||||
Flexible, // Some names are qualified by assembly versions - typerefs are not however.
|
||||
Precise, // All names are qualified by their partial assembly version (excludes build number)
|
||||
ExtraPrecise // All names are qualified by their full assembly version.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -128,7 +112,6 @@ namespace Semmle.Extraction
|
||||
public Extractor(bool standalone, string outputPath, ILogger logger)
|
||||
{
|
||||
Standalone = standalone;
|
||||
if (Standalone) TrapIdentifiers = TrapIdenfierMode.Imprecise;
|
||||
OutputPath = outputPath;
|
||||
Logger = logger;
|
||||
}
|
||||
@@ -214,7 +197,5 @@ namespace Semmle.Extraction
|
||||
public ILogger Logger { get; private set; }
|
||||
|
||||
public static string Version => $"{ThisAssembly.Git.BaseTag} ({ThisAssembly.Git.Sha})";
|
||||
|
||||
public TrapIdenfierMode TrapIdentifiers { get; } = TrapIdenfierMode.Imprecise;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user