mirror of
https://github.com/github/codeql.git
synced 2026-04-26 01:05:15 +02:00
Merge pull request #4041 from tamasvajk/feature/update-roslyn
C#: upgrade Roslyn dependencies to version 3.7
This commit is contained in:
@@ -136,16 +136,32 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.metadata_handle(this, Location, MetadataTokens.GetToken(handle.Value));
|
||||
}
|
||||
|
||||
static System.Reflection.PropertyInfo GetPropertyInfo(object o, string name) =>
|
||||
o.GetType().GetProperty(name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty);
|
||||
|
||||
public Handle? MetadataHandle
|
||||
{
|
||||
get
|
||||
{
|
||||
var propertyInfo = symbol.GetType().GetProperty("Handle",
|
||||
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty);
|
||||
var handleProp = GetPropertyInfo(symbol, "Handle");
|
||||
object handleObj = symbol;
|
||||
|
||||
if (propertyInfo != null)
|
||||
if (handleProp is null)
|
||||
{
|
||||
switch (propertyInfo.GetValue(symbol))
|
||||
var underlyingSymbolProp = GetPropertyInfo(symbol, "UnderlyingSymbol");
|
||||
if (underlyingSymbolProp is object)
|
||||
{
|
||||
if (underlyingSymbolProp.GetValue(symbol) is object underlying)
|
||||
{
|
||||
handleProp = GetPropertyInfo(underlying, "Handle");
|
||||
handleObj = underlying;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handleProp is object)
|
||||
{
|
||||
switch (handleProp.GetValue(handleObj))
|
||||
{
|
||||
case MethodDefinitionHandle md: return md;
|
||||
case TypeDefinitionHandle td: return td;
|
||||
|
||||
@@ -11,13 +11,24 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
class NamedType : Type<INamedTypeSymbol>
|
||||
{
|
||||
NamedType(Context cx, INamedTypeSymbol init)
|
||||
NamedType(Context cx, INamedTypeSymbol init, bool constructUnderlyingTupleType)
|
||||
: base(cx, init)
|
||||
{
|
||||
typeArgumentsLazy = new Lazy<Type[]>(() => symbol.TypeArguments.Select(t => Create(cx, t)).ToArray());
|
||||
this.constructUnderlyingTupleType = constructUnderlyingTupleType;
|
||||
}
|
||||
|
||||
public static NamedType Create(Context cx, INamedTypeSymbol type) => NamedTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
|
||||
public static NamedType Create(Context cx, INamedTypeSymbol type) =>
|
||||
NamedTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a named type entity from a tuple type. Unlike `Create`, this
|
||||
/// will create an entity for the underlying `System.ValueTuple` struct.
|
||||
/// For example, `(int, string)` will result in an entity for
|
||||
/// `System.ValueTuple<int, string>`.
|
||||
/// </summary>
|
||||
public static NamedType CreateNamedTypeFromTupleType(Context cx, INamedTypeSymbol type) =>
|
||||
UnderlyingTupleTypeFactory.Instance.CreateEntity(cx, (new SymbolEqualityWrapper(type), typeof(TupleType)), type);
|
||||
|
||||
public override bool NeedsPopulation => base.NeedsPopulation || symbol.TypeKind == TypeKind.Error;
|
||||
|
||||
@@ -51,7 +62,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.constructed_generic(this, Type.Create(Context, symbol.ConstructedFrom).TypeRef);
|
||||
var unbound = constructUnderlyingTupleType
|
||||
? CreateNamedTypeFromTupleType(Context, symbol.ConstructedFrom)
|
||||
: Type.Create(Context, symbol.ConstructedFrom);
|
||||
trapFile.constructed_generic(this, unbound.TypeRef);
|
||||
|
||||
for (int i = 0; i < symbol.TypeArguments.Length; ++i)
|
||||
{
|
||||
@@ -60,7 +74,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
PopulateType(trapFile);
|
||||
PopulateType(trapFile, constructUnderlyingTupleType);
|
||||
|
||||
if (symbol.EnumUnderlyingType != null)
|
||||
{
|
||||
@@ -76,6 +90,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
readonly Lazy<Type[]> typeArgumentsLazy;
|
||||
private readonly bool constructUnderlyingTupleType;
|
||||
|
||||
public Type[] TypeArguments => typeArgumentsLazy.Value;
|
||||
|
||||
public override IEnumerable<Type> TypeMentions => TypeArguments;
|
||||
@@ -115,7 +131,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.Write('*');
|
||||
else
|
||||
{
|
||||
symbol.BuildTypeId(Context, trapFile, symbol);
|
||||
symbol.BuildTypeId(Context, trapFile, symbol, constructUnderlyingTupleType);
|
||||
trapFile.Write(";type");
|
||||
}
|
||||
}
|
||||
@@ -161,7 +177,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
public static readonly NamedTypeFactory Instance = new NamedTypeFactory();
|
||||
|
||||
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init);
|
||||
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, false);
|
||||
}
|
||||
|
||||
class UnderlyingTupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType>
|
||||
{
|
||||
public static readonly UnderlyingTupleTypeFactory Instance = new UnderlyingTupleTypeFactory();
|
||||
|
||||
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, true);
|
||||
}
|
||||
|
||||
// Do not create typerefs of constructed generics as they are always in the current trap file.
|
||||
|
||||
@@ -41,7 +41,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
PopulateType(trapFile);
|
||||
PopulateGenerics();
|
||||
|
||||
var underlyingType = NamedType.Create(Context, symbol.TupleUnderlyingType);
|
||||
var underlyingType = NamedType.CreateNamedTypeFromTupleType(Context, symbol.TupleUnderlyingType ?? symbol);
|
||||
|
||||
trapFile.tuple_underlying_type(this, underlyingType);
|
||||
|
||||
int index = 0;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
symbol.ContainingType != null && ConstructedOrParentIsConstructed(symbol.ContainingType);
|
||||
}
|
||||
|
||||
static Kinds.TypeKind GetClassType(Context cx, ITypeSymbol t)
|
||||
static Kinds.TypeKind GetClassType(Context cx, ITypeSymbol t, bool constructUnderlyingTupleType)
|
||||
{
|
||||
switch (t.SpecialType)
|
||||
{
|
||||
@@ -72,7 +72,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
case TypeKind.Class: return Kinds.TypeKind.CLASS;
|
||||
case TypeKind.Struct:
|
||||
return ((INamedTypeSymbol)t).IsTupleType ? Kinds.TypeKind.TUPLE : Kinds.TypeKind.STRUCT;
|
||||
return ((INamedTypeSymbol)t).IsTupleType && !constructUnderlyingTupleType
|
||||
? Kinds.TypeKind.TUPLE
|
||||
: Kinds.TypeKind.STRUCT;
|
||||
case TypeKind.Interface: return Kinds.TypeKind.INTERFACE;
|
||||
case TypeKind.Array: return Kinds.TypeKind.ARRAY;
|
||||
case TypeKind.Enum: return Kinds.TypeKind.ENUM;
|
||||
@@ -85,7 +87,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
protected void PopulateType(TextWriter trapFile)
|
||||
protected void PopulateType(TextWriter trapFile, bool constructUnderlyingTupleType = false)
|
||||
{
|
||||
PopulateMetadataHandle(trapFile);
|
||||
PopulateAttributes();
|
||||
@@ -93,9 +95,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.Write("types(");
|
||||
trapFile.WriteColumn(this);
|
||||
trapFile.Write(',');
|
||||
trapFile.WriteColumn((int)GetClassType(Context, symbol));
|
||||
trapFile.WriteColumn((int)GetClassType(Context, symbol, constructUnderlyingTupleType));
|
||||
trapFile.Write(",\"");
|
||||
symbol.BuildDisplayName(Context, trapFile);
|
||||
symbol.BuildDisplayName(Context, trapFile, constructUnderlyingTupleType);
|
||||
trapFile.WriteLine("\")");
|
||||
|
||||
// Visit base types
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Delegate:
|
||||
case TypeKind.Error:
|
||||
var named = (INamedTypeSymbol)type;
|
||||
if (named.IsTupleType)
|
||||
if (named.IsTupleType && named.TupleUnderlyingType is object)
|
||||
named = named.TupleUnderlyingType;
|
||||
if (IdDependsOnImpl(named.ContainingType))
|
||||
return true;
|
||||
@@ -152,10 +152,11 @@ namespace Semmle.Extraction.CSharp
|
||||
/// <param name="cx">The extraction context.</param>
|
||||
/// <param name="trapFile">The trap builder used to store the result.</param>
|
||||
/// <param name="symbolBeingDefined">The outer symbol being defined (to avoid recursive ids).</param>
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined) =>
|
||||
type.BuildTypeId(cx, trapFile, symbolBeingDefined, true);
|
||||
/// <param name="constructUnderlyingTupleType">Whether to build a type ID for the underlying `System.ValueTuple` struct in the case of tuple types.</param>
|
||||
public static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool constructUnderlyingTupleType = false) =>
|
||||
type.BuildTypeId(cx, trapFile, symbolBeingDefined, true, constructUnderlyingTupleType);
|
||||
|
||||
static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass)
|
||||
static void BuildTypeId(this ITypeSymbol type, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
|
||||
{
|
||||
using (cx.StackGuard)
|
||||
{
|
||||
@@ -173,7 +174,7 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Delegate:
|
||||
case TypeKind.Error:
|
||||
var named = (INamedTypeSymbol)type;
|
||||
named.BuildNamedTypeId(cx, trapFile, symbolBeingDefined, addBaseClass);
|
||||
named.BuildNamedTypeId(cx, trapFile, symbolBeingDefined, addBaseClass, constructUnderlyingTupleType);
|
||||
return;
|
||||
case TypeKind.Pointer:
|
||||
var ptr = (IPointerTypeSymbol)type;
|
||||
@@ -195,7 +196,7 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
static void BuildOrWriteId(this ISymbol symbol, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass)
|
||||
static void BuildOrWriteId(this ISymbol symbol, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType = false)
|
||||
{
|
||||
// We need to keep track of the symbol being defined in order to avoid cyclic labels.
|
||||
// For example, in
|
||||
@@ -210,11 +211,13 @@ namespace Semmle.Extraction.CSharp
|
||||
//
|
||||
// ```
|
||||
// #123 = @"C`1 : IEnumerable<__self___T>"
|
||||
// ```
|
||||
// ```
|
||||
if (SymbolEqualityComparer.Default.Equals(symbol, symbolBeingDefined))
|
||||
trapFile.Write("__self__");
|
||||
else if (symbol is ITypeSymbol type && type.IdDependsOn(cx, symbolBeingDefined))
|
||||
type.BuildTypeId(cx, trapFile, symbolBeingDefined, addBaseClass);
|
||||
type.BuildTypeId(cx, trapFile, symbolBeingDefined, addBaseClass, constructUnderlyingTupleType);
|
||||
else if (symbol is INamedTypeSymbol namedType && namedType.IsTupleType && constructUnderlyingTupleType)
|
||||
trapFile.WriteSubId(NamedType.CreateNamedTypeFromTupleType(cx, namedType));
|
||||
else
|
||||
trapFile.WriteSubId(CreateEntity(cx, symbol));
|
||||
}
|
||||
@@ -262,9 +265,9 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.Write("::");
|
||||
}
|
||||
|
||||
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass)
|
||||
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, ISymbol symbolBeingDefined, bool addBaseClass, bool constructUnderlyingTupleType)
|
||||
{
|
||||
if (named.IsTupleType)
|
||||
if (!constructUnderlyingTupleType && named.IsTupleType)
|
||||
{
|
||||
trapFile.Write('(');
|
||||
trapFile.BuildList(",", named.TupleElements,
|
||||
@@ -308,10 +311,10 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
else
|
||||
{
|
||||
named.ConstructedFrom.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass);
|
||||
named.ConstructedFrom.BuildOrWriteId(cx, trapFile, symbolBeingDefined, addBaseClass, constructUnderlyingTupleType);
|
||||
trapFile.Write('<');
|
||||
// Encode the nullability of the type arguments in the label.
|
||||
// Type arguments with different nullability can result in
|
||||
// Type arguments with different nullability can result in
|
||||
// a constructed type with different nullability of its members and methods,
|
||||
// so we need to create a distinct database entity for it.
|
||||
trapFile.BuildList(",", named.GetAnnotatedTypeArguments(),
|
||||
@@ -360,7 +363,7 @@ namespace Semmle.Extraction.CSharp
|
||||
/// Constructs a display name string for this type symbol.
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trap builder used to store the result.</param>
|
||||
public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWriter trapFile)
|
||||
public static void BuildDisplayName(this ITypeSymbol type, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType = false)
|
||||
{
|
||||
using (cx.StackGuard)
|
||||
{
|
||||
@@ -384,7 +387,7 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Delegate:
|
||||
case TypeKind.Error:
|
||||
var named = (INamedTypeSymbol)type;
|
||||
named.BuildNamedTypeDisplayName(cx, trapFile);
|
||||
named.BuildNamedTypeDisplayName(cx, trapFile, constructUnderlyingTupleType);
|
||||
return;
|
||||
case TypeKind.Pointer:
|
||||
var ptr = (IPointerTypeSymbol)type;
|
||||
@@ -403,9 +406,9 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile)
|
||||
public static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType)
|
||||
{
|
||||
if (namedType.IsTupleType)
|
||||
if (!constructUnderlyingTupleType && namedType.IsTupleType)
|
||||
{
|
||||
trapFile.Write('(');
|
||||
trapFile.BuildList(",", namedType.TupleElements.Select(f => f.Type),
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.4.0" />
|
||||
<PackageReference Include="GitInfo" Version="2.0.20"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.7.0" />
|
||||
<PackageReference Include="GitInfo" Version="2.0.20">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -46,6 +46,8 @@ private predicate isNotNeeded(Element e) {
|
||||
or
|
||||
e instanceof AnonymousClass
|
||||
or
|
||||
e instanceof TupleType
|
||||
or
|
||||
isNotNeeded(e.(Declaration).getDeclaringType())
|
||||
or
|
||||
isNotNeeded(e.(Parameter).getDeclaringElement())
|
||||
|
||||
@@ -932,7 +932,7 @@ class UnknownType extends Type, @unknown_type { }
|
||||
*/
|
||||
class TupleType extends ValueType, @tuple_type {
|
||||
/** Gets the underlying type of this tuple, which is of type `System.ValueTuple`. */
|
||||
ConstructedStruct getUnderlyingType() { tuple_underlying_type(this, getTypeRef(result)) }
|
||||
Struct getUnderlyingType() { tuple_underlying_type(this, getTypeRef(result)) }
|
||||
|
||||
/**
|
||||
* Gets the `n`th element of this tuple, indexed from 0.
|
||||
|
||||
@@ -692,7 +692,7 @@ overrides(
|
||||
int base_id: @callable ref);
|
||||
|
||||
explicitly_implements(
|
||||
unique int id: @member ref,
|
||||
int id: @member ref,
|
||||
int interface_id: @interface_or_ref ref);
|
||||
|
||||
local_functions(
|
||||
|
||||
@@ -17,10 +17,18 @@ query predicate tooManyHandles(string s) {
|
||||
)
|
||||
}
|
||||
|
||||
private class UniqueMetadataEntity extends MetadataEntity {
|
||||
UniqueMetadataEntity() {
|
||||
// Tuple types such as `(,)` and `ValueTuple`2` share the same handle
|
||||
not this instanceof TupleType and
|
||||
not this.getQualifiedName().matches("System.ValueTuple%")
|
||||
}
|
||||
}
|
||||
|
||||
query predicate tooManyMatchingHandles(string s) {
|
||||
exists(MetadataEntity e, Assembly a, int handle |
|
||||
exists(UniqueMetadataEntity e, Assembly a, int handle |
|
||||
metadata_handle(e, a, handle) and
|
||||
strictcount(MetadataEntity e2 | metadata_handle(e2, a, handle)) > 2 and
|
||||
strictcount(UniqueMetadataEntity e2 | metadata_handle(e2, a, handle)) > 2 and
|
||||
s = e.getQualifiedName()
|
||||
)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Removed uniqueness constraint from 'explicitly_implements' relation
|
||||
compatibility: full
|
||||
Reference in New Issue
Block a user