protected IList<SyntaxNode> GetExpectedDescendants(IEnumerable<SyntaxNode> nodes, ImmutableArray<SyntaxKind> expected) { var descendants = new List<SyntaxNode>(); foreach (var node in nodes) { if (expected.Any(e => e == node.Kind())) { descendants.Add(node); continue; } foreach (var child in node.ChildNodes()) { if (expected.Any(e => e == child.Kind())) { descendants.Add(child); continue; } if (child.ChildNodes().Count() > 0) descendants.AddRange(GetExpectedDescendants(child.ChildNodes(), expected)); } } return descendants; }
private async Task<ImmutableArray<TaggedText>> TryAddSnippetInvocationPart( Document document, CompletionItem item, ImmutableArray<TaggedText> parts, CancellationToken cancellationToken) { var languageServices = document.Project.LanguageServices; var snippetService = languageServices.GetService<ISnippetInfoService>(); if (snippetService != null) { var change = await GetTextChangeAsync(document, item, ch: '\t', cancellationToken: cancellationToken).ConfigureAwait(false) ?? new TextChange(item.Span, item.DisplayText); var insertionText = change.NewText; if (snippetService != null && snippetService.SnippetShortcutExists_NonBlocking(insertionText)) { var note = string.Format(FeaturesResources.Note_colon_Tab_twice_to_insert_the_0_snippet, insertionText); if (parts.Any()) { parts = parts.Add(new TaggedText(TextTags.LineBreak, Environment.NewLine)); } parts = parts.Add(new TaggedText(TextTags.Text, note)); } } return parts; }
public SymbolImplementation(ImmutableArray<BoundStatement> statements, SymbolScope scope) { Scope = scope; Statements = statements; DeclaresVariables = statements.Any(x => x is BoundVariableDeclaration); }
internal SourceAttributeData( SyntaxReference applicationNode, NamedTypeSymbol attributeClass, MethodSymbol attributeConstructor, ImmutableArray<TypedConstant> constructorArguments, ImmutableArray<int> constructorArgumentsSourceIndices, ImmutableArray<KeyValuePair<string, TypedConstant>> namedArguments, bool hasErrors, bool isConditionallyOmitted) { Debug.Assert(!isConditionallyOmitted || (object)attributeClass != null && attributeClass.IsConditional); Debug.Assert(!constructorArguments.IsDefault); Debug.Assert(!namedArguments.IsDefault); Debug.Assert(constructorArgumentsSourceIndices.IsDefault || constructorArgumentsSourceIndices.Any() && constructorArgumentsSourceIndices.Length == constructorArguments.Length); this.attributeClass = attributeClass; this.attributeConstructor = attributeConstructor; this.constructorArguments = constructorArguments; this.constructorArgumentsSourceIndices = constructorArgumentsSourceIndices; this.namedArguments = namedArguments; this.isConditionallyOmitted = isConditionallyOmitted; this.hasErrors = hasErrors; this.applicationNode = applicationNode; }
private static void SetScriptInitializerReturnType( CSharpCompilation compilation, SynthesizedInteractiveInitializerMethod scriptInitializer, ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers, DiagnosticBag diagnostics) { bool isAsync = scriptInitializer.IsSubmissionInitializer && fieldInitializers.Any(i => i.Any(ContainsAwaitsVisitor.ContainsAwait)); var resultType = scriptInitializer.ResultType; TypeSymbol returnType; if ((object)resultType == null) { Debug.Assert(!isAsync); returnType = compilation.GetSpecialType(SpecialType.System_Void); } else if (!isAsync) { returnType = resultType; } else { var taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T); var useSiteDiagnostic = taskT.GetUseSiteDiagnostic(); if (useSiteDiagnostic != null) { diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton); } returnType = taskT.Construct(resultType); } scriptInitializer.SetReturnType(isAsync, returnType); }
private string BuildText(ImmutableArray<Todo> todos) { if (!todos.Any()) return string.Empty; if (todos.Count() == 1) return "1 item left"; return $"{todos.Count()} items left"; }
private static ImmutableArray<CompletionItem> FixItemSpans(ImmutableArray<CompletionItem> items, TextSpan defaultSpan) { if (defaultSpan != default(TextSpan) && items.Any(i => i.Span == default(TextSpan))) { items = items.Select(i => i.Span == default(TextSpan) ? i.WithSpan(defaultSpan) : i).ToImmutableArray(); } return items; }
/// <summary> /// Creates an instance of <see cref="DesktopStrongNameProvider"/>. /// </summary> /// <param name="keyFileSearchPaths"> /// An ordered set of fully qualified paths which are searched when locating a cryptographic key file. /// </param> public DesktopStrongNameProvider(ImmutableArray<string> keyFileSearchPaths = default(ImmutableArray<string>)) { if (!keyFileSearchPaths.IsDefault && keyFileSearchPaths.Any(path => !PathUtilities.IsAbsolute(path))) { throw new ArgumentException(CodeAnalysisResources.AbsolutePathExpected, "keyFileSearchPaths"); } _keyFileSearchPaths = keyFileSearchPaths.NullToEmpty(); }
public ExistingReferencesResolver( MetadataFileReferenceResolver resolver, ImmutableArray<PortableExecutableReference> availableReferences, AssemblyIdentityComparer assemblyIdentityComparer) { Debug.Assert(!availableReferences.Any(r => r.Properties.Kind != MetadataImageKind.Assembly)); _resolver = resolver; _availableReferences = availableReferences; _assemblyIdentityComparer = assemblyIdentityComparer; }
public AnalyzerImageReference(ImmutableArray<DiagnosticAnalyzer> analyzers, string fullPath = null, string display = null) { if (analyzers.Any(a => a == null)) { throw new ArgumentException("Cannot have null-valued analyzer", "analyzers"); } _analyzers = analyzers; _fullPath = fullPath; _display = display; }
private static void VerifyAnalyzersArgument(ImmutableArray<DiagnosticAnalyzer> analyzers) { if (analyzers.IsDefaultOrEmpty) { throw new ArgumentException(CodeAnalysisResources.ArgumentCannotBeEmpty, nameof(analyzers)); } if (analyzers.Any(a => a == null)) { throw new ArgumentException(CodeAnalysisResources.ArgumentElementCannotBeNull, nameof(analyzers)); } }
internal static void ValidateSearchPaths(ImmutableArray<string> paths, string argName) { if (paths.IsDefault) { throw new ArgumentNullException(argName); } if (paths.Any(path => !PathUtilities.IsAbsolute(path))) { throw new ArgumentException(CodeAnalysisResources.AbsolutePathExpected, argName); } }
public ExistingReferencesResolver( ImmutableArray<PortableExecutableReference> availableReferences, ImmutableArray<string> referencePaths, string baseDirectory, AssemblyIdentityComparer assemblyIdentityComparer, TouchedFileLogger logger) : base(referencePaths, baseDirectory, logger) { Debug.Assert(!availableReferences.Any(r => r.Properties.Kind != MetadataImageKind.Assembly)); _availableReferences = availableReferences; _assemblyIdentityComparer = assemblyIdentityComparer; }
internal LocalScope(uint offset, uint length, ImmutableArray<ILocalDefinition> constants, ImmutableArray<ILocalDefinition> locals) { // We should not create 0-length scopes as they are useless. // however we will allow the case of "begin == end" as that is how edge inclusive scopes of length 1 are represented. Debug.Assert(!locals.Any(l => l.Name == null)); Debug.Assert(!constants.Any(c => c.Name == null)); _offset = offset; _length = length; _constants = constants; _locals = locals; }
internal LocalScope(int offset, int endOffset, ImmutableArray<ILocalDefinition> constants, ImmutableArray<ILocalDefinition> locals) { Debug.Assert(!locals.Any(l => l.Name == null)); Debug.Assert(!constants.Any(c => c.Name == null)); Debug.Assert(offset >= 0); Debug.Assert(endOffset > offset); StartOffset = offset; EndOffset = endOffset; _constants = constants; _locals = locals; }
// Method to bind all attributes (attribute arguments and constructor) internal static void GetAttributes( ImmutableArray<Binder> binders, ImmutableArray<AttributeSyntax> attributesToBind, ImmutableArray<NamedTypeSymbol> boundAttributeTypes, CSharpAttributeData[] attributesBuilder, DiagnosticBag diagnostics) { Debug.Assert(binders.Any()); Debug.Assert(attributesToBind.Any()); Debug.Assert(boundAttributeTypes.Any()); Debug.Assert(binders.Length == attributesToBind.Length); Debug.Assert(boundAttributeTypes.Length == attributesToBind.Length); Debug.Assert(attributesBuilder != null); for (int i = 0; i < attributesToBind.Length; i++) { AttributeSyntax attributeSyntax = attributesToBind[i]; NamedTypeSymbol boundAttributeType = boundAttributeTypes[i]; Binder binder = binders[i]; var attribute = (SourceAttributeData)attributesBuilder[i]; if (attribute == null) { attributesBuilder[i] = binder.GetAttribute(attributeSyntax, boundAttributeType, diagnostics); } else { // attributesBuilder might contain some early bound well-known attributes, which had no errors. // We don't rebind the early bound attributes, but need to compute isConditionallyOmitted. // Note that AttributeData.IsConditionallyOmitted is required only during emit, but must be computed here as // its value depends on the values of conditional symbols, which in turn depends on the source file where the attribute is applied. Debug.Assert(!attribute.HasErrors); HashSet<DiagnosticInfo> useSiteDiagnostics = null; bool isConditionallyOmitted = binder.IsAttributeConditionallyOmitted(attribute.AttributeClass, attributeSyntax.SyntaxTree, ref useSiteDiagnostics); diagnostics.Add(attributeSyntax, useSiteDiagnostics); attributesBuilder[i] = attribute.WithOmittedCondition(isConditionallyOmitted); } } }
// Method to bind attributes types early for all attributes to enable early decoding of some well-known attributes used within the binder. // Note: attributesToBind contains merged attributes from all the different syntax locations (e.g. for named types, partial methods, etc.). // Note: Additionally, the attributes with non-matching target specifier for the given owner symbol have been filtered out, i.e. Binder.MatchAttributeTarget method returned true. // For example, if were binding attributes on delegate type symbol for below code snippet: // [A1] // [return: A2] // public delegate void Foo(); // attributesToBind will only contain first attribute syntax. internal static void BindAttributeTypes(ImmutableArray<Binder> binders, ImmutableArray<AttributeSyntax> attributesToBind, Symbol ownerSymbol, NamedTypeSymbol[] boundAttributeTypes, DiagnosticBag diagnostics) { Debug.Assert(binders.Any()); Debug.Assert(attributesToBind.Any()); Debug.Assert((object)ownerSymbol != null); Debug.Assert(binders.Length == attributesToBind.Length); Debug.Assert(boundAttributeTypes != null); for (int i = 0; i < attributesToBind.Length; i++) { // Some types may have been bound by an earlier stage. if ((object)boundAttributeTypes[i] == null) { var binder = binders[i]; // BindType for AttributeSyntax's name is handled specially during lookup, see Binder.LookupAttributeType. // When looking up a name in attribute type context, we generate a diagnostic + error type if it is not an attribute type, i.e. named type deriving from System.Attribute. // Hence we can assume here that BindType returns a NamedTypeSymbol. boundAttributeTypes[i] = (NamedTypeSymbol)binder.BindType(attributesToBind[i].Name, diagnostics); } } }
/// <summary> /// True - assert that the list contains a single const modifier. /// False - assert that the list is empty. /// </summary> private static void CheckCustomModifier(bool expectCustomModifier, ImmutableArray<CustomModifier> customModifiers) { if (expectCustomModifier) { Assert.Equal(ConstModOptType, customModifiers.Single().Modifier.ToTestDisplayString()); } else { Assert.False(customModifiers.Any()); } }
private static bool DeclaredLocalCausesCollision(ILookup <string, ISymbol> symbolNameToExistingSymbol, ImmutableArray <ILocalSymbol> locals) => locals.Any(local => symbolNameToExistingSymbol[local.Name].Any(otherLocal => !local.Equals(otherLocal)));
void AppendTypeParameters (StringBuilder result, ImmutableArray<ITypeParameterSymbol> typeParameters) { if (!typeParameters.Any ()) return; result.Append ("<"); int i = 0; foreach (var typeParameter in typeParameters) { if (i > 0) { if (i % 5 == 0) { result.AppendLine (","); result.Append ("\t"); } else { result.Append (", "); } } AppendVariance (result, typeParameter.Variance); result.Append (HighlightSemantically (CSharpAmbience.NetToCSharpTypeName (typeParameter.Name), colorStyle.UserTypes)); i++; } result.Append (">"); }
private SourcePropertyAccessorSymbol( NamedTypeSymbol containingType, string name, SourcePropertySymbol property, DeclarationModifiers propertyModifiers, ImmutableArray<MethodSymbol> explicitInterfaceImplementations, Location location, ArrowExpressionClauseSyntax syntax, DiagnosticBag diagnostics) : base(containingType, syntax.GetReference(), syntax.GetReference(), location) { _property = property; _explicitInterfaceImplementations = explicitInterfaceImplementations; _name = name; _isAutoPropertyAccessor = false; // The modifiers for the accessor are the same as the modifiers for the property, // minus the indexer bit var declarationModifiers = propertyModifiers & ~DeclarationModifiers.Indexer; // ReturnsVoid property is overridden in this class so // returnsVoid argument to MakeFlags is ignored. this.MakeFlags(MethodKind.PropertyGet, declarationModifiers, returnsVoid: false, isExtensionMethod: false, isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any()); CheckModifiersForBody(location, diagnostics); var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers); if (info != null) { diagnostics.Add(info, location); } this.CheckModifiers(location, isAutoPropertyOrExpressionBodied: true, diagnostics: 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; } } }
public DiagnosticDescriptorsInfo(ImmutableArray <DiagnosticDescriptor> supportedDescriptors, bool telemetryAllowed) { SupportedDescriptors = supportedDescriptors; TelemetryAllowed = telemetryAllowed; HasCompilationEndDescriptor = supportedDescriptors.Any(DiagnosticDescriptorExtensions.IsCompilationEnd); }
internal void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocationExpression = (InvocationExpressionSyntax)context.Node; var invokedMethod = context.SemanticModel.GetSymbolInfo(invocationExpression.Expression, context.CancellationToken).Symbol as IMethodSymbol; if (invokedMethod != null && this.getServiceMethods.Contains(invokedMethod.ReducedFrom ?? invokedMethod)) { bool isTask = Utils.IsTask(invokedMethod.ReturnType); SyntaxNode?startWalkFrom = isTask ? (SyntaxNode?)Utils.FindAncestor <AwaitExpressionSyntax>(invocationExpression, n => n is MemberAccessExpressionSyntax || n is InvocationExpressionSyntax, (aes, child) => aes.Expression == child) : invocationExpression; if (startWalkFrom == null) { return; } AssignmentExpressionSyntax?assignment; VariableDeclaratorSyntax? variableDeclarator; if (Utils.FindAncestor <MemberAccessExpressionSyntax>( startWalkFrom, n => n is CastExpressionSyntax || n is ParenthesizedExpressionSyntax || n is AwaitExpressionSyntax, (mae, child) => mae.Expression == child) != null) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, invocationExpression.Expression.GetLocation())); } else if ((assignment = Utils.FindAncestor <AssignmentExpressionSyntax>( startWalkFrom, n => n is CastExpressionSyntax || n is EqualsValueClauseSyntax || n is AwaitExpressionSyntax || (n is BinaryExpressionSyntax be && be.OperatorToken.IsKind(SyntaxKind.AsKeyword)), (aes, child) => aes.Right == child)) != null) { ISymbol leftSymbol = context.SemanticModel.GetSymbolInfo(assignment.Left, context.CancellationToken).Symbol; if (leftSymbol is object) { // If the assigned variable is actually a field, scan this block for Assumes.Present SyntaxNode?parentBlock = Utils.FindFirstAncestorOfTypes(invocationExpression, typeof(BlockSyntax), typeof(ArrowExpressionClauseSyntax)); if (!parentBlock?.DescendantNodes().Any(n => this.IsThrowingNullCheck(n, leftSymbol, context)) ?? true) { // Since we didn't find an Assumes.Present call for this symbol, // if this is a field or property, scan all blocks and expression bodies within this type. // otherwise just scan the blocks under this one. System.Collections.Generic.IEnumerable <Location> derefs; if (leftSymbol is IFieldSymbol || leftSymbol is IPropertySymbol) { derefs = from member in leftSymbol.ContainingType.GetMembers().OfType <IMethodSymbol>() from syntaxRef in member.DeclaringSyntaxReferences let methodSyntax = syntaxRef.GetSyntax(context.CancellationToken) as MethodDeclarationSyntax where methodSyntax != null let bodyOrExpression = (SyntaxNode)methodSyntax.Body ?? methodSyntax.ExpressionBody where bodyOrExpression != null from dref in this.ScanBlockForDereferencesWithoutNullCheck(context, leftSymbol, bodyOrExpression) select dref; } else if (parentBlock is object) { derefs = this.ScanBlockForDereferencesWithoutNullCheck(context, leftSymbol, parentBlock); } else { derefs = Enumerable.Empty <Location>(); } if (derefs.Any()) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, assignment.Left.GetLocation(), derefs)); } } } } else if ((variableDeclarator = Utils.FindAncestor <VariableDeclaratorSyntax>( startWalkFrom, n => n is CastExpressionSyntax || n is EqualsValueClauseSyntax || n is AwaitExpressionSyntax || (n is BinaryExpressionSyntax be && be.OperatorToken.IsKind(SyntaxKind.AsKeyword)), (vds, child) => vds.Initializer == child)) != null) { // The GetService call was assigned via an initializer to a new local variable. Search the code block for uses and null checks. var leftSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclarator, context.CancellationToken) as ILocalSymbol; if (leftSymbol != null) { BlockSyntax containingBlock = context.Node.FirstAncestorOrSelf <BlockSyntax>(); ImmutableArray <Location> derefs = this.ScanBlockForDereferencesWithoutNullCheck(context, leftSymbol, containingBlock); if (derefs.Any()) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, variableDeclarator.Identifier.GetLocation(), derefs)); } } } }
internal static List <TextChange> GetFixListChanges <TNode>( SyntaxNode containingNode, SyntaxNodeOrToken openNodeOrToken, IReadOnlyList <TNode> nodes, ListFixMode fixMode = ListFixMode.Fix, CancellationToken cancellationToken = default) where TNode : SyntaxNode { IndentationAnalysis indentationAnalysis = AnalyzeIndentation(containingNode, cancellationToken); string increasedIndentation = indentationAnalysis.GetIncreasedIndentation(); bool isSingleLine; SeparatedSyntaxList <TNode> separatedList = default; if (nodes is SyntaxList <TNode> list) { isSingleLine = list.IsSingleLine(includeExteriorTrivia: false, cancellationToken: cancellationToken); } else { separatedList = (SeparatedSyntaxList <TNode>)nodes; isSingleLine = separatedList.IsSingleLine( includeExteriorTrivia: false, cancellationToken: cancellationToken); } if (isSingleLine && fixMode == ListFixMode.Fix) { TNode node = nodes[0]; SyntaxTriviaList leading = node.GetLeadingTrivia(); TextSpan span = (leading.Any() && leading.Last().IsWhitespaceTrivia()) ? leading.Last().Span : new TextSpan(node.SpanStart, 0); return(new List <TextChange>() { new TextChange(span, increasedIndentation) }); } var textChanges = new List <TextChange>(); TextLineCollection lines = null; string endOfLine = DetermineEndOfLine(containingNode).ToString(); for (int i = 0; i < nodes.Count; i++) { SyntaxToken token; if (i == 0) { token = (openNodeOrToken.IsNode) ? openNodeOrToken.AsNode().GetLastToken() : openNodeOrToken.AsToken(); } else { token = (list == default) ? separatedList.GetSeparator(i - 1) : list[i - 1].GetLastToken(); } SyntaxTriviaList trailing = token.TrailingTrivia; TNode node = nodes[i]; var indentationAdded = false; if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing)) { SyntaxTrivia last = node.GetLeadingTrivia().LastOrDefault(); if (last.IsWhitespaceTrivia()) { if (last.Span.Length == increasedIndentation.Length) { continue; } textChanges.Add(last.Span, increasedIndentation); } else { textChanges.Add(new TextSpan(node.SpanStart, 0), increasedIndentation); } indentationAdded = true; } else { if (nodes.Count == 1 && node is ArgumentSyntax argument) { LambdaBlock lambdaBlock = GetLambdaBlock(argument, lines ??= argument.SyntaxTree.GetText().Lines); if (lambdaBlock.Block != null) { increasedIndentation = indentationAnalysis.Indentation.ToString(); } } if ((nodes.Count > 1 || fixMode == ListFixMode.Wrap) && ShouldWrapAndIndent(containingNode, i)) { textChanges.Add( (trailing.Any() && trailing.Last().IsWhitespaceTrivia()) ? trailing.Last().Span : new TextSpan(token.FullSpan.End, 0), endOfLine); textChanges.Add(new TextSpan(node.FullSpan.Start, 0), increasedIndentation); indentationAdded = true; } } ImmutableArray <IndentationInfo> indentations = FindIndentations(node, node.Span).ToImmutableArray(); if (!indentations.Any()) { continue; } LambdaBlock lambdaBlock2 = GetLambdaBlock(node, lines ??= node.SyntaxTree.GetText().Lines); bool isLambdaBlockWithOpenBraceAtEndOfLine = lambdaBlock2.Token == indentations.Last().Token; int baseIndentationLength = (isLambdaBlockWithOpenBraceAtEndOfLine) ? indentations.Last().Span.Length : indentations[0].Span.Length; for (int j = indentations.Length - 1; j >= 0; j--) { IndentationInfo indentationInfo = indentations[j]; if (indentationAdded && node is ArgumentSyntax argument && (argument.Expression as AnonymousFunctionExpressionSyntax)?.Block != null) { indentationAdded = false; } string replacement = increasedIndentation; if (indentationAdded) { replacement += indentationAnalysis.GetSingleIndentation(); } if ((j > 0 || isLambdaBlockWithOpenBraceAtEndOfLine) && indentationInfo.Span.Length > baseIndentationLength) { replacement += indentationInfo.ToString().Substring(baseIndentationLength); } if (indentationInfo.Span.Length != replacement.Length) { textChanges.Add(indentationInfo.Span, replacement); } } } FormattingVerifier.VerifyChangedSpansAreWhitespace(containingNode, textChanges); return(textChanges); }
private ImmutableArray<TypeSymbol> TransformTypeArguments(ImmutableArray<TypeSymbol> typeArguments) { if (!typeArguments.Any()) { return typeArguments; } var transformedTypeArgsBuilder = ArrayBuilder<TypeSymbol>.GetInstance(); bool anyTransformed = false; foreach (var typeArg in typeArguments) { TypeSymbol transformedTypeArg = TransformType(typeArg); if ((object)transformedTypeArg == null) { transformedTypeArgsBuilder.Free(); return default(ImmutableArray<TypeSymbol>); } transformedTypeArgsBuilder.Add(transformedTypeArg); anyTransformed |= transformedTypeArg != typeArg; } if (!anyTransformed) { transformedTypeArgsBuilder.Free(); return typeArguments; } return transformedTypeArgsBuilder.ToImmutableAndFree(); }
public static Task <Document> FixCallChainAsync( Document document, ExpressionSyntax expression, TextSpan span, CancellationToken cancellationToken = default) { IndentationAnalysis indentationAnalysis = AnalyzeIndentation(expression, cancellationToken); string indentation = indentationAnalysis.GetIncreasedIndentation(); string endOfLineAndIndentation = DetermineEndOfLine(expression).ToString() + indentation; var textChanges = new List <TextChange>(); int prevIndex = expression.Span.End; foreach (SyntaxNode node in new MethodChain(expression)) { SyntaxKind kind = node.Kind(); if (kind == SyntaxKind.SimpleMemberAccessExpression) { var memberAccess = (MemberAccessExpressionSyntax)node; if (!SetIndentation(memberAccess.OperatorToken)) { break; } } else if (kind == SyntaxKind.MemberBindingExpression) { var memberBinding = (MemberBindingExpressionSyntax)node; if (!SetIndentation(memberBinding.OperatorToken)) { break; } } } FormattingVerifier.VerifyChangedSpansAreWhitespace(expression, textChanges); return(document.WithTextChangesAsync(textChanges, cancellationToken)); bool SetIndentation(SyntaxToken token) { if (token.Span.End > span.End) { return(true); } if (token.SpanStart < span.Start) { return(false); } SyntaxTriviaList leading = token.LeadingTrivia; SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator(); if (!en.MoveNext()) { SyntaxTrivia trivia = expression.FindTrivia(token.SpanStart - 1); string newText = (trivia.IsEndOfLineTrivia()) ? indentation : endOfLineAndIndentation; textChanges.Add(new TextSpan(token.SpanStart, 0), newText); SetIndendation(token, prevIndex); prevIndex = (trivia.IsEndOfLineTrivia()) ? trivia.SpanStart : token.SpanStart; return(true); } SyntaxTrivia last = en.Current; SyntaxKind kind = en.Current.Kind(); if (kind == SyntaxKind.WhitespaceTrivia) { if (en.Current.Span.Length != indentation.Length) { if (!en.MoveNext() || en.Current.IsEndOfLineTrivia()) { SyntaxTrivia trivia = expression.FindTrivia(token.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { textChanges.Add((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span, indentation); SetIndendation(token, prevIndex); prevIndex = trivia.SpanStart; return(true); } } } } else if (kind == SyntaxKind.EndOfLineTrivia) { SyntaxTrivia trivia = expression.FindTrivia(token.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { textChanges.Add((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span, indentation); SetIndendation(token, prevIndex); prevIndex = trivia.SpanStart; return(true); } } prevIndex = leading.Span.Start - 1; return(true); } void SetIndendation(SyntaxToken token, int endIndex) { ImmutableArray <IndentationInfo> indentations = FindIndentations( expression, TextSpan.FromBounds(token.SpanStart, endIndex)) .ToImmutableArray(); if (!indentations.Any()) { return; } int firstIndentationLength = indentations[0].Span.Length; for (int j = 0; j < indentations.Length; j++) { IndentationInfo indentationInfo = indentations[j]; string replacement = indentation + indentationAnalysis.GetSingleIndentation(); if (j > 0 && indentationInfo.Span.Length > firstIndentationLength) { replacement += indentationInfo.ToString().Substring(firstIndentationLength); } if (indentationInfo.Span.Length != replacement.Length) { textChanges.Add(indentationInfo.Span, replacement); } } } }
public static Task <Document> FixBinaryExpressionAsync( Document document, BinaryExpressionSyntax binaryExpression, TextSpan span, CancellationToken cancellationToken) { IndentationAnalysis indentationAnalysis = AnalyzeIndentation(binaryExpression, cancellationToken); string indentation; if (indentationAnalysis.Indentation == binaryExpression.GetLeadingTrivia().LastOrDefault() && document.IsAnalyzerOptionEnabled(AnalyzerOptions.AddNewLineAfterBinaryOperatorInsteadOfBeforeIt)) { indentation = indentationAnalysis.Indentation.ToString(); } else { indentation = indentationAnalysis.GetIncreasedIndentation(); } string endOfLineAndIndentation = DetermineEndOfLine(binaryExpression).ToString() + indentation; var textChanges = new List <TextChange>(); int prevIndex = binaryExpression.Span.End; SyntaxKind binaryKind = binaryExpression.Kind(); while (true) { SyntaxToken token = binaryExpression.OperatorToken; if (token.Span.End > span.End) { continue; } if (token.SpanStart < span.Start) { break; } ExpressionSyntax left = binaryExpression.Left; ExpressionSyntax right = binaryExpression.Right; SyntaxTriviaList leftTrailing = left.GetTrailingTrivia(); SyntaxTriviaList tokenTrailing = token.TrailingTrivia; if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(leftTrailing)) { if (!SetIndentation(token)) { break; } } else if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(tokenTrailing)) { if (!SetIndentation(right)) { break; } } else if (leftTrailing.IsEmptyOrWhitespace() && tokenTrailing.IsEmptyOrWhitespace()) { if (document.IsAnalyzerOptionEnabled(AnalyzerOptions.AddNewLineAfterBinaryOperatorInsteadOfBeforeIt)) { if (!SetIndentation(right)) { break; } } else if (!SetIndentation(token)) { break; } } if (!left.IsKind(binaryKind)) { break; } binaryExpression = (BinaryExpressionSyntax)left; } if (textChanges.Count > 0) { SyntaxTriviaList leading = binaryExpression.GetLeadingTrivia(); if (!leading.Any()) { SyntaxTrivia trivia = binaryExpression.GetFirstToken().GetPreviousToken().TrailingTrivia.LastOrDefault(); if (trivia.IsEndOfLineTrivia() && trivia.Span.End == binaryExpression.SpanStart) { textChanges.Add(new TextSpan(binaryExpression.SpanStart, 0), indentation); } } } FormattingVerifier.VerifyChangedSpansAreWhitespace(binaryExpression, textChanges); return(document.WithTextChangesAsync(textChanges, cancellationToken)); bool SetIndentation(SyntaxNodeOrToken nodeOrToken) { SyntaxTriviaList leading = nodeOrToken.GetLeadingTrivia(); SyntaxTriviaList.Reversed.Enumerator en = leading.Reverse().GetEnumerator(); if (!en.MoveNext()) { SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.SpanStart - 1); string newText = (trivia.IsEndOfLineTrivia()) ? indentation : endOfLineAndIndentation; int start = (trivia.IsWhitespaceTrivia()) ? trivia.SpanStart : nodeOrToken.SpanStart; TextSpan span = (trivia.IsWhitespaceTrivia()) ? trivia.Span : new TextSpan(nodeOrToken.SpanStart, 0); textChanges.Add(span, newText); SetIndendation(nodeOrToken, prevIndex); prevIndex = start; return(true); } SyntaxTrivia last = en.Current; SyntaxKind kind = en.Current.Kind(); if (kind == SyntaxKind.WhitespaceTrivia) { if (en.Current.Span.Length != indentation.Length) { if (!en.MoveNext() || en.Current.IsEndOfLineTrivia()) { SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { AddTextChange((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span); SetIndendation(nodeOrToken, prevIndex); prevIndex = trivia.SpanStart; return(true); } } } } else if (kind == SyntaxKind.EndOfLineTrivia) { SyntaxTrivia trivia = binaryExpression.FindTrivia(nodeOrToken.FullSpan.Start - 1); if (trivia.IsEndOfLineTrivia()) { AddTextChange((leading.IsEmptyOrWhitespace()) ? leading.Span : last.Span); SetIndendation(nodeOrToken, prevIndex); prevIndex = trivia.SpanStart; return(true); } } prevIndex = leading.Span.Start - 1; return(true); void AddTextChange(TextSpan span) => textChanges.Add(span, indentation); } void SetIndendation(SyntaxNodeOrToken nodeOrToken, int endIndex) { ImmutableArray <IndentationInfo> indentations = FindIndentations( binaryExpression, TextSpan.FromBounds(nodeOrToken.SpanStart, endIndex)) .ToImmutableArray(); if (!indentations.Any()) { return; } int firstIndentationLength = indentations[0].Span.Length; for (int j = 0; j < indentations.Length; j++) { IndentationInfo indentationInfo = indentations[j]; string replacement = indentation + indentationAnalysis.GetSingleIndentation(); if (j > 0 && indentationInfo.Span.Length > firstIndentationLength) { replacement += indentationInfo.ToString().Substring(firstIndentationLength); } if (indentationInfo.Span.Length != replacement.Length) { textChanges.Add(indentationInfo.Span, replacement); } } } }
private CommandResult ListSyntax() { IEnumerable <SyntaxItem> items = SyntaxItems.Load(); string filter = Options.Filter; ImmutableArray <SyntaxSection> sections = Options.Sections; if (!string.IsNullOrEmpty(filter)) { items = items.Where(f => f.Text.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0 || f.Description.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0); } if (sections.Any()) { items = items.Join(sections, f => f.Section, f => f, (f, _) => f); } else { items = items.Where(f => f.Section != SyntaxSection.GeneralCategories && f.Section != SyntaxSection.NamedBlocks); } List <SyntaxItem> list; if (sections.Any()) { list = items.GroupBy(f => f.Section).OrderBy(f => sections.IndexOf(f.Key)).SelectMany(f => f).ToList(); } else { list = items.GroupBy(f => f.Section).OrderBy(f => f.Key).SelectMany(f => f).ToList(); } if (list.Count > 0) { int width = list.Max(f => f.Text.Length - f.Text.Count(ch => ch == '%')); foreach (IGrouping <SyntaxSection, SyntaxItem> grouping in list.GroupBy(f => f.Section)) { WriteLine(); WriteLine(TextHelpers.SplitCamelCase(grouping.Key.ToString()).ToUpper()); foreach (SyntaxItem item in grouping) { Write(" "); string text = item.Text; int length = text.Length; int prevIndex = 0; for (int i = 0; i < length; i++) { if (text[i] == '%') { Write(text, prevIndex, i - prevIndex, Colors.Syntax); int j = i + 1; while (j < length && text[j] != '%') { j++; } Write(text, i + 1, j - i - 1); i = j; prevIndex = j + 1; } } Write(text, prevIndex, length - prevIndex, Colors.Syntax); Write(' ', width - text.Length + text.Count(ch => ch == '%')); Write(" "); WriteLine(item.Description); } } return(CommandResult.Success); } else { WriteLine("No syntax found"); return(CommandResult.NoMatch); } }
private static bool IsReadOnly(SourceMemberContainerTypeSymbol containingType, ImmutableArray <Symbol> positionalMembers) { return(containingType.IsReadOnly || (containingType.IsRecordStruct && !positionalMembers.Any(m => hasNonReadOnlyGetter(m))));
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?.GetReference(), location) { _property = property; _explicitInterfaceImplementations = explicitInterfaceImplementations; _name = name; _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 & ~DeclarationModifiers.Indexer; // 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()); var bodyOpt = syntax.Body; if (bodyOpt != null) { CheckModifiersForBody(location, diagnostics); } 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. _name = overriddenMethod.Name; } } }
private static void VerifyDiagnosticsArgument(ImmutableArray<Diagnostic> diagnostics, TextSpan span) { if (diagnostics.IsDefault) { throw new ArgumentException(nameof(diagnostics)); } if (diagnostics.Length == 0) { throw new ArgumentException(WorkspacesResources.DiagnosticsCannotBeEmpty, nameof(diagnostics)); } if (diagnostics.Any(d => d == null)) { throw new ArgumentException(WorkspacesResources.DiagnosticCannotBeNull, nameof(diagnostics)); } if (diagnostics.Any(d => d.Location.SourceSpan != span)) { throw new ArgumentException(string.Format(WorkspacesResources.DiagnosticMustHaveMatchingSpan, span.ToString()), nameof(diagnostics)); } }
// Only when the caller passes allowAlpha=true do we tolerate substituted (alpha-renamed) type parameters as keys internal TypeMap(ImmutableArray <TypeParameterSymbol> from, ImmutableArray <TypeWithModifiers> to, bool allowAlpha = false) : base(ConstructMapping(from, to)) { // mapping contents are read-only hereafter Debug.Assert(allowAlpha || !from.Any(tp => tp is SubstitutedTypeParameterSymbol)); }
private void EarlyDecodeWellKnownAttributeTypes(ImmutableArray<NamedTypeSymbol> attributeTypes, ImmutableArray<AttributeSyntax> attributeSyntaxList) { Debug.Assert(attributeSyntaxList.Any()); Debug.Assert(attributeTypes.Any()); for (int i = 0; i < attributeTypes.Length; i++) { var attributeType = attributeTypes[i]; if (!attributeType.IsErrorType()) { this.EarlyDecodeWellKnownAttributeType(attributeType, attributeSyntaxList[i]); } } }
private async Task <ProjectFixResult> FixProjectAsync( Project project, ImmutableArray <DiagnosticAnalyzer> analyzers, ImmutableArray <CodeFixProvider> fixers, CancellationToken cancellationToken) { if (!analyzers.Any()) { WriteLine($" No analyzers found to analyze '{project.Name}'", ConsoleColor.DarkGray, Verbosity.Normal); return(ProjectFixResult.NoAnalyzers); } if (!fixers.Any()) { WriteLine($" No fixers found to fix '{project.Name}'", ConsoleColor.DarkGray, Verbosity.Normal); return(new ProjectFixResult(ProjectFixKind.NoFixers, analyzers: analyzers, fixers: fixers)); } Dictionary <string, ImmutableArray <CodeFixProvider> > fixersById = GetFixersById(fixers, Options); analyzers = analyzers .Where(analyzer => analyzer.SupportedDiagnostics.Any(descriptor => fixersById.ContainsKey(descriptor.Id))) .ToImmutableArray(); if (!analyzers.Any()) { WriteLine($" No fixable analyzers found to analyze '{project.Name}'", ConsoleColor.DarkGray, Verbosity.Normal); return(new ProjectFixResult(ProjectFixKind.NoFixableAnalyzers, analyzers: analyzers, fixers: fixers)); } Dictionary <string, ImmutableArray <DiagnosticAnalyzer> > analyzersById = GetAnalyzersById(analyzers); LogHelpers.WriteUsedAnalyzers(analyzers, project, Options, ConsoleColor.DarkGray, Verbosity.Diagnostic); LogHelpers.WriteUsedFixers(fixers, ConsoleColor.DarkGray, Verbosity.Diagnostic); ImmutableArray <Diagnostic> .Builder fixedDiagnostics = ImmutableArray.CreateBuilder <Diagnostic>(); ImmutableArray <Diagnostic> previousDiagnostics = ImmutableArray <Diagnostic> .Empty; ImmutableArray <Diagnostic> previousPreviousDiagnostics = ImmutableArray <Diagnostic> .Empty; var fixKind = ProjectFixKind.Success; for (int iterationCount = 1; ; iterationCount++) { cancellationToken.ThrowIfCancellationRequested(); project = CurrentSolution.GetProject(project.Id); WriteLine($" Compile '{project.Name}'{((iterationCount > 1) ? $" iteration {iterationCount}" : "")}", Verbosity.Normal); Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); if (!VerifyCompilerDiagnostics(compilerDiagnostics, project)) { return(new ProjectFixResult(ProjectFixKind.CompilerError, fixedDiagnostics, analyzers: analyzers, fixers: fixers)); } WriteLine($" Analyze '{project.Name}'", Verbosity.Normal); ImmutableArray <Diagnostic> diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(analyzers, Options.CompilationWithAnalyzersOptions, cancellationToken).ConfigureAwait(false); LogHelpers.WriteAnalyzerExceptionDiagnostics(diagnostics); diagnostics = GetFixableDiagnostics(diagnostics, compilerDiagnostics); int length = diagnostics.Length; if (length == 0) { break; } if (length == previousDiagnostics.Length && !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any()) { break; } if (length == previousPreviousDiagnostics.Length && !diagnostics.Except(previousPreviousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any()) { LogHelpers.WriteInfiniteLoopSummary(diagnostics, previousDiagnostics, project, FormatProvider); fixKind = ProjectFixKind.InfiniteLoop; break; } WriteLine($" Found {length} {((length == 1) ? "diagnostic" : "diagnostics")} in '{project.Name}'", Verbosity.Normal); foreach (DiagnosticDescriptor descriptor in GetSortedDescriptors(diagnostics)) { cancellationToken.ThrowIfCancellationRequested(); string diagnosticId = descriptor.Id; DiagnosticFixResult result = await FixDiagnosticsAsync( descriptor, (descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Compiler)) ?default(ImmutableArray <DiagnosticAnalyzer>) : analyzersById[diagnosticId], fixersById[diagnosticId], CurrentSolution.GetProject(project.Id), cancellationToken).ConfigureAwait(false); if (result.Kind == DiagnosticFixKind.Success) { fixedDiagnostics.AddRange(result.FixedDiagnostics); } else if (result.Kind == DiagnosticFixKind.CompilerError) { return(new ProjectFixResult(ProjectFixKind.CompilerError, fixedDiagnostics, analyzers: analyzers, fixers: fixers)); } } if (iterationCount == Options.MaxIterations) { break; } previousPreviousDiagnostics = previousDiagnostics; previousDiagnostics = diagnostics; } return(new ProjectFixResult(fixKind, fixedDiagnostics, analyzers: analyzers, fixers: fixers)); ImmutableArray <Diagnostic> GetFixableDiagnostics( ImmutableArray <Diagnostic> diagnostics, ImmutableArray <Diagnostic> compilerDiagnostics) { IEnumerable <Diagnostic> fixableCompilerDiagnostics = compilerDiagnostics .Where(f => f.Severity != DiagnosticSeverity.Error && !Options.IgnoredCompilerDiagnosticIds.Contains(f.Id) && fixersById.ContainsKey(f.Id)); return(diagnostics .Where(f => Options.IsSupportedDiagnostic(f) && analyzersById.ContainsKey(f.Id) && fixersById.ContainsKey(f.Id)) .Concat(fixableCompilerDiagnostics) .ToImmutableArray()); } IEnumerable <DiagnosticDescriptor> GetSortedDescriptors( ImmutableArray <Diagnostic> diagnostics) { Dictionary <DiagnosticDescriptor, int> countByDescriptor = diagnostics .GroupBy(f => f.Descriptor, DiagnosticDescriptorComparer.Id) .ToDictionary(f => f.Key, f => f.Count()); return(countByDescriptor .Select(f => f.Key) .OrderBy(f => f, new DiagnosticDescriptorFixComparer(countByDescriptor, fixersById))); } }
internal override void PostDecodeWellKnownAttributes(ImmutableArray <CSharpAttributeData> boundAttributes, ImmutableArray <AttributeSyntax> allAttributeSyntaxNodes, DiagnosticBag diagnostics, AttributeLocation symbolPart, WellKnownAttributeData decodedData) { Debug.Assert(!boundAttributes.IsDefault); Debug.Assert(!allAttributeSyntaxNodes.IsDefault); Debug.Assert(boundAttributes.Length == allAttributeSyntaxNodes.Length); Debug.Assert(_lazyCustomAttributesBag != null); Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed); Debug.Assert(symbolPart == AttributeLocation.None); var data = (TypeWellKnownAttributeData)decodedData; if (this.IsComImport) { Debug.Assert(boundAttributes.Any()); // Symbol with ComImportAttribute must have a GuidAttribute if (data == null || data.GuidString == null) { int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.ComImportAttribute); diagnostics.Add(ErrorCode.ERR_ComImportWithoutUuidAttribute, allAttributeSyntaxNodes[index].Name.Location, this.Name); } if (this.TypeKind == TypeKind.Class) { var baseType = this.BaseTypeNoUseSiteDiagnostics; if ((object)baseType != null && baseType.SpecialType != SpecialType.System_Object) { // CS0424: '{0}': a class with the ComImport attribute cannot specify a base class diagnostics.Add(ErrorCode.ERR_ComImportWithBase, this.Locations[0], this.Name); } var initializers = this.StaticInitializers; if (!initializers.IsDefaultOrEmpty) { foreach (var initializerGroup in initializers) { foreach (var singleInitializer in initializerGroup) { if (!singleInitializer.FieldOpt.IsMetadataConstant) { // CS8028: '{0}': a class with the ComImport attribute cannot specify field initializers. diagnostics.Add(ErrorCode.ERR_ComImportWithInitializers, singleInitializer.Syntax.GetLocation(), this.Name); } } } } initializers = this.InstanceInitializers; if (!initializers.IsDefaultOrEmpty) { foreach (var initializerGroup in initializers) { foreach (var singleInitializer in initializerGroup) { // CS8028: '{0}': a class with the ComImport attribute cannot specify field initializers. diagnostics.Add(ErrorCode.ERR_ComImportWithInitializers, singleInitializer.Syntax.GetLocation(), this.Name); } } } } } else if ((object)this.ComImportCoClass != null) { Debug.Assert(boundAttributes.Any()); // Symbol with CoClassAttribute must have a ComImportAttribute int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.CoClassAttribute); diagnostics.Add(ErrorCode.WRN_CoClassWithoutComImport, allAttributeSyntaxNodes[index].Location, this.Name); } // Report ERR_DefaultMemberOnIndexedType if type has a default member attribute and has indexers. if (data != null && data.HasDefaultMemberAttribute && this.Indexers.Any()) { Debug.Assert(boundAttributes.Any()); int index = boundAttributes.IndexOfAttribute(this, AttributeDescription.DefaultMemberAttribute); diagnostics.Add(ErrorCode.ERR_DefaultMemberOnIndexedType, allAttributeSyntaxNodes[index].Name.Location); } base.PostDecodeWellKnownAttributes(boundAttributes, allAttributeSyntaxNodes, diagnostics, symbolPart, decodedData); }
private async Task <DiagnosticFixResult> FixDiagnosticsAsync( DiagnosticDescriptor descriptor, ImmutableArray <DiagnosticAnalyzer> analyzers, ImmutableArray <CodeFixProvider> fixers, Project project, CancellationToken cancellationToken) { ImmutableArray <Diagnostic> .Builder fixedDiagostics = ImmutableArray.CreateBuilder <Diagnostic>(); ImmutableArray <Diagnostic> diagnostics = ImmutableArray <Diagnostic> .Empty; ImmutableArray <Diagnostic> previousDiagnostics = ImmutableArray <Diagnostic> .Empty; ImmutableArray <Diagnostic> previousDiagnosticsToFix = ImmutableArray <Diagnostic> .Empty; int length = 0; var fixKind = DiagnosticFixKind.NotFixed; while (true) { Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); if (!VerifyCompilerDiagnostics(compilerDiagnostics, project)) { fixKind = DiagnosticFixKind.CompilerError; if (!previousDiagnostics.Any()) { break; } } if (analyzers.IsDefault) { diagnostics = compilerDiagnostics; } else { diagnostics = await compilation.GetAnalyzerDiagnosticsAsync(analyzers, Options.CompilationWithAnalyzersOptions, cancellationToken).ConfigureAwait(false); } diagnostics = diagnostics .Where(f => f.Id == descriptor.Id && f.Severity >= Options.SeverityLevel) .ToImmutableArray(); if (fixKind == DiagnosticFixKind.CompilerError) { break; } else if (fixKind == DiagnosticFixKind.Success) { if (Options.BatchSize <= 0 || length <= Options.BatchSize) { break; } } else if (previousDiagnostics.Any() && fixKind != DiagnosticFixKind.PartiallyFixed) { break; } length = diagnostics.Length; if (length == 0) { break; } if (length == previousDiagnostics.Length && !diagnostics.Except(previousDiagnostics, DiagnosticDeepEqualityComparer.Instance).Any()) { break; } fixedDiagostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance)); previousDiagnostics = diagnostics; if (Options.BatchSize > 0 && length > Options.BatchSize) { diagnostics = ImmutableArray.CreateRange(diagnostics, 0, Options.BatchSize, f => f); } fixKind = await FixDiagnosticsAsync(diagnostics, descriptor, fixers, project, cancellationToken).ConfigureAwait(false); previousDiagnosticsToFix = diagnostics; project = CurrentSolution.GetProject(project.Id); } fixedDiagostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance)); return(new DiagnosticFixResult(fixKind, fixedDiagostics.ToImmutableArray())); }
/// <summary> /// This method does the following set of operations in the specified order: /// (1) GetAttributesToBind: Merge attributes from the given attributesSyntaxLists and filter out attributes by attribute target. /// (2) BindAttributeTypes: Bind all the attribute types to enable early decode of certain well-known attributes by type. /// (3) EarlyDecodeWellKnownAttributes: Perform early decoding of certain well-known attributes that could be queried by the binder in subsequent steps. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (4) GetAttributes: Bind the attributes (attribute arguments and constructor) using bound attribute types. /// (5) DecodeWellKnownAttributes: Decode and validate bound well known attributes. /// (NOTE: This step has the side effect of updating the symbol state based on the data extracted from well known attributes). /// (6) StoreBoundAttributesAndDoPostValidation: /// (a) Store the bound attributes in lazyCustomAttributes in a thread safe manner. /// (b) Perform some additional post attribute validations, such as /// 1) Duplicate attributes, attribute usage target validation, etc. /// 2) Post validation for attributes dependent on other attributes /// These validations cannot be performed prior to step 6(a) as we might need to /// perform a GetAttributes() call on a symbol which can introduce a cycle in attribute binding. /// We avoid this cycle by performing such validations in PostDecodeWellKnownAttributes after lazyCustomAttributes have been set. /// NOTE: PostDecodeWellKnownAttributes SHOULD NOT change the symbol state. /// </summary> /// <remarks> /// Current design of early decoding well-known attributes doesn't permit decoding attribute arguments/constructor as this can lead to binding cycles. /// For well-known attributes used by the binder, where we need the decoded arguments, we must handle them specially in one of the following possible ways: /// (a) Avoid decoding the attribute arguments during binding and delay the corresponding binder tasks to a separate post-pass executed after binding. /// (b) As the cycles can be caused only when we are binding attribute arguments/constructor, special case the corresponding binder tasks based on the current BinderFlags. /// </remarks> /// <param name="attributesSyntaxLists"></param> /// <param name="lazyCustomAttributesBag"></param> /// <param name="symbolPart">Specific part of the symbol to which the attributes apply, or <see cref="AttributeLocation.None"/> if the attributes apply to the symbol itself.</param> /// <param name="earlyDecodingOnly">Indicates that only early decoding should be performed. WARNING: the resulting bag will not be sealed.</param> /// <param name="binderOpt">Binder to use. If null, <see cref="DeclaringCompilation"/> GetBinderFactory will be used.</param> /// <param name="attributeMatchesOpt">If specified, only load attributes that match this predicate, and any diagnostics produced will be dropped.</param> /// <returns>Flag indicating whether lazyCustomAttributes were stored on this thread. Caller should check for this flag and perform NotePartComplete if true.</returns> internal bool LoadAndValidateAttributes( OneOrMany <SyntaxList <AttributeListSyntax> > attributesSyntaxLists, ref CustomAttributesBag <CSharpAttributeData> lazyCustomAttributesBag, AttributeLocation symbolPart = AttributeLocation.None, bool earlyDecodingOnly = false, Binder binderOpt = null, Func <AttributeSyntax, bool> attributeMatchesOpt = null) { var diagnostics = DiagnosticBag.GetInstance(); var compilation = this.DeclaringCompilation; ImmutableArray <Binder> binders; ImmutableArray <AttributeSyntax> attributesToBind = this.GetAttributesToBind(attributesSyntaxLists, symbolPart, diagnostics, compilation, attributeMatchesOpt, binderOpt, out binders); Debug.Assert(!attributesToBind.IsDefault); ImmutableArray <CSharpAttributeData> boundAttributes; WellKnownAttributeData wellKnownAttributeData; if (attributesToBind.Any()) { Debug.Assert(!binders.IsDefault); Debug.Assert(binders.Length == attributesToBind.Length); // Initialize the bag so that data decoded from early attributes can be stored onto it. if (lazyCustomAttributesBag == null) { Interlocked.CompareExchange(ref lazyCustomAttributesBag, new CustomAttributesBag <CSharpAttributeData>(), null); } // Bind the attribute types and then early decode them. int totalAttributesCount = attributesToBind.Length; var attributeTypesBuilder = new NamedTypeSymbol[totalAttributesCount]; Binder.BindAttributeTypes(binders, attributesToBind, this, attributeTypesBuilder, diagnostics); ImmutableArray <NamedTypeSymbol> boundAttributeTypes = attributeTypesBuilder.AsImmutableOrNull(); this.EarlyDecodeWellKnownAttributeTypes(boundAttributeTypes, attributesToBind); this.PostEarlyDecodeWellKnownAttributeTypes(); // Bind the attribute in two stages - early and normal. var attributesBuilder = new CSharpAttributeData[totalAttributesCount]; // Early bind and decode some well-known attributes. EarlyWellKnownAttributeData earlyData = this.EarlyDecodeWellKnownAttributes(binders, boundAttributeTypes, attributesToBind, symbolPart, attributesBuilder); Debug.Assert(!attributesBuilder.Contains((attr) => attr != null && attr.HasErrors)); // Store data decoded from early bound well-known attributes. // TODO: what if this succeeds on another thread, not ours? lazyCustomAttributesBag.SetEarlyDecodedWellKnownAttributeData(earlyData); if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return(false); } // Bind attributes. Binder.GetAttributes(binders, attributesToBind, boundAttributeTypes, attributesBuilder, diagnostics); boundAttributes = attributesBuilder.AsImmutableOrNull(); // All attributes must be bound by now. Debug.Assert(!boundAttributes.Any((attr) => attr == null)); // Validate attribute usage and Decode remaining well-known attributes. wellKnownAttributeData = this.ValidateAttributeUsageAndDecodeWellKnownAttributes(binders, attributesToBind, boundAttributes, diagnostics, symbolPart); // Store data decoded from remaining well-known attributes. // TODO: what if this succeeds on another thread but not this thread? lazyCustomAttributesBag.SetDecodedWellKnownAttributeData(wellKnownAttributeData); } else if (earlyDecodingOnly) { diagnostics.Free(); //NOTE: dropped. return(false); } else { boundAttributes = ImmutableArray <CSharpAttributeData> .Empty; wellKnownAttributeData = null; Interlocked.CompareExchange(ref lazyCustomAttributesBag, CustomAttributesBag <CSharpAttributeData> .WithEmptyData(), null); this.PostEarlyDecodeWellKnownAttributeTypes(); } this.PostDecodeWellKnownAttributes(boundAttributes, attributesToBind, diagnostics, symbolPart, wellKnownAttributeData); // Store attributes into the bag. bool lazyAttributesStoredOnThisThread = false; if (lazyCustomAttributesBag.SetAttributes(boundAttributes)) { if (attributeMatchesOpt is null) { this.RecordPresenceOfBadAttributes(boundAttributes); AddDeclarationDiagnostics(diagnostics); } lazyAttributesStoredOnThisThread = true; if (lazyCustomAttributesBag.IsEmpty) { lazyCustomAttributesBag = CustomAttributesBag <CSharpAttributeData> .Empty; } } Debug.Assert(lazyCustomAttributesBag.IsSealed); diagnostics.Free(); return(lazyAttributesStoredOnThisThread); }
public void My(ImmutableArray <B> analyzers) // Error [CS0122] { if (analyzers.Any(x => x == null)) //compliant, B is a class { } }
public static void AnalyzeBaseList(SyntaxNodeAnalysisContext context) { var baseList = (BaseListSyntax)context.Node; if (!baseList.IsParentKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration)) { return; } if (baseList.ContainsDiagnostics) { return; } if (baseList.SpanContainsDirectives()) { return; } SeparatedSyntaxList <BaseTypeSyntax> baseTypes = baseList.Types; if (baseTypes.Count <= 1) { return; } bool isFirst = true; INamedTypeSymbol typeSymbol = null; var baseClassInfo = default(SymbolInterfaceInfo); List <SymbolInterfaceInfo> baseInterfaceInfos = null; foreach (BaseTypeSyntax baseType in baseTypes) { TypeSyntax type = baseType.Type; if (type?.IsMissing == false && (context.SemanticModel.GetSymbol(type, context.CancellationToken) is INamedTypeSymbol baseSymbol)) { TypeKind typeKind = baseSymbol.TypeKind; ImmutableArray <INamedTypeSymbol> allInterfaces = baseSymbol.AllInterfaces; if (typeKind == TypeKind.Class) { if (!isFirst) { break; } if (allInterfaces.Any()) { baseClassInfo = new SymbolInterfaceInfo(baseType, baseSymbol, allInterfaces); } } else if (typeKind == TypeKind.Interface) { var baseInterfaceInfo = new SymbolInterfaceInfo(baseType, baseSymbol, allInterfaces); if (baseInterfaceInfos == null) { if (allInterfaces.Any()) { baseInterfaceInfos = new List <SymbolInterfaceInfo>() { baseInterfaceInfo } } ; } else { foreach (SymbolInterfaceInfo baseInterfaceInfo2 in baseInterfaceInfos) { Analyze(context, baseInterfaceInfo, baseInterfaceInfo2); Analyze(context, baseInterfaceInfo2, baseInterfaceInfo); } } if (baseClassInfo.IsValid) { if (typeSymbol == null) { typeSymbol = context.SemanticModel.GetDeclaredSymbol((TypeDeclarationSyntax)baseList.Parent, context.CancellationToken); } Analyze(context, baseInterfaceInfo, baseClassInfo, typeSymbol); } } } if (isFirst) { isFirst = false; } } }
private Task ReduceAsync( Document document, SyntaxNode root, ImmutableArray <NodeOrTokenToReduce> nodesAndTokensToReduce, ImmutableArray <AbstractReducer> reducers, OptionSet optionSet, SemanticModel semanticModel, ConcurrentDictionary <SyntaxNode, SyntaxNode> reducedNodesMap, ConcurrentDictionary <SyntaxToken, SyntaxToken> reducedTokensMap, CancellationToken cancellationToken) { Contract.ThrowIfFalse(nodesAndTokensToReduce.Any()); // Reduce each node or token in the given list by running it through each reducer. var simplifyTasks = new Task[nodesAndTokensToReduce.Length]; for (int i = 0; i < nodesAndTokensToReduce.Length; i++) { var nodeOrTokenToReduce = nodesAndTokensToReduce[i]; simplifyTasks[i] = Task.Run(async() => { var nodeOrToken = nodeOrTokenToReduce.OriginalNodeOrToken; var simplifyAllDescendants = nodeOrTokenToReduce.SimplifyAllDescendants; var semanticModelForReduce = semanticModel; var currentNodeOrToken = nodeOrTokenToReduce.NodeOrToken; var isNode = nodeOrToken.IsNode; foreach (var reducer in reducers) { cancellationToken.ThrowIfCancellationRequested(); using (var rewriter = reducer.GetOrCreateRewriter()) { rewriter.Initialize(document.Project.ParseOptions, optionSet, cancellationToken); do { if (currentNodeOrToken.SyntaxTree != semanticModelForReduce.SyntaxTree) { // currentNodeOrToken was simplified either by a previous reducer or // a previous iteration of the current reducer. // Create a speculative semantic model for the simplified node for semantic queries. // Certain node kinds (expressions/statements) require non-null parent nodes during simplification. // However, the reduced nodes haven't been parented yet, so do the required parenting using the original node's parent. if (currentNodeOrToken.Parent == null && nodeOrToken.Parent != null && (currentNodeOrToken.IsToken || currentNodeOrToken.AsNode() is TExpressionSyntax || currentNodeOrToken.AsNode() is TStatementSyntax || currentNodeOrToken.AsNode() is TCrefSyntax)) { var annotation = new SyntaxAnnotation(); currentNodeOrToken = currentNodeOrToken.WithAdditionalAnnotations(annotation); var replacedParent = isNode ? nodeOrToken.Parent.ReplaceNode(nodeOrToken.AsNode(), currentNodeOrToken.AsNode()) : nodeOrToken.Parent.ReplaceToken(nodeOrToken.AsToken(), currentNodeOrToken.AsToken()); currentNodeOrToken = replacedParent .ChildNodesAndTokens() .Single(c => c.HasAnnotation(annotation)); } if (isNode) { var currentNode = currentNodeOrToken.AsNode(); if (this.CanNodeBeSimplifiedWithoutSpeculation(nodeOrToken.AsNode())) { // Since this node cannot be speculated, we are replacing the Document with the changes and get a new SemanticModel var marker = new SyntaxAnnotation(); var newRoot = root.ReplaceNode(nodeOrToken.AsNode(), currentNode.WithAdditionalAnnotations(marker)); var newDocument = document.WithSyntaxRoot(newRoot); semanticModelForReduce = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); newRoot = await semanticModelForReduce.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); currentNodeOrToken = newRoot.DescendantNodes().Single(c => c.HasAnnotation(marker)); } else { // Create speculative semantic model for simplified node. semanticModelForReduce = GetSpeculativeSemanticModel(ref currentNode, semanticModel, nodeOrToken.AsNode()); currentNodeOrToken = currentNode; } } } // Reduce the current node or token. currentNodeOrToken = rewriter.VisitNodeOrToken(currentNodeOrToken, semanticModelForReduce, simplifyAllDescendants); }while (rewriter.HasMoreWork); } } // If nodeOrToken was simplified, add it to the appropriate dictionary of replaced nodes/tokens. if (currentNodeOrToken != nodeOrToken) { if (isNode) { reducedNodesMap[nodeOrToken.AsNode()] = currentNodeOrToken.AsNode(); } else { reducedTokensMap[nodeOrToken.AsToken()] = currentNodeOrToken.AsToken(); } } }, cancellationToken); } return(Task.WhenAll(simplifyTasks)); }
/// <summary> /// Apply type substitution to a generic method to create an method symbol with the given type parameters supplied. /// </summary> /// <param name="typeArguments"></param> /// <returns></returns> public MethodSymbol Construct(ImmutableArray<TypeSymbol> typeArguments) { if (!ReferenceEquals(this, ConstructedFrom) || this.Arity == 0) { throw new InvalidOperationException(); } if (typeArguments.IsDefault) { throw new ArgumentNullException(nameof(typeArguments)); } if (typeArguments.Any(TypeSymbolIsNullFunction)) { throw new ArgumentException(); // (CSharpResources.TypeArgumentCannotBeNull, nameof(typeArguments)); } if (typeArguments.Length != this.Arity) { throw new ArgumentException(); // (CSharpResources.WrongNumberOfTypeArguments, nameof(typeArguments)); } if (TypeParametersMatchTypeArguments(this.TypeParameters, typeArguments)) { return this; } return new ConstructedMethodSymbol(this, typeArguments); }
private static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context) { var classDeclaration = (ClassDeclarationSyntax)context.Node; if (classDeclaration.Modifiers.ContainsAny( SyntaxKind.StaticKeyword, SyntaxKind.AbstractKeyword, SyntaxKind.SealedKeyword, SyntaxKind.PartialKeyword)) { return; } if (!classDeclaration.Members.Any()) { return; } INamedTypeSymbol symbol = context.SemanticModel.GetDeclaredSymbol(classDeclaration, context.CancellationToken); if (symbol.BaseType?.IsObject() != true) { return; } if (!symbol.Interfaces.IsDefaultOrEmpty) { return; } ImmutableArray <ISymbol> members = symbol.GetMembers(); if (!members.Any()) { return; } if (!AnalyzeMembers(members)) { return; } bool canBeMadeStatic; MakeClassStaticWalker walker = null; try { walker = MakeClassStaticWalker.GetInstance(); walker.CanBeMadeStatic = true; walker.Symbol = symbol; walker.SemanticModel = context.SemanticModel; walker.CancellationToken = context.CancellationToken; walker.Visit(classDeclaration); canBeMadeStatic = walker.CanBeMadeStatic; } finally { if (walker != null) { MakeClassStaticWalker.Free(walker); } } if (canBeMadeStatic) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.MakeClassStatic, classDeclaration.Identifier); } }
void AppendTypeParameters (StringBuilder result, ImmutableArray<ITypeSymbol> typeParameters) { if (!typeParameters.Any ()) return; result.Append ("<"); int i = 0; foreach (var typeParameter in typeParameters) { if (i > 0) { if (i % 5 == 0) { result.AppendLine (","); result.Append ("\t"); } else { result.Append (", "); } } if (typeParameter is ITypeParameterSymbol) AppendVariance (result, ((ITypeParameterSymbol)typeParameter).Variance); result.Append (GetTypeReferenceString (typeParameter, false)); i++; } result.Append (">"); }
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, isIterator: SyntaxFacts.HasYieldOperations(syntax.Body)) { _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; _usesInit = syntax.Keyword.IsKind(SyntaxKind.InitKeyword); if (_usesInit) { Binder.CheckFeatureAvailability(syntax, MessageID.IDS_FeatureInitOnlySetters, diagnostics, syntax.Keyword.GetLocation()); } 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 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?.GetReference(), location) { _property = property; _explicitInterfaceImplementations = explicitInterfaceImplementations; _name = name; _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 & ~DeclarationModifiers.Indexer; // 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()); var bodyOpt = syntax.Body; if (bodyOpt != null) { CheckModifiersForBody(location, diagnostics); } 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. _name = overriddenMethod.Name; } } }
internal static bool ContainsAttributeType(this ImmutableArray <AttributeData> attributes, INamedTypeSymbol attributeType, bool exactMatch = false) { return(attributes.Any(a => attributeType.IsAssignableFrom(a.AttributeClass, exactMatch))); }
public static bool AnalyzeMembers(INamedTypeSymbol symbol) { ImmutableArray <ISymbol> members = symbol.GetMembers(); if (members.Any(f => !f.IsImplicitlyDeclared)) { foreach (ISymbol memberSymbol in members) { switch (memberSymbol.Kind) { case SymbolKind.ErrorType: { return(false); } case SymbolKind.NamedType: { var namedTypeSymbol = (INamedTypeSymbol)memberSymbol; switch (namedTypeSymbol.TypeKind) { case TypeKind.Unknown: case TypeKind.Error: { return(false); } case TypeKind.Class: case TypeKind.Delegate: case TypeKind.Enum: case TypeKind.Interface: case TypeKind.Struct: { if (memberSymbol.IsDeclaredAccessibility(Accessibility.Protected, Accessibility.ProtectedOrInternal)) { return(false); } break; } default: { Debug.Fail(namedTypeSymbol.TypeKind.ToString()); break; } } break; } default: { if (memberSymbol.IsDeclaredAccessibility(Accessibility.Protected, Accessibility.ProtectedOrInternal)) { return(false); } if (!memberSymbol.IsImplicitlyDeclared && !memberSymbol.IsStatic) { return(false); } break; } } } return(true); } return(false); }
internal static bool HasInAttributeModifier(this ImmutableArray <CustomModifier> modifiers) { return(modifiers.Any(modifier => !modifier.IsOptional && modifier.Modifier.IsWellKnownTypeInAttribute())); }
// Only when the caller passes allowAlpha=true do we tolerate substituted (alpha-renamed) type parameters as keys internal TypeMap(ImmutableArray<TypeParameterSymbol> from, ImmutableArray<TypeWithModifiers> to, bool allowAlpha = false) : base(ConstructMapping(from, to)) { // mapping contents are read-only hereafter Debug.Assert(allowAlpha || !from.Any(tp => tp is SubstitutedTypeParameterSymbol)); }
public static bool TryParse( IEnumerable <string> values, out PowerStatus status, out ImmutableArray <ParseError> errors) { ImmutableArray <string> array = values?.ToImmutableArray() ?? ImmutableArray <string> .Empty; if (array.Length == 0) { status = default; errors = new[] { new ParseError("Array is empty") }.ToImmutableArray(); return(false); } if (!array.Any(line => line.StartsWith($"{BatteryCharge}:", StringComparison.OrdinalIgnoreCase))) { errors = new[] { new ParseError($"Missing property {BatteryCharge}") }.ToImmutableArray(); status = default; return(false); } string PropertyValue(string lookup) { string[] matchingLines = array .Where(line => !string.IsNullOrWhiteSpace(line) && line.StartsWith($"{lookup}:", StringComparison.OrdinalIgnoreCase)) .ToArray(); if (matchingLines.Length != 1) { return(null); } string propertyAndValue = matchingLines[0]; if (!propertyAndValue.Contains(':')) { return(null); } string[] strings = propertyAndValue.Split(':'); if (strings.Length != 2) { return(null); } return(strings[1].Trim()); } double?NumericValue(string value) { if (string.IsNullOrWhiteSpace(value)) { return(null); } if (int.TryParse(value, out int numericInteger)) { return(numericInteger); } if (!double.TryParse(value, out double numeric)) { return(null); } return(numeric); } ImmutableDictionary <string, string> properties = array .Where(line => line.Contains(".") && line.Contains(":")) .Select(line => { string[] parts = line.Split(':'); if (parts.Length != 2) { return(default);
/// <summary> /// Method to early decode certain well-known attributes which can be queried by the binder. /// This method is called during attribute binding after we have bound the attribute types for all attributes, /// but haven't yet bound the attribute arguments/attribute constructor. /// Early decoding certain well-known attributes enables the binder to use this decoded information on this symbol /// when binding the attribute arguments/attribute constructor without causing attribute binding cycle. /// </summary> internal EarlyWellKnownAttributeData EarlyDecodeWellKnownAttributes( ImmutableArray<Binder> binders, ImmutableArray<NamedTypeSymbol> boundAttributeTypes, ImmutableArray<AttributeSyntax> attributesToBind, AttributeLocation symbolPart, CSharpAttributeData[] boundAttributesBuilder) { Debug.Assert(boundAttributeTypes.Any()); Debug.Assert(attributesToBind.Any()); Debug.Assert(binders.Any()); Debug.Assert(boundAttributesBuilder != null); Debug.Assert(!boundAttributesBuilder.Contains((attr) => attr != null)); var earlyBinder = new EarlyWellKnownAttributeBinder(binders[0]); var arguments = new EarlyDecodeWellKnownAttributeArguments<EarlyWellKnownAttributeBinder, NamedTypeSymbol, AttributeSyntax, AttributeLocation>(); arguments.SymbolPart = symbolPart; for (int i = 0; i < boundAttributeTypes.Length; i++) { NamedTypeSymbol boundAttributeType = boundAttributeTypes[i]; if (!boundAttributeType.IsErrorType()) { if (binders[i] != earlyBinder.Next) { earlyBinder = new EarlyWellKnownAttributeBinder(binders[i]); } arguments.Binder = earlyBinder; arguments.AttributeType = boundAttributeType; arguments.AttributeSyntax = attributesToBind[i]; // Early bind some well-known attributes CSharpAttributeData earlyBoundAttributeOpt = this.EarlyDecodeWellKnownAttribute(ref arguments); Debug.Assert(earlyBoundAttributeOpt == null || !earlyBoundAttributeOpt.HasErrors); boundAttributesBuilder[i] = earlyBoundAttributeOpt; } } return arguments.HasDecodedData ? arguments.DecodedData : null; }
private bool IsAnyNullRejected(ImmutableArray <ValueSlot> valueSlots) { return(valueSlots.Any(_nullRejectedRowBufferEntries.Contains)); }
/// <summary> /// This method validates attribute usage for each bound attribute and calls <see cref="DecodeWellKnownAttribute"/> /// on attributes with valid attribute usage. /// This method is called by the binder when it is finished binding a set of attributes on the symbol so that /// the symbol can extract data from the attribute arguments and potentially perform validation specific to /// some well known attributes. /// </summary> private WellKnownAttributeData ValidateAttributeUsageAndDecodeWellKnownAttributes( ImmutableArray<Binder> binders, ImmutableArray<AttributeSyntax> attributeSyntaxList, ImmutableArray<CSharpAttributeData> boundAttributes, DiagnosticBag diagnostics, AttributeLocation symbolPart) { Debug.Assert(binders.Any()); Debug.Assert(attributeSyntaxList.Any()); Debug.Assert(boundAttributes.Any()); Debug.Assert(binders.Length == boundAttributes.Length); Debug.Assert(attributeSyntaxList.Length == boundAttributes.Length); int totalAttributesCount = boundAttributes.Length; HashSet<NamedTypeSymbol> uniqueAttributeTypes = new HashSet<NamedTypeSymbol>(); var arguments = new DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation>(); arguments.Diagnostics = diagnostics; arguments.AttributesCount = totalAttributesCount; arguments.SymbolPart = symbolPart; for (int i = 0; i < totalAttributesCount; i++) { CSharpAttributeData boundAttribute = boundAttributes[i]; AttributeSyntax attributeSyntax = attributeSyntaxList[i]; Binder binder = binders[i]; // Decode attribute as a possible well-known attribute only if it has no binding errors and has valid AttributeUsage. if (!boundAttribute.HasErrors && ValidateAttributeUsage(boundAttribute, attributeSyntax, binder.Compilation, symbolPart, diagnostics, uniqueAttributeTypes)) { arguments.Attribute = boundAttribute; arguments.AttributeSyntaxOpt = attributeSyntax; arguments.Index = i; this.DecodeWellKnownAttribute(ref arguments); } } return arguments.HasDecodedData ? arguments.DecodedData : null; }
public static async Task <bool> IsUnusedSymbolAsync( ISymbol symbol, Solution solution, CancellationToken cancellationToken = default) { ImmutableArray <SyntaxReference> syntaxReferences = symbol.DeclaringSyntaxReferences; Debug.Assert(syntaxReferences.Any(), $"No syntax references for {symbol.ToDisplayString()}"); if (!syntaxReferences.Any()) { return(false); } if (IsReferencedInDebuggerDisplayAttribute(symbol)) { return(false); } IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false); foreach (ReferencedSymbol referencedSymbol in referencedSymbols) { foreach (ReferenceLocation referenceLocation in referencedSymbol.Locations) { if (referenceLocation.IsImplicit) { continue; } if (referenceLocation.IsCandidateLocation) { return(false); } Location location = referenceLocation.Location; if (!location.IsInSource) { continue; } foreach (SyntaxReference syntaxReference in syntaxReferences) { if (syntaxReference.SyntaxTree != location.SourceTree || !syntaxReference.Span.Contains(location.SourceSpan)) { return(false); } } } } if (symbol.Kind == SymbolKind.Field) { INamedTypeSymbol containingType = symbol.ContainingType; if (containingType.TypeKind == TypeKind.Enum && containingType.HasAttribute(MetadataNames.System_FlagsAttribute)) { var fieldSymbol = (IFieldSymbol)symbol; if (fieldSymbol.HasConstantValue) { ulong value = SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, containingType); if (value == 0) { return(false); } } } } if (symbol.Kind == SymbolKind.NamedType) { var namedType = (INamedTypeSymbol)symbol; if (namedType.TypeKind.Is(TypeKind.Class, TypeKind.Struct)) { foreach (ISymbol member in namedType.GetMembers()) { if (member.Kind == SymbolKind.Method) { var methodSymbol = (IMethodSymbol)member; if (SymbolUtility.CanBeEntryPoint(methodSymbol)) { return(false); } } } } } return(true); }
internal void VerifyNoNewCompilerDiagnostics( ImmutableArray <Diagnostic> diagnostics, ImmutableArray <Diagnostic> newDiagnostics, CodeVerificationOptions options) { ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds; if (allowedDiagnosticIds.IsDefault) { allowedDiagnosticIds = ImmutableArray <string> .Empty; } if (IsAnyNewCompilerDiagnostic()) { IEnumerable <Diagnostic> diff = newDiagnostics .Where(diagnostic => !allowedDiagnosticIds.Any(id => id == diagnostic.Id)) .Except(diagnostics, DiagnosticDeepEqualityComparer.Instance); Assert.True(false, $"Code fix introduced new compiler diagnostic(s).{diff.ToDebugString()}"); } bool IsAnyNewCompilerDiagnostic() { foreach (Diagnostic newDiagnostic in newDiagnostics) { if (!IsAllowed(newDiagnostic) && !EqualsAny(newDiagnostic)) { return(true); } } return(false); } bool IsAllowed(Diagnostic diagnostic) { foreach (string diagnosticId in allowedDiagnosticIds) { if (diagnostic.Id == diagnosticId) { return(true); } } return(false); } bool EqualsAny(Diagnostic newDiagnostic) { foreach (Diagnostic diagnostic in diagnostics) { if (DiagnosticDeepEqualityComparer.Instance.Equals(diagnostic, newDiagnostic)) { return(true); } } return(false); } }
internal void VerifyCompilerDiagnostics( ImmutableArray <Diagnostic> diagnostics, CodeVerificationOptions options) { DiagnosticSeverity maxAllowedSeverity = options.AllowedCompilerDiagnosticSeverity; ImmutableArray <string> allowedDiagnosticIds = options.AllowedCompilerDiagnosticIds; if (IsAny()) { IEnumerable <Diagnostic> notAllowed = diagnostics .Where(f => f.Severity > maxAllowedSeverity && !allowedDiagnosticIds.Any(id => id == f.Id)); Assert.True(false, $"No compiler diagnostics with severity higher than '{maxAllowedSeverity}' expected{notAllowed.ToDebugString()}"); } bool IsAny() { foreach (Diagnostic diagnostic in diagnostics) { if (diagnostic.Severity > maxAllowedSeverity && !IsAllowed(diagnostic)) { return(true); } } return(false); } bool IsAllowed(Diagnostic diagnostic) { foreach (string diagnosticId in allowedDiagnosticIds) { if (diagnostic.Id == diagnosticId) { return(true); } } return(false); } }
private static int GetMatchingNamedConstructorArgumentIndex(string parameterName, ImmutableArray<string> argumentNamesOpt, int startIndex, int argumentsCount) { Debug.Assert(parameterName != null); Debug.Assert(startIndex >= 0 && startIndex < argumentsCount); if (parameterName.IsEmpty() || !argumentNamesOpt.Any()) { return argumentsCount; } // get the matching named (constructor) argument int argIndex = startIndex; while (argIndex < argumentsCount) { var name = argumentNamesOpt[argIndex]; if (string.Equals(name, parameterName, StringComparison.Ordinal)) { break; } argIndex++; } return argIndex; }
private static bool IsArrangeActAssertUnitTestPattern([NotNull] string commentText) { return(ArrangeActAssertLines.Any(line => line.Equals(commentText))); }
public string GetLogicalGroupKey(ImmutableArray <BenchmarkCase> allBenchmarksCases, BenchmarkCase benchmarkCase) { var explicitRules = benchmarkCase.Config.GetLogicalGroupRules().ToList(); var implicitRules = new List <BenchmarkLogicalGroupRule>(); bool hasJobBaselines = allBenchmarksCases.Any(b => b.Job.Meta.Baseline); bool hasDescriptorBaselines = allBenchmarksCases.Any(b => b.Descriptor.Baseline); if (hasJobBaselines) { implicitRules.Add(BenchmarkLogicalGroupRule.ByParams); implicitRules.Add(BenchmarkLogicalGroupRule.ByMethod); } if (hasDescriptorBaselines) { implicitRules.Add(BenchmarkLogicalGroupRule.ByParams); implicitRules.Add(BenchmarkLogicalGroupRule.ByJob); } if (hasJobBaselines && hasDescriptorBaselines) { implicitRules.Remove(BenchmarkLogicalGroupRule.ByMethod); implicitRules.Remove(BenchmarkLogicalGroupRule.ByJob); } var rules = new List <BenchmarkLogicalGroupRule>(explicitRules); foreach (var rule in implicitRules.Where(rule => !rules.Contains(rule))) { rules.Add(rule); } var keys = new List <string>(); foreach (var rule in rules) { switch (rule) { case BenchmarkLogicalGroupRule.ByMethod: keys.Add(benchmarkCase.Descriptor.DisplayInfo); break; case BenchmarkLogicalGroupRule.ByJob: keys.Add(benchmarkCase.Job.DisplayInfo); break; case BenchmarkLogicalGroupRule.ByParams: keys.Add(benchmarkCase.Parameters.ValueInfo); break; case BenchmarkLogicalGroupRule.ByCategory: keys.Add(string.Join(",", benchmarkCase.Descriptor.Categories)); break; default: throw new ArgumentOutOfRangeException(nameof(rule), rule, $"Not supported {nameof(BenchmarkLogicalGroupRule)}"); } } string logicalGroupKey = string.Join("-", keys.Where(key => key != string.Empty)); return(logicalGroupKey == string.Empty ? "*" : logicalGroupKey); }
public UnboundLambda( CSharpSyntaxNode syntax, Binder binder, ImmutableArray <RefKind> refKinds, ImmutableArray <TypeSymbol> types, ImmutableArray <string> names, bool isAsync, bool hasErrors = false) : base(BoundKind.UnboundLambda, syntax, null, hasErrors || !types.IsDefault && types.Any(SymbolKind.ErrorType)) { Debug.Assert(binder != null); Debug.Assert(syntax.IsAnonymousFunction()); this.Data = new PlainUnboundLambdaState(this, binder, names, types, refKinds, isAsync); }