diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs b/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs index f22b90c261818..a59f739f3a5d5 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFlags.cs @@ -77,9 +77,9 @@ internal enum BinderFlags : uint ParameterDefaultValue = 1 << 23, /// - /// In the debugger, one can take the address of a managed object. + /// In the debugger, one can take the address of a moveable variable. /// - AllowManagedAddressOf = 1 << 24, + AllowMoveableAddressOf = 1 << 24, /// /// In the debugger, the context is always unsafe, but one can still await. @@ -112,6 +112,12 @@ internal enum BinderFlags : uint /// InExpressionTree = 1 << 30, + /// + /// Indicates whether the current context allows pointer types to managed types, + /// assuming we're already in an unsafe context (otherwise all pointer types are errors anyways). + /// + AllowManagedPointer = 1u << 31, + // Groups AllClearedAtExecutableCodeBoundary = InLockBody | InCatchBlock | InCatchFilter | InFinallyBlock | InTryBlockOfTryCatch | InNestedFinallyBlock, diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 787f558f0779b..806be214a2c43 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -1387,7 +1387,7 @@ private BoundExpression BindSizeOf(SizeOfExpressionSyntax node, BindingDiagnosti TypeWithAnnotations typeWithAnnotations = this.BindType(typeSyntax, diagnostics, out alias); TypeSymbol type = typeWithAnnotations.Type; - bool typeHasErrors = type.IsErrorType() || CheckManagedAddr(Compilation, type, node.Location, diagnostics); + bool typeHasErrors = type.IsErrorType() || CheckManagedAddr(Compilation, type, warnForManaged: false, node.Location, diagnostics); BoundTypeExpression boundType = new BoundTypeExpression(typeSyntax, alias, typeWithAnnotations, typeHasErrors); ConstantValue constantValue = GetConstantSizeOf(type); @@ -1397,23 +1397,31 @@ private BoundExpression BindSizeOf(SizeOfExpressionSyntax node, BindingDiagnosti } /// true if managed type-related errors were found, otherwise false. - internal static bool CheckManagedAddr(CSharpCompilation compilation, TypeSymbol type, Location location, BindingDiagnosticBag diagnostics) + internal static bool CheckManagedAddr(CSharpCompilation compilation, TypeSymbol type, bool warnForManaged, Location location, BindingDiagnosticBag diagnostics) { var useSiteInfo = new CompoundUseSiteInfo(diagnostics, compilation.Assembly); var managedKind = type.GetManagedKind(ref useSiteInfo); diagnostics.Add(location, useSiteInfo); - return CheckManagedAddr(compilation, type, managedKind, location, diagnostics); + return CheckManagedAddr(compilation, type, managedKind, warnForManaged, location, diagnostics); } /// true if managed type-related errors were found, otherwise false. - internal static bool CheckManagedAddr(CSharpCompilation compilation, TypeSymbol type, ManagedKind managedKind, Location location, BindingDiagnosticBag diagnostics) + internal static bool CheckManagedAddr(CSharpCompilation compilation, TypeSymbol type, ManagedKind managedKind, bool warnForManaged, Location location, BindingDiagnosticBag diagnostics) { switch (managedKind) { case ManagedKind.Managed: - diagnostics.Add(ErrorCode.ERR_ManagedAddr, location, type); - return true; + if (warnForManaged) + { + diagnostics.Add(ErrorCode.WRN_ManagedAddr, location, type); + return false; + } + else + { + diagnostics.Add(ErrorCode.ERR_ManagedAddr, location, type); + return true; + } case ManagedKind.UnmanagedWithGenerics when MessageID.IDS_FeatureUnmanagedConstructedTypes.GetFeatureAvailabilityDiagnosticInfo(compilation) is CSDiagnosticInfo diagnosticInfo: diagnostics.Add(diagnosticInfo, location); return true; @@ -2219,7 +2227,7 @@ private BoundBaseReference BindBase(BaseExpressionSyntax node, BindingDiagnostic private BoundExpression BindCast(CastExpressionSyntax node, BindingDiagnosticBag diagnostics) { BoundExpression operand = this.BindValue(node.Expression, diagnostics, BindValueKind.RValue); - TypeWithAnnotations targetTypeWithAnnotations = this.BindType(node.Type, diagnostics); + TypeWithAnnotations targetTypeWithAnnotations = this.WithAdditionalFlags(BinderFlags.AllowManagedPointer).BindType(node.Type, diagnostics); TypeSymbol targetType = targetTypeWithAnnotations.Type; if (targetType.IsNullableType() && @@ -3299,7 +3307,7 @@ private BoundExpression BindImplicitStackAllocArrayCreationExpression(ImplicitSt if (!bestType.IsErrorType()) { - CheckManagedAddr(Compilation, bestType, node.Location, diagnostics); + CheckManagedAddr(Compilation, bestType, warnForManaged: false, node.Location, diagnostics); } return BindStackAllocWithInitializer( @@ -3656,7 +3664,7 @@ private BoundExpression BindStackAllocArrayCreationExpression( TypeSymbol type = GetStackAllocType(node, elementType, diagnostics, out bool hasErrors); if (!elementType.Type.IsErrorType()) { - hasErrors = hasErrors || CheckManagedAddr(Compilation, elementType.Type, elementTypeSyntax.Location, diagnostics); + hasErrors = hasErrors || CheckManagedAddr(Compilation, elementType.Type, warnForManaged: false, elementTypeSyntax.Location, diagnostics); } SyntaxList rankSpecifiers = arrayTypeSyntax.RankSpecifiers; diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs index a57aa564dcebb..cdaa79cb3a517 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs @@ -2502,30 +2502,22 @@ private BoundExpression BindAddressOfExpression(PrefixUnaryExpressionSyntax node ManagedKind managedKind = operandType.GetManagedKind(ref useSiteInfo); diagnostics.Add(node.Location, useSiteInfo); - bool allowManagedAddressOf = Flags.Includes(BinderFlags.AllowManagedAddressOf); - if (!allowManagedAddressOf) + if (!hasErrors) { - if (!hasErrors) - { - hasErrors = CheckManagedAddr(Compilation, operandType, managedKind, node.Location, diagnostics); - } + hasErrors = CheckManagedAddr(Compilation, operandType, managedKind, warnForManaged: true, node.Location, diagnostics); + } - if (!hasErrors) + bool allowManagedAddressOf = Flags.Includes(BinderFlags.AllowMoveableAddressOf); + if (!hasErrors && !allowManagedAddressOf) + { + if (IsMoveableVariable(operand, accessedLocalOrParameterOpt: out _) != isFixedStatementAddressOfExpression) { - Symbol accessedLocalOrParameterOpt; - if (IsMoveableVariable(operand, out accessedLocalOrParameterOpt) != isFixedStatementAddressOfExpression) - { - Error(diagnostics, isFixedStatementAddressOfExpression ? ErrorCode.ERR_FixedNotNeeded : ErrorCode.ERR_FixedNeeded, node); - hasErrors = true; - } + Error(diagnostics, isFixedStatementAddressOfExpression ? ErrorCode.ERR_FixedNotNeeded : ErrorCode.ERR_FixedNeeded, node); + hasErrors = true; } } - TypeSymbol pointedAtType = managedKind == ManagedKind.Managed && allowManagedAddressOf - ? GetSpecialType(SpecialType.System_IntPtr, diagnostics, node) - : operandType ?? CreateErrorType(); - TypeSymbol pointerType = new PointerTypeSymbol(TypeWithAnnotations.Create(pointedAtType)); - + TypeSymbol pointerType = new PointerTypeSymbol(TypeWithAnnotations.Create(operandType)); return new BoundAddressOfOperator(node, operand, pointerType, hasErrors); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 566008ea46a62..daefce4d6a642 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -1334,7 +1334,7 @@ private bool IsValidFixedVariableInitializer(TypeSymbol declType, SourceLocalSym } } - if (CheckManagedAddr(Compilation, elementType, initializerSyntax.Location, diagnostics)) + if (CheckManagedAddr(Compilation, elementType, warnForManaged: false, initializerSyntax.Location, diagnostics)) { hasErrors = true; } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index 7c250425fafb2..51679f43f7957 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -575,7 +575,7 @@ NamespaceOrTypeOrAliasSymbolWithAnnotations bindPointer() if (!Flags.HasFlag(BinderFlags.SuppressConstraintChecks)) { - CheckManagedAddr(Compilation, elementType.Type, node.Location, diagnostics); + CheckManagedAddr(Compilation, elementType.Type, warnForManaged: Flags.HasFlag(BinderFlags.AllowManagedPointer), node.Location, diagnostics); } return TypeWithAnnotations.Create(new PointerTypeSymbol(elementType)); diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 04bff9bc269d8..ca02d21e77a84 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -990,6 +990,12 @@ Cannot take the address of, get the size of, or declare a pointer to a managed type ('{0}') + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + This takes the address of, gets the size of, or declares a pointer to a managed type + The type of a local declared in a fixed statement must be a pointer type diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index d49449df1f81b..938b5b53455be 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -1612,6 +1612,9 @@ internal enum ErrorCode ERR_ImplicitRangeIndexerWithName = 8429, // available range + WRN_ManagedAddr = 8500, + // available range + #region diagnostics introduced for recursive patterns ERR_WrongNumberOfSubpatterns = 8502, ERR_PropertyPatternNameMissing = 8503, diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index f9d9b37730345..055423539897b 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -504,6 +504,7 @@ internal static int GetWarningLevel(ErrorCode code) case ErrorCode.WRN_DuplicateAnalyzerReference: case ErrorCode.WRN_ScopedMismatchInParameterOfTarget: case ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation: + case ErrorCode.WRN_ManagedAddr: return 1; default: return 0; @@ -2229,6 +2230,7 @@ internal static bool IsBuildOnlyDiagnostic(ErrorCode code) case ErrorCode.ERR_RefReturnOnlyParameter: case ErrorCode.ERR_RefReturnOnlyParameter2: case ErrorCode.ERR_RefAssignReturnOnly: + case ErrorCode.WRN_ManagedAddr: return false; default: // NOTE: All error codes must be explicitly handled in this switch statement diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index cc5e37e36943b..62b2a683df648 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -183,6 +183,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter: case ErrorCode.WRN_UnconsumedEnumeratorCancellationAttributeUsage: case ErrorCode.WRN_UndecoratedCancellationTokenParameter: + case ErrorCode.WRN_ManagedAddr: case ErrorCode.WRN_SwitchExpressionNotExhaustive: case ErrorCode.WRN_CaseConstantNamedUnderscore: case ErrorCode.WRN_IsTypeNamedUnderscore: diff --git a/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs b/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs index 5918d1d848ee6..7d0ab5cfe1283 100644 --- a/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs +++ b/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs @@ -112,7 +112,7 @@ private static void StructDependsClosure(NamedTypeSymbol type, HashSet p /// all special types have spec'd values (basically, (non-string) primitives) are not managed; /// /// Only structs are complicated, because the definition is recursive. A struct type is managed - /// if one of its instance fields is managed. Unfortunately, this can result in infinite recursion. + /// if one of its instance fields is managed or a ref field. Unfortunately, this can result in infinite recursion. /// If the closure is finite, and we don't find anything definitely managed, then we return true. /// If the closure is infinite, we disregard all but a representative of any expanding cycle. /// @@ -128,13 +128,12 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type, ref CompoundUse { // Otherwise, we have to build and inspect the closure of depended-upon types. var hs = PooledHashSet.GetInstance(); - var result = DependsOnDefinitelyManagedType(type, hs, ref useSiteInfo); + var result = dependsOnDefinitelyManagedType(type, hs, ref useSiteInfo); definitelyManaged = result.definitelyManaged; hasGenerics = hasGenerics || result.hasGenerics; hs.Free(); } - if (definitelyManaged) { return ManagedKind.Managed; @@ -147,93 +146,99 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type, ref CompoundUse { return ManagedKind.Unmanaged; } - } - - // NOTE: If we do not check HasPointerType, we will unconditionally - // bind Type and that may cause infinite recursion. - // HasPointerType can use syntax directly and break recursion. - internal static TypeSymbol NonPointerType(this FieldSymbol field) => - field.HasPointerType ? null : field.Type; - - private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet partialClosure, ref CompoundUseSiteInfo useSiteInfo) - { - Debug.Assert((object)type != null); - var hasGenerics = false; - if (partialClosure.Add(type)) + static (bool definitelyManaged, bool hasGenerics) dependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet partialClosure, ref CompoundUseSiteInfo useSiteInfo) { - foreach (var member in type.GetInstanceFieldsAndEvents()) - { - // Only instance fields (including field-like events) affect the outcome. - FieldSymbol field; - switch (member.Kind) - { - case SymbolKind.Field: - field = (FieldSymbol)member; - Debug.Assert((object)(field.AssociatedSymbol as EventSymbol) == null, - "Didn't expect to find a field-like event backing field in the member list."); - break; - case SymbolKind.Event: - field = ((EventSymbol)member).AssociatedField; - break; - default: - throw ExceptionUtilities.UnexpectedValue(member.Kind); - } + Debug.Assert((object)type != null); - if ((object)field == null) + var hasGenerics = false; + if (partialClosure.Add(type)) + { + foreach (var member in type.GetInstanceFieldsAndEvents()) { - continue; - } + // Only instance fields (including field-like events) affect the outcome. + FieldSymbol field; + switch (member.Kind) + { + case SymbolKind.Field: + field = (FieldSymbol)member; + Debug.Assert((object)(field.AssociatedSymbol as EventSymbol) == null, + "Didn't expect to find a field-like event backing field in the member list."); + break; + case SymbolKind.Event: + field = ((EventSymbol)member).AssociatedField; + break; + default: + throw ExceptionUtilities.UnexpectedValue(member.Kind); + } - TypeSymbol fieldType = field.NonPointerType(); - if (fieldType is null) - { - // pointers are unmanaged - continue; - } + if ((object)field == null) + { + continue; + } - fieldType.AddUseSiteInfo(ref useSiteInfo); - NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol; - if ((object)fieldNamedType == null) - { - if (fieldType.IsManagedType(ref useSiteInfo)) + if (field.RefKind != RefKind.None) { + // A ref struct which has a ref field is never considered unmanaged return (true, hasGenerics); } - } - else - { - var result = IsManagedTypeHelper(fieldNamedType); - hasGenerics = hasGenerics || result.hasGenerics; - // NOTE: don't use ManagedKind.get on a NamedTypeSymbol - that could lead - // to infinite recursion. - switch (result.isManaged) - { - case ThreeState.True: - return (true, hasGenerics); - case ThreeState.False: - continue; + TypeSymbol fieldType = field.NonPointerType(); + if (fieldType is null) + { + // pointers are unmanaged + continue; + } - case ThreeState.Unknown: - if (!fieldNamedType.OriginalDefinition.KnownCircularStruct) - { - var (definitelyManaged, childHasGenerics) = DependsOnDefinitelyManagedType(fieldNamedType, partialClosure, ref useSiteInfo); - hasGenerics = hasGenerics || childHasGenerics; - if (definitelyManaged) + fieldType.AddUseSiteInfo(ref useSiteInfo); + NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol; + if ((object)fieldNamedType == null) + { + if (fieldType.IsManagedType(ref useSiteInfo)) + { + return (true, hasGenerics); + } + } + else + { + var result = IsManagedTypeHelper(fieldNamedType); + hasGenerics = hasGenerics || result.hasGenerics; + // NOTE: don't use ManagedKind.get on a NamedTypeSymbol - that could lead + // to infinite recursion. + switch (result.isManaged) + { + case ThreeState.True: + return (true, hasGenerics); + + case ThreeState.False: + continue; + + case ThreeState.Unknown: + if (!fieldNamedType.OriginalDefinition.KnownCircularStruct) { - return (true, hasGenerics); + var (definitelyManaged, childHasGenerics) = dependsOnDefinitelyManagedType(fieldNamedType, partialClosure, ref useSiteInfo); + hasGenerics = hasGenerics || childHasGenerics; + if (definitelyManaged) + { + return (true, hasGenerics); + } } - } - continue; + continue; + } } } } - } - return (false, hasGenerics); + return (false, hasGenerics); + } } + // NOTE: If we do not check HasPointerType, we will unconditionally + // bind Type and that may cause infinite recursion. + // HasPointerType can use syntax directly and break recursion. + internal static TypeSymbol NonPointerType(this FieldSymbol field) => + field.HasPointerType ? null : field.Type; + /// /// Returns True or False if we can determine whether the type is managed /// without looking at its fields and Unknown otherwise. diff --git a/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs b/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs index a365371a88687..52aedf5e4b316 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs @@ -545,7 +545,7 @@ private static bool CheckConstraintsSingleType(TypeSymbol type, in CheckConstrai } else if (type.Kind == SymbolKind.PointerType) { - Binder.CheckManagedAddr(args.CurrentCompilation, ((PointerTypeSymbol)type).PointedAtType, args.Location, args.Diagnostics); + Binder.CheckManagedAddr(args.CurrentCompilation, ((PointerTypeSymbol)type).PointedAtType, warnForManaged: false, args.Location, args.Diagnostics); } return false; // continue walking types } diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index c68eb4d8c7cbf..93f1535b4c860 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -1992,6 +1992,16 @@ Název typu obsahuje jenom malá písmena ASCII. Tyto názvy se můžou stát vyhrazenými pro daný jazyk. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Převádí se skupina metod {0} na nedelegující typ {1}. Chtěli jste volat tuto metodu? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 8692d8632c0c5..0cd0301c6ce04 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -1992,6 +1992,16 @@ Der Typname enthält nur ASCII-Zeichen in Kleinbuchstaben. Solche Namen können möglicherweise für die Sprache reserviert werden. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Die Methodengruppe „{0}“ wird in den Nichtdelegattyp „{1}“ konvertiert. Wollten Sie die Methode aufrufen? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index b02a146c93efb..d9eeff8773d2f 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -1992,6 +1992,16 @@ El nombre de tipo solo contiene caracteres ASCII en minúsculas. Estos nombres pueden reservarse para el idioma. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Convirtiendo el grupo de métodos '{0}' al tipo no delegado '{1}'. ¿Pretendía invocar el método? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index aba5fc45e761f..a57402a7261cc 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -1992,6 +1992,16 @@ Le nom de type contient uniquement des caractères ascii en minuscules. De tels noms peuvent devenir réservés pour la langue. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Impossible de convertir le groupe de méthodes '{0}' en type non-délégué '{1}'. Souhaitiez-vous appeler la méthode? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index c75a8e92291a4..b96fdd88773b8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -1992,6 +1992,16 @@ Il nome del tipo contiene solo caratteri ascii minuscoli. Tali nomi possono diventare riservati per la lingua. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Conversione del gruppo di metodi '{0}' nel tipo non delegato '{1}'. Si intendeva richiamare il metodo? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 65e1f9e213d31..cc765f42ff348 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -1992,6 +1992,16 @@ 型名には、小文字の ASCII 文字のみが含まれています。このような名前は、プログラミング言語用に予約されている可能性があります。 + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? メソッド グループ '{0}' を非デリゲート型 '{1}' に変換中です。このメソッドを呼び出すつもりでしたか? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index ff234ed42ab32..d1a6459409ae1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -1992,6 +1992,16 @@ 형식 이름에는 소문자 ASCII 문자만 포함됩니다. 이러한 이름은 언어에 대해 예약될 수 있습니다. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? 메서드 그룹 '{0}'을(를) 비 위임 유형 '{1}'(으)로 변환하는 중입니다. 메서드를 호출하려고 했습니까? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 3c9b7611cbe47..f722406808f32 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -1992,6 +1992,16 @@ Nazwa typu zawiera tylko małe litery ascii. Takie nazwy mogą zostać zarezerwowane dla języka. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Konwertowanie grupy metod „{0}” na typ inny niż delegowany „{1}”. Czy zamierzasz wywołać metodę? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 63c6224abaa39..4fcc67c3b55fb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -1992,6 +1992,16 @@ O nome do tipo contém apenas caracteres ascii em caixa baixa. Esses nomes podem ficar reservados para o idioma. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Convertendo grupo de métodos '{0}' em tipo não delegado '{1}'. Você pretendia invocar o método? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index de1fb4d926785..3fd3f1d3a6848 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -1992,6 +1992,16 @@ Имя типа содержит только строчные символы ASCII. Такие имена могут резервироваться для языка. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? Преобразование группы методов "{0}" в незаменяемый тип "{1}". Вы намеревались вызвать этот метод? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index bd7101a513967..62df728e7992d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -1992,6 +1992,16 @@ Tür adı yalnızca küçük harfli ascii karakterleri içerir. Bu tür adlar dil için ayrılmış hale gelebilir. + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? “{0}” yöntem grubunu temsilci olmayan tip “{1}”e dönüştürme. Yöntemi çağırmayı düşündünüz mü? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 4fff2340c997b..f9755782088ad 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -1992,6 +1992,16 @@ 该类型名称仅包含小写 ascii 字符。此类名称可能会成为该语言的保留值。 + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? 将方法组“{0}”转换为非委托类型“{1}”。是否希望调用此方法? diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 23e75df9fe506..587daf7e12884 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -1992,6 +1992,16 @@ 類型名稱只包含小寫的 ASCII 字元。此類名稱可能保留供此語言使用。 + + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + This takes the address of, gets the size of, or declares a pointer to a managed type ('{0}') + + + + This takes the address of, gets the size of, or declares a pointer to a managed type + This takes the address of, gets the size of, or declares a pointer to a managed type + + Converting method group '{0}' to non-delegate type '{1}'. Did you intend to invoke the method? 將方法群組 '{0}' 轉換成非委派類型 '{1}'。原本希望叫用該方法嗎? diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs index ad05993d5f927..c6c8919d9e329 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs @@ -593,8 +593,8 @@ unsafe static void Main() } "; CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (9,30): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('dynamic') - Diagnostic(ErrorCode.ERR_ManagedAddr, "&d").WithArguments("dynamic"), + // (9,30): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('dynamic') + Diagnostic(ErrorCode.WRN_ManagedAddr, "&d").WithArguments("dynamic"), // (10,15): error CS0193: The * or -> operator must be applied to a pointer Diagnostic(ErrorCode.ERR_PtrExpected, "*d"), // (11,15): error CS0193: The * or -> operator must be applied to a pointer diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs index 9640793d4366d..0af290fa4156f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs @@ -3319,9 +3319,12 @@ public unsafe void M2(MyStruct* ms) where T : unmanaged { } "; CreateCompilation(code, options: TestOptions.UnsafeReleaseDll) .VerifyDiagnostics( - // (12,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') + // (12,9): error CS8377: The type 'string' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'C.M2(MyStruct*)' // M2(&myStruct); - Diagnostic(ErrorCode.ERR_ManagedAddr, "&myStruct").WithArguments("MyStruct").WithLocation(12, 12)); + Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "M2").WithArguments("C.M2(MyStruct*)", "T", "string").WithLocation(12, 9), + // (12,12): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('MyStruct') + // M2(&myStruct); + Diagnostic(ErrorCode.WRN_ManagedAddr, "&myStruct").WithArguments("MyStruct").WithLocation(12, 12)); } [Fact] @@ -3491,9 +3494,15 @@ public unsafe void M2(MyStruct* ms) { } // (11,18): error CS8377: The type 'U' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'MyStruct' // MyStruct myStruct; Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "U").WithArguments("MyStruct", "T", "U").WithLocation(11, 18), - // (12,15): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') + // (12,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') + // M2(&myStruct); + Diagnostic(ErrorCode.ERR_ManagedAddr, "M2").WithArguments("MyStruct").WithLocation(12, 9), + // (12,9): error CS8377: The type 'U' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'MyStruct' + // M2(&myStruct); + Diagnostic(ErrorCode.ERR_UnmanagedConstraintNotSatisfied, "M2").WithArguments("MyStruct", "T", "U").WithLocation(12, 9), + // (12,15): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('MyStruct') // M2(&myStruct); - Diagnostic(ErrorCode.ERR_ManagedAddr, "&myStruct").WithArguments("MyStruct").WithLocation(12, 15), + Diagnostic(ErrorCode.WRN_ManagedAddr, "&myStruct").WithArguments("MyStruct").WithLocation(12, 15), // (15,43): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') // public unsafe void M2(MyStruct* ms) { } Diagnostic(ErrorCode.ERR_ManagedAddr, "ms").WithArguments("MyStruct").WithLocation(15, 43), @@ -3524,9 +3533,9 @@ public unsafe void M2(MyStruct* ms) { } "; CreateCompilation(code, options: TestOptions.UnsafeReleaseDll) .VerifyDiagnostics( - // (12,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') + // (12,12): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('MyStruct') // M2(&myStruct); - Diagnostic(ErrorCode.ERR_ManagedAddr, "&myStruct").WithArguments("MyStruct").WithLocation(12, 12), + Diagnostic(ErrorCode.WRN_ManagedAddr, "&myStruct").WithArguments("MyStruct").WithLocation(12, 12), // (15,45): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') // public unsafe void M2(MyStruct* ms) { } Diagnostic(ErrorCode.ERR_ManagedAddr, "ms").WithArguments("MyStruct").WithLocation(15, 45)); @@ -4090,9 +4099,9 @@ public unsafe void M() "; CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (12,19): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('MyStruct') + // (12,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('MyStruct') // var ptr = &ms; - Diagnostic(ErrorCode.ERR_ManagedAddr, "&ms").WithArguments("MyStruct").WithLocation(12, 19) + Diagnostic(ErrorCode.WRN_ManagedAddr, "&ms").WithArguments("MyStruct").WithLocation(12, 19) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 0c2ef3678a060..848207ab703bf 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -2706,15 +2706,21 @@ static void M(C x) // (6,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') // C* y1 = &x; Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(6, 9), - // (6,26): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // (6,26): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') // C* y1 = &x; - Diagnostic(ErrorCode.ERR_ManagedAddr, "&x").WithArguments("C").WithLocation(6, 26), + Diagnostic(ErrorCode.WRN_ManagedAddr, "&x").WithArguments("C").WithLocation(6, 26), + // (6,26): warning CS8619: Nullability of reference types in value of type 'C*' doesn't match target type 'C*'. + // C* y1 = &x; + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "&x").WithArguments("C*", "C*").WithLocation(6, 26), // (7,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') // C* y2 = &x!; Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(7, 9), - // (7,26): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // (7,26): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // C* y2 = &x!; + Diagnostic(ErrorCode.WRN_ManagedAddr, "&x!").WithArguments("C").WithLocation(7, 26), + // (7,26): warning CS8619: Nullability of reference types in value of type 'C*' doesn't match target type 'C*'. // C* y2 = &x!; - Diagnostic(ErrorCode.ERR_ManagedAddr, "&x!").WithArguments("C").WithLocation(7, 26), + Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "&x!").WithArguments("C*", "C*").WithLocation(7, 26), // (7,27): error CS8598: The suppression operator is not allowed in this context // C* y2 = &x!; Diagnostic(ErrorCode.ERR_IllegalSuppression, "x").WithLocation(7, 27) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 3f2efcf018f47..312b6d9ca962e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -568,6 +568,842 @@ ref struct R Diagnostic(ErrorCode.ERR_BadMemberFlag, "_v2").WithArguments("volatile").WithLocation(9, 31)); } + [Fact] + public void UnsafeContext_PointerType_MethodParameter() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + void M( + S* s, // 1 + S2* s2, // 2, 3 + C* c) // 4, 5 + { + } + + unsafe void M2( + S* s, + S2* s2, // 6 + C* c) // 7 + { + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (14,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // S* s, // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S*").WithLocation(14, 9), + // (15,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // S2* s2, // 2, 3 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S2*").WithLocation(15, 9), + // (15,13): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* s2, // 2, 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "s2").WithArguments("S2").WithLocation(15, 13), + // (16,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // C* c) // 4, 5 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "C*").WithLocation(16, 9), + // (16,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* c) // 4, 5 + Diagnostic(ErrorCode.ERR_ManagedAddr, "c").WithArguments("C").WithLocation(16, 12), + // (22,13): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* s2, // 6 + Diagnostic(ErrorCode.ERR_ManagedAddr, "s2").WithArguments("S2").WithLocation(22, 13), + // (23,12): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* c) // 7 + Diagnostic(ErrorCode.ERR_ManagedAddr, "c").WithArguments("C").WithLocation(23, 12) + ); + } + + [Fact] + public void UnsafeContext_PointerType_MethodReturnType() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +unsafe class C +{ + S* M1() => throw null; + S2* M2() => throw null; // 1 + C* M3() => throw null; // 2 +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (14,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* M2() => throw null; // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "M2").WithArguments("S2").WithLocation(14, 9), + // (15,8): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* M3() => throw null; // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "M3").WithArguments("C").WithLocation(15, 8) + ); + } + + [Fact] + public void UnsafeContext_PointerType_LocalDeclaration() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + void M() + { + S* s = null; // 1 + } + + unsafe void M2() + { + S* s = null; + S2* s2 = null; // 2 + C* c = null; // 3 + } +} +"; + // Note: declaring local of this type still possible with `var` + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (15,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // S* s = null; // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S*").WithLocation(15, 9), + // (21,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* s2 = null; // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(21, 9), + // (22,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* c = null; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(22, 9) + ); + } + + [Fact] + public void UnsafeContext_PointerType_FixedStatement() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + ref S Prop { get => throw null; } + ref S2 Prop2 { get => throw null; } + ref C Prop3 { get => throw null; } + + unsafe void M() + { + fixed (S* x1 = &Prop) { } + + fixed (S2* x2 = &Prop2) { } // 1 + fixed (void* y2 = &Prop2) { } // 2 + + fixed (C* x3 = &Prop3) { } // 3 + fixed (void* y3 = &Prop3) { } // 4 + } +} +"; + // SPEC: + // A fixed_pointer_initializer can be one of the following: + // The token “&” followed by a variable_reference to a moveable variable of an unmanaged type T, + // provided the type T* is implicitly convertible to the pointer type given in the fixed statement. + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (21,16): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // fixed (S2* x2 = &Prop2) { } // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(21, 16), + // (21,25): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // fixed (S2* x2 = &Prop2) { } // 1 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(21, 25), + // (21,25): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // fixed (S2* x2 = &Prop2) { } // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(21, 25), + // (22,27): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // fixed (void* y2 = &Prop2) { } // 2 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(22, 27), + // (22,27): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // fixed (void* y2 = &Prop2) { } // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "&Prop2").WithArguments("S2").WithLocation(22, 27), + // (24,16): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // fixed (C* x3 = &Prop3) { } // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(24, 16), + // (24,24): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // fixed (C* x3 = &Prop3) { } // 3 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(24, 24), + // (24,24): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // fixed (C* x3 = &Prop3) { } // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(24, 24), + // (25,27): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // fixed (void* y3 = &Prop3) { } // 4 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(25, 27), + // (25,27): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // fixed (void* y3 = &Prop3) { } // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "&Prop3").WithArguments("C").WithLocation(25, 27) + ); + } + + [Fact] + public void UnsafeContext_PointerType_Cast() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + void M(void* p) + { + _ = (S*)p; // 1 + _ = (S2*)p; // 2 + _ = (C*)p; // 3 + } + + unsafe void M2(void* p) + { + _ = (S*)p; + _ = (S2*)p; // 4 + _ = (C*)p; // 5 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (13,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void M(void* p) + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "void*").WithLocation(13, 12), + // (15,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S*)p; // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = (S*)p").WithLocation(15, 9), + // (15,13): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S*)p; // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(S*)p").WithLocation(15, 13), + // (15,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S*)p; // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S*").WithLocation(15, 14), + // (15,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S*)p; // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(15, 17), + // (16,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S2*)p; // 2 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = (S2*)p").WithLocation(16, 9), + // (16,13): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S2*)p; // 2 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(S2*)p").WithLocation(16, 13), + // (16,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S2*)p; // 2 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "S2*").WithLocation(16, 14), + // (16,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // _ = (S2*)p; // 2 + Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 14), + // (16,18): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (S2*)p; // 2 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(16, 18), + // (17,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (C*)p; // 3 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "_ = (C*)p").WithLocation(17, 9), + // (17,13): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (C*)p; // 3 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "(C*)p").WithLocation(17, 13), + // (17,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (C*)p; // 3 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "C*").WithLocation(17, 14), + // (17,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // _ = (C*)p; // 3 + Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 14), + // (17,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // _ = (C*)p; // 3 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(17, 17), + // (23,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // _ = (S2*)p; // 4 + Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(23, 14), + // (24,14): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // _ = (C*)p; // 5 + Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(24, 14) + ); + } + + [Fact] + public void UnsafeContext_SizeOf() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + unsafe void M() + { + _ = sizeof(S*); + _ = sizeof(S2*); // 1 + _ = sizeof(C*); // 2 + _ = sizeof(S2); // 3 + _ = sizeof(C); // 4 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (16,20): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // _ = sizeof(S2*); // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 20), + // (17,20): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // _ = sizeof(C*); // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 20), + // (18,13): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // _ = sizeof(S2); // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "sizeof(S2)").WithArguments("S2").WithLocation(18, 13), + // (19,13): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // _ = sizeof(C); // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "sizeof(C)").WithArguments("C").WithLocation(19, 13) + ); + } + + [Fact] + public void UnsafeContext_TypeOf() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + unsafe void M() + { + _ = typeof(S*); + _ = typeof(S2*); // 1 + _ = typeof(C*); // 2 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (16,20): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // _ = typeof(S2*); // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 20), + // (17,20): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // _ = typeof(C*); // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 20) + ); + } + + [Fact] + public void UnsafeContext_AddressOf() + { + var source = @" +ref struct S +{ + int F1; +} +ref struct S2 +{ + ref int F1; +} + +class C +{ + void M(S s) + { + var x = &s; // 1 + } + void M2(S2 s) + { + var x = &s; // 2 + } + void M3(ref S2 s) + { + var x = &s; // 3 + } +} + +unsafe class C2 +{ + void M(S s) + { + var x = &s; + } + void M2(S2 s) + { + var x = &s; // 4 + } + void M3(ref S2 s) + { + var x = &s; // 5 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (15,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var x = &s; // 1 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&s").WithLocation(15, 17), + // (19,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // var x = &s; // 2 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(19, 17), + // (19,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var x = &s; // 2 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&s").WithLocation(19, 17), + // (23,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // var x = &s; // 3 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(23, 17), + // (23,17): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer + // var x = &s; // 3 + Diagnostic(ErrorCode.ERR_FixedNeeded, "&s").WithLocation(23, 17), + // (35,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // var x = &s; // 4 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(35, 17), + // (39,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // var x = &s; // 5 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(39, 17), + // (39,17): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer + // var x = &s; // 5 + Diagnostic(ErrorCode.ERR_FixedNeeded, "&s").WithLocation(39, 17) + ); + + source = @" +ref struct S2 +{ + ref int F1; +} + +unsafe class C2 +{ + void* M2(S2 s) + { + var x = &s; // 1 + return x; + } +} +"; + comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (11,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // var x = &s; // 1 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(11, 17) + ); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped); + verifier.VerifyIL("C2.M2", @" +{ + // Code size 4 (0x4) + .maxstack 1 + IL_0000: ldarga.s V_1 + IL_0002: conv.u + IL_0003: ret +} +"); + } + + [Fact] + public void UnsafeContext_AddressOf_CastToIntPtrPointer() + { + var source = @" +using System; + +ref struct S2 +{ + ref int F1; +} + +unsafe class C2 +{ + IntPtr* M2(S2 s) + { + return (IntPtr*)&s; // 1 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (13,25): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // return (IntPtr*)&s; // 1 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(13, 25) + ); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped); + verifier.VerifyIL("C2.M2", @" +{ + // Code size 4 (0x4) + .maxstack 1 + IL_0000: ldarga.s V_1 + IL_0002: conv.u + IL_0003: ret +} +"); + } + + [Fact] + public void UnsafeContext_Assignment() + { + var source = @" +using System; + +public ref struct S2 +{ + public ref int F1; + + unsafe static void Assign(IntPtr* p, ref S2 r) + { + *(S2*)p = r; + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (10,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // *(S2*)p = r; + Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(10, 11) + ); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped); + verifier.VerifyIL("S2.Assign", @" +{ + // Code size 13 (0xd) + .maxstack 2 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: ldobj ""S2"" + IL_0007: stobj ""S2"" + IL_000c: ret +} +"); + } + + [Fact] + public void UnsafeContext_PointerMemberAccess() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +unsafe class C +{ + void M(S s) + { + _ = (&s)->F1; // 1 + } + int M2(S2 s) + { + return (&s)->F1; // 2 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (19,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // return (&s)->F1; // 2 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(19, 17) + ); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped); + verifier.VerifyIL("C.M2", @" +{ + // Code size 10 (0xa) + .maxstack 1 + IL_0000: ldarga.s V_1 + IL_0002: conv.u + IL_0003: ldfld ""ref int S2.F1"" + IL_0008: ldind.i4 + IL_0009: ret +} +"); + } + + [Fact] + public void UnsafeContext_PointerElementAccess() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +unsafe class C +{ + S M(S s) + { + return (&s)[0]; + } + S2 M2(S2 s) + { + return (&s)[0]; // 1 + } +} +"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (19,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // return (&s)[0]; // 1 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S2").WithLocation(19, 17) + ); + var verifier = CompileAndVerify(comp, verify: Verification.Skipped); + verifier.VerifyIL("C.M2", @" +{ + // Code size 9 (0x9) + .maxstack 1 + IL_0000: ldarga.s V_1 + IL_0002: conv.u + IL_0003: ldobj ""S2"" + IL_0008: ret +} +"); + } + + [Fact] + public void UnsafeContext_Stackalloc() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + unsafe void M() + { + var x1 = stackalloc S[0]; + var x2 = stackalloc S2[0]; // 1 + var x3 = stackalloc C[0]; // 2 + + S* y1 = stackalloc S[0]; + S2* y2 = stackalloc S2[0]; // 3 + C* y3 = stackalloc C[0]; // 4 + } +} +"; + + var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (16,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // var x2 = stackalloc S2[0]; // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2").WithArguments("S2").WithLocation(16, 29), + // (17,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // var x3 = stackalloc C[0]; // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C").WithArguments("C").WithLocation(17, 29), + // (20,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* y2 = stackalloc S2[0]; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9), + // (20,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* y2 = stackalloc S2[0]; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2").WithArguments("S2").WithLocation(20, 29), + // (21,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* y3 = stackalloc C[0]; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 9), + // (21,28): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* y3 = stackalloc C[0]; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C").WithArguments("C").WithLocation(21, 28) + ); + } + + [Fact] + public void UnsafeContext_Stackalloc_ImplicitType() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + unsafe void M() + { + var x1 = stackalloc[] { new S() }; + var x2 = stackalloc[] { new S2() }; // 1 + var x3 = stackalloc[] { new C() }; // 2 + + S* y1 = stackalloc[] { new S() }; + S2* y2 = stackalloc[] { new S2() }; // 3 + C* y3 = stackalloc[] { new C() }; // 4 + } +} +"; + + var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (16,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // var x2 = stackalloc[] { new S2() }; // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new S2() }").WithArguments("S2").WithLocation(16, 18), + // (17,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // var x3 = stackalloc[] { new C() }; // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new C() }").WithArguments("C").WithLocation(17, 18), + // (20,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* y2 = stackalloc[] { new S2() }; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9), + // (20,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2* y2 = stackalloc[] { new S2() }; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new S2() }").WithArguments("S2").WithLocation(20, 18), + // (21,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* y3 = stackalloc[] { new C() }; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 9), + // (21,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C* y3 = stackalloc[] { new C() }; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new C() }").WithArguments("C").WithLocation(21, 17) + ); + } + + [Fact] + public void UnsafeContext_Stackalloc_PointerElementType() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + unsafe void M() + { + var x1 = stackalloc S*[0]; + var x2 = stackalloc S2*[0]; // 1 + var x3 = stackalloc C*[0]; // 2 + + S** y1 = stackalloc S*[0]; + S2** y2 = stackalloc S2*[0]; // 3 + C** y3 = stackalloc C*[0]; // 4 + } +} +"; + + var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (16,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // var x2 = stackalloc S2*[0]; // 1 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 29), + // (17,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // var x3 = stackalloc C*[0]; // 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 29), + // (20,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2** y2 = stackalloc S2*[0]; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 9), + // (20,30): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2** y2 = stackalloc S2*[0]; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(20, 30), + // (21,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C** y3 = stackalloc C*[0]; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 9), + // (21,29): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C** y3 = stackalloc C*[0]; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(21, 29) + ); + } + + [Fact] + public void UnsafeContext_Stackalloc_PointerElementType_ImplicitType() + { + var source = @" +public ref struct S +{ + public int F1; +} +public ref struct S2 +{ + public ref int F1; +} + +class C +{ + unsafe void M() + { + var s1 = (S*)null; + var s2 = (S2*)null; // 1 + var s3 = (C*)null; // 2 + + var x1 = stackalloc[] { s1 }; + var x2 = stackalloc[] { s2 }; + var x3 = stackalloc[] { s3 }; + + S** y1 = stackalloc[] { s1 }; + S2** y2 = stackalloc[] { s2 }; // 3 + C** y3 = stackalloc[] { s3 }; // 4 + } +} +"; + + var spanReference = CreateCompilation(SpanSource, options: TestOptions.UnsafeReleaseDll); + var comp = CreateCompilation(source, references: new[] { spanReference.EmitToImageReference() }, options: TestOptions.UnsafeReleaseDll, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyEmitDiagnostics( + // (16,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // var s2 = (S2*)null; // 1 + Diagnostic(ErrorCode.WRN_ManagedAddr, "S2*").WithArguments("S2").WithLocation(16, 19), + // (17,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // var s3 = (C*)null; // 2 + Diagnostic(ErrorCode.WRN_ManagedAddr, "C*").WithArguments("C").WithLocation(17, 19), + // (24,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // S2** y2 = stackalloc[] { s2 }; // 3 + Diagnostic(ErrorCode.ERR_ManagedAddr, "S2*").WithArguments("S2").WithLocation(24, 9), + // (25,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') + // C** y3 = stackalloc[] { s3 }; // 4 + Diagnostic(ErrorCode.ERR_ManagedAddr, "C*").WithArguments("C").WithLocation(25, 9) + ); + } + [Fact, WorkItem(63018, "https://github.com/dotnet/roslyn/issues/63018")] public void InitRefField_AutoDefault() { @@ -7530,6 +8366,117 @@ static ref int F2() Diagnostic(ErrorCode.ERR_EscapeVariable, "s1").WithArguments("s1").WithLocation(7, 20)); } + [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")] + public void RefFieldsConsideredManaged() + { + var source = @" +unsafe +{ + StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2 + C.M(); // 3 +} + +public ref struct StructWithRefField +{ + public ref byte RefField; +} + +class C +{ + public static void M() where T : unmanaged { } +}"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyDiagnostics( + // (4,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithRefField') + // StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithRefField*").WithArguments("StructWithRefField").WithLocation(4, 5), + // (4,40): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithRefField') + // StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithRefField").WithArguments("StructWithRefField").WithLocation(4, 40), + // (5,7): error CS0306: The type 'StructWithRefField' may not be used as a type argument + // C.M(); // 3 + Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("StructWithRefField").WithLocation(5, 7) + ); + + Assert.True(comp.GetTypeByMetadataName("StructWithRefField").IsManagedTypeNoUseSiteDiagnostics); + } + + [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")] + public void RefFieldsConsideredManaged_Generic() + { + var source = @" +unsafe +{ + StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 + C.M(); // 3 +} + +ref struct StructWithIndirectRefField +{ + public StructWithRefField Field; +} +ref struct StructWithRefField +{ + public ref T RefField; +} + +class C +{ + public static void M() where T : unmanaged { } +}"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyDiagnostics( + // (4,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField') + // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField*").WithArguments("StructWithIndirectRefField").WithLocation(4, 5), + // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField') + // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48), + // (5,9): error CS0305: Using the generic type 'StructWithRefField' requires 1 type arguments + // C.M(); // 3 + Diagnostic(ErrorCode.ERR_BadArity, "StructWithRefField").WithArguments("StructWithRefField", "type", "1").WithLocation(5, 9), + // (10,36): warning CS0649: Field 'StructWithIndirectRefField.Field' is never assigned to, and will always have its default value + // public StructWithRefField Field; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("StructWithIndirectRefField.Field", "").WithLocation(10, 36), + // (14,18): warning CS0649: Field 'StructWithRefField.RefField' is never assigned to, and will always have its default value + // public ref T RefField; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "RefField").WithArguments("StructWithRefField.RefField", "").WithLocation(14, 18) + ); + + Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics); + } + + [Fact, WorkItem(63104, "https://github.com/dotnet/roslyn/issues/63104")] + public void RefFieldsConsideredManaged_Indirect() + { + var source = @" +unsafe +{ + StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 +} + +public ref struct StructWithIndirectRefField +{ + public StructWithRefField Field; +} + +public ref struct StructWithRefField +{ + public ref byte RefField; +}"; + var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe, runtimeFeature: RuntimeFlag.ByRefFields); + comp.VerifyDiagnostics( + // (4,5): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField') + // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField*").WithArguments("StructWithIndirectRefField").WithLocation(4, 5), + // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField') + // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 + Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48) + ); + + Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics); + } + // Breaking change in C#11: Cannot return an 'out' parameter by reference. [Fact] public void BreakingChange_ReturnOutByRef() diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index 5aa1491adc723..994fb3a246648 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -8122,26 +8122,26 @@ unsafe public static void Main() CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( // (25,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('myClass') // myClass* s2 = &s; // CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "myClass*").WithArguments("myClass"), - // (25,23): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('myClass') + Diagnostic(ErrorCode.ERR_ManagedAddr, "myClass*").WithArguments("myClass").WithLocation(25, 9), + // (25,23): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('myClass') // myClass* s2 = &s; // CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&s").WithArguments("myClass"), + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("myClass").WithLocation(25, 23), // (28,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('myProblemStruct') // int i = sizeof(myProblemStruct); //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "sizeof(myProblemStruct)").WithArguments("myProblemStruct"), + Diagnostic(ErrorCode.ERR_ManagedAddr, "sizeof(myProblemStruct)").WithArguments("myProblemStruct").WithLocation(28, 17), // (9,12): warning CS0169: The field 'myProblemStruct.s' is never used // string s; - Diagnostic(ErrorCode.WRN_UnreferencedField, "s").WithArguments("myProblemStruct.s"), + Diagnostic(ErrorCode.WRN_UnreferencedField, "s").WithArguments("myProblemStruct.s").WithLocation(9, 12), // (10,11): warning CS0169: The field 'myProblemStruct.f' is never used // float f; - Diagnostic(ErrorCode.WRN_UnreferencedField, "f").WithArguments("myProblemStruct.f"), + Diagnostic(ErrorCode.WRN_UnreferencedField, "f").WithArguments("myProblemStruct.f").WithLocation(10, 11), // (15,9): warning CS0169: The field 'myGoodStruct.i' is never used // int i; - Diagnostic(ErrorCode.WRN_UnreferencedField, "i").WithArguments("myGoodStruct.i"), + Diagnostic(ErrorCode.WRN_UnreferencedField, "i").WithArguments("myGoodStruct.i").WithLocation(15, 9), // (16,11): warning CS0169: The field 'myGoodStruct.f' is never used // float f; - Diagnostic(ErrorCode.WRN_UnreferencedField, "f").WithArguments("myGoodStruct.f")); + Diagnostic(ErrorCode.WRN_UnreferencedField, "f").WithArguments("myGoodStruct.f").WithLocation(16, 11)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 50e7e02337ae6..abd4b1bd79f49 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -3288,12 +3288,12 @@ public unsafe void M() where T : unmanaged var compilation = CreateCompilation(tree, new[] { metadata }, TestOptions.UnsafeReleaseDll); compilation.VerifyDiagnostics( - // (13,22): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('External') + // (13,22): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('External') // var badPtr = &bad; - Diagnostic(ErrorCode.ERR_ManagedAddr, "&bad").WithArguments("External").WithLocation(13, 22), - // (16,23): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('External') + Diagnostic(ErrorCode.WRN_ManagedAddr, "&bad").WithArguments("External").WithLocation(13, 22), + // (16,23): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('External') // var badPtr2 = &bad2; - Diagnostic(ErrorCode.ERR_ManagedAddr, "&bad2").WithArguments("External").WithLocation(16, 23) + Diagnostic(ErrorCode.WRN_ManagedAddr, "&bad2").WithArguments("External").WithLocation(16, 23) ); var model = compilation.GetSemanticModel(tree); @@ -3646,9 +3646,12 @@ enum Color // (53,19): error CS0211: Cannot take the address of the given expression // var s = &(array as object); //CS0208, CS0211 (managed) Diagnostic(ErrorCode.ERR_InvalidAddrOp, "array as object").WithLocation(53, 19), - // (54,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('Action') + // (54,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Action') // var t = &E; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&E").WithArguments("System.Action").WithLocation(54, 17), + Diagnostic(ErrorCode.WRN_ManagedAddr, "&E").WithArguments("System.Action").WithLocation(54, 17), + // (54,17): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer + // var t = &E; //CS0208 + Diagnostic(ErrorCode.ERR_FixedNeeded, "&E").WithLocation(54, 17), // (55,18): error CS0079: The event 'C.F' can only appear on the left hand side of += or -= // var u = &F; //CS0079 (can't use event like that) Diagnostic(ErrorCode.ERR_BadEventUsageNoField, "F").WithArguments("C.F").WithLocation(55, 18), @@ -3688,16 +3691,16 @@ unsafe class C { void M(T t) { - var p0 = &t; //CS0208 + var p0 = &t; // 1 C c = new C(); - var p1 = &c; //CS0208 + var p1 = &c; // 2 S s = new S(); - var p2 = &s; //CS0208 + var p2 = &s; // 3 var anon = new { }; - var p3 = &anon; //CS0208 + var p3 = &anon; // 4 } } @@ -3707,18 +3710,18 @@ public struct S } "; CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (6,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('T') - // var p0 = &t; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&t").WithArguments("T"), - // (9,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('C') - // var p1 = &c; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&c").WithArguments("C"), - // (12,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S') - // var p2 = &s; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&s").WithArguments("S"), - // (15,18): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('') - // var p3 = &anon; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&anon").WithArguments("")); + // (6,18): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('T') + // var p0 = &t; // 1 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&t").WithArguments("T").WithLocation(6, 18), + // (9,18): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('C') + // var p1 = &c; // 2 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&c").WithArguments("C").WithLocation(9, 18), + // (12,18): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S') + // var p2 = &s; // 3 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S").WithLocation(12, 18), + // (15,18): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('') + // var p3 = &anon; // 4 + Diagnostic(ErrorCode.WRN_ManagedAddr, "&anon").WithArguments("").WithLocation(15, 18)); } [Fact] @@ -3743,10 +3746,10 @@ public struct S CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( // (13,14): error CS0523: Struct member 'S.s' of type 'S' causes a cycle in the struct layout // public S s; //CS0523 - Diagnostic(ErrorCode.ERR_StructLayoutCycle, "s").WithArguments("S.s", "S"), - // (7,17): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S') + Diagnostic(ErrorCode.ERR_StructLayoutCycle, "s").WithArguments("S.s", "S").WithLocation(13, 14), + // (7,17): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S') // var p = &s; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&s").WithArguments("S")); + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S").WithLocation(7, 17)); } [Fact] @@ -4714,22 +4717,22 @@ static void Main() CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( // (13,9): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S') // S* p = &s; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "S*").WithArguments("S"), - // (13,16): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S') + Diagnostic(ErrorCode.ERR_ManagedAddr, "S*").WithArguments("S").WithLocation(13, 9), + // (13,16): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S') // S* p = &s; //CS0208 - Diagnostic(ErrorCode.ERR_ManagedAddr, "&s").WithArguments("S"), + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s").WithArguments("S").WithLocation(13, 16), // (16,9): error CS0176: Member 'S.StaticFieldLikeEvent' cannot be accessed with an instance reference; qualify it with a type name instead // p->StaticFieldLikeEvent += null; //CS0176 - Diagnostic(ErrorCode.ERR_ObjectProhibited, "p->StaticFieldLikeEvent").WithArguments("S.StaticFieldLikeEvent"), + Diagnostic(ErrorCode.ERR_ObjectProhibited, "p->StaticFieldLikeEvent").WithArguments("S.StaticFieldLikeEvent").WithLocation(16, 9), // (19,9): error CS0176: Member 'S.StaticCustomEvent' cannot be accessed with an instance reference; qualify it with a type name instead // p->StaticCustomEvent += null; //CS0176 - Diagnostic(ErrorCode.ERR_ObjectProhibited, "p->StaticCustomEvent").WithArguments("S.StaticCustomEvent"), + Diagnostic(ErrorCode.ERR_ObjectProhibited, "p->StaticCustomEvent").WithArguments("S.StaticCustomEvent").WithLocation(19, 9), // (5,32): warning CS0067: The event 'S.StaticFieldLikeEvent' is never used // static event System.Action StaticFieldLikeEvent; - Diagnostic(ErrorCode.WRN_UnreferencedEvent, "StaticFieldLikeEvent").WithArguments("S.StaticFieldLikeEvent"), + Diagnostic(ErrorCode.WRN_UnreferencedEvent, "StaticFieldLikeEvent").WithArguments("S.StaticFieldLikeEvent").WithLocation(5, 32), // (4,25): warning CS0067: The event 'S.InstanceFieldLikeEvent' is never used // event System.Action InstanceFieldLikeEvent; - Diagnostic(ErrorCode.WRN_UnreferencedEvent, "InstanceFieldLikeEvent").WithArguments("S.InstanceFieldLikeEvent") + Diagnostic(ErrorCode.WRN_UnreferencedEvent, "InstanceFieldLikeEvent").WithArguments("S.InstanceFieldLikeEvent").WithLocation(4, 25) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs index 655de1cc5b523..36cc6b91f9b78 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UseSiteErrorTests.cs @@ -2478,9 +2478,9 @@ unsafe void M(S2 s2) // (6,19): error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // var ptr = &s2; Diagnostic(ErrorCode.ERR_NoTypeDef, "&s2").WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(6, 19), - // (6,19): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') + // (6,19): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') // var ptr = &s2; - Diagnostic(ErrorCode.ERR_ManagedAddr, "&s2").WithArguments("S2").WithLocation(6, 19) + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s2").WithArguments("S2").WithLocation(6, 19) ); comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll, references: new[] { UnmanagedUseSiteError_Ref1, UnmanagedUseSiteError_Ref2 }); @@ -2610,6 +2610,12 @@ unsafe void M() // (7,26): error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // fixed (S2* ptr = &s2) Diagnostic(ErrorCode.ERR_NoTypeDef, "&s2").WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(7, 26), + // (7,26): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('S2') + // fixed (S2* ptr = &s2) + Diagnostic(ErrorCode.WRN_ManagedAddr, "&s2").WithArguments("S2").WithLocation(7, 26), + // (7,26): error CS0012: The type 'S1' is defined in an assembly that is not referenced. You must add a reference to assembly 'libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. + // fixed (S2* ptr = &s2) + Diagnostic(ErrorCode.ERR_NoTypeDef, "&s2").WithArguments("S1", "libS1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(7, 26), // (7,26): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('S2') // fixed (S2* ptr = &s2) Diagnostic(ErrorCode.ERR_ManagedAddr, "&s2").WithArguments("S2").WithLocation(7, 26) diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index 9e2b24cac5b2a..208fbe5bd0ef1 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -357,6 +357,7 @@ public void WarningLevel_2() case ErrorCode.WRN_DuplicateAnalyzerReference: case ErrorCode.WRN_ScopedMismatchInParameterOfTarget: case ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation: + case ErrorCode.WRN_ManagedAddr: Assert.Equal(1, ErrorFacts.GetWarningLevel(errorCode)); break; case ErrorCode.WRN_InvalidVersionFormat: diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs index 932effdfbd4e9..e06119a1f46c9 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs @@ -153,7 +153,7 @@ internal static CSharpCompilation ToCompilation(this ImmutableArrayx.<>m0"); - AssertIsIntPtrPointer(((MethodSymbol)methodData.Method).ReturnType); + AssertIsStringPointer(((MethodSymbol)methodData.Method).ReturnType); methodData.VerifyIL(@" { // Code size 4 (0x4) @@ -69,7 +69,7 @@ void M() Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); - AssertIsIntPtrPointer(((MethodSymbol)methodData.Method).ReturnType); + AssertIsStringPointer(((MethodSymbol)methodData.Method).ReturnType); methodData.VerifyIL(@" { // Code size 4 (0x4) @@ -105,7 +105,7 @@ void M() Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); - AssertIsIntPtrPointer(((MethodSymbol)methodData.Method).ReturnType); + AssertIsStringPointer(((MethodSymbol)methodData.Method).ReturnType); methodData.VerifyIL(@" { // Code size 8 (0x8) @@ -196,7 +196,7 @@ void M() } [Fact] - public void DisallowPointerType() + public void PointerTypeOfManagedType() { var source = @"class C @@ -212,8 +212,19 @@ void M() var testData = new CompilationTestData(); string error; context.CompileExpression("(string*)null", out error, testData); - // CONSIDER: change error code to make text less confusing? - Assert.Equal("error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('string')", error); + Assert.Null(error); + + var methodData = testData.GetMethodData("<>x.<>m0"); + AssertIsStringPointer(((MethodSymbol)methodData.Method).ReturnType); + methodData.VerifyIL(@" +{ + // Code size 3 (0x3) + .maxstack 1 + IL_0000: ldc.i4.0 + IL_0001: conv.u + IL_0002: ret +} +"); }); } @@ -243,10 +254,10 @@ void M(string[] args) }); } - private static void AssertIsIntPtrPointer(TypeSymbol returnType) + private static void AssertIsStringPointer(TypeSymbol returnType) { Assert.Equal(TypeKind.Pointer, returnType.TypeKind); - Assert.Equal(SpecialType.System_IntPtr, ((PointerTypeSymbol)returnType).PointedAtType.SpecialType); + Assert.Equal(SpecialType.System_String, ((PointerTypeSymbol)returnType).PointedAtType.SpecialType); } } } diff --git a/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginViewMargin.cs b/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginViewMargin.cs index df0a964c6d462..36478b38f4e16 100644 --- a/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginViewMargin.cs +++ b/src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginViewMargin.cs @@ -32,7 +32,6 @@ internal class InheritanceMarginViewMargin : ForegroundThreadAffinitizedObject, private readonly IGlobalOptionService _globalOptions; private readonly InheritanceGlyphManager _glyphManager; private readonly string _languageName; - private readonly Grid _grid; private readonly Canvas _mainCanvas; /// @@ -61,8 +60,6 @@ public InheritanceMarginViewMargin( _globalOptions = globalOptions; _languageName = languageName; _mainCanvas = new Canvas { ClipToBounds = true, Width = HeightAndWidthOfMargin }; - _grid = new Grid(); - _grid.Children.Add(_mainCanvas); _glyphManager = new InheritanceGlyphManager( workspace, textView, @@ -83,10 +80,6 @@ public InheritanceMarginViewMargin( _textView.ZoomLevelChanged += OnZoomLevelChanged; _globalOptions.OptionChanged += OnGlobalOptionChanged; - _grid.LayoutTransform = new ScaleTransform( - scaleX: _textView.ZoomLevel / 100, - scaleY: _textView.ZoomLevel / 100); - _grid.LayoutTransform.Freeze(); UpdateMarginVisibility(); } @@ -107,7 +100,6 @@ void IDisposable.Dispose() private void OnZoomLevelChanged(object sender, ZoomLevelChangedEventArgs e) { - _grid.LayoutTransform = e.ZoomTransform; _refreshAllGlyphs = true; } @@ -212,7 +204,7 @@ FrameworkElement IWpfTextViewMargin.VisualElement get { ThrowIfDisposed(); - return _grid; + return _mainCanvas; } } @@ -221,7 +213,7 @@ double ITextViewMargin.MarginSize get { ThrowIfDisposed(); - return _grid.ActualWidth; + return _mainCanvas.ActualWidth; } } diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpArgumentProvider.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpArgumentProvider.cs index 72292d72b4030..dd9e669d56121 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpArgumentProvider.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpArgumentProvider.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.Shared.TestHooks; using Roslyn.Test.Utilities; using Roslyn.VisualStudio.IntegrationTests; +using Roslyn.VisualStudio.IntegrationTests.InProcess; using WindowsInput.Native; using Xunit; @@ -46,17 +47,17 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString()$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -73,19 +74,19 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("object.Equ"); + await TestServices.Input.SendAsync("object.Equ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null$$, null)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null, null$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null, null)$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -102,16 +103,16 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("new obje"); + await TestServices.Input.SendAsync("new obje", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" var value = new object$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" var value = new object($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" var value = new object()$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -130,16 +131,16 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$;", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$);", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString()$$;", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -158,38 +159,38 @@ public void Method(IFormatProvider provider) } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(provider$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(null$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(null$$, provider)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("\"format\""); + await TestServices.Input.SendAsync("\"format\"", HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\"$$, provider)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\", provider$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.UP); + await TestServices.Input.SendAsync(VirtualKeyCode.UP, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\"$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.UP); + await TestServices.Input.SendAsync(VirtualKeyCode.UP, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(provider$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\"$$)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -210,29 +211,29 @@ void Test(int x, int y) { } } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("Test"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("Test", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$, 0)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$, 0)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -253,20 +254,20 @@ void Test(int x, int y) { } } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("Tes"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("Tes", HangMitigatingCancellationToken); // Trigger the session and type '0' without waiting for the session to finish initializing - await TestServices.Input.SendAsync(VirtualKeyCode.TAB, VirtualKeyCode.TAB, '0'); + await TestServices.Input.SendAsync(new InputKey[] { VirtualKeyCode.TAB, VirtualKeyCode.TAB, '0' }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$, 0)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.UP); + await TestServices.Input.SendAsync(VirtualKeyCode.UP, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -287,17 +288,17 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(';'); + await TestServices.Input.SendAsync(';', HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString();$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -318,20 +319,20 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("object.Equ"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("object.Equ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null$$, null)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null, null$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(';'); + await TestServices.Input.SendAsync(';', HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null, null);$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -356,17 +357,17 @@ public void Method2(int value) } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("this.M2"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("this.M2", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" this.Method2$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" this.Method2(value$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(';'); + await TestServices.Input.SendAsync(';', HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" this.Method2(value);$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -384,17 +385,17 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.RETURN, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.RETURN, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@" public class Test { @@ -423,20 +424,20 @@ public void Method() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("object.Equ"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("object.Equ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null$$, null)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" object.Equals(null, null$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.RETURN, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.RETURN, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@" public class Test { @@ -477,20 +478,20 @@ public void M(string s, int i, int i2) } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("M"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("M", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" M$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" M(null, 0)", cancellationToken: HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(parameterText); + await TestServices.Input.SendAsync(parameterText, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" M(" + parameterText + ", 0)", cancellationToken: HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" M(" + parameterText + ", 0, 0)", cancellationToken: HangMitigatingCancellationToken); } @@ -506,12 +507,12 @@ public class TestClass } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("#i"); + await TestServices.Input.SendAsync("#i", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync("#if$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync("#if true$$", assertCaretPosition: true, HangMitigatingCancellationToken); var expected = @" diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpCodeActions.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpCodeActions.cs index 111e60f6e8753..51bdc857cef6b 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpCodeActions.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpCodeActions.cs @@ -15,6 +15,7 @@ using Microsoft.VisualStudio.Extensibility.Testing; using Roslyn.Test.Utilities; using Roslyn.VisualStudio.IntegrationTests; +using Roslyn.VisualStudio.IntegrationTests.InProcess; using WindowsInput.Native; using Xunit; @@ -492,7 +493,7 @@ static void Main(string[] args) public class P2 { }", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.BACK, VirtualKeyCode.BACK, "Stream"); + await TestServices.Input.SendAsync(new InputKey[] { VirtualKeyCode.BACK, VirtualKeyCode.BACK, "Stream" }, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync( new[] { @@ -557,8 +558,7 @@ static void Main(string[] args) } } }", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.BACK, VirtualKeyCode.BACK, - "Foober"); + await TestServices.Input.SendAsync(new InputKey[] { VirtualKeyCode.BACK, VirtualKeyCode.BACK, "Foober" }, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync( new[] { @@ -865,7 +865,7 @@ await TestServices.Workspace.WaitForAllAsyncOperationsAsync( await TestServices.SolutionExplorer.AddFileAsync(ProjectName, ".editorconfig", open: true, cancellationToken: HangMitigatingCancellationToken); await TestServices.Input.SendAsync(@" [*.cs] -dotnet_diagnostic.CS0168.severity = "); +dotnet_diagnostic.CS0168.severity = ", HangMitigatingCancellationToken); // NOTE: Below wait is a critical step in repro-ing the original regression. await TestServices.Workspace.WaitForAllAsyncOperationsAsync( @@ -878,7 +878,7 @@ await TestServices.Workspace.WaitForAllAsyncOperationsAsync( }, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("error"); + await TestServices.Input.SendAsync("error", HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync( new[] diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpErrorListCommon.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpErrorListCommon.cs index df24ec7587ba8..6d267d1a55f69 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpErrorListCommon.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpErrorListCommon.cs @@ -107,7 +107,7 @@ static void Main(string[] args) await TestServices.Editor.ActivateAsync(HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("a = aa", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("a"); + await TestServices.Input.SendAsync("a", HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SolutionCrawler, FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles, FeatureAttribute.ErrorList }, HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); expectedContents = @@ -123,7 +123,7 @@ static void Main(string[] args) await TestServices.Editor.ActivateAsync(HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("aa = aa", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DELETE); + await TestServices.Input.SendAsync(VirtualKeyCode.DELETE, HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); expectedContents = new string[] { }; await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SolutionCrawler, FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles, FeatureAttribute.ErrorList }, HangMitigatingCancellationToken); @@ -156,7 +156,7 @@ static void Main(string[] args) await TestServices.Editor.ActivateAsync(HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("a = aa", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("a"); + await TestServices.Input.SendAsync("a", HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); expectedContents = new[] { "(Compiler) Class1.cs(7, 13): error CS0128: A local variable or function named 'aa' is already defined in this scope", @@ -174,7 +174,7 @@ static void Main(string[] args) // Assert the window title is Class1.cs, which also means the file has no unsaved changes Assert.Equal("Class1.cs", await TestServices.Shell.GetActiveWindowCaptionAsync(HangMitigatingCancellationToken)); - await TestServices.Input.SendAsync((VirtualKeyCode.F4, VirtualKeyCode.CONTROL)); + await TestServices.Input.SendAsync((VirtualKeyCode.F4, VirtualKeyCode.CONTROL), HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SolutionCrawler, FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles, FeatureAttribute.ErrorList }, HangMitigatingCancellationToken); actualContents = await TestServices.ErrorList.GetErrorsAsync(HangMitigatingCancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpFindReferences.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpFindReferences.cs index 80a75db577e65..44fd1e20ff7f3 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpFindReferences.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpFindReferences.cs @@ -50,7 +50,7 @@ void M() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken); @@ -96,7 +96,7 @@ static void Main() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken); @@ -134,7 +134,7 @@ static void Main() } ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpGoToGlobalImportsTests.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpGoToGlobalImportsTests.cs index 4b869844c7dcb..784aa4acbd66a 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpGoToGlobalImportsTests.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpGoToGlobalImportsTests.cs @@ -37,9 +37,9 @@ await TestServices.SolutionExplorer.OpenFileAsync( await TestServices.InheritanceMargin.ClickTheGlyphOnLine(1, HangMitigatingCancellationToken); // Move focus to menu item 'System' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); // Navigate to 'System' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.InheritanceMargin }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@"global using global::System;$$", assertCaretPosition: true); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpInheritanceMarginTests.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpInheritanceMarginTests.cs index 6315ae8f0dfb2..381fb960e80cb 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpInheritanceMarginTests.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpInheritanceMarginTests.cs @@ -46,9 +46,9 @@ class Implementation : IBar await TestServices.InheritanceMargin.ClickTheGlyphOnLine(2, HangMitigatingCancellationToken); // Move focus to menu item of 'IBar', the destination is targeting 'class Implementation' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); // Navigate to the destination - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.InheritanceMargin }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@"class Implementation$$", assertCaretPosition: true); } @@ -78,11 +78,11 @@ class Implementation : IBar // The context menu contains two members, e1 and e2. // Move focus to menu item of 'event e1' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); // Expand the submenu - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); // Navigate to the implemention - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.InheritanceMargin }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@"public event EventHandler e1$$, e2;", assertCaretPosition: true); } @@ -110,9 +110,9 @@ public IEnumerator GetEnumerator() await TestServices.InheritanceMargin.ClickTheGlyphOnLine(4, HangMitigatingCancellationToken); // Move focus to menu item of 'class Implementation' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); // Navigate to 'IEnumerable' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.InheritanceMargin }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@"public interface IEnumerable$$", assertCaretPosition: true); @@ -152,9 +152,9 @@ class Implementation : IBar await TestServices.InheritanceMargin.ClickTheGlyphOnLine(4, HangMitigatingCancellationToken); // Move focus to menu item of 'class Implementation' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); // Navigate to 'IBar' - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.InheritanceMargin }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@"Public Interface IBar$$", assertCaretPosition: true); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpSourceGenerators.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpSourceGenerators.cs index aef92a5d0acf5..0cad7fca4b869 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpSourceGenerators.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpSourceGenerators.cs @@ -92,7 +92,7 @@ public static void Main() Assert.Equal($"{HelloWorldGenerator.GeneratedEnglishClassName}.cs {ServicesVSResources.generated_suffix}", await TestServices.Shell.GetActiveWindowCaptionAsync(HangMitigatingCancellationToken)); } - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = (await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken)).OrderBy(r => r.GetLine()).ToArray(); @@ -134,7 +134,7 @@ public static void Main() }", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync(HelloWorldGenerator.GeneratedEnglishClassName, charsOffset: 0, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken); var referenceInGeneratedFile = results.Single(r => r.GetText()?.Contains("") ?? false); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/DocumentationCommentTests.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/DocumentationCommentTests.cs index 87f2fa8ee3ce5..20dd299556c66 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/DocumentationCommentTests.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/DocumentationCommentTests.cs @@ -37,7 +37,7 @@ class C2 { } class C3 { } "; await SetUpEditorAsync(code, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync('/'); + await TestServices.Input.SendAsync('/', HangMitigatingCancellationToken); var expected = @" /// diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EditorInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EditorInProcess.cs index 838be996ed036..38cf826921be4 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EditorInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EditorInProcess.cs @@ -520,13 +520,13 @@ public async Task SelectNavigationBarItemAsync(NavigationBarDropdownKind index, } await ExpandNavigationBarAsync(index, cancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.HOME); + await TestServices.Input.SendAsync(VirtualKeyCode.HOME, cancellationToken); for (var i = 0; i < itemIndex; i++) { - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, cancellationToken); } - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, cancellationToken); // Navigation and/or code generation following selection is tracked under FeatureAttribute.NavigationBar await TestServices.Workspace.WaitForAsyncOperationsAsync(FeatureAttribute.NavigationBar, cancellationToken); @@ -704,7 +704,7 @@ public async Task InvokeCodeActionListWithoutWaitingAsync(CancellationToken canc { // Workaround for extremely unstable async lightbulb (can dismiss itself when SuggestedActionsChanged // fires while expanding the light bulb). - await TestServices.Input.SendAsync((VirtualKeyCode.OEM_PERIOD, VirtualKeyCode.CONTROL)); + await TestServices.Input.SendAsync((VirtualKeyCode.OEM_PERIOD, VirtualKeyCode.CONTROL), cancellationToken); await Task.Delay(5000, cancellationToken); await TestServices.Editor.DismissLightBulbSessionAsync(cancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EncapsulateFieldInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EncapsulateFieldInProcess.cs index f0c3bd8e83fef..87c1861d3e89d 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EncapsulateFieldInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/EncapsulateFieldInProcess.cs @@ -19,7 +19,7 @@ internal Task InvokeAsync(CancellationToken cancellationToken) // Cancellation is not currently supported by SendAsync _ = cancellationToken; - return TestServices.Input.SendAsync((VirtualKeyCode.VK_R, VirtualKeyCode.CONTROL), (VirtualKeyCode.VK_E, VirtualKeyCode.CONTROL)); + return TestServices.Input.SendAsync(new InputKey[] { (VirtualKeyCode.VK_R, VirtualKeyCode.CONTROL), (VirtualKeyCode.VK_E, VirtualKeyCode.CONTROL) }, cancellationToken); } } } diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InheritanceMarginInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InheritanceMarginInProcess.cs index 16d4386b06828..db6846d5f38d8 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InheritanceMarginInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InheritanceMarginInProcess.cs @@ -68,7 +68,7 @@ public async Task DisableOptionsAsync(string languageName, CancellationToken can private async Task EnsureGlyphsAppearAsync(Func makeChangeFunc, int expectedGlyphsNumberInMargin, CancellationToken cancellationToken) { var margin = await GetTextViewMarginAsync(cancellationToken); - var marginCanvas = (Canvas)((Grid)margin.VisualElement).Children[0]; + var marginCanvas = (Canvas)margin.VisualElement; var taskCompletionSource = new TaskCompletionSource(); using var _ = cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()); @@ -104,9 +104,9 @@ public async Task ClickTheGlyphOnLine(int lineNumber, CancellationToken cancella var glyph = await GetTheGlyphOnLineAsync(lineNumber, cancellationToken); var point = await GetCenterOfGlyphOnScreenAsync(glyph, cancellationToken); - await TestServices.Input.MoveMouseAsync(point); + await TestServices.Input.MoveMouseAsync(point, cancellationToken); await TestServices.Input.SendWithoutActivateAsync( - simulator => simulator.Mouse.LeftButtonClick()); + simulator => simulator.Mouse.LeftButtonClick(), cancellationToken); } public async Task GetTheGlyphOnLineAsync(int lineNumber, CancellationToken cancellationToken) @@ -116,11 +116,7 @@ public async Task GetTheGlyphOnLineAsync(int lineNumber, var wpfTextViewLine = activeView.TextViewLines[lineNumber - 1]; var midOfTheLine = wpfTextViewLine.TextTop + wpfTextViewLine.Height / 2; var margin = await GetTextViewMarginAsync(cancellationToken); - - var grid = (Grid)margin.VisualElement; - // There will be only one Canvas element. - Assert.True(grid.Children.Count == 1); - var containingCanvas = (Canvas)((Grid)margin.VisualElement).Children[0]; + var containingCanvas = (Canvas)margin.VisualElement; var glyphsOnLine = new List(); foreach (var glyph in containingCanvas.Children) diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InputInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InputInProcess.cs index aba45ae199606..d2ed0238e9cf6 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InputInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/InputInProcess.cs @@ -20,7 +20,10 @@ namespace Roslyn.VisualStudio.IntegrationTests.InProcess [TestService] internal partial class InputInProcess { - internal Task SendAsync(params InputKey[] keys) + internal Task SendAsync(InputKey key, CancellationToken cancellationToken) + => SendAsync(new InputKey[] { key }, cancellationToken); + + internal Task SendAsync(InputKey[] keys, CancellationToken cancellationToken) { return SendAsync( simulator => @@ -29,28 +32,31 @@ internal Task SendAsync(params InputKey[] keys) { key.Apply(simulator); } - }); + }, cancellationToken); } - internal async Task SendAsync(Action callback) + internal async Task SendAsync(Action callback, CancellationToken cancellationToken) { // AbstractSendKeys runs synchronously, so switch to a background thread before the call await TaskScheduler.Default; TestServices.JoinableTaskFactory.Run(async () => { - await TestServices.Editor.ActivateAsync(CancellationToken.None); + await TestServices.Editor.ActivateAsync(cancellationToken); }); callback(new InputSimulator()); TestServices.JoinableTaskFactory.Run(async () => { - await WaitForApplicationIdleAsync(CancellationToken.None); + await WaitForApplicationIdleAsync(cancellationToken); }); } - internal Task SendWithoutActivateAsync(params InputKey[] keys) + internal Task SendWithoutActivateAsync(InputKey key, CancellationToken cancellationToken) + => SendWithoutActivateAsync(new[] { key }, cancellationToken); + + internal Task SendWithoutActivateAsync(InputKey[] keys, CancellationToken cancellationToken) { return SendWithoutActivateAsync( simulator => @@ -59,10 +65,10 @@ internal Task SendWithoutActivateAsync(params InputKey[] keys) { key.Apply(simulator); } - }); + }, cancellationToken); } - internal async Task SendWithoutActivateAsync(Action callback) + internal async Task SendWithoutActivateAsync(Action callback, CancellationToken cancellationToken) { // AbstractSendKeys runs synchronously, so switch to a background thread before the call await TaskScheduler.Default; @@ -71,7 +77,7 @@ internal async Task SendWithoutActivateAsync(Action callback) TestServices.JoinableTaskFactory.Run(async () => { - await WaitForApplicationIdleAsync(CancellationToken.None); + await WaitForApplicationIdleAsync(cancellationToken); }); } @@ -108,13 +114,13 @@ internal async Task SendToNavigateToAsync(Action callback) }); } - internal async Task MoveMouseAsync(Point point) + internal async Task MoveMouseAsync(Point point, CancellationToken cancellationToken) { var horizontalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CXSCREEN); var verticalResolution = NativeMethods.GetSystemMetrics(NativeMethods.SM_CYSCREEN); var virtualPoint = new ScaleTransform(65535.0 / horizontalResolution, 65535.0 / verticalResolution).Transform(point); - await SendAsync(simulator => simulator.Mouse.MoveMouseTo(virtualPoint.X, virtualPoint.Y)); + await SendAsync(simulator => simulator.Mouse.MoveMouseTo(virtualPoint.X, virtualPoint.Y), cancellationToken); // ⚠ The call to GetCursorPos is required for correct behavior. var actualPoint = NativeMethods.GetCursorPos(); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs index fd70e44acec22..9e746fb0ef35f 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs @@ -94,7 +94,7 @@ public async Task ResetHostSettingsAsync(CancellationToken cancellationToken) break; } - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.ESCAPE); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.ESCAPE, cancellationToken); var nextModalWindow = IntegrationHelper.GetModalWindowFromParentWindow(mainWindow); if (nextModalWindow == modalWindow) { diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InfrastructureTests.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InfrastructureTests.cs index e1c5c23dcbc13..f9648879c8ae6 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InfrastructureTests.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InfrastructureTests.cs @@ -8,6 +8,7 @@ using Microsoft.VisualStudio.IntegrationTest.Utilities; using Roslyn.Utilities; using Roslyn.VisualStudio.IntegrationTests; +using Roslyn.VisualStudio.IntegrationTests.InProcess; using WindowsInput.Native; using Xunit; @@ -34,14 +35,14 @@ namespace MyNamespace HangMitigatingCancellationToken); // Trigger a call to File.Close to ensure we can recover from it - await TestServices.Input.SendAsync((VirtualKeyCode.VK_F, VirtualKeyCode.MENU), VirtualKeyCode.VK_C); + await TestServices.Input.SendAsync(new InputKey[] { (VirtualKeyCode.VK_F, VirtualKeyCode.MENU), VirtualKeyCode.VK_C }, HangMitigatingCancellationToken); var modalWindow = IntegrationHelper.GetModalWindowFromParentWindow(await TestServices.Shell.GetMainWindowAsync(HangMitigatingCancellationToken)); Assert.NotEqual(IntPtr.Zero, modalWindow); Assert.Equal("Microsoft Visual Studio", IntegrationHelper.GetTitleForWindow(modalWindow)); - await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.ESCAPE); + await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.ESCAPE, HangMitigatingCancellationToken); modalWindow = IntegrationHelper.GetModalWindowFromParentWindow(await TestServices.Shell.GetMainWindowAsync(HangMitigatingCancellationToken)); if (modalWindow != IntPtr.Zero) diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicArgumentProvider.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicArgumentProvider.cs index 7bba82d17a4d7..6e5e3dea0265f 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicArgumentProvider.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicArgumentProvider.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.TestHooks; using Roslyn.VisualStudio.IntegrationTests; +using Roslyn.VisualStudio.IntegrationTests.InProcess; using WindowsInput.Native; using Xunit; @@ -43,17 +44,17 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString()$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -68,12 +69,12 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("Object.Equ"); + await TestServices.Input.SendAsync("Object.Equ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Object.Equals$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Object.Equals(Nothing$$)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -89,16 +90,16 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("New Obje"); + await TestServices.Input.SendAsync("New Obje", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Dim value = New Object$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Dim value = New Object($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Dim value = New Object()$$", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -115,38 +116,38 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(provider$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(Nothing$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(Nothing$$, provider)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("\"format\""); + await TestServices.Input.SendAsync("\"format\"", HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\"$$, provider)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\", provider$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.UP); + await TestServices.Input.SendAsync(VirtualKeyCode.UP, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\"$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.UP); + await TestServices.Input.SendAsync(VirtualKeyCode.UP, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(provider$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString(\"format\"$$)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -170,29 +171,29 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("Tes"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("Tes", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$, 0)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$, 0)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -216,20 +217,20 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("Tes"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("Tes", HangMitigatingCancellationToken); // Trigger the session and type '0' without waiting for the session to finish initializing - await TestServices.Input.SendAsync(VirtualKeyCode.TAB, VirtualKeyCode.TAB, '0'); + await TestServices.Input.SendAsync(new InputKey[] { VirtualKeyCode.TAB, VirtualKeyCode.TAB, '0' }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN); + await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$, 0)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.UP); + await TestServices.Input.SendAsync(VirtualKeyCode.UP, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" Test(0$$)", assertCaretPosition: true, HangMitigatingCancellationToken); } @@ -245,17 +246,17 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); - await TestServices.Input.SendAsync("f.ToSt"); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); + await TestServices.Input.SendAsync("f.ToSt", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString$$", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(VirtualKeyCode.TAB, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SignatureHelp }, HangMitigatingCancellationToken); await TestServices.EditorVerifier.CurrentLineTextAsync(" f.ToString($$)", assertCaretPosition: true, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.RETURN, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.RETURN, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextContainsAsync(@" Public Class Test Private f As Object diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicErrorListCommon.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicErrorListCommon.cs index 4fd8f1e3b8cb5..4c17f406a807a 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicErrorListCommon.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicErrorListCommon.cs @@ -74,7 +74,7 @@ End Class End Namespace ", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync(" Comment", charsOffset: -2, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("F = 0"); + await TestServices.Input.SendAsync("F = 0", HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); var expectedContents = Array.Empty(); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SolutionCrawler, FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles, FeatureAttribute.ErrorList }, HangMitigatingCancellationToken); @@ -85,7 +85,7 @@ End Namespace await TestServices.Editor.ActivateAsync(HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("F = 0 ' Comment", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("F"); + await TestServices.Input.SendAsync("F", HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); expectedContents = new[] { "(Compiler) Class1.vb(6, 13): error BC30451: 'FF' is not declared. It may be inaccessible due to its protection level.", @@ -98,7 +98,7 @@ End Namespace await TestServices.Editor.ActivateAsync(HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("FF = 0 ' Comment", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DELETE); + await TestServices.Input.SendAsync(VirtualKeyCode.DELETE, HangMitigatingCancellationToken); await TestServices.ErrorList.ShowErrorListAsync(HangMitigatingCancellationToken); expectedContents = Array.Empty(); await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace, FeatureAttribute.SolutionCrawler, FeatureAttribute.DiagnosticService, FeatureAttribute.ErrorSquiggles, FeatureAttribute.ErrorList }, HangMitigatingCancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicFindReferences.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicFindReferences.cs index 95f88a2e11dd4..f13cb9ed19b4b 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicFindReferences.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicFindReferences.cs @@ -36,7 +36,7 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken); @@ -79,7 +79,7 @@ End Sub End Class ", HangMitigatingCancellationToken); - await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT)); + await TestServices.Input.SendAsync((VirtualKeyCode.F12, VirtualKeyCode.SHIFT), HangMitigatingCancellationToken); var results = await TestServices.FindReferencesWindow.GetContentsAsync(HangMitigatingCancellationToken); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicLineCommit.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicLineCommit.cs index 5ad5f02bf5676..2abad245e6987 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicLineCommit.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/VisualBasic/BasicLineCommit.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio; using Roslyn.Test.Utilities; using Roslyn.VisualStudio.IntegrationTests; +using Roslyn.VisualStudio.IntegrationTests.InProcess; using WindowsInput.Native; using Xunit; @@ -36,7 +37,7 @@ End Sub End Module", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("Sub()", charsOffset: 1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.RETURN); + await TestServices.Input.SendAsync(VirtualKeyCode.RETURN, HangMitigatingCancellationToken); Assert.Equal(48, await TestServices.Editor.GetCaretPositionAsync(HangMitigatingCancellationToken)); } @@ -50,7 +51,7 @@ End Sub End Module", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync(" REM", charsOffset: 0, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("sub", VirtualKeyCode.ESCAPE, " goo()", VirtualKeyCode.RETURN); + await TestServices.Input.SendAsync(new InputKey[] { "sub", VirtualKeyCode.ESCAPE, " goo()", VirtualKeyCode.RETURN }, HangMitigatingCancellationToken); AssertEx.EqualOrDiff(@"Module Module1 Sub Main() End Sub @@ -73,7 +74,7 @@ End Sub End Module", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("Module1", charsOffset: 0, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(VirtualKeyCode.DOWN, VirtualKeyCode.RETURN); + await TestServices.Input.SendAsync(new InputKey[] { VirtualKeyCode.DOWN, VirtualKeyCode.RETURN }, HangMitigatingCancellationToken); AssertEx.EqualOrDiff(@"Module Module1 @@ -96,10 +97,10 @@ End Module ", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("(", charsOffset: 1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync("x As integer", VirtualKeyCode.TAB); + await TestServices.Input.SendAsync(new InputKey[] { "x As integer", VirtualKeyCode.TAB }, HangMitigatingCancellationToken); Assert.False(await TestServices.Editor.IsSavedAsync(HangMitigatingCancellationToken)); - await TestServices.Input.SendAsync((VirtualKeyCode.VK_S, VirtualKeyCode.CONTROL)); + await TestServices.Input.SendAsync((VirtualKeyCode.VK_S, VirtualKeyCode.CONTROL), HangMitigatingCancellationToken); // Wait for async save operations to complete before proceeding await TestServices.Workspace.WaitForAllAsyncOperationsAsync(new[] { FeatureAttribute.Workspace }, HangMitigatingCancellationToken); @@ -130,10 +131,10 @@ End Sub End Module", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("End Sub", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(" "); + await TestServices.Input.SendAsync(" ", HangMitigatingCancellationToken); await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "TestZ.vb", open: true, cancellationToken: HangMitigatingCancellationToken); // Cause focus lost await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "TestZ.vb", HangMitigatingCancellationToken); // Work around https://github.com/dotnet/roslyn/issues/18488 - await TestServices.Input.SendAsync(" "); + await TestServices.Input.SendAsync(" ", HangMitigatingCancellationToken); await TestServices.SolutionExplorer.CloseCodeFileAsync(ProjectName, "TestZ.vb", saveFile: false, cancellationToken: HangMitigatingCancellationToken); AssertEx.EqualOrDiff(@"Module M Sub M() @@ -153,10 +154,10 @@ End Sub End Module", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("End Sub", charsOffset: -1, HangMitigatingCancellationToken); - await TestServices.Input.SendAsync(" "); + await TestServices.Input.SendAsync(" ", HangMitigatingCancellationToken); await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "TestZ.vb", open: true, cancellationToken: HangMitigatingCancellationToken); // Cause focus lost await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "TestZ.vb", HangMitigatingCancellationToken); // Work around https://github.com/dotnet/roslyn/issues/18488 - await TestServices.Input.SendAsync(" "); + await TestServices.Input.SendAsync(" ", HangMitigatingCancellationToken); await TestServices.SolutionExplorer.CloseCodeFileAsync(ProjectName, "TestZ.vb", saveFile: false, HangMitigatingCancellationToken); AssertEx.EqualOrDiff(@"Module M Sub M()