public static AccessorDeclarationSyntax AccessorDeclaration(AccessorDeclarationKind kind = default(AccessorDeclarationKind), BlockSyntax body = null) { var result = new AccessorDeclarationSyntax(); result.Kind = kind; result.Body = body; return result; }
public static AccessorDeclarationSyntax AccessorDeclaration(AccessorDeclarationKind kind = default(AccessorDeclarationKind), IEnumerable<AttributeListSyntax> attributeLists = null, Modifiers modifiers = default(Modifiers), BlockSyntax body = null) { var result = new AccessorDeclarationSyntax(); result.Kind = kind; if (attributeLists != null) result.AttributeLists.AddRange(attributeLists); result.Modifiers = modifiers; result.Body = body; return result; }
private SourcePropertyAccessorSymbol( NamedTypeSymbol containingType, string name, SourcePropertySymbol property, DeclarationModifiers propertyModifiers, ImmutableArray <MethodSymbol> explicitInterfaceImplementations, Location location, AccessorDeclarationSyntax syntax, MethodKind methodKind, bool isAutoPropertyAccessor, bool isExplicitInterfaceImplementation, DiagnosticBag diagnostics) : base(containingType, syntax.GetReference(), location) { _property = property; _explicitInterfaceImplementations = explicitInterfaceImplementations; _name = name; _isAutoPropertyAccessor = isAutoPropertyAccessor; Debug.Assert(!_property.IsExpressionBodied, "Cannot have accessors in expression bodied lightweight properties"); var hasBody = syntax.Body != null; var hasExpressionBody = syntax.ExpressionBody != null; _isExpressionBodied = !hasBody && hasExpressionBody; bool modifierErrors; var declarationModifiers = this.MakeModifiers(syntax, isExplicitInterfaceImplementation, hasBody || hasExpressionBody, location, diagnostics, out modifierErrors); // Include some modifiers from the containing property, but not the accessibility modifiers. declarationModifiers |= GetAccessorModifiers(propertyModifiers) & ~DeclarationModifiers.AccessibilityMask; if ((declarationModifiers & DeclarationModifiers.Private) != 0) { // Private accessors cannot be virtual. declarationModifiers &= ~DeclarationModifiers.Virtual; } // ReturnsVoid property is overridden in this class so // returnsVoid argument to MakeFlags is ignored. this.MakeFlags(methodKind, declarationModifiers, returnsVoid: false, isExtensionMethod: false, isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any()); CheckFeatureAvailabilityAndRuntimeSupport(syntax, location, hasBody: hasBody || hasExpressionBody || isAutoPropertyAccessor, diagnostics); if (hasBody || hasExpressionBody) { CheckModifiersForBody(syntax, location, diagnostics); } var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers, this, isExplicitInterfaceImplementation); if (info != null) { diagnostics.Add(info, location); } if (!modifierErrors) { this.CheckModifiers(location, hasBody || hasExpressionBody, isAutoPropertyAccessor, diagnostics); } if (this.IsOverride) { MethodSymbol overriddenMethod = this.OverriddenMethod; if ((object)overriddenMethod != null) { // If this accessor is overriding a method from metadata, it is possible that // the name of the overridden method doesn't follow the C# get_X/set_X pattern. // We should copy the name so that the runtime will recognize this as an override. _name = overriddenMethod.Name; } } CheckForBlockAndExpressionBody( syntax.Body, syntax.ExpressionBody, syntax, diagnostics); }
private static (SyntaxNode newRoot, PropertyDeclarationSyntax newNode) AddCallToOnPropertyChanged(SyntaxNode root, AccessorDeclarationSyntax node) { InvocationExpressionSyntax invoc = SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName("OnPropertyChanged")); ExpressionStatementSyntax expr = SyntaxFactory.ExpressionStatement(invoc, SyntaxFactory.Token(SyntaxKind.SemicolonToken)); var annotation = new SyntaxAnnotation("new_call_node", ""); var newNode = node.AddBodyStatements(expr).WithAdditionalAnnotations(annotation); var newRoot = root.ReplaceNode(node, newNode); newNode = newRoot.GetAnnotatedNodes(annotation).First() as AccessorDeclarationSyntax; return(newRoot, newNode.Parent.Parent as PropertyDeclarationSyntax); }
public override void VisitAccessorDeclaration(AccessorDeclarationSyntax node) { }
private static void AnalyzeSummaryElement(SyntaxNodeAnalysisContext context, XmlNodeSyntax syntax, Location diagnosticLocation, PropertyDeclarationSyntax propertyDeclaration, string startingTextGets, string startingTextSets, string startingTextGetsOrSets, string startingTextReturns) { var diagnosticProperties = ImmutableDictionary.CreateBuilder <string, string>(); ArrowExpressionClauseSyntax expressionBody = propertyDeclaration.ExpressionBody; AccessorDeclarationSyntax getter = null; AccessorDeclarationSyntax setter = null; if (propertyDeclaration.AccessorList != null) { foreach (var accessor in propertyDeclaration.AccessorList.Accessors) { switch (accessor.Keyword.Kind()) { case SyntaxKind.GetKeyword: getter = accessor; break; case SyntaxKind.SetKeyword: setter = accessor; break; } } } if (!(syntax is XmlElementSyntax summaryElement)) { // This is reported by SA1604 or SA1606. return; } // Add a no code fix tag when the summary element is empty. // This will only impact SA1623, because SA1624 cannot trigger with an empty summary. if (summaryElement.Content.Count == 0) { diagnosticProperties.Add(NoCodeFixKey, string.Empty); } var textElement = XmlCommentHelper.TryGetFirstTextElementWithContent(summaryElement); string text = textElement is null ? string.Empty : XmlCommentHelper.GetText(textElement, normalizeWhitespace: true).TrimStart(); bool prefixIsGetsOrSets = text.StartsWith(startingTextGetsOrSets, StringComparison.OrdinalIgnoreCase); bool prefixIsGets = !prefixIsGetsOrSets && text.StartsWith(startingTextGets, StringComparison.OrdinalIgnoreCase); bool prefixIsSets = text.StartsWith(startingTextSets, StringComparison.OrdinalIgnoreCase); bool getterVisible, setterVisible; if (getter != null && setter != null) { if (!getter.Modifiers.Any() && !setter.Modifiers.Any()) { // The getter and setter have the same declared accessibility getterVisible = true; setterVisible = true; } else if (getter.Modifiers.Any(SyntaxKind.PrivateKeyword)) { getterVisible = false; setterVisible = true; } else if (setter.Modifiers.Any(SyntaxKind.PrivateKeyword)) { getterVisible = true; setterVisible = false; } else { var propertyAccessibility = propertyDeclaration.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken); bool propertyOnlyInternal = propertyAccessibility == Accessibility.Internal || propertyAccessibility == Accessibility.ProtectedAndInternal || propertyAccessibility == Accessibility.Private; if (propertyOnlyInternal) { // Property only internal and no accessor is explicitly private getterVisible = true; setterVisible = true; } else { var getterAccessibility = getter.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken); var setterAccessibility = setter.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken); switch (getterAccessibility) { case Accessibility.Public: case Accessibility.ProtectedOrInternal: case Accessibility.Protected: getterVisible = true; break; case Accessibility.Internal: case Accessibility.ProtectedAndInternal: case Accessibility.Private: default: // The property is externally accessible, so the setter must be more accessible. getterVisible = false; break; } switch (setterAccessibility) { case Accessibility.Public: case Accessibility.ProtectedOrInternal: case Accessibility.Protected: setterVisible = true; break; case Accessibility.Internal: case Accessibility.ProtectedAndInternal: case Accessibility.Private: default: // The property is externally accessible, so the getter must be more accessible. setterVisible = false; break; } } } } else { if (getter != null || expressionBody != null) { getterVisible = true; setterVisible = false; } else { getterVisible = false; setterVisible = setter != null; } } if (getterVisible) { if (setterVisible) { // Both getter and setter are visible. if (!prefixIsGetsOrSets) { ReportSA1623(context, diagnosticLocation, diagnosticProperties, text, expectedStartingText: startingTextGetsOrSets, unexpectedStartingText1: startingTextGets, unexpectedStartingText2: startingTextSets, unexpectedStartingText3: startingTextReturns); } } else if (setter != null) { // Both getter and setter exist, but only getter is visible. if (!prefixIsGets) { if (prefixIsGetsOrSets) { ReportSA1624(context, diagnosticLocation, diagnosticProperties, accessor: "get", expectedStartingText: startingTextGets, startingTextToRemove: startingTextGetsOrSets); } else { ReportSA1623(context, diagnosticLocation, diagnosticProperties, text, expectedStartingText: startingTextGets, unexpectedStartingText1: startingTextSets, unexpectedStartingText2: startingTextReturns); } } } else { // Getter exists and is visible. Setter does not exist. if (!prefixIsGets) { ReportSA1623(context, diagnosticLocation, diagnosticProperties, text, expectedStartingText: startingTextGets, unexpectedStartingText1: startingTextSets, unexpectedStartingText2: startingTextGetsOrSets, unexpectedStartingText3: startingTextReturns); } } } else if (setterVisible) { if (getter != null) { // Both getter and setter exist, but only setter is visible. if (!prefixIsSets) { if (prefixIsGetsOrSets) { ReportSA1624(context, diagnosticLocation, diagnosticProperties, accessor: "set", expectedStartingText: startingTextSets, startingTextToRemove: startingTextGetsOrSets); } else { ReportSA1623(context, diagnosticLocation, diagnosticProperties, text, expectedStartingText: startingTextSets, unexpectedStartingText1: startingTextGets, unexpectedStartingText2: startingTextReturns); } } } else { // Setter exists and is visible. Getter does not exist. if (!prefixIsSets) { ReportSA1623(context, diagnosticLocation, diagnosticProperties, text, expectedStartingText: startingTextSets, unexpectedStartingText1: startingTextGetsOrSets, unexpectedStartingText2: startingTextGets, unexpectedStartingText3: startingTextReturns); } } } }
public void TestGetSpeculativeSemanticModelForPropertyAccessorBody() { var compilation = CreateStandardCompilation(@" class R { private int _p; } class C : R { private int M { set { int y = 1000; } } } "); var blockStatement = (BlockSyntax)SyntaxFactory.ParseStatement(@" { int z = 0; _p = 123L; } "); var tree = compilation.SyntaxTrees[0]; var root = tree.GetCompilationUnitRoot(); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: true); AccessorDeclarationSyntax accessorDecl = root.DescendantNodes().OfType <AccessorDeclarationSyntax>().Single(); var speculatedMethod = accessorDecl.ReplaceNode(accessorDecl.Body, blockStatement); SemanticModel speculativeModel; var success = model.TryGetSpeculativeSemanticModelForMethodBody( accessorDecl.Body.Statements[0].SpanStart, speculatedMethod, out speculativeModel); Assert.True(success); Assert.NotNull(speculativeModel); var p = speculativeModel.SyntaxTree.GetRoot() .DescendantNodes() .OfType <IdentifierNameSyntax>() .Single(s => s.Identifier.ValueText == "_p"); var symbolSpeculation = speculativeModel.GetSpeculativeSymbolInfo(p.FullSpan.Start, p, SpeculativeBindingOption.BindAsExpression); Assert.Equal("_p", symbolSpeculation.Symbol.Name); var typeSpeculation = speculativeModel.GetSpeculativeTypeInfo(p.FullSpan.Start, p, SpeculativeBindingOption.BindAsExpression); Assert.Equal("Int32", typeSpeculation.Type.Name); }
protected IEnumerable <CodeAction> GetActions(Document document, SyntaxNode root, AccessorDeclarationSyntax node) { var propertyOrIndexerDeclaration = node.Ancestors().Where(n => n.GetType().Equals(typeof(PropertyDeclarationSyntax)) || n.GetType().Equals(typeof(IndexerDeclarationSyntax))).FirstOrDefault(); var nullableType = propertyOrIndexerDeclaration.ChildNodes().OfType <NullableTypeSyntax>().FirstOrDefault(); var objectType = propertyOrIndexerDeclaration.ChildNodes().OfType <IdentifierNameSyntax>().FirstOrDefault(); return(GetActions(document, root, node, nullableType, objectType)); }
private static SyntaxNode ReformatAccessorAsMultipleLines(IndentationSettings indentationSettings, AccessorDeclarationSyntax accessor) { var accessorList = (AccessorListSyntax)accessor.Parent; var indentationSteps = IndentationHelper.GetIndentationSteps(indentationSettings, accessorList.OpenBraceToken) + 1; var indentation = IndentationHelper.GenerateWhitespaceTrivia(indentationSettings, indentationSteps); var indentationStatements = IndentationHelper.GenerateWhitespaceTrivia(indentationSettings, indentationSteps + 1); var newAccessor = accessor .WithModifiers(ReformatModifiersAsMultipleLines(accessor.Modifiers, indentation)) .WithKeyword(ReformatKeywordAsMultipleLines(accessor.Keyword, indentation, accessor.Modifiers.Count == 0)) .WithBody(ReformatBodyAsMultipleLines(accessor.Body, indentation, indentationStatements)); return(newAccessor); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindToken(root, context.Span.Start, out SyntaxToken token)) { return; } SyntaxKind kind = token.Kind(); foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.OperatorCannotBeAppliedToOperand: { if (kind == SyntaxKind.QuestionToken && token.Parent is ConditionalAccessExpressionSyntax conditionalAccess) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(conditionalAccess.Expression, context.CancellationToken); if (typeSymbol?.IsErrorType() == false && !typeSymbol.IsNullableType()) { if (typeSymbol.IsValueType) { if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConditionalAccess)) { CodeAction codeAction = CodeAction.Create( "Remove '?' operator", cancellationToken => { var textChange = new TextChange(token.Span, ""); return(context.Document.WithTextChangeAsync(textChange, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } else if (typeSymbol.IsReferenceType) { if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddArgumentList) && conditionalAccess.WhenNotNull is MemberBindingExpressionSyntax memberBindingExpression) { ConditionalAccessExpressionSyntax newNode = conditionalAccess.WithWhenNotNull( InvocationExpression( memberBindingExpression.WithoutTrailingTrivia(), ArgumentList().WithTrailingTrivia(memberBindingExpression.GetTrailingTrivia()))); CodeAction codeAction = CodeAction.Create( "Add argument list", cancellationToken => context.Document.ReplaceNodeAsync(conditionalAccess, newNode, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } } } break; } case CompilerDiagnosticIdentifiers.PartialModifierCanOnlyAppearImmediatelyBeforeClassStructInterfaceOrVoid: { if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.OrderModifiers)) { break; } ModifiersCodeFixRegistrator.MoveModifier(context, diagnostic, token.Parent, token); break; } case CompilerDiagnosticIdentifiers.ValueCannotBeUsedAsDefaultParameter: { if (!(token.Parent is ParameterSyntax parameter)) { break; } ExpressionSyntax value = parameter.Default?.Value; if (value == null) { break; } if (value.IsKind(SyntaxKind.NullLiteralExpression)) { if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); CodeFixRegistrator.ReplaceNullWithDefaultValue(context, diagnostic, value, semanticModel); } } else if (!value.IsKind(SyntaxKind.DefaultExpression, SyntaxKind.DefaultLiteralExpression)) { if (Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeParameterType)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(value, context.CancellationToken); if (!typeSymbol.IsKind(SymbolKind.ErrorType)) { CodeFixRegistrator.ChangeType(context, diagnostic, parameter.Type, typeSymbol, semanticModel); } } } break; } case CompilerDiagnosticIdentifiers.ObjectOfTypeConvertibleToTypeIsRequired: { if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ReturnDefaultValue)) { break; } if (token.Kind() != SyntaxKind.ReturnKeyword) { break; } if (!token.IsParentKind(SyntaxKind.ReturnStatement)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol symbol = semanticModel.GetEnclosingSymbol(token.SpanStart, context.CancellationToken); if (symbol == null) { break; } SymbolKind symbolKind = symbol.Kind; ITypeSymbol typeSymbol = null; if (symbolKind == SymbolKind.Method) { var methodSymbol = (IMethodSymbol)symbol; typeSymbol = methodSymbol.ReturnType; if (methodSymbol.IsAsync && (typeSymbol is INamedTypeSymbol namedTypeSymbol)) { ImmutableArray <ITypeSymbol> typeArguments = namedTypeSymbol.TypeArguments; if (typeArguments.Any()) { typeSymbol = typeArguments[0]; } } } else if (symbolKind == SymbolKind.Property) { typeSymbol = ((IPropertySymbol)symbol).Type; } else { Debug.Fail(symbolKind.ToString()); } if (typeSymbol == null) { break; } if (typeSymbol.Kind == SymbolKind.ErrorType) { break; } if (!typeSymbol.SupportsExplicitDeclaration()) { break; } var returnStatement = (ReturnStatementSyntax)token.Parent; CodeAction codeAction = CodeAction.Create( "Return default value", cancellationToken => { ExpressionSyntax expression = typeSymbol.GetDefaultValueSyntax(context.Document.GetDefaultSyntaxOptions()); if (expression.IsKind(SyntaxKind.DefaultExpression) && context.Document.SupportsLanguageFeature(CSharpLanguageFeature.DefaultLiteral)) { expression = CSharpFactory.DefaultLiteralExpression().WithTriviaFrom(expression); } ReturnStatementSyntax newNode = returnStatement.WithExpression(expression); return(context.Document.ReplaceNodeAsync(returnStatement, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.TypeExpected: { if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddMissingType)) { break; } if (token.Kind() != SyntaxKind.CloseParenToken) { break; } if (!(token.Parent is DefaultExpressionSyntax defaultExpression)) { break; } if (!(defaultExpression.Type is IdentifierNameSyntax identifierName)) { break; } if (!identifierName.IsMissing) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeInfo typeInfo = semanticModel.GetTypeInfo(defaultExpression, context.CancellationToken); ITypeSymbol convertedType = typeInfo.ConvertedType; if (convertedType?.SupportsExplicitDeclaration() != true) { break; } CodeAction codeAction = CodeAction.Create( $"Add type '{SymbolDisplay.ToMinimalDisplayString(convertedType, semanticModel, defaultExpression.SpanStart, SymbolDisplayFormats.DisplayName)}'", ct => { TypeSyntax newType = convertedType.ToTypeSyntax() .WithTriviaFrom(identifierName) .WithFormatterAndSimplifierAnnotation(); return(context.Document.ReplaceNodeAsync(identifierName, newType, ct)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.SemicolonAfterMethodOrAccessorBlockIsNotValid: { if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveSemicolon)) { break; } if (token.Kind() != SyntaxKind.SemicolonToken) { break; } switch (token.Parent) { case MethodDeclarationSyntax methodDeclaration: { BlockSyntax body = methodDeclaration.Body; if (body == null) { break; } CodeAction codeAction = CodeAction.Create( "Remove semicolon", cancellationToken => { SyntaxTriviaList trivia = body .GetTrailingTrivia() .EmptyIfWhitespace() .AddRange(token.LeadingTrivia.EmptyIfWhitespace()) .AddRange(token.TrailingTrivia); MethodDeclarationSyntax newNode = methodDeclaration .WithBody(body.WithTrailingTrivia(trivia)) .WithSemicolonToken(default(SyntaxToken)); return(context.Document.ReplaceNodeAsync(methodDeclaration, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case PropertyDeclarationSyntax propertyDeclaration: { AccessorListSyntax accessorList = propertyDeclaration.AccessorList; if (accessorList == null) { break; } CodeAction codeAction = CodeAction.Create( "Remove semicolon", cancellationToken => { SyntaxTriviaList trivia = accessorList .GetTrailingTrivia() .EmptyIfWhitespace() .AddRange(token.LeadingTrivia.EmptyIfWhitespace()) .AddRange(token.TrailingTrivia); PropertyDeclarationSyntax newNode = propertyDeclaration .WithAccessorList(accessorList.WithTrailingTrivia(trivia)) .WithSemicolonToken(default(SyntaxToken)); return(context.Document.ReplaceNodeAsync(propertyDeclaration, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case AccessorDeclarationSyntax accessorDeclaration: { BlockSyntax body = accessorDeclaration.Body; if (body == null) { break; } CodeAction codeAction = CodeAction.Create( "Remove semicolon", cancellationToken => { SyntaxTriviaList trivia = body .GetTrailingTrivia() .EmptyIfWhitespace() .AddRange(token.LeadingTrivia.EmptyIfWhitespace()) .AddRange(token.TrailingTrivia); AccessorDeclarationSyntax newNode = accessorDeclaration .WithBody(body.WithTrailingTrivia(trivia)) .WithSemicolonToken(default(SyntaxToken)); return(context.Document.ReplaceNodeAsync(accessorDeclaration, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } break; } case CompilerDiagnosticIdentifiers.CannotConvertType: { if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeForEachType)) { break; } if (token.Kind() != SyntaxKind.ForEachKeyword) { break; } if (!(token.Parent is ForEachStatementSyntax forEachStatement)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); ITypeSymbol typeSymbol = info.ElementType; if (typeSymbol.SupportsExplicitDeclaration()) { CodeFixRegistrator.ChangeType(context, diagnostic, forEachStatement.Type, typeSymbol, semanticModel, CodeFixIdentifiers.ChangeForEachType); } CodeFixRegistrator.ChangeTypeToVar(context, diagnostic, forEachStatement.Type, CodeFixIdentifiers.ChangeTypeToVar); break; } case CompilerDiagnosticIdentifiers.OptionalParametersMustAppearAfterAllRequiredParameters: { if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddDefaultValueToParameter)) { break; } if (!(token.Parent is BaseParameterListSyntax parameterList)) { break; } SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters; ParameterSyntax parameter = null; for (int i = 0; i < parameters.Count; i++) { ParameterSyntax p = parameters[i]; if (p.FullSpan.End <= token.SpanStart) { parameter = p; } else { break; } } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); IParameterSymbol parameterSymbol = semanticModel.GetDeclaredSymbol(parameter, context.CancellationToken); ITypeSymbol typeSymbol = parameterSymbol.Type; if (typeSymbol.Kind == SymbolKind.ErrorType) { break; } CodeAction codeAction = CodeAction.Create( "Add default value", cancellationToken => { ExpressionSyntax defaultValue = typeSymbol.GetDefaultValueSyntax(context.Document.GetDefaultSyntaxOptions()); ParameterSyntax newParameter = parameter .WithDefault(EqualsValueClause(defaultValue).WithTrailingTrivia(parameter.GetTrailingTrivia())) .WithoutTrailingTrivia() .WithFormatterAnnotation(); return(context.Document.ReplaceNodeAsync(parameter, newParameter, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
public override void VisitAccessorDeclaration(AccessorDeclarationSyntax node) { VisitBlock(node.Body); }
private static bool IsMultiline(AccessorDeclarationSyntax accessorDeclaration) { var lineSpan = accessorDeclaration.GetLineSpan(); return(lineSpan.StartLinePosition.Line != lineSpan.EndLinePosition.Line); }
private static void AnalyzeAccessorDeclarationBlock( SyntaxNodeAnalysisContext context, AccessorDeclarationSyntax accessor, BlockSyntax body) { if (body.ContainsDirectives) return; if (accessor.AttributeLists.Any()) return; BodyStyle style = context.GetBodyStyle(); if (style.IsDefault) return; bool isGetter = accessor.IsKind(SyntaxKind.GetAccessorDeclaration); BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(body, allowExpressionStatement: !isGetter); ExpressionSyntax expression = analysis.Expression; if (expression == null) return; if (!style.UseExpression) return; if (style.UseBlockWhenExpressionIsMultiLine == true && expression.IsMultiLine()) { return; } if (isGetter && accessor.Parent is AccessorListSyntax accessorList && accessorList.Accessors.Count == 1) { if (!SyntaxTriviaAnalysis.IsExteriorTriviaEmptyOrWhitespace(accessorList.OpenBraceToken)) return; if (!SyntaxTriviaAnalysis.IsExteriorTriviaEmptyOrWhitespace(accessor.Keyword)) return; if (!SyntaxTriviaAnalysis.IsExteriorTriviaEmptyOrWhitespace(body.OpenBraceToken)) return; if (style.UseBlockWhenDeclarationIsMultiLine == true) { switch (accessorList.Parent.Kind()) { case SyntaxKind.PropertyDeclaration: { if (accessor.SyntaxTree.IsMultiLineSpan(((PropertyDeclarationSyntax)accessorList.Parent).HeaderSpan())) return; break; } case SyntaxKind.IndexerDeclaration: { if (accessor.SyntaxTree.IsMultiLineSpan(((IndexerDeclarationSyntax)accessorList.Parent).HeaderSpan())) return; break; } default: { SyntaxDebug.Fail(accessorList.Parent); break; } } return; } ReportDiagnostic(context, accessorList); return; } if (!accessor.Keyword.TrailingTrivia.IsEmptyOrWhitespace()) return; if (!SyntaxTriviaAnalysis.IsExteriorTriviaEmptyOrWhitespace(body.OpenBraceToken)) return; if (!accessor.Keyword.LeadingTrivia.IsEmptyOrWhitespace()) return; ReportDiagnostic(context, body); }
internal static bool TryGetAccessorDeclaration(this BasePropertyDeclarationSyntax property, SyntaxKind kind, out AccessorDeclarationSyntax result) { result = null; var accessors = property?.AccessorList?.Accessors; if (accessors == null) { return(false); } foreach (var accessor in accessors.Value) { if (accessor.IsKind(kind)) { result = accessor; return(true); } } return(false); }
internal static bool TryGetSetAccessorDeclaration(this BasePropertyDeclarationSyntax property, out AccessorDeclarationSyntax result) { return(TryGetAccessorDeclaration(property, SyntaxKind.SetAccessorDeclaration, out result)); }
public static void AnalyzePropertyDeclaration(SyntaxNodeAnalysisContext context) { var property = (PropertyDeclarationSyntax)context.Node; if (property.ContainsDiagnostics) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IFieldSymbol fieldSymbol = null; AccessorDeclarationSyntax getter = null; AccessorDeclarationSyntax setter = null; ArrowExpressionClauseSyntax expressionBody = property.ExpressionBody; if (expressionBody != null) { IdentifierNameSyntax identifierName = GetIdentifierNameFromExpression(expressionBody.Expression); if (identifierName != null) { fieldSymbol = GetBackingFieldSymbol(identifierName, semanticModel, cancellationToken); } } else { getter = property.Getter(); if (getter != null) { setter = property.Setter(); if (setter != null) { fieldSymbol = GetBackingFieldSymbol(getter, setter, semanticModel, cancellationToken); } else { IdentifierNameSyntax identifierName = GetIdentifierNameFromGetter(getter); if (identifierName != null) { fieldSymbol = GetBackingFieldSymbol(identifierName, semanticModel, cancellationToken); } } } } if (fieldSymbol == null) { return; } var variableDeclarator = (VariableDeclaratorSyntax)fieldSymbol.GetSyntax(cancellationToken); if (variableDeclarator.SyntaxTree != property.SyntaxTree) { return; } if (!CheckPreprocessorDirectives(property)) { return; } if (!CheckPreprocessorDirectives(variableDeclarator)) { return; } IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(property, cancellationToken); if (propertySymbol?.IsStatic != fieldSymbol.IsStatic) { return; } if (!propertySymbol.ExplicitInterfaceImplementations.IsDefaultOrEmpty) { return; } if (!propertySymbol.Type.Equals(fieldSymbol.Type)) { return; } if (propertySymbol.ContainingType?.Equals(fieldSymbol.ContainingType) != true) { return; } if (setter == null && propertySymbol.IsOverride && propertySymbol.OverriddenProperty?.SetMethod != null) { return; } cancellationToken.ThrowIfCancellationRequested(); foreach (AttributeData attributeData in fieldSymbol.GetAttributes()) { if (attributeData.AttributeClass.HasMetadataName(MetadataNames.System_NonSerializedAttribute)) { return; } } if (HasStructLayoutAttributeWithExplicitKind(propertySymbol.ContainingType)) { return; } if (!IsFixableBackingField(property, propertySymbol, fieldSymbol, context.Compilation, semanticModel, cancellationToken)) { return; } context.ReportDiagnostic(DiagnosticDescriptors.UseAutoProperty, property.Identifier); if (property.ExpressionBody != null) { context.ReportNode(DiagnosticDescriptors.UseAutoPropertyFadeOut, property.ExpressionBody); } else { if (getter != null) { FadeOut(getter); } if (setter != null) { FadeOut(setter); } } void FadeOut(AccessorDeclarationSyntax accessor) { BlockSyntax body = accessor.Body; if (body != null) { switch (body.Statements.First()) { case ReturnStatementSyntax returnStatement: { context.ReportToken(DiagnosticDescriptors.UseAutoPropertyFadeOut, returnStatement.ReturnKeyword); context.ReportNode(DiagnosticDescriptors.UseAutoPropertyFadeOut, returnStatement.Expression); break; } case ExpressionStatementSyntax expressionStatement: { context.ReportNode(DiagnosticDescriptors.UseAutoPropertyFadeOut, expressionStatement.Expression); break; } } context.ReportBraces(DiagnosticDescriptors.UseAutoPropertyFadeOut, body); } else { context.ReportNode(DiagnosticDescriptors.UseAutoPropertyFadeOut, accessor.ExpressionBody); } } }
private static IdentifierNameSyntax?GetIdentifierUsedInGetter(AccessorDeclarationSyntax getter) { if (getter.Body is { Statements : { Count : 1 } } && getter.Body.Statements[0] is ReturnStatementSyntax returnStatement)
private static bool OnlyThrows(AccessorDeclarationSyntax accessor) => (accessor.Body?.Statements.Count == 1 && accessor.Body.Statements[0] is ThrowStatementSyntax) || ThrowExpressionSyntaxWrapper.IsInstance(accessor.ExpressionBody()?.Expression);
protected IEnumerable <CodeAction> GetActions(Document document, SyntaxNode root, MethodDeclarationSyntax methodNode, AccessorDeclarationSyntax getterNode) { if (methodNode != null) { return(GetActions(document, root, methodNode)); } if (getterNode != null) { return(GetActions(document, root, getterNode)); } return(Enumerable.Empty <CodeAction>()); }
public static BlockExpressionAnalysis Create(AccessorDeclarationSyntax accessor) { return(Create(accessor.Body)); }
public static string AccessorDeclaration(AccessorDeclarationSyntax node) { //TODO: implement this return(SyntaxNode(node.Body)); }
public override void VisitAccessorDeclaration(AccessorDeclarationSyntax node) { AddLocation(node.Keyword); base.VisitAccessorDeclaration(node); }
private static bool IsAutoAccessor(AccessorDeclarationSyntax accessor) { return(accessor.Body == null && accessor.ExpressionBody == null); }
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out SemanticModel speculativeModel) { return(GetSpeculativeSemanticModelForMethodBody(parentModel, position, accessor.Body, out speculativeModel)); }
public override void VisitAccessorDeclaration(AccessorDeclarationSyntax node) { Visit(node.Body); Visit(node.ExpressionBody); }
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out SemanticModel speculativeModel) { throw ExceptionUtilities.Unreachable; }
private static ExpressionSyntax GetExpressionOrThrowExpression(AccessorDeclarationSyntax accessor) { return(GetExpression(accessor.Body)); }
private SourcePropertyAccessorSymbol( NamedTypeSymbol containingType, string name, SourcePropertySymbol property, DeclarationModifiers propertyModifiers, ImmutableArray <MethodSymbol> explicitInterfaceImplementations, Location location, AccessorDeclarationSyntax syntax, MethodKind methodKind, bool isAutoPropertyAccessor, DiagnosticBag diagnostics) : base(containingType, syntax.GetReference(), syntax.Body.GetReferenceOrNull(), location) { this.property = property; this.explicitInterfaceImplementations = explicitInterfaceImplementations; this.name = name; this.isAutoPropertyAccessor = isAutoPropertyAccessor; bool modifierErrors; var declarationModifiers = this.MakeModifiers(syntax, location, diagnostics, out modifierErrors); // Include modifiers from the containing property. propertyModifiers &= ~DeclarationModifiers.AccessibilityMask; if ((declarationModifiers & DeclarationModifiers.Private) != 0) { // Private accessors cannot be virtual. propertyModifiers &= ~DeclarationModifiers.Virtual; } declarationModifiers |= propertyModifiers; // ReturnsVoid property is overridden in this class so // returnsVoid argument to MakeFlags is ignored. this.flags = MakeFlags(methodKind, declarationModifiers, returnsVoid: false, isExtensionMethod: false, isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any()); var bodyOpt = syntax.Body; if (bodyOpt != null) { if (containingType.IsInterface) { diagnostics.Add(ErrorCode.ERR_InterfaceMemberHasBody, location, this); } else if (IsExtern && !IsAbstract) { diagnostics.Add(ErrorCode.ERR_ExternHasBody, location, this); } else if (IsAbstract && !IsExtern) { diagnostics.Add(ErrorCode.ERR_AbstractHasBody, location, this); } // Do not report error for IsAbstract && IsExtern. Dev10 reports CS0180 only // in that case ("member cannot be both extern and abstract"). } var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers); if (info != null) { diagnostics.Add(info, location); } if (!modifierErrors) { this.CheckModifiers(location, isAutoPropertyAccessor, diagnostics); } if (this.IsOverride) { MethodSymbol overriddenMethod = this.OverriddenMethod; if ((object)overriddenMethod != null) { // If this accessor is overriding a method from metadata, it is possible that // the name of the overridden method doesn't follow the C# get_X/set_X pattern. // We should copy the name so that the runtime will recognize this as an override. this.name = overriddenMethod.Name; } } }
internal override bool TryGetSpeculativeSemanticModelForMethodBodyCore(SyntaxTreeSemanticModel parentModel, int position, AccessorDeclarationSyntax accessor, out SemanticModel speculativeModel) { speculativeModel = null; return(false); }
private void HandleProperty(SyntaxNodeAnalysisContext context) { var propertyDeclaration = (PropertyDeclarationSyntax)context.Node; if (propertyDeclaration.ExpressionBody != null) { return; } foreach (var declaration in propertyDeclaration.DescendantNodesAndTokensAndSelf()) { foreach (var trivia in declaration.GetLeadingTrivia()) { if (!trivia.IsWhitespaceTrivia()) { return; } } foreach (var trivia in declaration.GetTrailingTrivia()) { if (!trivia.IsWhitespaceTrivia()) { return; } } } foreach (var accessor in propertyDeclaration.AccessorList.Accessors) { if (accessor.Keyword.IsKind(SyntaxKind.SetKeyword)) { return; } } AccessorDeclarationSyntax getter = null; foreach (var accessor in propertyDeclaration.AccessorList.Accessors) { if (accessor.Keyword.IsKind(SyntaxKind.GetKeyword)) { getter = accessor; break; } } if (getter == null) { return; } foreach (var list in getter.AttributeLists) { if (list.Attributes.Any()) { return; } } if (getter.Body?.Statements.Count != 1) { return; } if (!Nodes.Contains(getter.Body.Statements[0].Kind())) { return; } var statement = getter.Body.Statements.First(); context.ReportDiagnostic(Diagnostic.Create(Rule, statement.GetLocation(), "Property", propertyDeclaration.Identifier)); }
private static IEnumerable <SyntaxKind> GetModifierKinds(AccessorDeclarationSyntax accessor) { return(accessor.Modifiers.Select(m => m.Kind())); }
private static SyntaxNode ReformatAccessorAsSingleLine(IndentationSettings indentationSettings, AccessorDeclarationSyntax accessor) { var newAccessor = accessor .WithModifiers(ReformatModifiersAsSingleLine(accessor.Modifiers)) .WithKeyword(ReformatKeywordAsSingleLine(accessor.Keyword)) .WithBody(ReformatBodyAsSingleLine(accessor.Body)); var accessorList = (AccessorListSyntax)accessor.Parent; var indentationSteps = IndentationHelper.GetIndentationSteps(indentationSettings, accessorList.OpenBraceToken); var indentation = IndentationHelper.GenerateWhitespaceTrivia(indentationSettings, indentationSteps + 1); newAccessor = newAccessor.WithLeadingTrivia(newAccessor.GetLeadingTrivia().Insert(0, indentation)); return(newAccessor); }
public virtual void VisitAccessorDeclaration(AccessorDeclarationSyntax node) { DefaultVisit(node); }
public void VisitAccessorDeclaration(AccessorDeclarationSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); WriteLeadingTrivia(node); var accessorList = node.Parent as AccessorListSyntax; bool isSimple = _writer.Configuration.LineBreaksAndWrapping.Other.PlaceAbstractAutoPropertyIndexerEventDeclarationOnSingleLine && accessorList != null && accessorList.Accessors.All(p => (!HasExtras(p) || _writer.Configuration.LineBreaksAndWrapping.Other.PlaceSingleLineAccessorAttributeOnSameLine) && p.Body == null ); if (!isSimple) { isSimple = _writer.Configuration.LineBreaksAndWrapping.Other.PlaceSimplePropertyIndexerEventDeclarationOnSingleLine && accessorList != null && accessorList.Accessors.All(p => (!HasExtras(p) || _writer.Configuration.LineBreaksAndWrapping.Other.PlaceSingleLineAccessorAttributeOnSameLine) && IsSimpleBody(p.Body) ); } if (!isSimple) _writer.WriteIndent(); bool isBodySimple = node.Body == null || IsSimpleBody(node.Body); WriteAttributes( node, _writer.Configuration.LineBreaksAndWrapping.Other.PlaceMethodAttributeOnSameLine || ( isBodySimple ? _writer.Configuration.LineBreaksAndWrapping.Other.PlaceSingleLineAccessorAttributeOnSameLine : _writer.Configuration.LineBreaksAndWrapping.Other.PlaceMultiLineAccessorAttributeOnSameLine ) ); if (node.Modifiers != Modifiers.None) { _writer.WriteModifiers(node.Modifiers); _writer.WriteSpace(); } switch (node.Kind) { case AccessorDeclarationKind.Add: _writer.WriteKeyword(PrinterKeyword.Add); break; case AccessorDeclarationKind.Get: _writer.WriteKeyword(PrinterKeyword.Get); break; case AccessorDeclarationKind.Remove: _writer.WriteKeyword(PrinterKeyword.Remove); break; case AccessorDeclarationKind.Set: _writer.WriteKeyword(PrinterKeyword.Set); break; default: throw new InvalidOperationException("Invalid enum value"); } if (node.Body != null) { if ( isSimple || ( _writer.Configuration.LineBreaksAndWrapping.Other.PlaceSimpleAccessorOnSingleLine && isBodySimple ) ) { _writer.PushSingleLineBody(true); node.Body.Accept(this); if (!isSimple) _writer.WriteLine(); _writer.PopSingleLineBody(); } else { node.Body.Accept(this); } } else { _writer.WriteSyntax(Syntax.Semicolon); if (!isSimple) _writer.WriteLine(); } WriteTrailingTrivia(node); }