-
Notifications
You must be signed in to change notification settings - Fork 128
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Propagate DynamicallyAccessedMemberTypes through Nullable<T> to T (#2675
) Add intrinsic support for Nullable.GetUnderlyingType and support for MakeGenericType with Nullables Adds ArrayCreationOperation visitors to create ArrayValue's in the analyzer, and adds start of dataflow analysis for array values. Adds tests to validate dataflow in Arrays. Co-authored-by: vitek-karas <[email protected]>
- Loading branch information
1 parent
2303da0
commit ed8b22a
Showing
43 changed files
with
1,410 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,71 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using ILLink.Shared.DataFlow; | ||
using MultiValue = ILLink.Shared.DataFlow.ValueSet<ILLink.Shared.DataFlow.SingleValue>; | ||
|
||
namespace ILLink.Shared.TrimAnalysis | ||
{ | ||
partial record ArrayValue | ||
{ | ||
public ArrayValue (SingleValue size) => Size = size; | ||
public readonly Dictionary<int, MultiValue> IndexValues; | ||
|
||
#pragma warning disable IDE0060 // Remove unused parameter | ||
public partial bool TryGetValueByIndex (int index, out MultiValue value) => throw new NotImplementedException (); | ||
#pragma warning restore IDE0060 // Remove unused parameter | ||
public static MultiValue Create (MultiValue size) | ||
{ | ||
MultiValue result = MultiValueLattice.Top; | ||
foreach (var sizeValue in size) { | ||
result = MultiValueLattice.Meet (result, new MultiValue (new ArrayValue (sizeValue))); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
ArrayValue (SingleValue size) | ||
{ | ||
Size = size; | ||
IndexValues = new Dictionary<int, MultiValue> (); | ||
} | ||
|
||
public partial bool TryGetValueByIndex (int index, out MultiValue value) | ||
{ | ||
if (IndexValues.TryGetValue (index, out value)) | ||
return true; | ||
|
||
value = default; | ||
return false; | ||
} | ||
|
||
public override int GetHashCode () | ||
{ | ||
return HashUtils.Combine (GetType ().GetHashCode (), Size); | ||
} | ||
|
||
public bool Equals (ArrayValue? otherArr) | ||
{ | ||
if (otherArr == null) | ||
return false; | ||
|
||
bool equals = Size.Equals (otherArr.Size); | ||
equals &= IndexValues.Count == otherArr.IndexValues.Count; | ||
if (!equals) | ||
return false; | ||
|
||
// If both sets T and O are the same size and "T intersect O" is empty, then T == O. | ||
HashSet<KeyValuePair<int, MultiValue>> thisValueSet = new (IndexValues); | ||
thisValueSet.ExceptWith (otherArr.IndexValues); | ||
return thisValueSet.Count == 0; | ||
} | ||
|
||
// Lattice Meet() is supposed to copy values, so we need to make a deep copy since ArrayValue is mutable through IndexValues | ||
public override SingleValue DeepCopy () | ||
{ | ||
var newArray = new ArrayValue (Size); | ||
foreach (var kvp in IndexValues) { | ||
newArray.IndexValues.Add (kvp.Key, kvp.Value.Clone ()); | ||
} | ||
|
||
return newArray; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/ILLink.RoslynAnalyzer/TrimAnalysis/RuntimeMethodHandleValue.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using ILLink.Shared.DataFlow; | ||
|
||
namespace ILLink.Shared.TrimAnalysis | ||
{ | ||
partial record RuntimeMethodHandleValue | ||
{ | ||
public override SingleValue DeepCopy () => this; // immutable value | ||
|
||
public override string ToString () => this.ValueToString (); | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
src/ILLink.RoslynAnalyzer/TrimAnalysis/SingleValueExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Linq; | ||
using ILLink.Shared.DataFlow; | ||
using ILLink.Shared.TrimAnalysis; | ||
using ILLink.Shared.TypeSystemProxy; | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace ILLink.RoslynAnalyzer.TrimAnalysis | ||
{ | ||
public static class SingleValueExtensions | ||
{ | ||
public static SingleValue? FromTypeSymbol (ITypeSymbol type) | ||
{ | ||
if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { | ||
var underlyingType = (type as INamedTypeSymbol)?.TypeArguments.FirstOrDefault (); | ||
return underlyingType?.TypeKind switch { | ||
TypeKind.TypeParameter => | ||
new NullableValueWithDynamicallyAccessedMembers (new TypeProxy (type), | ||
new GenericParameterValue ((ITypeParameterSymbol) underlyingType)), | ||
// typeof(Nullable<>) | ||
TypeKind.Error => new SystemTypeValue (new TypeProxy (type)), | ||
TypeKind.Class or TypeKind.Struct or TypeKind.Interface => | ||
new NullableSystemTypeValue (new TypeProxy (type), new SystemTypeValue (new TypeProxy (underlyingType))), | ||
_ => UnknownValue.Instance | ||
}; | ||
} | ||
return type.Kind switch { | ||
SymbolKind.TypeParameter => new GenericParameterValue ((ITypeParameterSymbol) type), | ||
SymbolKind.NamedType => new SystemTypeValue (new TypeProxy (type)), | ||
// If the symbol is an Array type, the BaseType is System.Array | ||
SymbolKind.ArrayType => new SystemTypeValue (new TypeProxy (type.BaseType!)), | ||
SymbolKind.ErrorType => UnknownValue.Instance, | ||
_ => null | ||
}; | ||
|
||
} | ||
} | ||
} |
Oops, something went wrong.