Пример #1
0
        public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false)
        {
            string text = id.ValueText;

            var keywordKind = SyntaxFacts.GetKeywordKind(text);

            if (keywordKind != Microsoft.CodeAnalysis.CSharp.SyntaxKind.None)
            {
                return(SyntaxFactory.Identifier("@" + text));
            }

            if (id.SyntaxTree == _semanticModel.SyntaxTree)
            {
                var symbol = _semanticModel.GetSymbolInfo(id.Parent).Symbol;
                if (symbol != null && !string.IsNullOrWhiteSpace(symbol.Name))
                {
                    if (symbol.IsConstructor() && isAttribute)
                    {
                        text = symbol.ContainingType.Name;
                        if (text.EndsWith("Attribute", StringComparison.OrdinalIgnoreCase))
                        {
                            text = text.Remove(text.Length - "Attribute".Length);
                        }
                    }
                    else if (symbol.IsKind(SymbolKind.Parameter) && symbol.ContainingSymbol.IsAccessorPropertySet() && ((symbol.IsImplicitlyDeclared && symbol.Name == "Value") || symbol.ContainingSymbol.GetParameters().FirstOrDefault(x => !x.IsImplicitlyDeclared) == symbol))
                    {
                        // The case above is basically that if the symbol is a parameter, and the corresponding definition is a property set definition
                        // AND the first explicitly declared parameter is this symbol, we need to replace it with value.
                        text = "value";
                    }
                    else if (text.StartsWith("_", StringComparison.OrdinalIgnoreCase) && symbol is IFieldSymbol propertyFieldSymbol && propertyFieldSymbol.AssociatedSymbol?.IsKind(SymbolKind.Property) == true)
                    {
                        text = propertyFieldSymbol.AssociatedSymbol.Name;
                    }
                    else if (text.EndsWith("Event", StringComparison.OrdinalIgnoreCase) && symbol is IFieldSymbol eventFieldSymbol && eventFieldSymbol.AssociatedSymbol?.IsKind(SymbolKind.Event) == true)
                    {
                        text = eventFieldSymbol.AssociatedSymbol.Name;
                    }
                }
            }
Пример #2
0
        internal static void ReportQueryInferenceFailed(
            CSharpSyntaxNode queryClause,
            string methodName,
            BoundExpression receiver,
            AnalyzedArguments arguments,
            ImmutableArray <Symbol> symbols,
            BindingDiagnosticBag diagnostics
            )
        {
            string clauseKind = null;
            bool   multiple   = false;

            switch (queryClause.Kind())
            {
            case SyntaxKind.JoinClause:
                clauseKind = SyntaxFacts.GetText(SyntaxKind.JoinKeyword);
                multiple   = true;
                break;

            case SyntaxKind.LetClause:
                clauseKind = SyntaxFacts.GetText(SyntaxKind.LetKeyword);
                break;

            case SyntaxKind.SelectClause:
                clauseKind = SyntaxFacts.GetText(SyntaxKind.SelectKeyword);
                break;

            case SyntaxKind.WhereClause:
                clauseKind = SyntaxFacts.GetText(SyntaxKind.WhereKeyword);
                break;

            case SyntaxKind.OrderByClause:
            case SyntaxKind.AscendingOrdering:
            case SyntaxKind.DescendingOrdering:
                clauseKind = SyntaxFacts.GetText(SyntaxKind.OrderByKeyword);
                multiple   = true;
                break;

            case SyntaxKind.QueryContinuation:
                clauseKind = SyntaxFacts.GetText(SyntaxKind.IntoKeyword);
                break;

            case SyntaxKind.GroupClause:
                clauseKind =
                    SyntaxFacts.GetText(SyntaxKind.GroupKeyword)
                    + " "
                    + SyntaxFacts.GetText(SyntaxKind.ByKeyword);
                multiple = true;
                break;

            case SyntaxKind.FromClause:
                if (
                    ReportQueryInferenceFailedSelectMany(
                        (FromClauseSyntax)queryClause,
                        methodName,
                        receiver,
                        arguments,
                        symbols,
                        diagnostics
                        )
                    )
                {
                    return;
                }
                clauseKind = SyntaxFacts.GetText(SyntaxKind.FromKeyword);
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(queryClause.Kind());
            }

            diagnostics.Add(
                new DiagnosticInfoWithSymbols(
                    multiple
                      ? ErrorCode.ERR_QueryTypeInferenceFailedMulti
                      : ErrorCode.ERR_QueryTypeInferenceFailed,
                    new object[] { clauseKind, methodName },
                    symbols
                    ),
                queryClause.GetFirstToken().GetLocation()
                );
        }
Пример #3
0
 private void AddKeyword(SyntaxKind keywordKind)
 {
     builder.Add(
         CreatePart(SymbolDisplayPartKind.Keyword, null, SyntaxFacts.GetText(keywordKind))
         );
 }
Пример #4
0
        /// <summary>
        /// Bind and return a single type parameter constraint clause.
        /// </summary>
        private TypeParameterConstraintClause BindTypeParameterConstraints(
            string name, TypeParameterConstraintClauseSyntax constraintClauseSyntax, DiagnosticBag diagnostics)
        {
            var constraints     = TypeParameterConstraintKind.None;
            var constraintTypes = ArrayBuilder <TypeSymbolWithAnnotations> .GetInstance();

            var syntaxBuilder = ArrayBuilder <TypeConstraintSyntax> .GetInstance();

            SeparatedSyntaxList <TypeParameterConstraintSyntax> constraintsSyntax = constraintClauseSyntax.Constraints;

            Debug.Assert(!InExecutableBinder); // Cannot eagerly report diagnostics handled by LazyMissingNonNullTypesContextDiagnosticInfo

            for (int i = 0, n = constraintsSyntax.Count; i < n; i++)
            {
                var syntax = constraintsSyntax[i];
                switch (syntax.Kind())
                {
                case SyntaxKind.ClassConstraint:
                    if (i != 0)
                    {
                        diagnostics.Add(ErrorCode.ERR_RefValBoundMustBeFirst, syntax.GetFirstToken().GetLocation());
                    }

                    SyntaxToken questionToken = ((ClassOrStructConstraintSyntax)syntax).QuestionToken;
                    if (questionToken.IsKind(SyntaxKind.QuestionToken))
                    {
                        constraints |= TypeParameterConstraintKind.NullableReferenceType;
                        diagnostics.Add(new LazyMissingNonNullTypesContextDiagnosticInfo(Compilation, NonNullTypesContext, type: default), questionToken.GetLocation());
                    }
                    else
                    {
                        constraints |= TypeParameterConstraintKind.ReferenceType;
                    }

                    continue;

                case SyntaxKind.StructConstraint:
                    if (i != 0)
                    {
                        diagnostics.Add(ErrorCode.ERR_RefValBoundMustBeFirst, syntax.GetFirstToken().GetLocation());
                    }

                    constraints |= TypeParameterConstraintKind.ValueType;
                    continue;

                case SyntaxKind.ConstructorConstraint:
                    if ((constraints & TypeParameterConstraintKind.ValueType) != 0)
                    {
                        diagnostics.Add(ErrorCode.ERR_NewBoundWithVal, syntax.GetFirstToken().GetLocation());
                    }
                    if ((constraints & TypeParameterConstraintKind.Unmanaged) != 0)
                    {
                        diagnostics.Add(ErrorCode.ERR_NewBoundWithUnmanaged, syntax.GetFirstToken().GetLocation());
                    }

                    if (i != n - 1)
                    {
                        diagnostics.Add(ErrorCode.ERR_NewBoundMustBeLast, syntax.GetFirstToken().GetLocation());
                    }

                    constraints |= TypeParameterConstraintKind.Constructor;
                    continue;

                case SyntaxKind.TypeConstraint:
                {
                    var typeConstraintSyntax = (TypeConstraintSyntax)syntax;
                    var typeSyntax           = typeConstraintSyntax.Type;
                    var typeSyntaxKind       = typeSyntax.Kind();

                    // For pointer types, don't report this error. It is already reported during binding typeSyntax below.
                    switch (typeSyntaxKind)
                    {
                    case SyntaxKind.PredefinedType:
                    case SyntaxKind.PointerType:
                    case SyntaxKind.NullableType:
                        break;

                    default:
                        if (!SyntaxFacts.IsName(typeSyntax.Kind()))
                        {
                            diagnostics.Add(ErrorCode.ERR_BadConstraintType, typeSyntax.GetLocation());
                        }
                        break;
                    }

                    var type = BindTypeOrUnmanagedKeyword(typeSyntax, diagnostics, out var isUnmanaged);

                    if (isUnmanaged)
                    {
                        if (constraints != 0 || constraintTypes.Any())
                        {
                            diagnostics.Add(ErrorCode.ERR_UnmanagedConstraintMustBeFirst, typeSyntax.GetLocation());
                            continue;
                        }

                        // This should produce diagnostics if the types are missing
                        GetWellKnownType(WellKnownType.System_Runtime_InteropServices_UnmanagedType, diagnostics, typeSyntax);
                        GetSpecialType(SpecialType.System_ValueType, diagnostics, typeSyntax);

                        constraints |= TypeParameterConstraintKind.Unmanaged;
                        continue;
                    }

                    constraintTypes.Add(type);
                    syntaxBuilder.Add(typeConstraintSyntax);
                }
                    continue;

                default:
                    throw ExceptionUtilities.UnexpectedValue(syntax.Kind());
                }
            }

            return(TypeParameterConstraintClause.Create(constraints, constraintTypes.ToImmutableAndFree(), syntaxBuilder.ToImmutableAndFree()));
        }
Пример #5
0
        private static string EscapeIdentifier(string identifier)
        {
            var kind = SyntaxFacts.GetKeywordKind(identifier);

            return(kind == SyntaxKind.None ? identifier : $"@{identifier}");
        }
Пример #6
0
 private void AddPunctuation(SyntaxKind punctuationKind)
 {
     builder.Add(CreatePart(SymbolDisplayPartKind.Punctuation, null, SyntaxFacts.GetText(punctuationKind)));
 }
        private BoundExpression BindInterpolatedString(InterpolatedStringExpressionSyntax node, DiagnosticBag diagnostics)
        {
            var builder = ArrayBuilder <BoundExpression> .GetInstance();

            var stringType = GetSpecialType(SpecialType.System_String, diagnostics, node);
            var objectType = GetSpecialType(SpecialType.System_Object, diagnostics, node);
            var intType    = GetSpecialType(SpecialType.System_Int32, diagnostics, node);

            foreach (var content in node.Contents)
            {
                switch (content.Kind())
                {
                case SyntaxKind.Interpolation:
                {
                    var interpolation = (InterpolationSyntax)content;
                    var value         = BindValue(interpolation.Expression, diagnostics, BindValueKind.RValue);
                    if (value.Type is null)
                    {
                        value = GenerateConversionForAssignment(objectType, value, diagnostics);
                    }
                    else
                    {
                        value = BindToNaturalType(value, diagnostics);
                        _     = GenerateConversionForAssignment(objectType, value, diagnostics);
                    }

                    // We need to ensure the argument is not a lambda, method group, etc. It isn't nice to wait until lowering,
                    // when we perform overload resolution, to report a problem. So we do that check by calling
                    // GenerateConversionForAssignment with objectType. However we want to preserve the original expression's
                    // natural type so that overload resolution may select a specialized implementation of string.Format,
                    // so we discard the result of that call and only preserve its diagnostics.
                    BoundExpression?alignment = null;
                    BoundLiteral?   format    = null;
                    if (interpolation.AlignmentClause != null)
                    {
                        alignment = GenerateConversionForAssignment(intType, BindValue(interpolation.AlignmentClause.Value, diagnostics, Binder.BindValueKind.RValue), diagnostics);
                        var alignmentConstant = alignment.ConstantValue;
                        if (alignmentConstant != null && !alignmentConstant.IsBad)
                        {
                            const int magnitudeLimit = 32767;
                            // check that the magnitude of the alignment is "in range".
                            int alignmentValue = alignmentConstant.Int32Value;
                            //  We do the arithmetic using negative numbers because the largest negative int has no corresponding positive (absolute) value.
                            alignmentValue = (alignmentValue > 0) ? -alignmentValue : alignmentValue;
                            if (alignmentValue < -magnitudeLimit)
                            {
                                diagnostics.Add(ErrorCode.WRN_AlignmentMagnitude, alignment.Syntax.Location, alignmentConstant.Int32Value, magnitudeLimit);
                            }
                        }
                        else if (!alignment.HasErrors)
                        {
                            diagnostics.Add(ErrorCode.ERR_ConstantExpected, interpolation.AlignmentClause.Value.Location);
                        }
                    }

                    if (interpolation.FormatClause != null)
                    {
                        var  text = interpolation.FormatClause.FormatStringToken.ValueText;
                        char lastChar;
                        bool hasErrors = false;
                        if (text.Length == 0)
                        {
                            diagnostics.Add(ErrorCode.ERR_EmptyFormatSpecifier, interpolation.FormatClause.Location);
                            hasErrors = true;
                        }
                        else if (SyntaxFacts.IsWhitespace(lastChar = text[text.Length - 1]) || SyntaxFacts.IsNewLine(lastChar))
                        {
                            diagnostics.Add(ErrorCode.ERR_TrailingWhitespaceInFormatSpecifier, interpolation.FormatClause.Location);
                            hasErrors = true;
                        }

                        format = new BoundLiteral(interpolation.FormatClause, ConstantValue.Create(text), stringType, hasErrors);
                    }

                    builder.Add(new BoundStringInsert(interpolation, value, alignment, format, null));
                    continue;
                }

                case SyntaxKind.InterpolatedStringText:
                {
                    var text = ((InterpolatedStringTextSyntax)content).TextToken.ValueText;
                    builder.Add(new BoundLiteral(content, ConstantValue.Create(text, SpecialType.System_String), stringType));
                    continue;
                }

                default:
                    throw ExceptionUtilities.UnexpectedValue(content.Kind());
                }
            }

            return(new BoundInterpolatedString(node, builder.ToImmutableAndFree(), stringType));
        }
Пример #8
0
 internal static bool IsTypeInContextWhichNeedsDynamicAttribute(this IdentifierNameSyntax typeNode)
 {
     Debug.Assert(typeNode != null);
     return(SyntaxFacts.IsInTypeOnlyContext(typeNode) && IsInContextWhichNeedsDynamicAttribute(typeNode));
 }
Пример #9
0
        public override void VisitMethod(IMethodSymbol symbol)
        {
            if (symbol.MethodKind == MethodKind.AnonymousFunction)
            {
                // TODO(cyrusn): Why is this a literal?  Why don't we give the appropriate signature
                // of the method as asked?
                builder.Add(CreatePart(SymbolDisplayPartKind.NumericLiteral, symbol, "lambda expression"));
                return;
            }
            else if (symbol is SynthesizedGlobalMethodSymbol) // It would be nice to handle VB symbols too, but it's not worth the effort.
            {
                // Represents a compiler generated synthesized method symbol with a null containing
                // type.

                // TODO(cyrusn); Why is this a literal?
                builder.Add(CreatePart(SymbolDisplayPartKind.NumericLiteral, symbol, symbol.Name));
                return;
            }

            if (symbol.IsExtensionMethod && format.ExtensionMethodStyle != SymbolDisplayExtensionMethodStyle.Default)
            {
                if (symbol.MethodKind == MethodKind.ReducedExtension && format.ExtensionMethodStyle == SymbolDisplayExtensionMethodStyle.StaticMethod)
                {
                    symbol = symbol.GetConstructedReducedFrom();
                }
                else if (symbol.MethodKind != MethodKind.ReducedExtension && format.ExtensionMethodStyle == SymbolDisplayExtensionMethodStyle.InstanceMethod)
                {
                    // If we cannot reduce this to an instance form then display in the static form
                    symbol = symbol.ReduceExtensionMethod(symbol.Parameters.First().Type) ?? symbol;
                }
            }

            // Method members always have a type unless (1) this is a lambda method symbol, which we
            // have dealt with already, or (2) this is an error method symbol. If we have an error method
            // symbol then we do not know its accessibility, modifiers, etc, all of which require knowing
            // the containing type, so we'll skip them.

            if ((object)symbol.ContainingType != null || (symbol.ContainingSymbol is ITypeSymbol))
            {
                AddAccessibilityIfRequired(symbol);
                AddMemberModifiersIfRequired(symbol);

                if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeType))
                {
                    switch (symbol.MethodKind)
                    {
                    case MethodKind.Constructor:
                    case MethodKind.StaticConstructor:
                        break;

                    case MethodKind.Destructor:
                    case MethodKind.Conversion:
                        // If we're using the metadata format, then include the return type.
                        // Otherwise we eschew it since it is redundant in an conversion
                        // signature.
                        if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames))
                        {
                            goto default;
                        }

                        break;

                    default:
                        // The display code is called by the debugger; if a developer is debugging Roslyn and attempts
                        // to visualize a symbol *during its construction*, the parameters and return type might
                        // still be null.

                        if (symbol.ReturnsByRef)
                        {
                            AddRefIfRequired();
                        }
                        else if (symbol.ReturnsByRefReadonly)
                        {
                            AddRefReadonlyIfRequired();
                        }

                        AddCustomModifiersIfRequired(symbol.RefCustomModifiers);

                        if (symbol.ReturnsVoid)
                        {
                            AddKeyword(SyntaxKind.VoidKeyword);
                        }
                        else if (symbol.ReturnType != null)
                        {
                            symbol.ReturnType.Accept(this.NotFirstVisitor);
                        }

                        AddSpace();
                        AddCustomModifiersIfRequired(symbol.ReturnTypeCustomModifiers);
                        break;
                    }
                }

                if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeContainingType))
                {
                    ITypeSymbol containingType;
                    bool        includeType;

                    if (symbol.MethodKind == MethodKind.LocalFunction)
                    {
                        includeType    = false;
                        containingType = null;
                    }
                    else if (symbol.MethodKind == MethodKind.ReducedExtension)
                    {
                        containingType = symbol.ReceiverType;
                        includeType    = true;
                        Debug.Assert(containingType != null);
                    }
                    else
                    {
                        containingType = symbol.ContainingType;

                        if ((object)containingType != null)
                        {
                            includeType = IncludeNamedType(symbol.ContainingType);
                        }
                        else
                        {
                            containingType = (ITypeSymbol)symbol.ContainingSymbol;
                            includeType    = true;
                        }
                    }

                    if (includeType)
                    {
                        containingType.Accept(this.NotFirstVisitor);
                        AddPunctuation(SyntaxKind.DotToken);
                    }
                }
            }

            bool isAccessor = false;

            switch (symbol.MethodKind)
            {
            case MethodKind.Ordinary:
            case MethodKind.DelegateInvoke:
            case MethodKind.ReducedExtension:
            case MethodKind.LocalFunction:
                //containing type will be the delegate type, name will be Invoke
                builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.Name));
                break;

            case MethodKind.PropertyGet:
            case MethodKind.PropertySet:
                isAccessor = true;
                var associatedProperty = (IPropertySymbol)symbol.AssociatedSymbol;
                if (associatedProperty == null)
                {
                    goto case MethodKind.Ordinary;
                }
                AddPropertyNameAndParameters(associatedProperty);
                AddPunctuation(SyntaxKind.DotToken);
                AddKeyword(symbol.MethodKind == MethodKind.PropertyGet ? SyntaxKind.GetKeyword : SyntaxKind.SetKeyword);
                break;

            case MethodKind.EventAdd:
            case MethodKind.EventRemove:
                isAccessor = true;
                var associatedEvent = (IEventSymbol)symbol.AssociatedSymbol;
                if (associatedEvent == null)
                {
                    goto case MethodKind.Ordinary;
                }
                AddEventName(associatedEvent);
                AddPunctuation(SyntaxKind.DotToken);
                AddKeyword(symbol.MethodKind == MethodKind.EventAdd ? SyntaxKind.AddKeyword : SyntaxKind.RemoveKeyword);
                break;

            case MethodKind.Constructor:
            case MethodKind.StaticConstructor:
                // Note: we are using the metadata name also in the case that
                // symbol.containingType is null (which should never be the case here) or is an
                //       anonymous type (which 'does not have a name').
                var name = format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames) || symbol.ContainingType == null || symbol.ContainingType.IsAnonymousType
                        ? symbol.Name
                        : symbol.ContainingType.Name;
                builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, name));
                break;

            case MethodKind.Destructor:
                // Note: we are using the metadata name also in the case that symbol.containingType is null, which should never be the case here.
                if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames) || symbol.ContainingType == null)
                {
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.Name));
                }
                else
                {
                    AddPunctuation(SyntaxKind.TildeToken);
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.ContainingType.Name));
                }
                break;

            case MethodKind.ExplicitInterfaceImplementation:
                AddExplicitInterfaceIfRequired(symbol.ExplicitInterfaceImplementations);
                builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol,
                                       ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(symbol.Name)));
                break;

            case MethodKind.UserDefinedOperator:
            case MethodKind.BuiltinOperator:
                if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames))
                {
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.MetadataName));
                }
                else
                {
                    AddKeyword(SyntaxKind.OperatorKeyword);
                    AddSpace();
                    if (symbol.MetadataName == WellKnownMemberNames.TrueOperatorName)
                    {
                        AddKeyword(SyntaxKind.TrueKeyword);
                    }
                    else if (symbol.MetadataName == WellKnownMemberNames.FalseOperatorName)
                    {
                        AddKeyword(SyntaxKind.FalseKeyword);
                    }
                    else
                    {
                        builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol,
                                               SyntaxFacts.GetText(SyntaxFacts.GetOperatorKind(symbol.MetadataName))));
                    }
                }
                break;

            case MethodKind.Conversion:
                if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames))
                {
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.MetadataName));
                }
                else
                {
                    // "System.IntPtr.explicit operator System.IntPtr(int)"

                    if (symbol.MetadataName == WellKnownMemberNames.ExplicitConversionName)
                    {
                        AddKeyword(SyntaxKind.ExplicitKeyword);
                    }
                    else if (symbol.MetadataName == WellKnownMemberNames.ImplicitConversionName)
                    {
                        AddKeyword(SyntaxKind.ImplicitKeyword);
                    }
                    else
                    {
                        builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol,
                                               SyntaxFacts.GetText(SyntaxFacts.GetOperatorKind(symbol.MetadataName))));
                    }

                    AddSpace();
                    AddKeyword(SyntaxKind.OperatorKeyword);
                    AddSpace();
                    symbol.ReturnType.Accept(this.NotFirstVisitor);
                }
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(symbol.MethodKind);
            }

            if (!isAccessor)
            {
                AddTypeArguments(symbol.TypeArguments);
                AddParameters(symbol);
                AddTypeParameterConstraints(symbol);
            }
        }