未验证 提交 3735f11e 编写于 作者: A Andy Gocke 提交者: GitHub

Add ITypeSymbol.IsUnmanagedType and ITypeSymbol.IsRefLikeType (#32277)

* Add ITypeSymbol.IsUnmanagedType and ITypeSymbol.IsRefLikeType

Fixes #30427 and #30426
上级 16b21be7
......@@ -1145,7 +1145,7 @@ bool isRefEscape
}
// check receiver if ref-like
if (receiverOpt?.Type?.IsByRefLikeType == true)
if (receiverOpt?.Type?.IsRefLikeType == true)
{
escapeScope = Math.Max(escapeScope, GetValEscape(receiverOpt, scopeOfTheContainingExpression));
}
......@@ -1261,7 +1261,7 @@ bool isRefEscape
}
// check receiver if ref-like
if (receiverOpt?.Type?.IsByRefLikeType == true)
if (receiverOpt?.Type?.IsRefLikeType == true)
{
return CheckValEscape(receiverOpt.Syntax, receiverOpt, escapeFrom, escapeTo, false, diagnostics);
}
......@@ -1294,7 +1294,7 @@ bool isRefEscape
// collect all writeable ref-like arguments, including receiver
var receiverType = receiverOpt?.Type;
if (receiverType?.IsByRefLikeType == true && receiverType?.IsReadOnly == false)
if (receiverType?.IsRefLikeType == true && receiverType?.IsReadOnly == false)
{
escapeTo = GetValEscape(receiverOpt, scopeOfTheContainingExpression);
}
......@@ -1313,7 +1313,7 @@ bool isRefEscape
}
var paramIndex = argsToParamsOpt.IsDefault ? argIndex : argsToParamsOpt[argIndex];
if (parameters[paramIndex].RefKind.IsWritableReference() && argument.Type?.IsByRefLikeType == true)
if (parameters[paramIndex].RefKind.IsWritableReference() && argument.Type?.IsRefLikeType == true)
{
escapeTo = Math.Min(escapeTo, GetValEscape(argument, scopeOfTheContainingExpression));
}
......@@ -1328,7 +1328,7 @@ bool isRefEscape
{
var argument = argListArgs[argIndex];
var refKind = argListRefKindsOpt.IsDefault ? RefKind.None : argListRefKindsOpt[argIndex];
if (refKind.IsWritableReference() && argument.Type?.IsByRefLikeType == true)
if (refKind.IsWritableReference() && argument.Type?.IsRefLikeType == true)
{
escapeTo = Math.Min(escapeTo, GetValEscape(argument, scopeOfTheContainingExpression));
}
......@@ -1387,7 +1387,7 @@ bool isRefEscape
// They have "outer" val escape, so cannot be worse than escapeTo.
// check val escape of receiver if ref-like
if (receiverOpt?.Type?.IsByRefLikeType == true)
if (receiverOpt?.Type?.IsRefLikeType == true)
{
return CheckValEscape(receiverOpt.Syntax, receiverOpt, scopeOfTheContainingExpression, escapeTo, false, diagnostics);
}
......@@ -1448,7 +1448,7 @@ private static ParameterSymbol TryGetunmatchedInParameterAndFreeMatchedArgs(Immu
if (parameter.RefKind == RefKind.In &&
inParametersMatchedWithArgs?[i] != true &&
parameter.Type.TypeSymbol.IsByRefLikeType == false)
parameter.Type.TypeSymbol.IsRefLikeType == false)
{
return parameter;
}
......@@ -2157,7 +2157,7 @@ internal static uint GetValEscape(BoundExpression expr, uint scopeOfTheContainin
}
// to have local-referring values an expression must have a ref-like type
if (expr.Type?.IsByRefLikeType != true)
if (expr.Type?.IsRefLikeType != true)
{
return Binder.ExternalScope;
}
......@@ -2227,7 +2227,7 @@ internal static uint GetValEscape(BoundExpression expr, uint scopeOfTheContainin
var fieldAccess = (BoundFieldAccess)expr;
var fieldSymbol = fieldAccess.FieldSymbol;
if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsByRefLikeType)
if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsRefLikeType)
{
// Already an error state.
return Binder.ExternalScope;
......@@ -2454,7 +2454,7 @@ internal static bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint
}
// to have local-referring values an expression must have a ref-like type
if (expr.Type?.IsByRefLikeType != true)
if (expr.Type?.IsRefLikeType != true)
{
return true;
}
......@@ -2534,7 +2534,7 @@ internal static bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint
var fieldAccess = (BoundFieldAccess)expr;
var fieldSymbol = fieldAccess.FieldSymbol;
if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsByRefLikeType)
if (fieldSymbol.IsStatic || !fieldSymbol.ContainingType.IsRefLikeType)
{
// Already an error state.
return true;
......
......@@ -1444,7 +1444,7 @@ private BoundExpression SynthesizeMethodGroupReceiver(CSharpSyntaxNode syntax, A
private bool IsBadLocalOrParameterCapture(Symbol symbol, TypeSymbol type, RefKind refKind)
{
if (refKind != RefKind.None || type.IsByRefLikeType)
if (refKind != RefKind.None || type.IsRefLikeType)
{
var containingMethod = this.ContainingMemberOrLambda as MethodSymbol;
if ((object)containingMethod != null && (object)symbol.ContainingSymbol != (object)containingMethod)
......
......@@ -450,7 +450,7 @@ private BoundPattern BindDiscardPattern(DiscardPatternSyntax node, TypeSymbol in
/// </summary>
private static uint GetValEscape(TypeSymbol type, uint possibleValEscape)
{
return type.IsByRefLikeType ? possibleValEscape : Binder.ExternalScope;
return type.IsRefLikeType ? possibleValEscape : Binder.ExternalScope;
}
TypeSymbol BindRecursivePatternType(
......
......@@ -677,7 +677,7 @@ internal MethodSymbol TryFindDisposePatternMethod(BoundExpression expr, SyntaxNo
{
Debug.Assert(!(expr is null));
Debug.Assert(!(expr.Type is null));
Debug.Assert(expr.Type.IsValueType && expr.Type.IsByRefLikeType); // pattern dispose lookup is only valid on ref structs
Debug.Assert(expr.Type.IsValueType && expr.Type.IsRefLikeType); // pattern dispose lookup is only valid on ref structs
// Don't try and lookup if we're not enabled
if (MessageID.IDS_FeatureUsingDeclarations.RequiredVersion() > Compilation.LanguageVersion)
......@@ -1397,7 +1397,7 @@ private BoundExpression InferTypeForDiscardAssignment(BoundDiscardExpression op1
}
}
if (op1.Type.IsByRefLikeType)
if (op1.Type.IsRefLikeType)
{
var leftEscape = GetValEscape(op1, LocalScopeDepth);
op2 = ValidateEscape(op2, leftEscape, isByRef: false, diagnostics);
......
......@@ -319,7 +319,7 @@ public override Conversion GetStackAllocConversion(BoundStackAllocArrayCreation
else
{
var spanType = _binder.GetWellKnownType(WellKnownType.System_Span_T, ref useSiteDiagnostics);
if (spanType.TypeKind == TypeKind.Struct && spanType.IsByRefLikeType)
if (spanType.TypeKind == TypeKind.Struct && spanType.IsRefLikeType)
{
var spanType_T = spanType.Construct(sourceExpression.ElementType);
var spanConversion = ClassifyImplicitConversionFromType(spanType_T, destination, ref useSiteDiagnostics);
......
......@@ -162,7 +162,7 @@ bool populateDisposableConversionOrDisposeMethod(bool fromExpression)
// If this is a ref struct, try binding via pattern.
// We won't need to try and bind a second time if it fails, as async dispose can't be pattern based (ref structs are not allowed in async methods)
if (!(type is null) && type.IsValueType && type.IsByRefLikeType)
if (!(type is null) && type.IsValueType && type.IsRefLikeType)
{
BoundExpression receiver = fromExpression
? expressionOpt
......
......@@ -4971,7 +4971,7 @@ private void SetUnknownResultNullability()
public override BoundNode VisitStackAllocArrayCreation(BoundStackAllocArrayCreation node)
{
var result = base.VisitStackAllocArrayCreation(node);
Debug.Assert((object)node.Type == null || node.Type.IsPointerType() || node.Type.IsByRefLikeType);
Debug.Assert((object)node.Type == null || node.Type.IsPointerType() || node.Type.IsRefLikeType);
SetResult(node);
return result;
}
......
......@@ -651,7 +651,7 @@ private void AddTypeKind(INamedTypeSymbol symbol)
AddSpace();
}
if (csharpType.IsByRefLikeType)
if (csharpType.IsRefLikeType)
{
AddKeyword(SyntaxKind.RefKeyword);
AddSpace();
......
......@@ -173,7 +173,7 @@ public override bool IsAbstract
get { return false; }
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get { return false; }
}
......
......@@ -288,7 +288,7 @@ public override bool IsAbstract
get { return false; }
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get { return false; }
}
......
......@@ -228,7 +228,7 @@ internal sealed override bool IsManagedType
}
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......
......@@ -112,7 +112,7 @@ internal sealed override bool IsManagedType
}
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......
......@@ -103,7 +103,7 @@ public sealed override bool IsValueType
get { return false; }
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......
......@@ -629,13 +629,13 @@ public override ImmutableArray<CSharpAttributeData> GetAttributes()
MightContainExtensionMethods ? AttributeDescription.CaseSensitiveExtensionAttribute : default,
out _,
// Filter out [Obsolete], unless it was user defined
(IsByRefLikeType && ObsoleteAttributeData is null) ? AttributeDescription.ObsoleteAttribute : default,
(IsRefLikeType && ObsoleteAttributeData is null) ? AttributeDescription.ObsoleteAttribute : default,
out _,
// Filter out [IsReadOnly]
IsReadOnly ? AttributeDescription.IsReadOnlyAttribute : default,
out _,
// Filter out [IsByRefLike]
IsByRefLikeType ? AttributeDescription.IsByRefLikeAttribute : default);
IsRefLikeType ? AttributeDescription.IsByRefLikeAttribute : default);
ImmutableInterlocked.InterlockedInitialize(ref uncommon.lazyCustomAttributes, loadedCustomAttributes);
}
......@@ -2041,7 +2041,7 @@ public override bool IsSerializable
get { return (_flags & TypeAttributes.Serializable) != 0; }
}
internal override bool IsByRefLikeType
public override bool IsRefLikeType
{
get
{
......@@ -2162,7 +2162,7 @@ internal override ObsoleteAttributeData ObsoleteAttributeData
return null;
}
bool ignoreByRefLikeMarker = this.IsByRefLikeType;
bool ignoreByRefLikeMarker = this.IsRefLikeType;
ObsoleteAttributeHelpers.InitializeObsoleteDataFromMetadata(ref uncommon.lazyObsoleteAttributeData, _handle, ContainingPEModule, ignoreByRefLikeMarker);
return uncommon.lazyObsoleteAttributeData;
}
......
......@@ -107,7 +107,7 @@ internal sealed override bool IsManagedType
}
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......
......@@ -705,7 +705,7 @@ public override bool IsStatic
}
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......@@ -1404,7 +1404,7 @@ protected void AfterMembersChecks(DiagnosticBag diagnostics)
CheckForUnmatchedOperators(diagnostics);
var location = Locations[0];
if (this.IsByRefLikeType)
if (this.IsRefLikeType)
{
this.DeclaringCompilation.EnsureIsByRefLikeAttributeExists(diagnostics, location, modifyCompilation: true);
}
......
......@@ -55,7 +55,7 @@ protected void TypeChecks(TypeSymbol type, DiagnosticBag diagnostics)
{
diagnostics.Add(ErrorCode.ERR_FieldCantBeRefAny, TypeSyntax?.Location ?? this.Locations[0], type);
}
else if (type.IsByRefLikeType && (this.IsStatic || !containingType.IsByRefLikeType))
else if (type.IsRefLikeType && (this.IsStatic || !containingType.IsRefLikeType))
{
diagnostics.Add(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, TypeSyntax?.Location ?? this.Locations[0], type);
}
......
......@@ -1161,7 +1161,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor));
}
if (this.IsByRefLikeType)
if (this.IsRefLikeType)
{
AddSynthesizedAttribute(ref attributes, moduleBuilder.SynthesizeIsByRefLikeAttribute(this));
......
......@@ -469,7 +469,7 @@ private static BaseListSyntax GetBaseListOpt(SingleTypeDeclaration decl)
diagnostics.Add(ErrorCode.ERR_StaticClassInterfaceImpl, location, this, baseType);
}
if (this.IsByRefLikeType)
if (this.IsRefLikeType)
{
// '{0}': ref structs cannot implement interfaces
diagnostics.Add(ErrorCode.ERR_RefStructInterfaceImpl, location, this, baseType);
......
......@@ -1415,7 +1415,7 @@ internal override void ForceComplete(SourceLocation locationOpt, CancellationTok
{
diagnostics.Add(ErrorCode.ERR_FieldCantBeRefAny, this.CSharpSyntaxNode.Type.Location, type);
}
else if (this.IsAutoProperty && type.IsByRefLikeType && (this.IsStatic || !this.ContainingType.IsByRefLikeType))
else if (this.IsAutoProperty && type.IsRefLikeType && (this.IsStatic || !this.ContainingType.IsRefLikeType))
{
diagnostics.Add(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, this.CSharpSyntaxNode.Type.Location, type);
}
......
......@@ -162,7 +162,7 @@ internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
public override bool IsStatic => false;
internal sealed override bool IsByRefLikeType => false;
public sealed override bool IsRefLikeType => false;
internal sealed override bool IsReadOnly => false;
......
......@@ -118,7 +118,7 @@ private static NamedTypeSymbol MakeBaseType(CSharpCompilation compilation, Diagn
public override bool IsStatic => false;
internal override bool IsByRefLikeType => false;
public override bool IsRefLikeType => false;
internal override bool IsReadOnly => false;
......
......@@ -593,7 +593,7 @@ internal sealed override bool IsManagedType
}
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......
......@@ -634,6 +634,8 @@ public virtual NamedTypeSymbol TupleUnderlyingType
/// </remarks>
internal abstract bool IsManagedType { get; }
bool ITypeSymbol.IsUnmanagedType => !IsManagedType;
internal bool NeedsNullableAttribute()
{
return TypeSymbolWithAnnotations.NeedsNullableAttribute(typeWithAnnotationsOpt: default, typeOpt: this);
......@@ -671,7 +673,7 @@ internal TypeSymbol SetSpeakableNullabilityForReferenceTypes()
/// <summary>
/// Returns true if the type may contain embedded references
/// </summary>
internal abstract bool IsByRefLikeType { get; }
public abstract bool IsRefLikeType { get; }
/// <summary>
/// Returns true if the type is a readonly struct
......
......@@ -1056,7 +1056,7 @@ internal static bool IsValidV6SwitchGoverningType(this TypeSymbol type, bool isT
return ignoreSpanLikeTypes ?
false :
type.IsByRefLikeType;
type.IsRefLikeType;
}
public static bool IsIntrinsicType(this TypeSymbol type)
......
......@@ -207,9 +207,9 @@ public override bool IsSerializable
get { return _underlyingType.IsSerializable; }
}
internal override bool IsByRefLikeType
public override bool IsRefLikeType
{
get { return _underlyingType.IsByRefLikeType; }
get { return _underlyingType.IsRefLikeType; }
}
internal override bool IsReadOnly
......
......@@ -657,7 +657,7 @@ class Test
void validate(ModuleSymbol module)
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
Assert.True(type.IsRefLikeType);
var assemblyName = module.ContainingAssembly.Name;
......@@ -741,7 +741,7 @@ class Test
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
Assert.True(type.IsRefLikeType);
var attribute = type.GetAttributes().Single();
Assert.Equal("Windows.Foundation.Metadata.DeprecatedAttribute", attribute.AttributeClass.ToDisplayString());
......@@ -788,7 +788,7 @@ class Test
CompileAndVerify(text, verify: Verification.Passes, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");
Assert.True(type.IsByRefLikeType);
Assert.True(type.IsRefLikeType);
var attributes = type.GetAttributes();
......@@ -991,7 +991,7 @@ namespace System
private static void AssertReferencedIsByRefLike(TypeSymbol type, bool hasObsolete = true)
{
var peType = (PENamedTypeSymbol)type;
Assert.True(peType.IsByRefLikeType);
Assert.True(peType.IsRefLikeType);
// there is no [Obsolete] or [IsByRef] attribute returned
Assert.Empty(peType.GetAttributes());
......
......@@ -12,6 +12,62 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public class RefEscapingTests : CompilingTestBase
{
[Fact]
public void RefStructSemanticModel()
{
var tree = SyntaxFactory.ParseSyntaxTree(@"
using System;
struct S1 { }
ref struct S2 { public S1 F1; }
enum E1 { }
class C<T>
{
unsafe void M<U>() where U : unmanaged
{
Span<int> span = default;
var s1 = new S1();
var s2 = new S2();
var i0 = 0;
var e1 = new E1();
var o1 = new object();
var c1 = new C<int>();
var t1 = default(T);
var u1 = default(U);
void* p1 = null;
var a1 = new { X = 0 };
var a2 = new int[1];
var t2 = (0, 0);
}
}", options: TestOptions.Regular7_3);
var comp = CreateCompilationWithSpan(tree, TestOptions.UnsafeDebugDll);
Assert.True(comp.GetDiagnostics().All(d => d.Severity != DiagnosticSeverity.Error));
var model = comp.GetSemanticModel(tree);
var root = tree.GetRoot();
Assert.True(getLocalType("span").IsRefLikeType);
Assert.False(getLocalType("s1").IsRefLikeType);
Assert.True(getLocalType("s2").IsRefLikeType);
Assert.False(getLocalType("i0").IsRefLikeType);
Assert.False(getLocalType("t1").IsRefLikeType);
Assert.False(getLocalType("e1").IsRefLikeType);
Assert.False(getLocalType("o1").IsRefLikeType);
Assert.False(getLocalType("c1").IsRefLikeType);
Assert.False(getLocalType("t1").IsRefLikeType);
Assert.False(getLocalType("u1").IsRefLikeType);
Assert.False(getLocalType("p1").IsRefLikeType);
Assert.False(getLocalType("a1").IsRefLikeType);
Assert.False(getLocalType("a2").IsRefLikeType);
Assert.False(getLocalType("t2").IsRefLikeType);
ITypeSymbol getLocalType(string name)
{
var decl = root.DescendantNodes()
.OfType<VariableDeclaratorSyntax>()
.Single(n => n.Identifier.ValueText == name);
return ((ILocalSymbol)model.GetDeclaredSymbol(decl)).Type;
}
}
[Fact]
public void RefStructUsing()
{
......
......@@ -3012,6 +3012,71 @@ public void PointerToStructInPartialMethodSignature()
CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics();
}
[Fact]
public void IsUnmanagedTypeSemanticModel()
{
var tree = SyntaxFactory.ParseSyntaxTree(@"
struct S1 { }
struct S2 { public S1 F1; }
struct S3 { public object F1; }
struct S4<T> { public T F1; }
struct S5<T> where T : unmanaged { public T F1; }
enum E1 { }
class C<T>
{
unsafe void M<U>() where U : unmanaged
{
var s1 = new S1();
var s2 = new S2();
var s3 = new S3();
var s4 = new S4<int>();
var s5 = new S4<int>();
var i0 = 0;
var e1 = new E1();
var o1 = new object();
var c1 = new C<int>;
var t1 = default(T);
var u1 = default(U);
void* p1 = null;
var a1 = new { X = 0 };
var a2 = new int[1];
var t2 = (0, 0);
}
}");
var comp = CreateCompilation(tree);
var model = comp.GetSemanticModel(tree);
var root = tree.GetRoot();
// The spec states the following are unmanaged types:
// sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool.
// Any enum_type.
// Any pointer_type.
// Any user-defined struct_type that is not a constructed type and contains fields of unmanaged_types only.
// A type parameter with an unmanaged constraint
Assert.True(getLocalType("s1").IsUnmanagedType);
Assert.True(getLocalType("s2").IsUnmanagedType);
Assert.False(getLocalType("s3").IsUnmanagedType);
Assert.False(getLocalType("s4").IsUnmanagedType);
Assert.False(getLocalType("s5").IsUnmanagedType);
Assert.True(getLocalType("i0").IsUnmanagedType);
Assert.True(getLocalType("e1").IsUnmanagedType);
Assert.False(getLocalType("o1").IsUnmanagedType);
Assert.False(getLocalType("c1").IsUnmanagedType);
Assert.False(getLocalType("t1").IsUnmanagedType);
Assert.True(getLocalType("u1").IsUnmanagedType);
Assert.True(getLocalType("p1").IsUnmanagedType);
Assert.False(getLocalType("a1").IsUnmanagedType);
Assert.False(getLocalType("a2").IsUnmanagedType);
Assert.False(getLocalType("t2").IsUnmanagedType);
ITypeSymbol getLocalType(string name)
{
var decl = root.DescendantNodes()
.OfType<VariableDeclaratorSyntax>()
.Single(n => n.Identifier.ValueText == name);
return ((ILocalSymbol)model.GetDeclaredSymbol(decl)).Type;
}
}
#endregion IsManagedType
#region AddressOf operand kinds
......
......@@ -5301,6 +5301,10 @@ public string ToMinimalDisplayString(SemanticModel semanticModel, int position,
public bool IsSerializable => throw new NotImplementedException();
public bool IsRefLikeType => throw new NotImplementedException();
public bool IsUnmanagedType => throw new NotImplementedException();
#endregion
}
......
......@@ -181,7 +181,7 @@ public override bool IsStatic
}
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get
{
......
......@@ -39,19 +39,19 @@ class Program
var s1 = comp.GetTypeByMetadataName("Program+S1");
Assert.False(s1.IsByRefLikeType);
Assert.False(s1.IsRefLikeType);
Assert.True(s1.IsReadOnly);
Assert.Equal(Accessibility.Private, s1.DeclaredAccessibility);
Assert.Equal(TypeKind.Struct, s1.TypeKind);
var s2 = comp.GetTypeByMetadataName("Program+S2");
Assert.False(s2.IsByRefLikeType);
Assert.False(s2.IsRefLikeType);
Assert.True(s2.IsReadOnly);
Assert.Equal(Accessibility.Public, s2.DeclaredAccessibility);
Assert.Equal(TypeKind.Struct, s2.TypeKind);
var s3 = comp.GetTypeByMetadataName("Program+S3");
Assert.False(s3.IsByRefLikeType);
Assert.False(s3.IsRefLikeType);
Assert.True(s3.IsReadOnly);
Assert.Equal(Accessibility.Public, s3.DeclaredAccessibility);
Assert.Equal(TypeKind.Struct, s3.TypeKind);
......@@ -113,19 +113,19 @@ class Program
);
var s1 = comp.GetTypeByMetadataName("Program+S1");
Assert.False(s1.IsByRefLikeType);
Assert.False(s1.IsRefLikeType);
Assert.False(s1.IsReadOnly);
Assert.Equal(Accessibility.Private, s1.DeclaredAccessibility);
Assert.Equal(TypeKind.Class, s1.TypeKind);
var s2 = comp.GetTypeByMetadataName("Program+S2");
Assert.False(s2.IsByRefLikeType);
Assert.False(s2.IsRefLikeType);
Assert.False(s2.IsReadOnly);
Assert.Equal(Accessibility.Public, s2.DeclaredAccessibility);
Assert.Equal(TypeKind.Delegate, s2.TypeKind);
var s3 = comp.GetTypeByMetadataName("Program+S3");
Assert.False(s3.IsByRefLikeType);
Assert.False(s3.IsRefLikeType);
Assert.False(s3.IsReadOnly);
Assert.Equal(Accessibility.Public, s3.DeclaredAccessibility);
Assert.Equal(TypeKind.Interface, s3.TypeKind);
......@@ -148,13 +148,13 @@ class Program
);
var s1 = comp.GetTypeByMetadataName("Program+S1");
Assert.True(s1.IsByRefLikeType);
Assert.True(s1.IsRefLikeType);
Assert.True(s1.IsReadOnly);
Assert.Equal(Accessibility.Private, s1.DeclaredAccessibility);
Assert.Equal(TypeKind.Struct, s1.TypeKind);
var s2 = comp.GetTypeByMetadataName("Program+S2");
Assert.True(s2.IsByRefLikeType);
Assert.True(s2.IsRefLikeType);
Assert.True(s2.IsReadOnly);
Assert.Equal(Accessibility.Public, s2.DeclaredAccessibility);
Assert.Equal(TypeKind.Struct, s2.TypeKind);
......@@ -181,11 +181,11 @@ class Program
);
var s1 = comp.GetTypeByMetadataName("Program+S1");
Assert.False(s1.IsByRefLikeType);
Assert.False(s1.IsRefLikeType);
Assert.True(s1.IsReadOnly);
var s2 = comp.GetTypeByMetadataName("Program+S2");
Assert.True(s2.IsByRefLikeType);
Assert.True(s2.IsRefLikeType);
Assert.True(s2.IsReadOnly);
}
......@@ -215,15 +215,15 @@ partial struct S3{}
);
var s1 = comp.GetTypeByMetadataName("Program+S1");
Assert.True(s1.IsByRefLikeType);
Assert.True(s1.IsRefLikeType);
Assert.True(s1.IsReadOnly);
var s2 = comp.GetTypeByMetadataName("Program+S2");
Assert.False(s2.IsByRefLikeType);
Assert.False(s2.IsRefLikeType);
Assert.True(s2.IsReadOnly);
var s3 = comp.GetTypeByMetadataName("Program+S3");
Assert.True(s3.IsByRefLikeType);
Assert.True(s3.IsRefLikeType);
Assert.True(s3.IsReadOnly);
}
}
......
*REMOVED*Microsoft.CodeAnalysis.Operations.IEventAssignmentOperation.EventReference.get -> Microsoft.CodeAnalysis.Operations.IEventReferenceOperation
Microsoft.CodeAnalysis.IFieldSymbol.IsFixedSizeBuffer.get -> bool
Microsoft.CodeAnalysis.ITypeSymbol.IsRefLikeType.get -> bool
Microsoft.CodeAnalysis.ITypeSymbol.IsUnmanagedType.get -> bool
Microsoft.CodeAnalysis.OperationKind.Binary = 32 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.ConstructorBody = 89 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.DiscardPattern = 104 -> Microsoft.CodeAnalysis.OperationKind
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
......@@ -95,6 +96,21 @@ public interface ITypeSymbol : INamespaceOrTypeSymbol
/// Must be a non-null interface property, method, or event.
/// </param>
ISymbol FindImplementationForInterfaceMember(ISymbol interfaceMember);
/// <summary>
/// True if the type is ref-like, meaning it follows rules similar to CLR by-ref variables. False if the type
/// is not ref-like or if the language has no concept of ref-like types.
/// </summary>
/// <remarks>
/// <see cref="Span{T}" /> is a commonly used ref-like type.
/// </remarks>
bool IsRefLikeType { get; }
/// <summary>
/// True if the type is unmanaged according to language rules. False if managed or if the language
/// has no concept of unmanaged types.
/// </summary>
bool IsUnmanagedType { get; }
}
// Intentionally not extension methods. We don't want them ever be called for symbol classes
......
......@@ -1746,6 +1746,22 @@ protected static void VerifyFlowGraph(CSharpCompilation compilation, SyntaxNode
#region Span
protected static CSharpCompilation CreateCompilationWithSpan(SyntaxTree tree, CSharpCompilationOptions options = null)
{
var reference = CreateCompilation(
SpanSource,
options: TestOptions.UnsafeReleaseDll);
reference.VerifyDiagnostics();
var comp = CreateCompilation(
tree,
references: new[] { reference.EmitToImageReference() },
options: options);
return comp;
}
protected static CSharpCompilation CreateCompilationWithMscorlibAndSpan(string text, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null)
{
var reference = CreateEmptyCompilation(
......
......@@ -510,6 +510,20 @@ Done:
End Get
End Property
Private ReadOnly Property ITypeSymbol_IsRefLikeType As Boolean Implements ITypeSymbol.IsRefLikeType
Get
' VB has no concept of ref-like types
Return False
End Get
End Property
Private ReadOnly Property ITypeSymbol_IsUnmanagedType As Boolean Implements ITypeSymbol.IsUnmanagedType
Get
' VB has no concept of unmanaged types
Return False
End Get
End Property
#End Region
#Region "Interface checks"
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
......@@ -2900,6 +2901,83 @@ End Class
#Region "Msic."
<Fact>
Public Sub IsUnmanagedType()
Dim csharpComp = CreateCSharpCompilation("
public struct S1 { }
public struct S2 { public S1 F1; }
public struct S3 { public object F1; }
public struct S4<T> { public T F1; }
public enum E1 { }
")
Dim tree = SyntaxFactory.ParseSyntaxTree("
Class C
Sub M()
Dim s1 = new S1()
Dim s2 = new S2()
Dim s3 = new S3()
Dim s4 = new S4(Of Integer)()
Dim e1 = new E1()
End Sub
End Class")
Dim comp = CreateCompilation(tree, references:={csharpComp.EmitToImageReference()})
comp.AssertTheseCompileDiagnostics()
Dim model = comp.GetSemanticModel(tree)
Dim root = tree.GetRoot()
Dim getLocalType = Function(name As String) As ITypeSymbol
Dim decl = root.DescendantNodes().
OfType(Of ModifiedIdentifierSyntax)().
Single(Function(n) n.Identifier.ValueText = name)
Return CType(model.GetDeclaredSymbol(decl), ILocalSymbol).Type
End Function
' VB does not have a concept of a managed type
Assert.False(getLocalType("s1").IsUnmanagedType)
Assert.False(getLocalType("s2").IsUnmanagedType)
Assert.False(getLocalType("s3").IsUnmanagedType)
Assert.False(getLocalType("s4").IsUnmanagedType)
Assert.False(getLocalType("e1").IsUnmanagedType)
End Sub
<Fact>
Public Sub IsRefLikeType()
Dim csharpComp = CreateCSharpCompilation("
public struct S1 { }
public ref struct S2 { public S1 F1; }
public enum E1 { }
", parseOptions:=New CSharp.CSharpParseOptions(CSharp.LanguageVersion.CSharp7_3))
Dim tree = SyntaxFactory.ParseSyntaxTree("
Structure S3
Dim F1 As Object
End Structure
Class C
Sub M()
Dim s1 = new S1()
Dim s2 = new S2()
Dim s3 = new S3()
Dim e1 = new E1()
End Sub
End Class")
Dim comp = CreateCompilation(tree, references:={csharpComp.EmitToImageReference()})
comp.AssertTheseDiagnostics(<errors>
BC30668: 'S2' is obsolete: 'Types with embedded references are not supported in this version of your compiler.'.
Dim s2 = new S2()
~~
</errors>)
Dim model = comp.GetSemanticModel(tree)
Dim root = tree.GetRoot()
Dim getLocalType = Function(name As String) As ITypeSymbol
Dim decl = root.DescendantNodes().
OfType(Of ModifiedIdentifierSyntax)().
Single(Function(n) n.Identifier.ValueText = name)
Return CType(model.GetDeclaredSymbol(decl), ILocalSymbol).Type
End Function
' VB does not have a concept of a ref-like type
Assert.False(getLocalType("s1").IsRefLikeType)
Assert.False(getLocalType("s2").IsRefLikeType)
Assert.False(getLocalType("s3").IsRefLikeType)
Assert.False(getLocalType("e1").IsRefLikeType)
End Sub
<Fact()>
Public Sub IsAccessible()
Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40(
......
......@@ -305,7 +305,7 @@ public override bool IsAbstract
get { return false; }
}
internal sealed override bool IsByRefLikeType
public sealed override bool IsRefLikeType
{
get { return false; }
}
......
......@@ -144,6 +144,10 @@ public override ImmutableArray<INamedTypeSymbol> GetTypeMembers(string name, int
public new INamedTypeSymbol OriginalDefinition => this;
public bool IsSerializable => throw new NotImplementedException();
public bool IsRefLikeType => throw new NotImplementedException();
public bool IsUnmanagedType => throw new NotImplementedException();
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Editing;
......@@ -74,7 +75,7 @@ public ImmutableArray<CustomModifier> GetTypeArgumentCustomModifiers(int ordinal
{
if (ordinal < 0 || ordinal >= Arity)
{
throw new System.IndexOutOfRangeException();
throw new IndexOutOfRangeException();
}
return ImmutableArray.Create<CustomModifier>();
......@@ -97,5 +98,9 @@ public override string MetadataName
public bool MightContainExtensionMethods => false;
public bool IsComImport => false;
public bool IsUnmanagedType => throw new NotImplementedException();
public bool IsRefLikeType => throw new NotImplementedException();
}
}
......@@ -54,5 +54,9 @@ public ImmutableArray<INamedTypeSymbol> AllInterfaces
public override bool IsType => true;
public bool IsSerializable => false;
bool ITypeSymbol.IsRefLikeType => throw new System.NotImplementedException();
bool ITypeSymbol.IsUnmanagedType => throw new System.NotImplementedException();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册