blob: c0ce80263aad8c807be4608e0036d9cba2ed05b0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Debug = System.Diagnostics.Debug;
namespace Internal.TypeSystem
{
// Implements canonicalization for types
partial class TypeDesc
{
/// <summary>
/// Stores a cached version of the canonicalized form of this type since
/// calculating it is a recursive operation
/// </summary>
TypeDesc _specificCanonCache;
TypeDesc _universalCanonCache;
TypeDesc GetCachedCanonValue(CanonicalFormKind kind)
{
switch (kind)
{
case CanonicalFormKind.Specific:
return _specificCanonCache;
case CanonicalFormKind.Universal:
return _universalCanonCache;
default:
Debug.Fail("Invalid CanonicalFormKind: " + kind);
return null;
}
}
void SetCachedCanonValue(CanonicalFormKind kind, TypeDesc value)
{
switch (kind)
{
case CanonicalFormKind.Specific:
Debug.Assert(_specificCanonCache == null || _specificCanonCache == value);
_specificCanonCache = value;
break;
case CanonicalFormKind.Universal:
Debug.Assert(_universalCanonCache == null || _universalCanonCache == value);
_universalCanonCache = value;
break;
default:
Debug.Fail("Invalid CanonicalFormKind: " + kind);
break;
}
}
/// <summary>
/// Returns the canonical form of this type
/// </summary>
public TypeDesc ConvertToCanonForm(CanonicalFormKind kind)
{
TypeDesc canonForm = GetCachedCanonValue(kind);
if (canonForm == null)
{
canonForm = ConvertToCanonFormImpl(kind);
SetCachedCanonValue(kind, canonForm);
}
return canonForm;
}
/// <summary>
/// Derived types that override this should convert their generic parameters to canonical ones
/// </summary>
protected abstract TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind);
/// <summary>
/// Returns true if this type matches the discovery policy or if it's parameterized over one that does.
/// </summary>
public abstract bool IsCanonicalSubtype(CanonicalFormKind policy);
/// <summary>
/// Gets a value indicating whether this type is considered to be canonical type.
/// Note this will only return true if this is type is the actual __Canon/__UniversalCanon type,
/// or a struct instantiated over one of those. See also <see cref="IsCanonicalSubtype(CanonicalFormKind)"/>.
/// </summary>
internal bool IsCanonicalType
{
get
{
if (Context.IsCanonicalDefinitionType(this, CanonicalFormKind.Any))
return true;
else if (this.IsValueType)
return this.IsCanonicalSubtype(CanonicalFormKind.Any);
else
return false;
}
}
}
}
|