Exemple #1
0
 private IEnumerable <string> GetConstraintNames(TypeParameterConstraintClauseSyntax constraintClause, SemanticModel semanticModel)
 {
     foreach (var constraint in constraintClause.Constraints)
     {
         yield return(constraint switch
         {
             TypeConstraintSyntax typeConstraint => semanticModel.GetTypeInfo(typeConstraint.Type).Type.ToString(),
             _ => constraint.ToString()
         });
Exemple #2
0
        public override void VisitTypeConstraint(TypeConstraintSyntax node)
        {
            if (!PreVisit(node))
            {
                return;
            }

            node.Type?.Accept(this);

            base.VisitTypeConstraint(node);

            PostVisit(node);
        }
Exemple #3
0
        private void StoreTypeConstraint(TypeConstraintSyntax asType, RDomTypeParameter newItem, SemanticModel model)
        {
            var newConstraintType = OutputContext.Corporation
                                    .Create(asType.Type, newItem, model)
                                    .FirstOrDefault()
                                    as IReferencedType;

            StoreConstraintWhitespace(asType, newConstraintType);
            if (newConstraintType != null)
            {
                newItem.ConstraintTypes.AddOrMove(newConstraintType);
            }
        }
Exemple #4
0
 private void StoreConstraintWhitespace(TypeConstraintSyntax syntax, IReferencedType newItem)
 {
     CreateFromWorker.StoreListMemberWhitespace(syntax,
                                                SyntaxKind.CommaToken, LanguageElement.Identifier, newItem);
     //var whitespace2 = newItem.Whitespace2Set[LanguageElement.Identifier];
     //if (string.IsNullOrEmpty(whitespace2.LeadingWhitespace))
     //{
     //   var prevNodeOrToken = syntax.Parent
     //                             .ChildNodesAndTokens()
     //                             .PreviousSiblings(syntax)
     //                             .LastOrDefault();
     //   var sepKind = SyntaxKind.CommaToken;
     //   if (prevNodeOrToken.Kind() == sepKind)
     //   {
     //      var commaToken = prevNodeOrToken.AsToken();
     //      whitespace2.LeadingWhitespace = commaToken.TrailingTrivia.ToString();
     //   }
     //}
 }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            // TODO: Replace the following code with your own analysis, generating a CodeAction for each fix to suggest
            Diagnostic diagnostic     = context.Diagnostics.First();
            TextSpan   diagnosticSpan = diagnostic.Location.SourceSpan;

            // Find the type declaration identified by the diagnostic.
            IEnumerable <SyntaxNode> ancestorsAndSelf = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf();

            NullableTypeSyntax   nullableTypeSyntax = ancestorsAndSelf.OfType <NullableTypeSyntax>().FirstOrDefault();
            TypeConstraintSyntax typeConstraint     = ancestorsAndSelf.OfType <TypeConstraintSyntax>().FirstOrDefault();

            NullableDirectiveTriviaSyntax nullableDirective = root.FindTrivia(diagnosticSpan.Start).GetStructure() as NullableDirectiveTriviaSyntax;

            if (nullableTypeSyntax == null && typeConstraint == null && nullableDirective == null)
            {
                return;
            }

            // Register a code action that will invoke the fix.
            Func <CancellationToken, Task <Document> > fix;

            if (nullableTypeSyntax != null)
            {
                fix = c => AddNullableComment(context.Document, nullableTypeSyntax, c);
            }
            else if (typeConstraint != null)
            {
                fix = c => AddNullableComment(context.Document, typeConstraint, c);
            }
            else
            {
                fix = c => AddNullableComment(context.Document, nullableDirective, c);
            }

            CodeAction codeAction = CodeAction.Create(title, fix, title);

            context.RegisterCodeFix(codeAction, diagnostic);
        }
Exemple #6
0
 private Doc PrintTypeConstraintSyntax(TypeConstraintSyntax node)
 {
     return(this.Print(node.Type));
 }
Exemple #7
0
        public override void VisitTypeConstraint(TypeConstraintSyntax node)
        {
            node.Type?.Accept(this);

            base.VisitTypeConstraint(node);
        }
        private async Task<Document> AddNullableComment(Document document, TypeConstraintSyntax typeConstraintNode, CancellationToken cancellationToken)
        {
            var constraintClause = (TypeParameterConstraintClauseSyntax)typeConstraintNode.Parent;

            TypeConstraintSyntax[] otherTypeConstraints = constraintClause.ChildNodes().OfType<TypeConstraintSyntax>().Except(new[] { typeConstraintNode }).ToArray();

            SyntaxNode root = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            IdentifierNameSyntax idNameSyntax = constraintClause.ChildNodes().OfType<IdentifierNameSyntax>().First();

            SyntaxToken identifierToken = typeConstraintNode.ChildNodes().First().ChildTokens().First();

            TypeParameterConstraintClauseSyntax newConstraintClause;

            if (otherTypeConstraints.Length > 0)
            {
                // Only this type constraint must be removed, since the where clause contains others

                // Adding the starting comment before the type constraint
                SyntaxToken newIdentifierToken = SyntaxFactory.Identifier(identifierToken.LeadingTrivia.Add(SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.Start)),
                                                                          SyntaxKind.IdentifierName, identifierToken.Text, identifierToken.ValueText,
                                                                          SyntaxTriviaList.Empty);

                TypeConstraintSyntax newNode = typeConstraintNode.ReplaceToken(identifierToken, newIdentifierToken);

                // Moving the new type constraint to the first of list
                SeparatedSyntaxList<TypeParameterConstraintSyntax> newConstraintList = SyntaxFactory.SeparatedList<TypeParameterConstraintSyntax>(otherTypeConstraints.Prepend(newNode));
                newConstraintClause = SyntaxFactory.TypeParameterConstraintClause(idNameSyntax.WithLeadingTrivia(SyntaxFactory.Space)).WithConstraints(newConstraintList);

                // Adding the end type constraint after the first comma.
                SyntaxToken firstCommaToken = newConstraintClause.ChildTokens().First(token => token.IsKind(SyntaxKind.CommaToken));
                SyntaxToken newCommaToken = SyntaxFactory.Token(firstCommaToken.LeadingTrivia,
                                                                SyntaxKind.CommaToken,
                                                                firstCommaToken.TrailingTrivia.Insert(0, SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.End)));

                newConstraintClause = newConstraintClause.ReplaceToken(firstCommaToken, newCommaToken);
            }
            else
            {
                // the whole where clause needs to be removed, so adding the comments before and after it.

                SyntaxToken oldWhereKeyword = constraintClause.ChildTokens().First(it => it.IsKind(SyntaxKind.WhereKeyword));

                SyntaxToken newWhereKeyword = SyntaxFactory.Token(oldWhereKeyword.LeadingTrivia.Add(SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.Start)),
                                                                  SyntaxKind.WhereKeyword,
                                                                  oldWhereKeyword.TrailingTrivia);

                SyntaxToken newIdentifierToken = SyntaxFactory.Identifier(identifierToken.LeadingTrivia, SyntaxKind.IdentifierName,
                                                                          identifierToken.Text, identifierToken.ValueText,
                                                                          identifierToken.TrailingTrivia.Insert(0, SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.End)));

                TypeConstraintSyntax newNode = typeConstraintNode.ReplaceToken(identifierToken, newIdentifierToken);

                newConstraintClause = SyntaxFactory.TypeParameterConstraintClause(newWhereKeyword,
                                                                                  constraintClause.ChildNodes().OfType<IdentifierNameSyntax>().First(),
                                                                                  constraintClause.ChildTokens().First(it => it.IsKind(SyntaxKind.ColonToken)),
                                                                                  SyntaxFactory.SeparatedList<TypeParameterConstraintSyntax>(new[] { newNode }));
            }

            // for some reason Roslyn adds formatting annotations that results in some strange new lines being added
            // by formatter later in internal CleanupDocumentAsync method of CodeAction class.
            newConstraintClause = RemoveAnnotationFromDescendantTrivias(newConstraintClause, SyntaxAnnotation.ElasticAnnotation);

            SyntaxNode newRoot = root.ReplaceNode(constraintClause, newConstraintClause);

            Document result = document.WithSyntaxRoot(newRoot);

            return result;
        }
        /// <summary>
        /// Returns true if the type is a valid constraint type.
        /// Otherwise returns false and generates a diagnostic.
        /// </summary>
        private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbol type, DiagnosticBag diagnostics)
        {
            switch (type.SpecialType)
            {
            case SpecialType.System_Object:
            case SpecialType.System_ValueType:
            case SpecialType.System_Enum:
            case SpecialType.System_Delegate:
            case SpecialType.System_MulticastDelegate:
            case SpecialType.System_Array:
                // "Constraint cannot be special class '{0}'"
                Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type);
                return(false);
            }

            switch (type.TypeKind)
            {
            case TypeKind.Error:
            case TypeKind.TypeParameter:
                return(true);

            case TypeKind.Interface:
                break;

            case TypeKind.DynamicType:
                // "Constraint cannot be the dynamic type"
                Error(diagnostics, ErrorCode.ERR_DynamicTypeAsBound, syntax);
                return(false);

            case TypeKind.Class:
                if (type.IsSealed)
                {
                    goto case TypeKind.Struct;
                }
                else if (type.IsStatic)
                {
                    // "'{0}': static classes cannot be used as constraints"
                    Error(diagnostics, ErrorCode.ERR_ConstraintIsStaticClass, syntax, type);
                    return(false);
                }
                break;

            case TypeKind.Delegate:
            case TypeKind.Enum:
            case TypeKind.Struct:
                // "'{0}' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter."
                Error(diagnostics, ErrorCode.ERR_BadBoundType, syntax, type);
                return(false);

            case TypeKind.ArrayType:
            case TypeKind.PointerType:
                // CS0706 already reported by parser.
                return(false);

            case TypeKind.Submission:
            // script class is synthetized, never used as a constraint

            default:
                Debug.Assert(false, "Unexpected type kind: " + type.TypeKind);
                return(false);
            }

            if (type.ContainsDynamic())
            {
                // "Constraint cannot be a dynamic type '{0}'"
                Error(diagnostics, ErrorCode.ERR_ConstructedDynamicTypeAsBound, syntax, type);
                return(false);
            }

            return(true);
        }
Exemple #10
0
 public override void VisitTypeConstraint(TypeConstraintSyntax node)
 {
 }
        //public override void VisitTupleExpression(TupleExpressionSyntax node)
        //{
        //    base.VisitTupleExpression(node);
        //}

        //public override void VisitTupleType(TupleTypeSyntax node)
        //{
        //    base.VisitTupleType(node);
        //}

        //public override void VisitTypeArgumentList(TypeArgumentListSyntax node)
        //{
        //    base.VisitTypeArgumentList(node);
        //}

        public override void VisitTypeConstraint(TypeConstraintSyntax node)
        {
            Debug.Fail(node.ToString());
            base.VisitTypeConstraint(node);
        }
        /// <summary>
        /// Returns true if the constraint is valid. Otherwise
        /// returns false and generates a diagnostic.
        /// </summary>
        internal static bool IsValidConstraint(
            string typeParameterName,
            TypeConstraintSyntax syntax,
            TypeSymbolWithAnnotations type,
            TypeParameterConstraintKind constraints,
            ArrayBuilder <TypeSymbolWithAnnotations> constraintTypes,
            DiagnosticBag diagnostics)
        {
            if (!IsValidConstraintType(syntax, type, diagnostics))
            {
                return(false);
            }

            // Ignore nullability when comparing constraints.
            if (constraintTypes.Contains(c => type.Equals(c, TypeCompareKind.IgnoreNullableModifiersForReferenceTypes)))
            {
                // "Duplicate constraint '{0}' for type parameter '{1}'"
                Error(diagnostics, ErrorCode.ERR_DuplicateBound, syntax, type.TypeSymbol.SetUnknownNullabilityForReferenceTypes(), typeParameterName);
                return(false);
            }

            if (type.TypeKind == TypeKind.Class)
            {
                // If there is already a struct or class constraint (class constraint could be
                // 'class' or explicit type), report an error and drop this class. If we don't
                // drop this additional class, we may end up with conflicting class constraints.

                if (constraintTypes.Count > 0)
                {
                    // "The class type constraint '{0}' must come before any other constraints"
                    Error(diagnostics, ErrorCode.ERR_ClassBoundNotFirst, syntax, type.TypeSymbol);
                    return(false);
                }

                if ((constraints & (TypeParameterConstraintKind.ReferenceType)) != 0)
                {
                    switch (type.SpecialType)
                    {
                    case SpecialType.System_Enum:
                    case SpecialType.System_Delegate:
                    case SpecialType.System_MulticastDelegate:
                        break;

                    default:
                        // "'{0}': cannot specify both a constraint class and the 'class' or 'struct' constraint"
                        Error(diagnostics, ErrorCode.ERR_RefValBoundWithClass, syntax, type.TypeSymbol);
                        return(false);
                    }
                }
                else if (type.SpecialType != SpecialType.System_Enum)
                {
                    if ((constraints & TypeParameterConstraintKind.ValueType) != 0)
                    {
                        // "'{0}': cannot specify both a constraint class and the 'class' or 'struct' constraint"
                        Error(diagnostics, ErrorCode.ERR_RefValBoundWithClass, syntax, type.TypeSymbol);
                        return(false);
                    }
                    else if ((constraints & TypeParameterConstraintKind.Unmanaged) != 0)
                    {
                        // "'{0}': cannot specify both a constraint class and the 'unmanaged' constraint"
                        Error(diagnostics, ErrorCode.ERR_UnmanagedBoundWithClass, syntax, type.TypeSymbol);
                        return(false);
                    }
                }
            }

            return(true);
        }
 public TypeConstraintTranslation(TypeConstraintSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
     Type = syntax.Type.Get<TypeTranslation>(this);
 }
        public void VisitTypeConstraint(TypeConstraintSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            node.Type.Accept(this);
        }
Exemple #15
0
 public override SyntaxNode VisitTypeConstraint(TypeConstraintSyntax node)
 {
     node = (TypeConstraintSyntax)base.VisitTypeConstraint(node);
     Classes.Add(node);
     return(node);
 }
Exemple #16
0
 public TameTypeConstraintSyntax(TypeConstraintSyntax node)
 {
     Node = node;
     AddChildren();
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitTypeConstraint(TypeConstraintSyntax node)
 {
     this.OnNodeVisited(node, this.type.IsInstanceOfType(node));
     base.VisitTypeConstraint(node);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitTypeConstraint(TypeConstraintSyntax node)
 {
     this.OnNodeVisited(node);
     if (!this.traverseRootOnly) base.VisitTypeConstraint(node);
 }
Exemple #19
0
 public TypeConstraintTranslation(TypeConstraintSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
     Type = syntax.Type.Get <TypeTranslation>(this);
 }
 public override SyntaxNode VisitTypeConstraint(TypeConstraintSyntax node) =>
 Expand(node);
        /// <summary>
        /// Returns true if the type is a valid constraint type.
        /// Otherwise returns false and generates a diagnostic.
        /// </summary>
        private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbolWithAnnotations typeWithAnnotations, DiagnosticBag diagnostics)
        {
            TypeSymbol type = typeWithAnnotations.TypeSymbol;

            switch (type.SpecialType)
            {
            case SpecialType.System_Enum:
                CheckFeatureAvailability(syntax, MessageID.IDS_FeatureEnumGenericTypeConstraint, diagnostics);
                break;

            case SpecialType.System_Delegate:
            case SpecialType.System_MulticastDelegate:
                CheckFeatureAvailability(syntax, MessageID.IDS_FeatureDelegateGenericTypeConstraint, diagnostics);
                break;

            case SpecialType.System_Object:
                if (typeWithAnnotations.NullableAnnotation == NullableAnnotation.Annotated)
                {
                    // "Constraint cannot be special class '{0}'"
                    Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, typeWithAnnotations);
                    return(false);
                }

                CheckFeatureAvailability(syntax, MessageID.IDS_FeatureObjectGenericTypeConstraint, diagnostics);
                break;

            case SpecialType.core_Array_T:
                // "Constraint cannot be special class '{0}'"
                Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type);
                return(false);
            }

            switch (type.TypeKind)
            {
            case TypeKind.Error:
            case TypeKind.TypeParameter:
                return(true);

            case TypeKind.Interface:
                break;

            case TypeKind.Class:
                if (type.IsSealed)
                {
                    goto case TypeKind.Struct;
                }
                else if (type.IsStatic)
                {
                    // "'{0}': static classes cannot be used as constraints"
                    Error(diagnostics, ErrorCode.ERR_ConstraintIsStaticClass, syntax, type);
                    return(false);
                }
                break;

            case TypeKind.Delegate:
            case TypeKind.Enum:
            case TypeKind.Struct:
                if (!(syntax is ConstConstraintSyntax))
                {
                    // "'{0}' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter."
                    Error(diagnostics, ErrorCode.ERR_BadBoundType, syntax, type);
                    return(false);
                }
                break;

            case TypeKind.Array:
            case TypeKind.Pointer:
                // CS0706 already reported by parser.
                return(false);

            case TypeKind.Submission:
            // script class is synthesized, never used as a constraint

            default:
                throw ExceptionUtilities.UnexpectedValue(type.TypeKind);
            }

            return(true);
        }
 public override void VisitTypeConstraint(TypeConstraintSyntax node)
 {
     // skip
 }
Exemple #23
0
 public override void VisitTypeConstraint(TypeConstraintSyntax node)
 {
     AddDependentType(node.Type);
     base.VisitTypeConstraint(node);
 }
        /// <summary>
        /// Returns true if the type is a valid constraint type.
        /// Otherwise returns false and generates a diagnostic.
        /// </summary>
        private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbol type, DiagnosticBag diagnostics)
        {
            switch (type.SpecialType)
            {
                case SpecialType.System_Object:
                case SpecialType.System_ValueType:
                case SpecialType.System_Enum:
                case SpecialType.System_Delegate:
                case SpecialType.System_MulticastDelegate:
                case SpecialType.System_Array:
                    // "Constraint cannot be special class '{0}'"
                    Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type);
                    return false;
            }

            switch (type.TypeKind)
            {
                case TypeKind.Error:
                case TypeKind.TypeParameter:
                    return true;

                case TypeKind.Interface:
                    break;

                case TypeKind.DynamicType:
                    // "Constraint cannot be the dynamic type"
                    Error(diagnostics, ErrorCode.ERR_DynamicTypeAsBound, syntax);
                    return false;

                case TypeKind.Class:
                    if (type.IsSealed)
                    {
                        goto case TypeKind.Struct;
                    }
                    else if (type.IsStatic)
                    {
                        // "'{0}': static classes cannot be used as constraints"
                        Error(diagnostics, ErrorCode.ERR_ConstraintIsStaticClass, syntax, type);
                        return false;
                    }
                    break;

                case TypeKind.Delegate:
                case TypeKind.Enum:
                case TypeKind.Struct:
                    // "'{0}' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter."
                    Error(diagnostics, ErrorCode.ERR_BadBoundType, syntax, type);
                    return false;

                case TypeKind.ArrayType:
                case TypeKind.PointerType:
                    // CS0706 already reported by parser.
                    return false;

                case TypeKind.Submission:
                // script class is synthetized, never used as a constraint

                default:
                    Debug.Assert(false, "Unexpected type kind: " + type.TypeKind);
                    return false;
            }

            if (type.ContainsDynamic())
            {
                // "Constraint cannot be a dynamic type '{0}'"
                Error(diagnostics, ErrorCode.ERR_ConstructedDynamicTypeAsBound, syntax, type);
                return false;
            }

            return true;
        }
 public static Doc Print(TypeConstraintSyntax node)
 {
     return(Node.Print(node.Type));
 }
Exemple #26
0
 public override void VisitTypeConstraint(TypeConstraintSyntax node)
 {
     throw new NotImplementedException();
 }
Exemple #27
0
        public override Evaluation VisitTypeConstraint(TypeConstraintSyntax node)
        {
            node.Type?.Accept <Evaluation>(this);

            return(base.VisitTypeConstraint(node));
        }
 //
 // Summary:
 //     Called when the visitor visits a TypeConstraintSyntax node.
 public virtual void VisitTypeConstraint(TypeConstraintSyntax node);