public static MethodDeclarationSyntax MethodDeclaration( SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, TypeSyntax returnType, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, ParameterListSyntax parameterList, SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses, BlockSyntax body, SyntaxToken semicolonToken) { return SyntaxFactory.MethodDeclaration( attributeLists, modifiers, default(SyntaxToken), returnType, explicitInterfaceSpecifier, identifier, typeParameterList, parameterList, constraintClauses, body, default(ArrowExpressionClauseSyntax), semicolonToken); }
/// <summary> /// Only valid for field/constructor/property/method /// </summary> /// <param name="syntax"></param> /// <returns></returns> public static bool IsStaticMember(this MemberDeclarationSyntax syntax) { SyntaxTokenList modifiers = new SyntaxTokenList(); switch (syntax.Kind()) { case SyntaxKind.FieldDeclaration: var field = syntax as FieldDeclarationSyntax; modifiers = field.Modifiers; break; case SyntaxKind.PropertyDeclaration: var property = syntax as PropertyDeclarationSyntax; modifiers = property.Modifiers; break; case SyntaxKind.MethodDeclaration: var method = syntax as MethodDeclarationSyntax; modifiers = method.Modifiers; break; case SyntaxKind.ConstructorDeclaration: var ctor = syntax as ConstructorDeclarationSyntax; modifiers = ctor.Modifiers; break; } foreach (var modifier in modifiers) { if (modifier.Kind() == SyntaxKind.StaticKeyword) return true; } return false; }
private static TextSpan CreateSpan(SyntaxTokenList startOpt, SyntaxNodeOrToken startFallbackOpt, SyntaxNodeOrToken endOpt) { Debug.Assert(startFallbackOpt != default(SyntaxNodeOrToken) || endOpt != default(SyntaxNodeOrToken)); int startPos; if (startOpt.Count > 0) { startPos = startOpt.First().SpanStart; } else if (startFallbackOpt != default(SyntaxNodeOrToken)) { startPos = startFallbackOpt.SpanStart; } else { startPos = endOpt.SpanStart; } int endPos; if (endOpt != default(SyntaxNodeOrToken)) { endPos = GetEndPosition(endOpt); } else { endPos = GetEndPosition(startFallbackOpt); } return TextSpan.FromBounds(startPos, endPos); }
static void AdjustAccessibility (SyntaxTokenList modifiers, ref Accessibility acc, ref bool isStatic, ref bool result) { isStatic = modifiers.Any (mod => mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.StaticKeyword); if (modifiers.Any (mod => mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.ProtectedKeyword) && modifiers.Any (mod => mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.InternalKeyword)) { acc = Accessibility.ProtectedOrInternal; result = true; return; } foreach (var mod in modifiers) { if (mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.PublicKeyword) { acc = Accessibility.Public; result = true; return; } if (mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrivateKeyword) { acc = Accessibility.Private; result = true; return; } if (mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.ProtectedKeyword) { acc = Accessibility.Protected; result = true; return; } if (mod.Kind () == Microsoft.CodeAnalysis.CSharp.SyntaxKind.InternalKeyword) { acc = Accessibility.Internal; result = true; return; } } }
static void HandleDefaultModifier(SyntaxNodeAnalysisContext context, SyntaxTokenList modifiers, SyntaxKind defaultModifier) { var index = modifiers.IndexOf(defaultModifier); if (index != -1) { context.ReportDiagnostic(Diagnostic.Create(Rule, modifiers[index].GetLocation())); } }
private static async Task<Document> ChangeTypeAccessibilityInDocumentAsync(Solution solution, SyntaxTokenList newAccessibilityModifiers, Location typeLocation, CancellationToken cancellationToken) { var document = solution.GetDocument(typeLocation.SourceTree); var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = ChangeTypeAccessibilityInSyntaxRoot(syntaxRoot, newAccessibilityModifiers, typeLocation, cancellationToken); return document.WithSyntaxRoot(newRoot); }
public static XmlTextAttributeSyntax TextAttribute(XmlNameSyntax name, SyntaxKind quoteKind, SyntaxTokenList textTokens) { return SyntaxFactory.XmlTextAttribute( name, SyntaxFactory.Token(quoteKind), textTokens, SyntaxFactory.Token(quoteKind)) .WithLeadingTrivia(SyntaxFactory.Whitespace(" ")); }
void MarkUnsafe(SyntaxTokenList modifiers, bool isUnsafe) { var state = unsafeStateStack.Pop(); if (isUnsafe && !state.UseUnsafeConstructs) { ctx.ReportDiagnostic(Diagnostic.Create( descriptor, modifiers.First(m => m.IsKind(SyntaxKind.UnsafeKeyword)).GetLocation() )); } }
public static PropertyDeclarationSyntax PropertyDeclaration(SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, SyntaxToken identifier, AccessorListSyntax accessorList, ArrowExpressionClauseSyntax expressionBody, EqualsValueClauseSyntax initializer, SyntaxToken semicolonToken) { return PropertyDeclaration( attributeLists, modifiers, refKeyword: default(SyntaxToken), type: type, explicitInterfaceSpecifier: explicitInterfaceSpecifier, identifier: identifier, accessorList: accessorList, expressionBody: expressionBody, initializer: initializer, semicolonToken: semicolonToken); }
public static TypeDeclarationSyntax TypeDeclaration(SyntaxKind kind, SyntaxList<AttributeListSyntax> attributes, SyntaxTokenList modifiers, SyntaxToken keyword, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, BaseListSyntax baseList, SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses, SyntaxToken openBraceToken, SyntaxList<MemberDeclarationSyntax> members, SyntaxToken closeBraceToken, SyntaxToken semicolonToken) { switch (kind) { case SyntaxKind.ClassDeclaration: return SyntaxFactory.ClassDeclaration(attributes, modifiers, keyword, identifier, typeParameterList, baseList, constraintClauses, openBraceToken, members, closeBraceToken, semicolonToken); case SyntaxKind.StructDeclaration: return SyntaxFactory.StructDeclaration(attributes, modifiers, keyword, identifier, typeParameterList, baseList, constraintClauses, openBraceToken, members, closeBraceToken, semicolonToken); case SyntaxKind.InterfaceDeclaration: return SyntaxFactory.InterfaceDeclaration(attributes, modifiers, keyword, identifier, typeParameterList, baseList, constraintClauses, openBraceToken, members, closeBraceToken, semicolonToken); default: throw new ArgumentException("kind"); } }
// This code was copied from the Roslyn code base (and slightly modified). It can be removed if // TypeDeclarationSyntaxExtensions.WithModifiers is made public (Roslyn issue #2186) private static TypeDeclarationSyntax ReplaceModifiers(TypeDeclarationSyntax node, SyntaxTokenList modifiers) { switch (node.Kind()) { case SyntaxKind.ClassDeclaration: return ((ClassDeclarationSyntax)node).WithModifiers(modifiers); case SyntaxKind.InterfaceDeclaration: return ((InterfaceDeclarationSyntax)node).WithModifiers(modifiers); case SyntaxKind.StructDeclaration: return ((StructDeclarationSyntax)node).WithModifiers(modifiers); } return node; }
public static DelegateDeclarationSyntax DelegateDeclaration(SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, SyntaxToken delegateKeyword, TypeSyntax returnType, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, ParameterListSyntax parameterList, SyntaxList<TypeParameterConstraintClauseSyntax> constraintClauses, SyntaxToken semicolonToken) { return DelegateDeclaration( attributeLists, modifiers, delegateKeyword, refKeyword: default(SyntaxToken), returnType: returnType, identifier: identifier, typeParameterList: typeParameterList, parameterList: parameterList, constraintClauses: constraintClauses, semicolonToken: semicolonToken); }
public static TypeDeclarationSyntax WithModifiers( this TypeDeclarationSyntax node, SyntaxTokenList modifiers) { switch (node.Kind()) { case SyntaxKind.ClassDeclaration: return ((ClassDeclarationSyntax)node).WithModifiers(modifiers); case SyntaxKind.InterfaceDeclaration: return ((InterfaceDeclarationSyntax)node).WithModifiers(modifiers); case SyntaxKind.StructDeclaration: return ((StructDeclarationSyntax)node).WithModifiers(modifiers); } throw new InvalidOperationException (); }
public static TypeDeclarationSyntax WithModifiers( this TypeDeclarationSyntax node, SyntaxTokenList modifiers) { switch (node.CSharpKind()) { case SyntaxKind.ClassDeclaration: return ((ClassDeclarationSyntax)node).WithModifiers(modifiers); case SyntaxKind.InterfaceDeclaration: return ((InterfaceDeclarationSyntax)node).WithModifiers(modifiers); case SyntaxKind.StructDeclaration: return ((StructDeclarationSyntax)node).WithModifiers(modifiers); } throw Contract.Unreachable; }
public static DestructorDeclarationSyntax DestructorDeclaration( SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, SyntaxToken identifier, ParameterListSyntax parameterList, ArrowExpressionClauseSyntax expressionBody) => DestructorDeclaration( attributeLists, modifiers, SyntaxFactory.Token(SyntaxKind.TildeToken), identifier, parameterList, default(BlockSyntax), expressionBody, default(SyntaxToken));
protected void ProcessAttribute(SyntaxNodeAnalysisContext context, SyntaxTokenList textTokens) { var token = textTokens.First(); if (token.Span.Length >= 2) { var text = token.Text; if (text[1] == ':') { var location = Location.Create(token.SyntaxTree, textTokens.Span); context.ReportDiagnostic(Diagnostic.Create(Rule, location, text.Substring(0, 2))); } } }
/// <summary>Determines the access level for the given <paramref name="modifiers"/>.</summary> /// <param name="modifiers">The modifiers.</param> /// <returns>A <see cref="AccessLevel"/> value representing the access level.</returns> internal static AccessLevel GetAccessLevel(SyntaxTokenList modifiers) { bool isProtected = false; bool isInternal = false; foreach (var modifier in modifiers) { switch (modifier.Kind()) { case SyntaxKind.PublicKeyword: return AccessLevel.Public; case SyntaxKind.PrivateKeyword: return AccessLevel.Private; case SyntaxKind.InternalKeyword: if (isProtected) { return AccessLevel.ProtectedInternal; } else { isInternal = true; } break; case SyntaxKind.ProtectedKeyword: if (isInternal) { return AccessLevel.ProtectedInternal; } else { isProtected = true; } break; } } if (isProtected) { return AccessLevel.Protected; } else if (isInternal) { return AccessLevel.Internal; } return AccessLevel.NotSpecified; }
public static ConstructorDeclarationSyntax ConstructorDeclaration( SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, SyntaxToken identifier, ParameterListSyntax parameterList, ConstructorInitializerSyntax initializer, ArrowExpressionClauseSyntax expressionBody) => ConstructorDeclaration( attributeLists, modifiers, identifier, parameterList, initializer, default(BlockSyntax), expressionBody, default(SyntaxToken));
internal SyntaxTree(string sourceText, SyntaxNode root, SyntaxTokenList tokens, IReadOnlyList<TextLineExtent> textLines, IReadOnlyList<Diagnostic> diagnostics, FileInfo fileInfo, Encoding encoding) { _sourceText = sourceText ?? String.Empty; _root = root; _fileInfo = fileInfo; _encoding = encoding; _diagnostics = diagnostics ?? Enumerable.Empty<Diagnostic>().ToList(); _tokens = tokens ?? new SyntaxTokenList(); _textLines = textLines ?? new List<TextLineExtent>(); }
public static DestructorDeclarationSyntax DestructorDeclaration( SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, SyntaxToken tildeToken, SyntaxToken identifier, ParameterListSyntax parameterList, BlockSyntax body, SyntaxToken semicolonToken) => DestructorDeclaration( attributeLists, modifiers, tildeToken, identifier, parameterList, body, default(ArrowExpressionClauseSyntax), semicolonToken);
public ConstructorDeclarationSyntax Update( SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, SyntaxToken identifier, ParameterListSyntax parameterList, ConstructorInitializerSyntax initializer, BlockSyntax body, SyntaxToken semicolonToken) => Update( attributeLists, modifiers, identifier, parameterList, initializer, body, default(ArrowExpressionClauseSyntax), semicolonToken);
public static IndexerDeclarationSyntax IndexerDeclaration( SyntaxList<AttributeListSyntax> attributeLists, SyntaxTokenList modifiers, TypeSyntax type, ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifier, BracketedParameterListSyntax parameterList, AccessorListSyntax accessorList) { return SyntaxFactory.IndexerDeclaration( attributeLists: attributeLists, modifiers: modifiers, type: type, explicitInterfaceSpecifier: explicitInterfaceSpecifier, parameterList: parameterList, accessorList: accessorList, expressionBody: default(ArrowExpressionClauseSyntax)); }
private async Task<Document> AddPublicAccessModifierAsync(Document document, InterfaceDeclarationSyntax interfaceDeclaration, CancellationToken cancellationToken) { SyntaxTokenList newModifiers = new SyntaxTokenList(); newModifiers = newModifiers.Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); newModifiers = newModifiers.AddRange(interfaceDeclaration.Modifiers.Where(x => !x.IsKind(SyntaxKind.ProtectedKeyword) && !x.IsKind(SyntaxKind.InternalKeyword) && !x.IsKind(SyntaxKind.PrivateKeyword)) ); InterfaceDeclarationSyntax newInterfaceDeclaration = interfaceDeclaration.WithModifiers(newModifiers); SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken); SyntaxNode newRoot = root.ReplaceNode(interfaceDeclaration, newInterfaceDeclaration); return document.WithSyntaxRoot(newRoot); }
internal static DeclarationModifiers MakeAndCheckNontypeMemberModifiers( SyntaxTokenList modifiers, DeclarationModifiers defaultAccess, DeclarationModifiers allowedModifiers, Location errorLocation, DiagnosticBag diagnostics, out bool modifierErrors) { var result = modifiers.ToDeclarationModifiers(); result = CheckModifiers(result, allowedModifiers, errorLocation, diagnostics, out modifierErrors); if ((result & DeclarationModifiers.AccessibilityMask) == 0) { result |= defaultAccess; } return result; }
// TODO: CLSCompliantAttribute internal SourceEventSymbol( SourceMemberContainerTypeSymbol containingType, CSharpSyntaxNode syntax, SyntaxTokenList modifiers, ExplicitInterfaceSpecifierSyntax interfaceSpecifierSyntaxOpt, SyntaxToken nameTokenSyntax, DiagnosticBag diagnostics) { _location = nameTokenSyntax.GetLocation(); this.containingType = containingType; _syntaxRef = syntax.GetReference(); var isExplicitInterfaceImplementation = interfaceSpecifierSyntaxOpt != null; bool modifierErrors; _modifiers = MakeModifiers(modifiers, isExplicitInterfaceImplementation, _location, diagnostics, out modifierErrors); this.CheckAccessibility(_location, diagnostics); }
public static SyntaxTokenList Organize(SyntaxTokenList modifiers) { if (modifiers.Count > 1 && !modifiers.SpansPreprocessorDirective()) { var initialList = new List<SyntaxToken>(modifiers); var leadingTrivia = initialList.First().LeadingTrivia; initialList[0] = initialList[0].WithLeadingTrivia(SpecializedCollections.EmptyEnumerable<SyntaxTrivia>()); var finalList = initialList.OrderBy(new Comparer()).ToList(); if (!initialList.SequenceEqual(finalList)) { finalList[0] = finalList[0].WithLeadingTrivia(leadingTrivia); return finalList.ToSyntaxTokenList(); } } return modifiers; }
/// <summary> /// Generic Field declaration creation. /// </summary> /// <param name="type">Field type.</param> /// <param name="fieldVariableName">Name of the field.</param> /// <param name="modifiers">Modifiers - null creates public modifier list</param> /// <returns>Complete field declaration syntax.</returns> public static FieldDeclarationSyntax GenericFieldDeclaration(Type type, string fieldVariableName, SyntaxTokenList? modifiers = null) { if(modifiers == null) { modifiers = SyntaxFactory.TokenList( SyntaxFactory.Token(SyntaxKind.PublicKeyword) ); } return SyntaxFactory.FieldDeclaration( SyntaxFactory.VariableDeclaration( GenericTypeSyntax(type), SyntaxFactory.SingletonSeparatedList( SyntaxFactory.VariableDeclarator( SyntaxFactory.Identifier(fieldVariableName) ) ) ) ).WithModifiers(modifiers.Value); }
public static void GenerateClass(string namespaceName, string className, SyntaxTree syntaxTree) { var attributeList = new SyntaxList<AttributeListSyntax>(); var modifiers = new SyntaxTokenList() .Add(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .Add(SyntaxFactory.Token(SyntaxKind.OverrideKeyword)); var returnType = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)); var identifier = SyntaxFactory.Identifier("ToHashCode"); var typeParameterListSyntax = SyntaxFactory.TypeParameterList(); var parameterList = SyntaxFactory.ParameterList(); var typeParameterConstraints = new SyntaxList<TypeParameterConstraintClauseSyntax>(); var block = GenerateBlock(syntaxTree); var semicolonToken = SyntaxFactory.Token(SyntaxKind.SemicolonToken); var methodDecl = SyntaxFactory.MethodDeclaration( attributeLists: attributeList, modifiers: modifiers, returnType: returnType, explicitInterfaceSpecifier: null, identifier: identifier, typeParameterList: null, parameterList: parameterList, constraintClauses: typeParameterConstraints, body: block, semicolonToken: semicolonToken); CompilationUnitSyntax compilationUnit = SyntaxFactory.CompilationUnit() .AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName("System"))) .AddMembers(SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(namespaceName)) .AddMembers(SyntaxFactory.ClassDeclaration(className) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword)) .AddMembers(methodDecl))); SyntaxNode formattedNode = Formatter.Format(compilationUnit, new AdhocWorkspace()); StringBuilder sb = new StringBuilder(); using (StringWriter writer = new StringWriter(sb)) { formattedNode.WriteTo(writer); Console.WriteLine( ); } }
private const string _set = "";//"set"; static void WriteRegion(bool get, string body, ITypeSymbol iface, OutputWriter writer, string typeString, string name, SyntaxTokenList modifiers, string parameters, bool isindexer, bool hasGetter) { //no inline in D // if (get) writer.Write((get ? (typeString) : (hasGetter ? typeString : "void")) + " "); // else // writer.Write("void "); if (!isindexer) { writer.Write( (get?(_get+name):(_set+(name))) + (get ? "(" + (iface != null ? (TypeProcessor.ConvertType(iface) + " __ig=null") : "") + ")" : "(" + typeString + " value " + (iface != null ? ("," + TypeProcessor.ConvertType(iface) + " __ig=null") : "") + ")") + " "); } else { writer.Write((name) + (get ? "(" + parameters + ")" : "(" + typeString + " value, " + parameters + ")") + ""); } if (modifiers.Any(SyntaxKind.AbstractKeyword) || body == null) writer.Write(";\r\n"); else { writer.WriteLine(); writer.OpenBrace(); writer.WriteLine(body); writer.CloseBrace(); writer.WriteLine(); } }
internal static void GetFirstLocalOrFieldBreakpointSpan(SyntaxTokenList modifiers, VariableDeclaratorSyntax declaratorSyntax, out SyntaxNode node, out TextSpan? part) { var declarationSyntax = (VariableDeclarationSyntax)declaratorSyntax.Parent; int start = modifiers.Any() ? modifiers[0].SpanStart : declarationSyntax.SpanStart; int end; if (declarationSyntax.Variables.Count == 1) { // [|int x = 1;|] // [|public static int x = 1;|] end = declarationSyntax.Parent.Span.End; } else { // [|int x = 1|], y = 2; // [|public static int x = 1|], y = 2; end = declaratorSyntax.Span.End; } part = TextSpan.FromBounds(start, end); node = declarationSyntax.Parent; }
public static bool IsConst(this SyntaxTokenList modifiers) { return(modifiers.Any(i => i.IsKind(SyntaxKind.ConstKeyword))); }
internal static DeclarationModifiers MakeModifiers(NamedTypeSymbol containingType, SyntaxToken firstIdentifier, SyntaxTokenList modifiers, DiagnosticBag diagnostics, out bool modifierErrors) { DeclarationModifiers defaultAccess = (containingType.IsInterface) ? DeclarationModifiers.Public : DeclarationModifiers.Private; DeclarationModifiers allowedModifiers = DeclarationModifiers.AccessibilityMask | DeclarationModifiers.Const | DeclarationModifiers.New | DeclarationModifiers.ReadOnly | DeclarationModifiers.Static | DeclarationModifiers.Volatile | DeclarationModifiers.Fixed | DeclarationModifiers.Unsafe | DeclarationModifiers.Abstract; // filtered out later var errorLocation = new SourceLocation(firstIdentifier); DeclarationModifiers result = ModifierUtils.MakeAndCheckNontypeMemberModifiers( modifiers, defaultAccess, allowedModifiers, errorLocation, diagnostics, out modifierErrors); if ((result & DeclarationModifiers.Abstract) != 0) { diagnostics.Add(ErrorCode.ERR_AbstractField, errorLocation); result &= ~DeclarationModifiers.Abstract; } if ((result & DeclarationModifiers.Fixed) != 0) { if ((result & DeclarationModifiers.Static) != 0) { // The modifier 'static' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.StaticKeyword)); } if ((result & DeclarationModifiers.ReadOnly) != 0) { // The modifier 'readonly' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); } if ((result & DeclarationModifiers.Const) != 0) { // The modifier 'const' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ConstKeyword)); } if ((result & DeclarationModifiers.Volatile) != 0) { // The modifier 'volatile' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword)); } result &= ~(DeclarationModifiers.Static | DeclarationModifiers.ReadOnly | DeclarationModifiers.Const | DeclarationModifiers.Volatile); Debug.Assert((result & ~(DeclarationModifiers.AccessibilityMask | DeclarationModifiers.Fixed | DeclarationModifiers.Unsafe | DeclarationModifiers.New)) == 0); } if ((result & DeclarationModifiers.Const) != 0) { if ((result & DeclarationModifiers.Static) != 0) { // The constant '{0}' cannot be marked static diagnostics.Add(ErrorCode.ERR_StaticConstant, errorLocation, firstIdentifier.ValueText); } if ((result & DeclarationModifiers.ReadOnly) != 0) { // The modifier 'readonly' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.ReadOnlyKeyword)); } if ((result & DeclarationModifiers.Volatile) != 0) { // The modifier 'volatile' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.VolatileKeyword)); } if ((result & DeclarationModifiers.Unsafe) != 0) { // The modifier 'unsafe' is not valid for this item diagnostics.Add(ErrorCode.ERR_BadMemberFlag, errorLocation, SyntaxFacts.GetText(SyntaxKind.UnsafeKeyword)); } result |= DeclarationModifiers.Static; // "constants are considered static members" } else { // NOTE: always cascading on a const, so suppress. // NOTE: we're being a bit sneaky here - we're using the containingType rather than this symbol // to determine whether or not unsafe is allowed. Since this symbol and the containing type are // in the same compilation, it won't make a difference. We do, however, have to pass the error // location explicitly. containingType.CheckUnsafeModifier(result, errorLocation, diagnostics); } return(result); }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindToken(root, context.Span.Start, out SyntaxToken token)) { return; } SyntaxNode node = token.Parent; if (!CSharpFacts.CanHaveModifiers(node.Kind())) { node = node.FirstAncestor(f => CSharpFacts.CanHaveModifiers(f.Kind())); } Debug.Assert(node != null, $"{nameof(node)} is null"); if (node == null) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.CS0106_ModifierIsNotValidForThisItem: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { break; } SyntaxTokenList modifiers = SyntaxInfo.ModifierListInfo(node).Modifiers; if (modifiers.Contains(token)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token); break; } else if (IsInterfaceMemberOrExplicitInterfaceImplementation(node)) { ModifiersCodeFixRegistrator.RemoveModifiers( context, diagnostic, node, modifiers, f => { switch (f.Kind()) { case SyntaxKind.PublicKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.InternalKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.StaticKeyword: case SyntaxKind.VirtualKeyword: case SyntaxKind.OverrideKeyword: case SyntaxKind.AbstractKeyword: { return(true); } } return(false); }); } else if (node.IsKind(SyntaxKind.MethodDeclaration, SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration) && node.IsParentKind(SyntaxKind.StructDeclaration, SyntaxKind.RecordStructDeclaration) && modifiers.Contains(SyntaxKind.VirtualKeyword)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword); } else if (node.IsKind(SyntaxKind.IndexerDeclaration) && modifiers.Contains(SyntaxKind.StaticKeyword)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword); } else if (node.IsKind(SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.EventDeclaration, SyntaxKind.EventFieldDeclaration) && modifiers.Contains(SyntaxKind.AsyncKeyword)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword); } break; } case CompilerDiagnosticIdentifiers.CS0107_MoreThanOneProtectionModifier: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, token); } break; } case CompilerDiagnosticIdentifiers.CS0275_AccessibilityModifiersMayNotBeUsedOnAccessorsInInterface: case CompilerDiagnosticIdentifiers.CS0515_AccessModifiersAreNotAllowedOnStaticConstructors: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveAccessibility(context, diagnostic, node); } break; } case CompilerDiagnosticIdentifiers.CS1609_ModifiersCannotBePlacedOnEventAccessorDeclarations: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifiers(context, diagnostic, node); } break; } case CompilerDiagnosticIdentifiers.CS0753_OnlyMethodsClassesStructsOrInterfacesMayBePartial: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword); } break; } case CompilerDiagnosticIdentifiers.CS0441_ClassCannotBeBothStaticAndSealed: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { break; } ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword)); ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword, additionalKey: nameof(SyntaxKind.SealedKeyword)); break; } case CompilerDiagnosticIdentifiers.CS0678_FieldCanNotBeBothVolatileAndReadOnly: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { break; } var fieldDeclaration = (FieldDeclarationSyntax)node; ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.VolatileKeyword, additionalKey: nameof(SyntaxKind.VolatileKeyword)); ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, fieldDeclaration, SyntaxKind.ReadOnlyKeyword, additionalKey: nameof(SyntaxKind.ReadOnlyKeyword)); break; } case CompilerDiagnosticIdentifiers.CS0628_NewProtectedMemberDeclaredInSealedClass: case CompilerDiagnosticIdentifiers.CS1057_StaticClassesCannotContainProtectedMembers: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrPrivate); } break; } case CompilerDiagnosticIdentifiers.CS0621_VirtualOrAbstractMembersCannotBePrivate: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveVirtualModifier, context.Document, root.SyntaxTree)) { ModifierListInfo modifierInfo = SyntaxInfo.ModifierListInfo(node); if (modifierInfo.IsVirtual) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword)); } } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected); } break; } case CompilerDiagnosticIdentifiers.CS0442_AbstractPropertiesCannotHavePrivateAccessors: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveAccessibility(context, diagnostic, node, additionalKey: CodeFixIdentifiers.RemoveInvalidModifier); } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternalOrProtected); } break; } case CompilerDiagnosticIdentifiers.CS0112_StaticMemberCannotBeMarkedOverrideVirtualOrAbstract: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { break; } if (!node.IsParentKind(SyntaxKind.ClassDeclaration) || !((ClassDeclarationSyntax)node.Parent).Modifiers.Contains(SyntaxKind.StaticKeyword)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.StaticKeyword, additionalKey: nameof(SyntaxKind.StaticKeyword)); } ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword, additionalKey: nameof(SyntaxKind.OverrideKeyword)); ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: nameof(SyntaxKind.VirtualKeyword)); ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword, additionalKey: nameof(SyntaxKind.AbstractKeyword)); break; } case CompilerDiagnosticIdentifiers.CS1994_AsyncModifierCanOnlyBeUsedInMethodsThatHaveBody: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.AsyncKeyword); } break; } case CompilerDiagnosticIdentifiers.CS0750_PartialMethodCannotHaveAccessModifiersOrVirtualAbstractOverrideNewSealedOrExternModifiers: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { break; } ModifiersCodeFixRegistrator.RemoveModifiers( context, diagnostic, node, f => { switch (f.Kind()) { case SyntaxKind.PublicKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.InternalKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.VirtualKeyword: case SyntaxKind.AbstractKeyword: case SyntaxKind.OverrideKeyword: case SyntaxKind.NewKeyword: case SyntaxKind.SealedKeyword: case SyntaxKind.ExternKeyword: { return(true); } } return(false); }); break; } case CompilerDiagnosticIdentifiers.CS1105_ExtensionMethodMustBeStatic: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree)) { AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier); } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier, context.Document, root.SyntaxTree)) { var methodDeclaration = (MethodDeclarationSyntax)node; ParameterSyntax parameter = methodDeclaration.ParameterList.Parameters[0]; SyntaxToken modifier = parameter.Modifiers.Find(SyntaxKind.ThisKeyword); ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, parameter, modifier, additionalKey: CodeFixIdentifiers.RemoveThisModifier); } break; } case CompilerDiagnosticIdentifiers.CS1106_ExtensionMethodMustBeDefinedInNonGenericStaticClass: { if (node is not ClassDeclarationSyntax classDeclaration) { return; } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree) && !classDeclaration.Modifiers.Contains(SyntaxKind.StaticKeyword)) { AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier); } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier, context.Document, root.SyntaxTree)) { IEnumerable <ParameterSyntax> thisParameters = classDeclaration.Members .Where(f => f.IsKind(SyntaxKind.MethodDeclaration)) .Cast <MethodDeclarationSyntax>() .Select(f => f.ParameterList?.Parameters.FirstOrDefault()) .Where(f => f?.Modifiers.Contains(SyntaxKind.ThisKeyword) == true); ModifiersCodeFixRegistrator.RemoveModifier( context, diagnostic, thisParameters, SyntaxKind.ThisKeyword, title: "Remove 'this' modifier from extension methods", additionalKey: CodeFixIdentifiers.RemoveThisModifier); } break; } case CompilerDiagnosticIdentifiers.CS0759_NoDefiningDeclarationFoundForImplementingDeclarationOfPartialMethod: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.PartialKeyword); } break; } case CompilerDiagnosticIdentifiers.CS1100_MethodHasParameterModifierThisWhichIsNotOnFirstParameter: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveThisModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, token.Parent, token); } break; } case CompilerDiagnosticIdentifiers.CS0708_CannotDeclareInstanceMembersInStaticClass: case CompilerDiagnosticIdentifiers.CS0710_StaticClassesCannotHaveInstanceConstructors: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree)) { AddStaticModifier(context, diagnostic, node, CodeFixIdentifiers.AddStaticModifier); } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassNonStatic, context.Document, root.SyntaxTree)) { var classDeclaration = (ClassDeclarationSyntax)node.Parent; ModifiersCodeFixRegistrator.RemoveModifier( context, diagnostic, classDeclaration, classDeclaration.Modifiers.Find(SyntaxKind.StaticKeyword), title: "Make containing class non-static", additionalKey: CodeFixIdentifiers.MakeContainingClassNonStatic); } break; } case CompilerDiagnosticIdentifiers.CS1527_ElementsDefinedInNamespaceCannotBeExplicitlyDeclaredAsPrivateProtectedOrProtectedInternal: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.ChangeAccessibility, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.ChangeAccessibility(context, diagnostic, node, _publicOrInternal); } break; } case CompilerDiagnosticIdentifiers.CS0101_NamespaceAlreadyContainsDefinition: case CompilerDiagnosticIdentifiers.CS0102_TypeAlreadyContainsDefinition: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddPartialModifier, context.Document, root.SyntaxTree)) { break; } if (!node.IsKind( SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.RecordStructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.MethodDeclaration)) { return; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ISymbol symbol = semanticModel.GetDeclaredSymbol(node, context.CancellationToken); ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences; if (syntaxReferences.Length <= 1) { break; } ModifiersCodeFixRegistrator.AddModifier( context, diagnostic, ImmutableArray.CreateRange(syntaxReferences, f => f.GetSyntax(context.CancellationToken)), SyntaxKind.PartialKeyword, title: $"Make {CSharpFacts.GetTitle(node)} partial"); break; } case CompilerDiagnosticIdentifiers.CS0115_NoSuitableMethodFoundToOverride: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveInvalidModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OverrideKeyword); } break; } case CompilerDiagnosticIdentifiers.CS1988_AsyncMethodsCannotHaveRefOrOutParameters: case CompilerDiagnosticIdentifiers.CS1623_IteratorsCannotHaveRefOrOutParameters: case CompilerDiagnosticIdentifiers.CS0192_ReadOnlyFieldCannotBePassedAsRefOrOutValue: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveRefModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.RefKeyword, additionalKey: nameof(SyntaxKind.RefKeyword)); } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveOutModifier, context.Document, root.SyntaxTree)) { ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.OutKeyword, additionalKey: nameof(SyntaxKind.OutKeyword)); } break; } case CompilerDiagnosticIdentifiers.CS0573_CannotHaveInstancePropertyOrFieldInitializersInStruct: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddStaticModifier, context.Document, root.SyntaxTree)) { AddStaticModifier(context, diagnostic, node); } break; } case CompilerDiagnosticIdentifiers.CS0501_MemberMustDeclareBodyBecauseItIsNotMarkedAbstractExternOrPartial: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.AddModifierAbstract, context.Document, root.SyntaxTree) && node.IsKind(SyntaxKind.MethodDeclaration) && (node.Parent as ClassDeclarationSyntax)?.Modifiers.Contains(SyntaxKind.AbstractKeyword) == true) { ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.AbstractKeyword); } break; } case CompilerDiagnosticIdentifiers.CS0549_NewVirtualMemberInSealedClass: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveVirtualModifier, context.Document, root.SyntaxTree)) { if (node is AccessorDeclarationSyntax && SyntaxInfo.ModifierListInfo(node.Parent.Parent).IsVirtual) { node = node.Parent.Parent; } ModifiersCodeFixRegistrator.RemoveModifier( context, diagnostic, node, SyntaxKind.VirtualKeyword, additionalKey: CodeFixIdentifiers.RemoveVirtualModifier); } if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeContainingClassUnsealed, context.Document, root.SyntaxTree) && node.Parent is ClassDeclarationSyntax classDeclaration) { ModifiersCodeFixRegistrator.RemoveModifier( context, diagnostic, classDeclaration, SyntaxKind.SealedKeyword, title: "Make containing class unsealed", additionalKey: CodeFixIdentifiers.MakeContainingClassUnsealed); } break; } case CompilerDiagnosticIdentifiers.CS8340_InstanceFieldsOfReadOnlyStructsMustBeReadOnly: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MakeMemberReadOnly, context.Document, root.SyntaxTree)) { break; } ModifiersCodeFixRegistrator.AddModifier(context, diagnostic, node, SyntaxKind.ReadOnlyKeyword); break; } case CompilerDiagnosticIdentifiers.CS0238_MemberCannotBeSealedBecauseItIsNotOverride: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveSealedModifier, context.Document, root.SyntaxTree)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (semanticModel.GetDiagnostic( CompilerDiagnosticIdentifiers.CS0114_MemberHidesInheritedMemberToMakeCurrentMethodOverrideThatImplementationAddOverrideKeyword, CSharpUtility.GetIdentifier(node).Span, context.CancellationToken) != null) { break; } ModifiersCodeFixRegistrator.RemoveModifier(context, diagnostic, node, SyntaxKind.SealedKeyword); break; } } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsAnyCodeFixEnabled( CodeFixIdentifiers.AddComparisonWithBooleanLiteral, CodeFixIdentifiers.CreateSingletonArray, CodeFixIdentifiers.UseUncheckedExpression, CodeFixIdentifiers.RemoveConstModifier, CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); var expression = root.FindNode(context.Span, getInnermostNodeForTie: true) as ExpressionSyntax; Debug.Assert(expression != null, $"{nameof(expression)} is null"); if (expression == null) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken); ITypeSymbol type = typeInfo.Type; ITypeSymbol convertedType = typeInfo.ConvertedType; if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral) && type?.IsNullableOf(SpecialType.System_Boolean) == true) { if (convertedType?.IsBoolean() == true || AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression)) { CodeAction codeAction = CodeAction.Create( AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression), cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) && type?.IsErrorType() == false && !type.Equals(convertedType) && convertedType.IsArrayType()) { var arrayType = (IArrayTypeSymbol)convertedType; if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType)) { CodeAction codeAction = CodeAction.Create( "Create singleton array", cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } } break; } case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression)) { break; } CodeAction codeAction = CodeAction.Create( "Use 'unchecked'", cancellationToken => { CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia()); newNode = newNode.WithTriviaFrom(expression); return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier)) { break; } LocalDeclarationStatementSyntax localDeclarationStatement = GetLocalDeclarationStatement(expression); if (localDeclarationStatement == null) { break; } SyntaxTokenList modifiers = localDeclarationStatement.Modifiers; if (!modifiers.Contains(SyntaxKind.ConstKeyword)) { break; } CodeAction codeAction = CodeAction.Create( "Remove 'const' modifier", cancellationToken => { LocalDeclarationStatementSyntax newNode = localDeclarationStatement.RemoveModifier(SyntaxKind.ConstKeyword); return(context.Document.ReplaceNodeAsync(localDeclarationStatement, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType; if (typeSymbol?.SupportsExplicitDeclaration() == true) { CodeAction codeAction = CodeAction.Create( "Replace 'null' with default value", cancellationToken => { ExpressionSyntax newNode = typeSymbol.ToDefaultValueSyntax(semanticModel, expression.SpanStart); return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } break; } } } }
public static bool IsPartial(this SyntaxTokenList modifiers) { return(modifiers.Any(i => i.IsKind(SyntaxKind.PartialKeyword))); }
public static SyntaxTokenList CloneAccessibilityModifiers(this SyntaxTokenList modifiers) { var accessibilityModifiers = modifiers.Where(token => token.IsKind(SyntaxKind.PublicKeyword) || token.IsKind(SyntaxKind.ProtectedKeyword) || token.IsKind(SyntaxKind.InternalKeyword) || token.IsKind(SyntaxKind.PrivateKeyword)).Select(token => SyntaxFactory.Token(token.Kind())); return(SyntaxFactory.TokenList(accessibilityModifiers.EnsureProtectedBeforeInternal())); }
private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context) { var typeDeclaration = (TypeDeclarationSyntax)context.Node; if (typeDeclaration.Modifiers.Contains(SyntaxKind.PartialKeyword)) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; INamedTypeSymbol declarationSymbol = null; ImmutableArray <AttributeData> attributes = default; if (typeDeclaration.IsKind(SyntaxKind.StructDeclaration)) { declarationSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken); attributes = declarationSymbol.GetAttributes(); if (attributes.Any(f => f.AttributeClass.HasMetadataName(MetadataNames.System_Runtime_InteropServices_StructLayoutAttribute))) { return; } } bool?canContainUnityScriptMethods = null; SyntaxList <MemberDeclarationSyntax> members = typeDeclaration.Members; UnusedMemberWalker walker = null; foreach (MemberDeclarationSyntax member in members) { if (member.ContainsDiagnostics) { continue; } if (member.ContainsUnbalancedIfElseDirectives(member.Span)) { continue; } switch (member.Kind()) { case SyntaxKind.DelegateDeclaration: { var declaration = (DelegateDeclarationSyntax)member; if (SyntaxAccessibility <DelegateDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private) { if (walker == null) { walker = UnusedMemberWalker.GetInstance(); } walker.AddDelegate(declaration.Identifier.ValueText, declaration); } break; } case SyntaxKind.EventDeclaration: { var declaration = (EventDeclarationSyntax)member; if (declaration.ExplicitInterfaceSpecifier == null && SyntaxAccessibility <EventDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private) { if (walker == null) { walker = UnusedMemberWalker.GetInstance(); } walker.AddNode(declaration.Identifier.ValueText, declaration); } break; } case SyntaxKind.EventFieldDeclaration: { var declaration = (EventFieldDeclarationSyntax)member; if (SyntaxAccessibility <EventFieldDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private) { if (walker == null) { walker = UnusedMemberWalker.GetInstance(); } walker.AddNodes(declaration.Declaration); } break; } case SyntaxKind.FieldDeclaration: { var declaration = (FieldDeclarationSyntax)member; SyntaxTokenList modifiers = declaration.Modifiers; if (SyntaxAccessibility <FieldDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private) { if (walker == null) { walker = UnusedMemberWalker.GetInstance(); } walker.AddNodes(declaration.Declaration, isConst: modifiers.Contains(SyntaxKind.ConstKeyword)); } break; } case SyntaxKind.MethodDeclaration: { var declaration = (MethodDeclarationSyntax)member; SyntaxTokenList modifiers = declaration.Modifiers; if (declaration.ExplicitInterfaceSpecifier != null || declaration.AttributeLists.Any() || SyntaxAccessibility <MethodDeclarationSyntax> .Instance.GetAccessibility(declaration) != Accessibility.Private) { break; } string methodName = declaration.Identifier.ValueText; if (IsMainMethod(declaration, modifiers, methodName)) { break; } if (declaration.ReturnsVoid() && AnalyzerOptions.SuppressUnityScriptMethods.IsEnabled(context)) { if (canContainUnityScriptMethods == null) { if (declarationSymbol == null) { declarationSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, context.CancellationToken); } canContainUnityScriptMethods = declarationSymbol.InheritsFrom(UnityScriptMethods.MonoBehaviourClassName); } if (canContainUnityScriptMethods == true && UnityScriptMethods.MethodNames.Contains(methodName)) { break; } } if (walker == null) { walker = UnusedMemberWalker.GetInstance(); } walker.AddNode(methodName, declaration); break; } case SyntaxKind.PropertyDeclaration: { var declaration = (PropertyDeclarationSyntax)member; if (declaration.ExplicitInterfaceSpecifier == null && SyntaxAccessibility <PropertyDeclarationSyntax> .Instance.GetAccessibility(declaration) == Accessibility.Private) { if (walker == null) { walker = UnusedMemberWalker.GetInstance(); } walker.AddNode(declaration.Identifier.ValueText, declaration); } break; } } } if (walker == null) { return; } Collection <NodeSymbolInfo> nodes = walker.Nodes; if (ShouldAnalyzeDebuggerDisplayAttribute() && nodes.Any(f => f.CanBeInDebuggerDisplayAttribute)) { if (attributes.IsDefault) { attributes = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken).GetAttributes(); } string value = attributes .FirstOrDefault(f => f.AttributeClass.HasMetadataName(MetadataNames.System_Diagnostics_DebuggerDisplayAttribute))? .ConstructorArguments .SingleOrDefault(shouldThrow: false) .Value? .ToString(); if (value != null) { RemoveMethodsAndPropertiesThatAreInDebuggerDisplayAttributeValue(value, ref nodes); } } if (nodes.Count > 0) { walker.SemanticModel = semanticModel; walker.CancellationToken = cancellationToken; walker.Visit(typeDeclaration); foreach (NodeSymbolInfo node in nodes) { ReportDiagnostic(context, node.Node); } } UnusedMemberWalker.Free(walker); bool ShouldAnalyzeDebuggerDisplayAttribute() { foreach (AttributeListSyntax attributeList in typeDeclaration.AttributeLists) { foreach (AttributeSyntax attribute in attributeList.Attributes) { if (attribute.ArgumentList?.Arguments.Count(f => f.NameEquals == null) == 1) { return(true); } } } return(false); } }
public static bool Any(this SyntaxTokenList list, SyntaxKind kind1, SyntaxKind kind2) => list.IndexOf(kind1) >= 0 || list.IndexOf(kind2) >= 0;
private static void CheckAccessModifiers(SyntaxNodeAnalysisContext context, SyntaxToken identifier, SyntaxTokenList modifiers, SyntaxNode declarationNode = null) { if (identifier.IsMissing) { return; } foreach (SyntaxToken token in modifiers) { switch (token.Kind()) { case SyntaxKind.PublicKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.InternalKeyword: case SyntaxKind.PrivateKeyword: return; case SyntaxKind.StaticKeyword: if (context.Node is ConstructorDeclarationSyntax) { return; } break; case SyntaxKind.PartialKeyword: // the access modifier might be declared on another part, which isn't handled at this time return; default: break; } } // missing access modifier ISymbol symbol = context.SemanticModel.GetDeclaredSymbol(declarationNode ?? context.Node, context.CancellationToken); string name = symbol?.Name; if (string.IsNullOrEmpty(name)) { return; } context.ReportDiagnostic(Diagnostic.Create(Descriptor, identifier.GetLocation(), name)); }
/// <summary>Creates a new LocalDeclarationStatementSyntax instance.</summary> public static LocalDeclarationStatementSyntax LocalDeclarationStatement(SyntaxTokenList modifiers, VariableDeclarationSyntax declaration, SyntaxToken semicolonToken) { return(LocalDeclarationStatement(modifiers, default(SyntaxToken), declaration, semicolonToken)); }
static bool IsConst(SyntaxTokenList modifiers) { return(modifiers.Any(mod => mod.Kind() == Microsoft.CodeAnalysis.CSharp.SyntaxKind.ConstKeyword)); }
public override VBasic.VisualBasicSyntaxNode VisitXmlTextAttribute(CSSyntax.XmlTextAttributeSyntax node) { VBSyntax.XmlNodeSyntax Name = (VBSyntax.XmlNodeSyntax)node.Name.Accept(this); var TextTokens = TriviaListSupport.TranslateTokenList(node.TextTokens); var XmlText = VBFactory.XmlText(TextTokens); VBSyntax.XmlNodeSyntax Value = VBFactory.XmlString(VisualBasicSyntaxFactory.DoubleQuoteToken, SyntaxTokenList.Create(VBFactory.XmlTextLiteralToken(XmlText.ToString(), XmlText.ToString())), VisualBasicSyntaxFactory.DoubleQuoteToken); return(VBFactory.XmlAttribute(Name, Value)); }
public override VBasic.VisualBasicSyntaxNode VisitXmlNameAttribute(CSSyntax.XmlNameAttributeSyntax node) { var Name = ((VBSyntax.XmlNodeSyntax)node.Name.Accept(this)); string ValueString = node.Identifier.ToString(); VBSyntax.XmlNodeSyntax Value = VBFactory.XmlString(VisualBasicSyntaxFactory.DoubleQuoteToken, SyntaxTokenList.Create(VBFactory.XmlTextLiteralToken(ValueString, ValueString)), VisualBasicSyntaxFactory.DoubleQuoteToken); return(VBFactory.XmlAttribute(Name, Value)); }
public static SyntaxList <XmlNodeSyntax> WithoutFirstAndLastNewlines(this SyntaxList <XmlNodeSyntax> summaryContent) { if (summaryContent.Count == 0) { return(summaryContent); } XmlTextSyntax firstSyntax = summaryContent[0] as XmlTextSyntax; if (firstSyntax == null) { return(summaryContent); } XmlTextSyntax lastSyntax = summaryContent[summaryContent.Count - 1] as XmlTextSyntax; if (lastSyntax == null) { return(summaryContent); } SyntaxTokenList firstSyntaxTokens = firstSyntax.TextTokens; int removeFromStart; if (IsXmlNewLine(firstSyntaxTokens[0])) { removeFromStart = 1; } else { if (!IsXmlWhitespace(firstSyntaxTokens[0])) { return(summaryContent); } if (!IsXmlNewLine(firstSyntaxTokens[1])) { return(summaryContent); } removeFromStart = 2; } SyntaxTokenList lastSyntaxTokens = lastSyntax.TextTokens; int removeFromEnd; if (IsXmlNewLine(lastSyntaxTokens[lastSyntaxTokens.Count - 1])) { removeFromEnd = 1; } else { if (!IsXmlWhitespace(lastSyntaxTokens[lastSyntaxTokens.Count - 1])) { return(summaryContent); } if (!IsXmlNewLine(lastSyntaxTokens[lastSyntaxTokens.Count - 2])) { return(summaryContent); } removeFromEnd = 2; } for (int i = 0; i < removeFromStart; i++) { firstSyntaxTokens = firstSyntaxTokens.RemoveAt(0); } if (firstSyntax == lastSyntax) { lastSyntaxTokens = firstSyntaxTokens; } for (int i = 0; i < removeFromEnd; i++) { lastSyntaxTokens = lastSyntaxTokens.RemoveAt(lastSyntaxTokens.Count - 1); } summaryContent = summaryContent.RemoveAt(summaryContent.Count - 1); if (lastSyntaxTokens.Count != 0) { summaryContent = summaryContent.Add(lastSyntax.WithTextTokens(lastSyntaxTokens)); } if (firstSyntax != lastSyntax) { summaryContent = summaryContent.RemoveAt(0); if (firstSyntaxTokens.Count != 0) { summaryContent = summaryContent.Insert(0, firstSyntax.WithTextTokens(firstSyntaxTokens)); } } if (summaryContent.Count > 0) { // Make sure to remove the leading trivia summaryContent = summaryContent.Replace(summaryContent[0], summaryContent[0].WithLeadingTrivia()); // Remove leading spaces (between the <para> start tag and the start of the paragraph content) XmlTextSyntax firstTextSyntax = summaryContent[0] as XmlTextSyntax; if (firstTextSyntax != null && firstTextSyntax.TextTokens.Count > 0) { SyntaxToken firstTextToken = firstTextSyntax.TextTokens[0]; string firstTokenText = firstTextToken.Text; string trimmed = firstTokenText.TrimStart(); if (trimmed != firstTokenText) { SyntaxToken newFirstToken = SyntaxFactory.Token( firstTextToken.LeadingTrivia, firstTextToken.Kind(), trimmed, firstTextToken.ValueText.TrimStart(), firstTextToken.TrailingTrivia); summaryContent = summaryContent.Replace(firstTextSyntax, firstTextSyntax.ReplaceToken(firstTextToken, newFirstToken)); } } } return(summaryContent); }
private static bool EqualAccessibility(SyntaxNode x, SyntaxTokenList xModifiers, SyntaxNode y, SyntaxTokenList yModifiers, out int comparisonResult) { var xAccessibility = GetAccessibilityPrecedence(x, x.Parent ?? y.Parent, xModifiers); var yAccessibility = GetAccessibilityPrecedence(y, y.Parent ?? x.Parent, yModifiers); comparisonResult = xAccessibility - yAccessibility; return(comparisonResult == 0); }
private static bool EqualConstness(SyntaxTokenList x, SyntaxTokenList y, out int comparisonResult) { return(BothHaveModifier(x, y, SyntaxKind.ConstKeyword, out comparisonResult)); }
private static SyntaxTokenList RemoveModifier(SyntaxTokenList list, params SyntaxKind[] modifiers) { return(SyntaxFactory.TokenList(list.Where(t => Array.IndexOf(modifiers, t.Kind()) < 0))); }
public static VisualScriptCompilerResult Generate(VisualScriptAsset visualScriptAsset, VisualScriptCompilerOptions options) { var result = new VisualScriptCompilerResult(); var members = new List <MemberDeclarationSyntax>(); var className = options.Class; // Generate variables foreach (var variable in visualScriptAsset.Properties) { var variableType = variable.Type; if (variableType == null) { result.Error($"Variable {variable.Name} has no type, using \"object\" instead."); variableType = "object"; } var field = FieldDeclaration( VariableDeclaration( ParseTypeName(variableType)) .WithVariables( SingletonSeparatedList( VariableDeclarator( Identifier(variable.Name))))) .WithModifiers( TokenList( Token(SyntaxKind.PublicKeyword))); members.Add(field); } // Process each function foreach (var method in visualScriptAsset.Methods) { var functionStartBlock = method.Blocks.Values.OfType <FunctionStartBlock>().FirstOrDefault(); if (functionStartBlock == null) { continue; } var context = new VisualScriptCompilerContext(visualScriptAsset, method, result); context.ProcessEntryBlock(functionStartBlock); var methodModifiers = new SyntaxTokenList(); methodModifiers = ConvertAccessibility(methodModifiers, method.Accessibility); methodModifiers = ConvertVirtualModifier(methodModifiers, method.VirtualModifier); if (method.IsStatic) { methodModifiers = methodModifiers.Add(Token(SyntaxKind.StaticKeyword)); } var parameters = new List <SyntaxNodeOrToken>(); foreach (var parameter in method.Parameters) { if (parameters.Count > 0) { parameters.Add(Token(SyntaxKind.CommaToken)); } parameters.Add( Parameter(Identifier(parameter.Name)) .WithModifiers(ConvertRefKind(parameter.RefKind)) .WithType(ParseTypeName(parameter.Type))); } // Generate method var methodDeclaration = MethodDeclaration( method.ReturnType == "void" ? PredefinedType(Token(SyntaxKind.VoidKeyword)) : ParseTypeName(method.ReturnType), Identifier(method.Name)) .WithModifiers(methodModifiers) .WithParameterList(ParameterList( SeparatedList <ParameterSyntax>(parameters))) .WithBody( Block(context.Blocks.SelectMany(x => x.Statements))) .WithAdditionalAnnotations(GenerateAnnotation(method)); members.Add(methodDeclaration); } // Generate class var classModifiers = new SyntaxTokenList(); classModifiers = ConvertAccessibility(classModifiers, visualScriptAsset.Accessibility).Add(Token(SyntaxKind.PartialKeyword)); if (visualScriptAsset.IsStatic) { classModifiers = classModifiers.Add(Token(SyntaxKind.StaticKeyword)); } var @class = ClassDeclaration(className) .WithMembers(List(members)) .WithModifiers(classModifiers); if (visualScriptAsset.BaseType != null) { @class = @class.WithBaseList(BaseList(SingletonSeparatedList <BaseTypeSyntax>(SimpleBaseType(IdentifierName(visualScriptAsset.BaseType))))); } // Generate namespace around class (if any) MemberDeclarationSyntax namespaceOrClass = @class; var @namespace = !string.IsNullOrEmpty(visualScriptAsset.Namespace) ? visualScriptAsset.Namespace : options.DefaultNamespace; if (@namespace != null) { namespaceOrClass = NamespaceDeclaration( IdentifierName(@namespace)) .WithMembers( SingletonList <MemberDeclarationSyntax>(@class)); } // Generate compilation unit var compilationUnit = CompilationUnit() .WithUsings( List(visualScriptAsset.UsingDirectives.Select(x => UsingDirective( IdentifierName(x))))) .WithMembers( SingletonList(namespaceOrClass)) .NormalizeWhitespace(); // Generate actual source code result.GeneratedSource = compilationUnit.ToFullString(); result.SyntaxTree = SyntaxTree(compilationUnit, path: options.FilePath ?? string.Empty); return(result); }
public static bool IsReadOnly(this SyntaxTokenList modifiers) { return(modifiers.Any(i => i.IsKind(SyntaxKind.ReadOnlyKeyword))); }
private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, bool explicitInterfaceImplementation, bool isFieldLike, Location location, DiagnosticBag diagnostics, out bool modifierErrors) { bool isInterface = this.ContainingType.IsInterface; var defaultAccess = isInterface && !explicitInterfaceImplementation ? DeclarationModifiers.Public : DeclarationModifiers.Private; var defaultInterfaceImplementationModifiers = DeclarationModifiers.None; // Check that the set of modifiers is allowed var allowedModifiers = DeclarationModifiers.Unsafe; if (!explicitInterfaceImplementation) { allowedModifiers |= DeclarationModifiers.New | DeclarationModifiers.Sealed | DeclarationModifiers.Abstract | DeclarationModifiers.Static | DeclarationModifiers.Virtual | DeclarationModifiers.AccessibilityMask; if (!isInterface) { allowedModifiers |= DeclarationModifiers.Override; } else { // This is needed to make sure we can detect 'public' modifier specified explicitly and // check it against language version below. defaultAccess = DeclarationModifiers.None; allowedModifiers |= DeclarationModifiers.Extern; defaultInterfaceImplementationModifiers |= DeclarationModifiers.Sealed | DeclarationModifiers.Abstract | DeclarationModifiers.Static | DeclarationModifiers.Virtual | DeclarationModifiers.Extern | DeclarationModifiers.AccessibilityMask; } } else if (isInterface) { Debug.Assert(explicitInterfaceImplementation); allowedModifiers |= DeclarationModifiers.Abstract; } if (this.ContainingType.IsStructType()) { allowedModifiers |= DeclarationModifiers.ReadOnly; } if (!isInterface) { allowedModifiers |= DeclarationModifiers.Extern; } var mods = ModifierUtils.MakeAndCheckNontypeMemberModifiers(modifiers, defaultAccess, allowedModifiers, location, diagnostics, out modifierErrors); this.CheckUnsafeModifier(mods, diagnostics); ModifierUtils.ReportDefaultInterfaceImplementationModifiers(!isFieldLike, mods, defaultInterfaceImplementationModifiers, location, diagnostics); // Let's overwrite modifiers for interface events with what they are supposed to be. // Proper errors must have been reported by now. if (isInterface) { mods = ModifierUtils.AdjustModifiersForAnInterfaceMember(mods, !isFieldLike, explicitInterfaceImplementation); } return(mods); }
private static bool GetAbstractModifier(SyntaxTokenList tokens) { return(tokens.Any(m => m.Kind() == SyntaxKind.AbstractKeyword) ? true : false); }
public static bool IsOutOrRef(this SyntaxTokenList modifiers) { return(modifiers.Any(i => i.IsKind(SyntaxKind.OutKeyword) || i.IsKind(SyntaxKind.RefKeyword))); }
private static int GetAccessibilityPrecedence(SyntaxNode declaration, SyntaxNode parent, SyntaxTokenList modifiers) { if (ContainsToken(modifiers, SyntaxKind.PublicKeyword)) { return((int)Accessibility.Public); } else if (ContainsToken(modifiers, SyntaxKind.ProtectedKeyword)) { if (ContainsToken(modifiers, SyntaxKind.InternalKeyword)) { return((int)Accessibility.ProtectedInternal); } return((int)Accessibility.Protected); } else if (ContainsToken(modifiers, SyntaxKind.InternalKeyword)) { return((int)Accessibility.Internal); } else if (ContainsToken(modifiers, SyntaxKind.PrivateKeyword)) { return((int)Accessibility.Private); } // Determine default accessibility: This declaration is internal if we traverse up // the syntax tree and don't find a containing named type. for (var node = parent; node != null; node = node.Parent) { if (node.CSharpKind() == SyntaxKind.InterfaceDeclaration) { // All interface members are public return((int)Accessibility.Public); } else if (node.CSharpKind() == SyntaxKind.StructDeclaration || node.CSharpKind() == SyntaxKind.ClassDeclaration) { // Members and nested types default to private return((int)Accessibility.Private); } } return((int)Accessibility.Internal); }
protected override SyntaxNode WithModifiers(SyntaxNode fieldSyntax, SyntaxTokenList modifiers) { var field = (FieldDeclarationSyntax)fieldSyntax; return(field.WithModifiers(modifiers)); }
protected static IList <SyntaxToken> GetUpdatedDeclarationAccessibilityModifiers(IList <SyntaxToken> newModifierTokens, SyntaxTokenList modifiersList, Func <SyntaxToken, bool> isAccessibilityModifier) { var updatedModifiersList = new List <SyntaxToken>(); var anyAccessModifierSeen = false; foreach (var modifier in modifiersList) { SyntaxToken newModifier; if (isAccessibilityModifier(modifier)) { if (newModifierTokens.Count == 0) { continue; } newModifier = newModifierTokens.ElementAt(0) .WithLeadingTrivia(modifier.LeadingTrivia) .WithTrailingTrivia(modifier.TrailingTrivia); newModifierTokens.RemoveAt(0); anyAccessModifierSeen = true; } else { if (anyAccessModifierSeen && newModifierTokens.Any()) { updatedModifiersList.AddRange(newModifierTokens); newModifierTokens.Clear(); } newModifier = modifier; } updatedModifiersList.Add(newModifier); } if (!anyAccessModifierSeen) { updatedModifiersList.InsertRange(0, newModifierTokens); } else { updatedModifiersList.AddRange(newModifierTokens); } return(updatedModifiersList); }
private void FormatTextTokens(SyntaxTokenList textTokens) { foreach (var token in textTokens) { if (token.HasLeadingTrivia) { AddTrivia(token.LeadingTrivia); } string tokenText = token.Text; int wordStart = 0; int breakStart = 0; bool allowSentenceSpace = false; for (int i = 0; i < tokenText.Length; ++i) { char c = tokenText[i]; bool isSpace = IsWhitespace(c) || c == '\r' || c == '\n'; // Preserve one extra space after sentence end. if (isSpace && allowSentenceSpace) { char nextC = i + 1 < tokenText.Length ? tokenText[i + 1] : token.Span.End < _text.Length ? _text[token.Span.End] : ' '; if (IsWhitespace(nextC) || nextC == '\r' || nextC == '\n') { isSpace = false; allowSentenceSpace = false; } } if (isSpace) { if (wordStart < i) { AddWord(new TextSpan(token.SpanStart + wordStart, i - wordStart)); } wordStart = i + 1; allowSentenceSpace = false; } else { if (breakStart < i) { AddBreak(new TextSpan(token.SpanStart + breakStart, i - breakStart)); } breakStart = i + 1; if ("!.:?".IndexOf(c) >= 0) { allowSentenceSpace = true; } else if (char.IsLetterOrDigit(c)) { allowSentenceSpace = false; } } } if (wordStart < tokenText.Length) { AddWord(new TextSpan(token.SpanStart + wordStart, tokenText.Length - wordStart)); } if (breakStart < tokenText.Length) { AddBreak(new TextSpan(token.SpanStart + breakStart, tokenText.Length - breakStart)); } if (token.HasTrailingTrivia) { AddTrivia(token.TrailingTrivia); } } }
private static bool ContainsToken(SyntaxTokenList list, SyntaxKind kind) { return(list.Contains(token => token.Kind() == kind)); }
private SourceMemberMethodSymbol( NamedTypeSymbol containingType, TypeSymbol explicitInterfaceType, string name, Location location, Binder bodyBinder, MethodDeclarationSyntax syntax, MethodKind methodKind, DiagnosticBag diagnostics) : base(containingType, syntax.GetReference(), // Prefer a block body if both exist syntax.Body?.GetReference() ?? syntax.ExpressionBody?.GetReference(), location) { _name = name; _explicitInterfaceType = explicitInterfaceType; SyntaxTokenList modifiers = syntax.Modifiers; // The following two values are used to compute and store the initial value of the flags // However, these two components are placeholders; the correct value will be // computed lazily later and then the flags will be fixed up. const bool returnsVoid = false; var firstParam = syntax.ParameterList.Parameters.FirstOrDefault(); bool isExtensionMethod = firstParam != null && !firstParam.IsArgList && firstParam.Modifiers.Any(SyntaxKind.ThisKeyword); bool modifierErrors; var declarationModifiers = this.MakeModifiers(modifiers, methodKind, location, diagnostics, out modifierErrors); var isMetadataVirtualIgnoringModifiers = (object)explicitInterfaceType != null; //explicit impls must be marked metadata virtual this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers); // NOTE: by creating a WithMethodTypeParametersBinder, we are effectively duplicating the // functionality of the BinderFactory. Unfortunately, we cannot use the BinderFactory // because it depends on having access to the member list of our containing type and // that list cannot be complete because we're not finished constructing this member. // TODO: at least keep this in sync with BinderFactory.VisitMethodDeclaration. bodyBinder = bodyBinder.WithUnsafeRegionIfNecessary(modifiers); Binder withTypeParamsBinder; if (syntax.Arity == 0) { withTypeParamsBinder = bodyBinder; _typeParameters = ImmutableArray <TypeParameterSymbol> .Empty; } else { var parameterBinder = new WithMethodTypeParametersBinder(this, bodyBinder); withTypeParamsBinder = parameterBinder; _typeParameters = MakeTypeParameters(syntax, diagnostics); } bool hasBlockBody = syntax.Body != null; _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; if (hasBlockBody || _isExpressionBodied) { CheckModifiersForBody(location, diagnostics); } var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers); if (info != null) { diagnostics.Add(info, location); } if (this.IsPartial) { // Partial methods must be completed early because they are matched up // by signature while producing the enclosing type's member list. However, // that means any type parameter constraints will be bound before the method // is added to the containing type. To enable binding of constraints before the // .ctor completes we hold on to the current binder while the .ctor is executing. // If we change the handling of partial methods, so that partial methods are // completed lazily, the 'constraintClauseBinder' field should be removed. _constraintClauseBinder = withTypeParamsBinder; state.NotePartComplete(CompletionPart.StartMethodChecks); MethodChecks(syntax, withTypeParamsBinder, diagnostics); state.NotePartComplete(CompletionPart.FinishMethodChecks); _constraintClauseBinder = null; } }
public static MemberDeclarationSyntax WithModifiers(this MemberDeclarationSyntax declaration, SyntaxTokenList newModifiers) { var result = declaration; switch (declaration.Kind()) { case SyntaxKind.ClassDeclaration: result = ((ClassDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.StructDeclaration: result = ((StructDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.InterfaceDeclaration: result = ((InterfaceDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.EnumDeclaration: result = ((EnumDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.DelegateDeclaration: result = ((DelegateDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.FieldDeclaration: result = ((FieldDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.EventFieldDeclaration: result = ((EventFieldDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.MethodDeclaration: result = ((MethodDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.OperatorDeclaration: result = ((OperatorDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.ConversionOperatorDeclaration: result = ((ConversionOperatorDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.ConstructorDeclaration: result = ((ConstructorDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.DestructorDeclaration: result = ((DestructorDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.PropertyDeclaration: result = ((PropertyDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.IndexerDeclaration: result = ((IndexerDeclarationSyntax)declaration).WithModifiers(newModifiers); break; case SyntaxKind.EventDeclaration: result = ((EventDeclarationSyntax)declaration).WithModifiers(newModifiers); break; default: break; } return(result); }
public MethodDeclarationSyntax GenerateUnitTestMethodDeclaration(string returnTypeName, SyntaxTokenList modifiers, string methodName, string testFramework, GeneratedTest generatedTestModel) { var annotation = "nunit".Equals(testFramework) ? "Test" : "Fact"; var bodyStatements = new List <StatementSyntax>(); var addedArrange = false; if (!string.IsNullOrWhiteSpace(generatedTestModel.ReturnType)) { bodyStatements.Add(SyntaxFactory.ParseStatement($"var expected = default({generatedTestModel.ReturnType});\n").WithLeadingTrivia(SyntaxFactory.Comment("//Arrange\n"))); addedArrange = true; } var methodParams = ""; if (generatedTestModel.MethodParameters != null && generatedTestModel.MethodParameters.Any()) { foreach (var parameter in generatedTestModel.MethodParameters) { if (!addedArrange) { bodyStatements.Add(SyntaxFactory.ParseStatement($"var {parameter.Name} = default({parameter.ClassName});\n").WithLeadingTrivia(SyntaxFactory.Comment("//Arrange\n"))); addedArrange = true; } else { bodyStatements.Add(SyntaxFactory.ParseStatement($"var {parameter.Name} = default({parameter.ClassName});\n")); } methodParams += $"{parameter.Name}, "; } } var ctorParams = ""; if (generatedTestModel.ClassConstructorParameters != null && generatedTestModel.ClassConstructorParameters.Any()) { foreach (var parameter in generatedTestModel.ClassConstructorParameters) { if (!addedArrange) { if (parameter.IsInterface) { bodyStatements.Add(SyntaxFactory.ParseStatement($"var {parameter.Name} = new Mock<{parameter.ClassName}>();\n").WithLeadingTrivia(SyntaxFactory.Comment("//Arrange\n"))); } else { bodyStatements.Add(SyntaxFactory.ParseStatement($"var {parameter.Name} = default({parameter.ClassName});\n").WithLeadingTrivia(SyntaxFactory.Comment("//Arrange\n"))); } addedArrange = true; } else { if (parameter.IsInterface) { bodyStatements.Add(SyntaxFactory.ParseStatement($"var {parameter.Name} = new Mock<{parameter.ClassName}>();\n")); } else { bodyStatements.Add(SyntaxFactory.ParseStatement($"var {parameter.Name} = default({parameter.ClassName});\n")); } } ctorParams += parameter.IsInterface ? $"{parameter.Name}.Object, " : $"{parameter.Name}, "; } } var classCtor = SyntaxFactory.ParseStatement($"var vm = new {generatedTestModel.ClassName}({ctorParams.TrimEnd(' ').TrimEnd(',')});\n").WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed); bodyStatements.Add(classCtor); var resultSection = string.IsNullOrWhiteSpace(generatedTestModel.ReturnType) ? "" : "var result = "; var awaitSection = generatedTestModel.IsTask ? "await " : ""; bodyStatements.Add(SyntaxFactory.ParseStatement($"{resultSection}{awaitSection}vm.{generatedTestModel.MethodName}({methodParams.TrimEnd(' ').TrimEnd(',')});\n").WithLeadingTrivia(SyntaxFactory.Comment("//Act\n"))); //Generate the assert section if ("nunit".Equals(testFramework)) { if (!string.IsNullOrWhiteSpace(generatedTestModel.ReturnType)) { bodyStatements.Add(SyntaxFactory.ParseStatement("Assert.That(expected == result);\n").WithLeadingTrivia(SyntaxFactory.Comment("//Assert\n"))); } else { bodyStatements.Add(SyntaxFactory.ParseStatement("Assert.That(true);\n").WithLeadingTrivia(SyntaxFactory.Comment("//Assert\n"))); } } else { if (!string.IsNullOrWhiteSpace(generatedTestModel.ReturnType)) { bodyStatements.Add(SyntaxFactory.ParseStatement($"Assert.Equal<{generatedTestModel.ReturnType}>(expected, result);\n").WithLeadingTrivia(SyntaxFactory.Comment("//Assert\n"))); } else { bodyStatements.Add(SyntaxFactory.ParseStatement("Assert.True(true);\n").WithLeadingTrivia(SyntaxFactory.Comment("//Assert\n"))); } } var method = SyntaxFactory.MethodDeclaration(attributeLists: SyntaxFactory.List <AttributeListSyntax>(), modifiers: modifiers, returnType: SyntaxFactory.ParseTypeName(returnTypeName), explicitInterfaceSpecifier: null, identifier: SyntaxFactory.Identifier(methodName), typeParameterList: null, parameterList: SyntaxFactory.ParameterList(), constraintClauses: SyntaxFactory.List <TypeParameterConstraintClauseSyntax>(), body: SyntaxFactory.Block(bodyStatements), semicolonToken: SyntaxFactory.Token(SyntaxKind.None)) // Annotate that this node should be formatted .WithAdditionalAnnotations(Formatter.Annotation) .WithAttributeLists( SyntaxFactory.SingletonList( SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Attribute( SyntaxFactory.IdentifierName(annotation)))))); return(method); }