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; } } }
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() ); }
private void AddKeyword(SyntaxKind keywordKind) { builder.Add( CreatePart(SymbolDisplayPartKind.Keyword, null, SyntaxFacts.GetText(keywordKind)) ); }
/// <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())); }
private static string EscapeIdentifier(string identifier) { var kind = SyntaxFacts.GetKeywordKind(identifier); return(kind == SyntaxKind.None ? identifier : $"@{identifier}"); }
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)); }
internal static bool IsTypeInContextWhichNeedsDynamicAttribute(this IdentifierNameSyntax typeNode) { Debug.Assert(typeNode != null); return(SyntaxFacts.IsInTypeOnlyContext(typeNode) && IsInContextWhichNeedsDynamicAttribute(typeNode)); }
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); } }