Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port type system tests from CoreRT repo #38128

Merged
merged 4 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
$(CoreClrProjectRoot)src\tools\dotnet-pgo\dotnet-pgo.csproj;
$(CoreClrProjectRoot)src\tools\r2rtest\R2RTest.csproj" Category="clr" BuildInParallel="true" />
<ProjectToBuild Include="$(CoreClrProjectRoot)src\tools\aot\crossgen2\crossgen2.csproj" Category="clr" />
<ProjectToBuild Include="$(CoreClrProjectRoot)src\tools\aot\ILCompiler.TypeSystem.ReadyToRun.Tests\ILCompiler.TypeSystem.ReadyToRun.Tests.csproj" Test="true" Category="clr" />
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

<ItemGroup Condition="$(_subset.Contains('+clr.packages+'))">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Internal.TypeSystem
{
public static class ConstructedTypeRewritingHelpers
{
/// <summary>
/// Determine if the construction of a type contains one of a given set of types. This is a deep
/// scan. For instance, given type MyType&lt;SomeGeneric&lt;int[]&gt;&gt;, and a set of typesToFind
/// that includes int, this function will return true. Does not detect the open generics that may be
/// instantiated over in this type. IsConstructedOverType would return false if only passed MyType,
/// or SomeGeneric for the above examplt.
/// </summary>
/// <param name="type">type to examine</param>
/// <param name="typesToFind">types to search for in the construction of type</param>
/// <returns>true if a type in typesToFind is found</returns>
public static bool IsConstructedOverType(this TypeDesc type, TypeDesc[] typesToFind)
{
int directDiscoveryIndex = Array.IndexOf(typesToFind, type);

if (directDiscoveryIndex != -1)
return true;

if (type.HasInstantiation)
{
for (int instantiationIndex = 0; instantiationIndex < type.Instantiation.Length; instantiationIndex++)
{
if (type.Instantiation[instantiationIndex].IsConstructedOverType(typesToFind))
{
return true;
}
}
}
else if (type.IsParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType)type;
return parameterizedType.ParameterType.IsConstructedOverType(typesToFind);
}
else if (type.IsFunctionPointer)
{
MethodSignature functionPointerSignature = ((FunctionPointerType)type).Signature;
if (functionPointerSignature.ReturnType.IsConstructedOverType(typesToFind))
return true;

for (int paramIndex = 0; paramIndex < functionPointerSignature.Length; paramIndex++)
{
if (functionPointerSignature[paramIndex].IsConstructedOverType(typesToFind))
return true;
}
}

return false;
}

/// <summary>
/// Replace some of the types in a type's construction with a new set of types. This function does not
/// support any situation where there is an instantiated generic that is not represented by an
/// InstantiatedType. Does not replace the open generics that may be instantiated over in this type.
///
/// For instance, Given MyType&lt;object, int[]&gt;,
/// an array of types to replace such as {int,object}, and
/// an array of replacement types such as {string,__Canon}.
/// The result shall be MyType&lt;__Canon, string[]&gt;
///
/// This function cannot be used to replace MyType in the above example.
/// </summary>
public static TypeDesc ReplaceTypesInConstructionOfType(this TypeDesc type, TypeDesc[] typesToReplace, TypeDesc[] replacementTypes)
{
int directReplacementIndex = Array.IndexOf(typesToReplace, type);

if (directReplacementIndex != -1)
return replacementTypes[directReplacementIndex];

if (type.HasInstantiation)
{
TypeDesc[] newInstantiation = null;
Debug.Assert(type is InstantiatedType);
int instantiationIndex = 0;
for (; instantiationIndex < type.Instantiation.Length; instantiationIndex++)
{
TypeDesc oldType = type.Instantiation[instantiationIndex];
TypeDesc newType = oldType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
if ((oldType != newType) || (newInstantiation != null))
{
if (newInstantiation == null)
{
newInstantiation = new TypeDesc[type.Instantiation.Length];
for (int i = 0; i < instantiationIndex; i++)
newInstantiation[i] = type.Instantiation[i];
}
newInstantiation[instantiationIndex] = newType;
}
}
if (newInstantiation != null)
return type.Context.GetInstantiatedType((MetadataType)type.GetTypeDefinition(), new Instantiation(newInstantiation));
}
else if (type.IsParameterizedType)
{
ParameterizedType parameterizedType = (ParameterizedType)type;
TypeDesc oldParameter = parameterizedType.ParameterType;
TypeDesc newParameter = oldParameter.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
if (oldParameter != newParameter)
{
if (type.IsArray)
{
ArrayType arrayType = (ArrayType)type;
if (arrayType.IsSzArray)
return type.Context.GetArrayType(newParameter);
else
return type.Context.GetArrayType(newParameter, arrayType.Rank);
}
else if (type.IsPointer)
{
return type.Context.GetPointerType(newParameter);
}
else if (type.IsByRef)
{
return type.Context.GetByRefType(newParameter);
}
Debug.Fail("Unknown form of type");
}
}
else if (type.IsFunctionPointer)
{
MethodSignature oldSig = ((FunctionPointerType)type).Signature;
MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(oldSig);
sigBuilder.ReturnType = oldSig.ReturnType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
for (int paramIndex = 0; paramIndex < oldSig.Length; paramIndex++)
sigBuilder[paramIndex] = oldSig[paramIndex].ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);

MethodSignature newSig = sigBuilder.ToSignature();
if (newSig != oldSig)
return type.Context.GetFunctionPointerType(newSig);
}

return type;
}

/// <summary>
/// Replace some of the types in a method's construction with a new set of types.
/// Does not replace the open generics that may be instantiated over in this type.
///
/// For instance, Given MyType&lt;object, int[]&gt;.Function&lt;short&gt;(),
/// an array of types to replace such as {int,short}, and
/// an array of replacement types such as {string,char}.
/// The result shall be MyType&lt;object, string[]&gt;.Function&lt;char&gt;
///
/// This function cannot be used to replace MyType in the above example.
/// </summary>
public static MethodDesc ReplaceTypesInConstructionOfMethod(this MethodDesc method, TypeDesc[] typesToReplace, TypeDesc[] replacementTypes)
{
TypeDesc newOwningType = method.OwningType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
MethodDesc methodOnOwningType = null;
bool owningTypeChanged = false;
if (newOwningType == method.OwningType)
{
methodOnOwningType = method.GetMethodDefinition();
}
else
{
methodOnOwningType = TypeSystemHelpers.FindMethodOnExactTypeWithMatchingTypicalMethod(newOwningType, method);
owningTypeChanged = true;
}

MethodDesc result;
if (!method.HasInstantiation)
{
result = methodOnOwningType;
}
else
{
Debug.Assert(method is InstantiatedMethod);

TypeDesc[] newInstantiation = null;
int instantiationIndex = 0;
for (; instantiationIndex < method.Instantiation.Length; instantiationIndex++)
{
TypeDesc oldType = method.Instantiation[instantiationIndex];
TypeDesc newType = oldType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
if ((oldType != newType) || (newInstantiation != null))
{
if (newInstantiation == null)
{
newInstantiation = new TypeDesc[method.Instantiation.Length];
for (int i = 0; i < instantiationIndex; i++)
newInstantiation[i] = method.Instantiation[i];
}
newInstantiation[instantiationIndex] = newType;
}
}

if (newInstantiation != null)
result = method.Context.GetInstantiatedMethod(methodOnOwningType, new Instantiation(newInstantiation));
else if (owningTypeChanged)
result = method.Context.GetInstantiatedMethod(methodOnOwningType, method.Instantiation);
else
result = method;
}

return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public void TestSameSizeArrayTypeCasting()
}

[Fact]
[ActiveIssue("corert port")]
public void TestArrayInterfaceCasting()
{
TypeDesc intType = _context.GetWellKnownType(WellKnownType.Int32);
Expand Down Expand Up @@ -169,6 +170,7 @@ public void TestGenericParameterCasting()
}

[Fact]
[ActiveIssue("corert port")]
public void TestVariantCasting()
{
TypeDesc stringType = _context.GetWellKnownType(WellKnownType.String);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>CoreTestAssembly</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<IsCoreAssembly>true</IsCoreAssembly>
<SkipTestRun>true</SkipTestRun>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- Don't add references to the netstandard platform since this is a core assembly -->
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<!-- CSC needs explicit metadata version when it has no core library to reference -->
<RuntimeMetadataVersion>v4.0.30319</RuntimeMetadataVersion>
<!-- <EnsureRuntimePackageDependencies>false</EnsureRuntimePackageDependencies> -->
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
</PropertyGroup>
<ItemGroup>
<Compile Include="Canonicalization.cs" />
<Compile Include="Casting.cs" />
<Compile Include="GCPointerMap.cs" />
<Compile Include="GenericConstraints.cs" />
<Compile Include="Hashcode.cs" />
<Compile Include="InterfaceArrangements.cs" />
<Compile Include="GenericTypes.cs" />
<Compile Include="Platform.cs" />
<Compile Include="InstanceFieldLayout.cs" />
<Compile Include="StaticFieldLayout.cs" />
<Compile Include="SyntheticVirtualOverride.cs" />
<Compile Include="TypeNameParsing.cs" />
<Compile Include="ValueTypeShapeCharacteristics.cs" />
<Compile Include="VirtualFunctionOverride.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,5 @@ public void TestInstanceMap()
Assert.Equal("11111111111111111111111111111111", map.ToString());
}
}

[Fact]
public void TestStaticMap()
{
MetadataType mixedStaticClass = _testModule.GetType("GCPointerMap", "MixedStaticClass");
var map = GCPointerMap.FromStaticLayout(mixedStaticClass);
Assert.Equal(12, map.Size);
Assert.Equal("010100101001", map.ToString());
}

[Fact]
public void TestThreadStaticMap()
{
MetadataType mixedThreadStaticClass = _testModule.GetType("GCPointerMap", "MixedThreadStaticClass");
var map = GCPointerMap.FromThreadStaticLayout(mixedThreadStaticClass);
Assert.Equal(14, map.Size);
Assert.Equal("00010010100110", map.ToString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public void TestFinalize()
/// Testing lookup up of a method in an instantiated type.
/// </summary>
[Fact]
[ActiveIssue(-1)]
[ActiveIssue("")]
public void TestMethodLookup()
{
MetadataType t = _testModule.GetType("GenericTypes", "GenericClass`1").MakeInstantiatedType(_context.GetWellKnownType(WellKnownType.Int32));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>TypeSystem.Tests</AssemblyName>
<RootNamespace>TypeSystem.Tests</RootNamespace>
<AssemblyName>ILCompiler.TypeSystem.ReadyToRun.Tests</AssemblyName>
<TargetFramework>netstandard2.0</TargetFramework>
<!-- Don't warn if some dependencies were rolled forward -->
<NoWarn>$(NoWarn);NU1603</NoWarn>
<Configurations>Debug;Release;Checked</Configurations>
<!-- This seems to be required for supporting assemblies to be copied into the output -->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<TestRunnerAdditionalArguments>-notrait category=failing</TestRunnerAdditionalArguments>
<!-- xunit.runner.visualstudio is restored for .NET Framework instead of Core-->
<NoWarn>$(NoWarn);NU1701</NoWarn>
<!-- By default the subdirectories containing CoreTestAssembly and ILTestAssembly would be
included in compilation of this project -->
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit">
<Version>$(XUnitPackageVersion)</Version>
</PackageReference>
<PackageReference Include="Microsoft.DotNet.XUnitExtensions">
<Version>$(MicrosoftDotNetXUnitExtensionsVersion)</Version>
</PackageReference>
<PackageReference Include="System.Reflection.Metadata">
<Version>$(SystemReflectionMetadataVersion)</Version>
</PackageReference>

<ItemGroup>
<PackageReference Include="xunit.core" Version="$(XUnitVersion)" ExcludeAssets="build" />
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" Version="$(MicrosoftDotNetXUnitExtensionsVersion)" />
<PackageReference Include="System.Reflection.Metadata" Version="1.8.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\src\ILCompiler.TypeSystem.csproj" />
<ProjectReference Include="..\ILCompiler.TypeSystem.ReadyToRun\ILCompiler.TypeSystem.ReadyToRun.csproj" />
<!-- Make sure the test data gets built -->
<ProjectReference Include="CoreTestAssembly\CoreTestAssembly.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Targets>Build;DebugSymbolsProjectOutputGroup</Targets>
</ProjectReference>
<ProjectReference Include="ILTestAssembly\ILTestAssembly.ilproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Content</OutputItemType>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Targets>Build</Targets>
</ProjectReference>
</ItemGroup>
<ItemGroup>
Expand All @@ -57,5 +55,4 @@
<Compile Include="TestTypeSystemContext.cs" />
<Compile Include="WellKnownTypeTests.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<Project Sdk="Microsoft.NET.Sdk.IL">

<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>ILTestAssembly</AssemblyName>
<SkipTestRun>true</SkipTestRun>
<TargetFramework>netstandard2.0</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>

<ItemGroup>
Expand All @@ -17,5 +18,4 @@
<Compile Include="VirtualFunctionOverride.il" />
</ItemGroup>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public void TestMultidimensionalArrays()
}

[Fact]
[ActiveIssue("corert port")]
public void TestSingleDimensionalArrays()
{
DefType systemArrayType = _context.GetWellKnownType(WellKnownType.Array);
Expand Down
Loading