private static ReferenceInfo?BuildReference( ProjectAssetsFile projectAssets, string referenceName, bool treatAsUsed, ImmutableDictionary <string, ImmutableDictionary <string, string> > targetLibraryKeys, Dictionary <string, ReferenceInfo?> builtReferences) { var dependencyNames = new HashSet <string>(); var compilationAssemblies = ImmutableArray.CreateBuilder <string>(); var referenceType = ReferenceType.Unknown; var itemSpecification = referenceName; var packagesPath = projectAssets.Project?.Restore?.PackagesPath ?? string.Empty; RoslynDebug.AssertNotNull(projectAssets.Targets); RoslynDebug.AssertNotNull(projectAssets.Libraries); foreach (var(targetName, libraryKeys) in targetLibraryKeys) { if (!libraryKeys.TryGetValue(referenceName, out var key) || !projectAssets.Libraries.TryGetValue(key, out var library)) { continue; } var target = projectAssets.Targets[targetName]; var targetLibrary = target[key]; referenceType = targetLibrary.Type switch { "package" => ReferenceType.Package, "project" => ReferenceType.Project, _ => ReferenceType.Assembly }; if (referenceType == ReferenceType.Project && library.Path is not null) { // Project references are keyed by their filename but the // item specification should be the path to the project file // with Windows-style directory separators. itemSpecification = library.Path.Replace('/', '\\'); } if (targetLibrary.Dependencies != null) { dependencyNames.AddRange(targetLibrary.Dependencies.Keys); } if (targetLibrary.Compile != null) { foreach (var assemblyPath in targetLibrary.Compile.Keys) { if (!assemblyPath.EndsWith(NuGetEmptyFileName)) { compilationAssemblies.Add(Path.GetFullPath(Path.Combine(packagesPath, library.Path ?? "", assemblyPath))); } } } } if (referenceType == ReferenceType.Unknown) { return(null); } if (referenceType == ReferenceType.Package && itemSpecification == ".NETStandard.Library") { // Referencing .NETStandard.Library brings along references to a number of common .NET libraries // for which the .NET SDK already brings into the compilation. This makes it very easy for // the parent reference to be considered transitively used. return(null); } if (builtReferences.TryGetValue(itemSpecification, out var builtReference)) { return(builtReference); } var dependencies = dependencyNames .Select(dependency => BuildReference(projectAssets, dependency, treatAsUsed: false, targetLibraryKeys, builtReferences)) .WhereNotNull() .ToImmutableArray(); var reference = new ReferenceInfo(referenceType, itemSpecification, treatAsUsed, compilationAssemblies.ToImmutable(), dependencies); builtReferences.Add(reference.ItemSpecification, reference); return(reference); } }
internal static UsedNamespaceOrType CreateType(ITypeReference type, string?aliasOpt = null) { RoslynDebug.Assert(type != null); return(new UsedNamespaceOrType(alias: aliasOpt, targetType: type)); }
internal static UsedNamespaceOrType CreateExternAlias(string alias) { RoslynDebug.Assert(alias != null); return(new UsedNamespaceOrType(alias: alias)); }
internal MetadataLocation(IModuleSymbolInternal module) { RoslynDebug.Assert(module != null); _module = module; }
public ArrayTypeSymbol(Symbols.ArrayTypeSymbol underlying, CodeAnalysis.NullableAnnotation nullableAnnotation) : base(nullableAnnotation) { RoslynDebug.Assert(underlying is object); _underlying = underlying; }
protected virtual bool FileExists(string fullPath) { RoslynDebug.Assert(fullPath != null); RoslynDebug.Assert(PathUtilities.IsAbsolute(fullPath)); return(File.Exists(fullPath)); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { if (!compilationStartAnalysisContext.Compilation.TryGetOrCreateTypeByMetadataName( WellKnownTypeNames.SystemSecurityAuthenticationSslProtocols, out INamedTypeSymbol? sslProtocolsSymbol)) { return; } compilationStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IFieldReferenceOperation fieldReferenceOperation = (IFieldReferenceOperation)operationAnalysisContext.Operation; if (IsReferencingSslProtocols( fieldReferenceOperation, out bool isDeprecatedProtocol, out bool isHardcodedOkayProtocol)) { if (isDeprecatedProtocol) { operationAnalysisContext.ReportDiagnostic( fieldReferenceOperation.CreateDiagnostic( DeprecatedRule, fieldReferenceOperation.Field.Name)); } else if (isHardcodedOkayProtocol) { operationAnalysisContext.ReportDiagnostic( fieldReferenceOperation.CreateDiagnostic( HardcodedRule, fieldReferenceOperation.Field.Name)); } } }, OperationKind.FieldReference); compilationStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IOperation?valueOperation; switch (operationAnalysisContext.Operation) { case IAssignmentOperation assignmentOperation: // Make sure this is an assignment operation for a SslProtocols value. if (!sslProtocolsSymbol.Equals(assignmentOperation.Target.Type)) { return; } valueOperation = assignmentOperation.Value; break; case IArgumentOperation argumentOperation: if (!sslProtocolsSymbol.Equals(argumentOperation.Type)) { return; } valueOperation = argumentOperation.Value; break; case IReturnOperation returnOperation: if (returnOperation.ReturnedValue == null || !sslProtocolsSymbol.Equals(returnOperation.ReturnedValue.Type)) { return; } valueOperation = returnOperation.ReturnedValue; break; case IVariableInitializerOperation variableInitializerOperation: if (variableInitializerOperation.Value == null || !sslProtocolsSymbol.Equals(variableInitializerOperation.Value.Type)) { return; } valueOperation = variableInitializerOperation.Value; break; default: Debug.Fail("Unhandled IOperation " + operationAnalysisContext.Operation.Kind); return; } // Find the topmost operation with a bad bit set, unless we find an operation that would've been // flagged by the FieldReference callback above. IOperation?foundDeprecatedOperation = null; bool foundDeprecatedReference = false; IOperation?foundHardcodedOperation = null; bool foundHardcodedReference = false; foreach (IOperation childOperation in valueOperation.DescendantsAndSelf()) { if (childOperation is IFieldReferenceOperation fieldReferenceOperation && IsReferencingSslProtocols( fieldReferenceOperation, out var isDeprecatedProtocol, out var isHardcodedOkayProtocol)) { if (isDeprecatedProtocol) { foundDeprecatedReference = true; } else if (isHardcodedOkayProtocol) { foundHardcodedReference = true; } if (foundDeprecatedReference && foundHardcodedReference) { return; } } if (childOperation.ConstantValue.HasValue && childOperation.ConstantValue.Value is int integerValue) { if (foundDeprecatedOperation == null && // Only want the first. (integerValue & UnsafeBits) != 0) { foundDeprecatedOperation = childOperation; } if (foundHardcodedOperation == null && // Only want the first. (integerValue & HardcodedBits) != 0) { foundHardcodedOperation = childOperation; } } } if (foundDeprecatedOperation != null && !foundDeprecatedReference) { operationAnalysisContext.ReportDiagnostic( foundDeprecatedOperation.CreateDiagnostic( DeprecatedRule, foundDeprecatedOperation.ConstantValue)); } if (foundHardcodedOperation != null && !foundHardcodedReference) { operationAnalysisContext.ReportDiagnostic( foundHardcodedOperation.CreateDiagnostic( HardcodedRule, foundHardcodedOperation.ConstantValue)); } }, OperationKind.SimpleAssignment, OperationKind.CompoundAssignment, OperationKind.Argument, OperationKind.Return, OperationKind.VariableInitializer); return; // Local function(s). bool IsReferencingSslProtocols( IFieldReferenceOperation fieldReferenceOperation, out bool isDeprecatedProtocol, out bool isHardcodedOkayProtocol) { RoslynDebug.Assert(sslProtocolsSymbol != null); if (sslProtocolsSymbol.Equals(fieldReferenceOperation.Field.ContainingType)) { if (HardcodedSslProtocolsMetadataNames.Contains(fieldReferenceOperation.Field.Name)) { isHardcodedOkayProtocol = true; isDeprecatedProtocol = false; } else if (fieldReferenceOperation.Field.Name == "None") { isHardcodedOkayProtocol = false; isDeprecatedProtocol = false; } else { isDeprecatedProtocol = true; isHardcodedOkayProtocol = false; } return(true); } else { isHardcodedOkayProtocol = false; isDeprecatedProtocol = false; return(false); } } }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( WellKnownTypeNames.SystemNetSecurityProtocolType, out var securityProtocolTypeTypeSymbol) || !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName( WellKnownTypeNames.SystemNetServicePointManager, out var servicePointManagerTypeSymbol)) { return; } compilationStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var fieldReferenceOperation = (IFieldReferenceOperation)operationAnalysisContext.Operation; // Make sure we're not inside an &= assignment like: // ServicePointManager.SecurityProtocol &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11) // cuz &= is at worst, disabling protocol versions. if (IsReferencingSecurityProtocolType( fieldReferenceOperation, out var isDeprecatedProtocol, out var isHardCodedOkayProtocol) && null == fieldReferenceOperation.GetAncestor <ICompoundAssignmentOperation>( OperationKind.CompoundAssignment, IsAndEqualsServicePointManagerAssignment)) { if (isDeprecatedProtocol) { operationAnalysisContext.ReportDiagnostic( fieldReferenceOperation.CreateDiagnostic( DeprecatedRule, fieldReferenceOperation.Field.Name)); } else if (isHardCodedOkayProtocol) { operationAnalysisContext.ReportDiagnostic( fieldReferenceOperation.CreateDiagnostic( HardCodedRule, fieldReferenceOperation.Field.Name)); } } }, OperationKind.FieldReference); compilationStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var assignmentOperation = (IAssignmentOperation)operationAnalysisContext.Operation; // Make sure this is an assignment operation for a SecurityProtocolType, and not // an assignment like: // ServicePointManager.SecurityProtocol &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11) // cuz &= is at worst, disabling protocol versions. if (!securityProtocolTypeTypeSymbol.Equals(assignmentOperation.Target.Type) || (assignmentOperation is ICompoundAssignmentOperation compoundAssignmentOperation && IsAndEqualsServicePointManagerAssignment(compoundAssignmentOperation))) { return; } // Find the topmost operation with a bad bit set, unless we find an operation that would've been // flagged by the FieldReference callback above. IOperation?foundDeprecatedOperation = null; bool foundDeprecatedReference = false; IOperation?foundHardCodedOperation = null; bool foundHardCodedReference = false; foreach (IOperation childOperation in assignmentOperation.Value.DescendantsAndSelf()) { if (childOperation is IFieldReferenceOperation fieldReferenceOperation && IsReferencingSecurityProtocolType( fieldReferenceOperation, out var isDeprecatedProtocol, out var isHardCodedOkayProtocol)) { if (isDeprecatedProtocol) { foundDeprecatedReference = true; } else if (isHardCodedOkayProtocol) { foundHardCodedReference = true; } if (foundDeprecatedReference && foundHardCodedReference) { return; } } if (childOperation.ConstantValue.HasValue && childOperation.ConstantValue.Value is int integerValue) { if (foundDeprecatedOperation == null && // Only want the first. (integerValue & UnsafeBits) != 0) { foundDeprecatedOperation = childOperation; } if (foundHardCodedOperation == null && // Only want the first. (integerValue & HardCodedBits) != 0) { foundHardCodedOperation = childOperation; } } } if (foundDeprecatedOperation != null && !foundDeprecatedReference) { operationAnalysisContext.ReportDiagnostic( foundDeprecatedOperation.CreateDiagnostic( DeprecatedRule, foundDeprecatedOperation.ConstantValue)); } if (foundHardCodedOperation != null && !foundHardCodedReference) { operationAnalysisContext.ReportDiagnostic( foundHardCodedOperation.CreateDiagnostic( HardCodedRule, foundHardCodedOperation.ConstantValue)); } }, OperationKind.SimpleAssignment, OperationKind.CompoundAssignment); return; // Local function(s). bool IsReferencingSecurityProtocolType( IFieldReferenceOperation fieldReferenceOperation, out bool isDeprecatedProtocol, out bool isHardCodedOkayProtocol) { RoslynDebug.Assert(securityProtocolTypeTypeSymbol != null); if (securityProtocolTypeTypeSymbol.Equals(fieldReferenceOperation.Field.ContainingType)) { if (HardCodedSafeProtocolMetadataNames.Contains(fieldReferenceOperation.Field.Name)) { isHardCodedOkayProtocol = true; isDeprecatedProtocol = false; } else if (fieldReferenceOperation.Field.Name == SystemDefaultName) { isHardCodedOkayProtocol = false; isDeprecatedProtocol = false; } else { isDeprecatedProtocol = true; isHardCodedOkayProtocol = false; } return(true); } else { isHardCodedOkayProtocol = false; isDeprecatedProtocol = false; return(false); } } bool IsAndEqualsServicePointManagerAssignment(ICompoundAssignmentOperation compoundAssignmentOperation) { RoslynDebug.Assert(servicePointManagerTypeSymbol != null); return(compoundAssignmentOperation.OperatorKind == BinaryOperatorKind.And && compoundAssignmentOperation.Target is IPropertyReferenceOperation targetPropertyReference && targetPropertyReference.Instance == null && servicePointManagerTypeSymbol.Equals(targetPropertyReference.Property.ContainingType) && targetPropertyReference.Property.MetadataName == "SecurityProtocol"); } }); }
internal CodeAnalysisResourcesLocalizableErrorArgument(string targetResourceId) { RoslynDebug.Assert(targetResourceId != null); _targetResourceId = targetResourceId; }
private void AnalyzeNode(SyntaxNodeAnalysisContext context) { var cancellationToken = context.CancellationToken; var node = (TMemberAccessExpressionSyntax)context.Node; var syntaxFacts = GetSyntaxFacts(); var expr = syntaxFacts.GetExpressionOfMemberAccessExpression(node); if (!(expr is TThisExpressionSyntax)) { return; } var analyzerOptions = context.Options; var syntaxTree = node.SyntaxTree; var optionSet = analyzerOptions.GetAnalyzerOptionSet(syntaxTree, cancellationToken); var model = context.SemanticModel; if (!CanSimplifyTypeNameExpression( model, node, optionSet, out var issueSpan, cancellationToken)) { return; } if (model.SyntaxTree.OverlapsHiddenPosition(issueSpan, cancellationToken)) { return; } var symbolInfo = model.GetSymbolInfo(node, cancellationToken); if (symbolInfo.Symbol == null) { return; } var applicableOption = QualifyMembersHelpers.GetApplicableOptionFromSymbolKind(symbolInfo.Symbol.Kind); var optionValue = optionSet.GetOption(applicableOption, GetLanguageName()); if (optionValue == null) { return; } var severity = optionValue.Notification.Severity; RoslynDebug.AssertNotNull(DescriptorId); var descriptor = CreateUnnecessaryDescriptor(DescriptorId); var tree = model.SyntaxTree; var builder = ImmutableDictionary.CreateBuilder <string, string>(); // used so we can provide a link in the preview to the options page. This value is // hard-coded there to be the one that will go to the code-style page. builder["OptionName"] = nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration); builder["OptionLanguage"] = model.Language; var diagnostic = DiagnosticHelper.Create( descriptor, tree.GetLocation(issueSpan), severity, ImmutableArray.Create(node.GetLocation()), builder.ToImmutable()); context.ReportDiagnostic(diagnostic); }
internal ValidTargetsStringLocalizableErrorArgument(string[] targetResourceIds) { RoslynDebug.Assert(targetResourceIds != null); _targetResourceIds = targetResourceIds; }
private static void UpdateLocation( SemanticModel semanticModel, INamedTypeSymbol interfaceType, SyntaxEditor editor, ISyntaxFactsService syntaxFacts, Location location, CancellationToken cancellationToken) { var identifierName = location.FindNode(getInnermostNodeForTie: true, cancellationToken); if (identifierName == null || !syntaxFacts.IsIdentifierName(identifierName)) { return; } var node = syntaxFacts.IsNameOfMemberAccessExpression(identifierName) || syntaxFacts.IsMemberBindingExpression(identifierName.Parent) ? identifierName.Parent : identifierName; RoslynDebug.Assert(node is object); if (syntaxFacts.IsInvocationExpression(node.Parent)) { node = node.Parent; } var operation = semanticModel.GetOperation(node, cancellationToken); var instance = operation switch { IMemberReferenceOperation memberReference => memberReference.Instance, IInvocationOperation invocation => invocation.Instance, _ => null, }; if (instance == null) { return; } if (instance.IsImplicit) { if (instance is IInstanceReferenceOperation instanceReference && instanceReference.ReferenceKind != InstanceReferenceKind.ContainingTypeInstance) { return; } // Accessing the member not off of <dot>. i.e just plain `Goo()`. Replace with // ((IGoo)this).Goo(); var generator = editor.Generator; editor.ReplaceNode( identifierName, generator.MemberAccessExpression( generator.AddParentheses(generator.CastExpression(interfaceType, generator.ThisExpression())), identifierName.WithoutTrivia()).WithTriviaFrom(identifierName)); } else { // Accessing the member like `x.Goo()`. Replace with `((IGoo)x).Goo()` editor.ReplaceNode( instance.Syntax, (current, g) => g.AddParentheses( g.CastExpression(interfaceType, current.WithoutTrivia())).WithTriviaFrom(current)); } }
public WrappedEventSymbol(EventSymbol underlyingEvent) { RoslynDebug.Assert((object)underlyingEvent != null); _underlyingEvent = underlyingEvent; }
/// <summary> /// Zero or more named arguments that specify values for fields and properties of the attribute. /// </summary> public ImmutableArray <Cci.IMetadataNamedArgument> GetNamedArguments(EmitContext context) { // Perform fixup Cci.ITypeReference stringType = context.Module.GetPlatformType( Cci.PlatformType.SystemString, context ); #if DEBUG // Must have exactly 1 named argument. var namedArgs = _sourceAttribute.GetNamedArguments(context); Debug.Assert(namedArgs.Length == 1); // Named argument must be 'File' property of string type var fileArg = namedArgs.First(); Debug.Assert(fileArg.ArgumentName == FilePropertyName); Debug.Assert( context.Module.IsPlatformType(fileArg.Type, Cci.PlatformType.SystemString) ); // Named argument value must be a non-empty string Debug.Assert(fileArg.ArgumentValue is MetadataConstant); var fileName = (string?)((MetadataConstant)fileArg.ArgumentValue).Value; Debug.Assert(!String.IsNullOrEmpty(fileName)); // PermissionSetAttribute type must have a writable public string type property member 'Hex' ISymbol iSymbol = _sourceAttribute.GetType(context).GetInternalSymbol() !.GetISymbol(); Debug.Assert( ((INamedTypeSymbol)iSymbol) .GetMembers(HexPropertyName) .Any( member => member.Kind == SymbolKind.Property && ((IPropertySymbol)member).Type.SpecialType == SpecialType.System_String ) ); #endif string hexFileContent; // Read the file contents at the resolved file path into a byte array. // May throw PermissionSetFileReadException, which is handled in Compilation.Emit. var resolver = context.Module.CommonCompilation.Options.XmlReferenceResolver; // If the resolver isn't available we won't get here since we had to use it to resolve the path. RoslynDebug.Assert(resolver != null); try { using (Stream stream = resolver.OpenReadChecked(_resolvedPermissionSetFilePath)) { // Convert the byte array contents into a string in hexadecimal format. hexFileContent = ConvertToHex(stream); } } catch (IOException e) { throw new PermissionSetFileReadException(e.Message, _resolvedPermissionSetFilePath); } // Synthesize a named attribute argument "Hex = hexFileContent". return(ImmutableArray.Create <Cci.IMetadataNamedArgument>( new HexPropertyMetadataNamedArgument( stringType, new MetadataConstant(stringType, hexFileContent) ) )); }
private async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(IEnumerable <DiagnosticData> diagnosticsToFix, Func <Project, bool> shouldFixInProject, bool filterStaleDiagnostics, CancellationToken cancellationToken) { var builder = ImmutableDictionary.CreateBuilder <DocumentId, List <DiagnosticData> >(); foreach (var diagnosticData in diagnosticsToFix.Where(IsDocumentDiagnostic)) { RoslynDebug.AssertNotNull(diagnosticData.DocumentId); if (!builder.TryGetValue(diagnosticData.DocumentId, out var diagnosticsPerDocument)) { diagnosticsPerDocument = new List <DiagnosticData>(); builder[diagnosticData.DocumentId] = diagnosticsPerDocument; } diagnosticsPerDocument.Add(diagnosticData); } if (builder.Count == 0) { return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty); } var finalBuilder = ImmutableDictionary.CreateBuilder <Document, ImmutableArray <Diagnostic> >(); var latestDocumentDiagnosticsMap = filterStaleDiagnostics ? new Dictionary <DocumentId, ImmutableHashSet <DiagnosticData> >() : null; foreach (var group in builder.GroupBy(kvp => kvp.Key.ProjectId)) { var projectId = group.Key; var project = _workspace.CurrentSolution.GetProject(projectId); if (project == null || !shouldFixInProject(project)) { continue; } if (filterStaleDiagnostics) { RoslynDebug.AssertNotNull(latestDocumentDiagnosticsMap); var uniqueDiagnosticIds = group.SelectMany(kvp => kvp.Value.Select(d => d.Id)).ToImmutableHashSet(); var latestProjectDiagnostics = (await _diagnosticService.GetDiagnosticsForIdsAsync(project.Solution, project.Id, diagnosticIds: uniqueDiagnosticIds, includeSuppressedDiagnostics: true, cancellationToken: cancellationToken) .ConfigureAwait(false)).Where(IsDocumentDiagnostic); latestDocumentDiagnosticsMap.Clear(); foreach (var kvp in latestProjectDiagnostics.Where(d => d.DocumentId != null).GroupBy(d => d.DocumentId !)) { latestDocumentDiagnosticsMap.Add(kvp.Key, kvp.ToImmutableHashSet()); } } foreach (var documentDiagnostics in group) { var document = project.GetDocument(documentDiagnostics.Key); if (document == null) { continue; } IEnumerable <DiagnosticData> documentDiagnosticsToFix; if (filterStaleDiagnostics) { RoslynDebug.AssertNotNull(latestDocumentDiagnosticsMap); if (!latestDocumentDiagnosticsMap.TryGetValue(document.Id, out var latestDocumentDiagnostics)) { // Ignore stale diagnostics in error list. latestDocumentDiagnostics = ImmutableHashSet <DiagnosticData> .Empty; } // Filter out stale diagnostics in error list. documentDiagnosticsToFix = documentDiagnostics.Value.Where(d => latestDocumentDiagnostics.Contains(d) || SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(d)); } else { documentDiagnosticsToFix = documentDiagnostics.Value; } if (documentDiagnosticsToFix.Any()) { var diagnostics = await documentDiagnosticsToFix.ToDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false); finalBuilder.Add(document, diagnostics); } } } return(finalBuilder.ToImmutableDictionary());
private static void AnalyzeSymbol( SymbolAnalysisContext context, INamedTypeSymbol?iCollectionType, INamedTypeSymbol?gCollectionType, INamedTypeSymbol?iEnumerableType, INamedTypeSymbol?gEnumerableType, INamedTypeSymbol?iListType, INamedTypeSymbol?gListType) { var namedTypeSymbol = (INamedTypeSymbol)context.Symbol; // FxCop compat: only fire on externally visible types by default. if (!namedTypeSymbol.MatchesConfiguredVisibility(context.Options, Rule, context.CancellationToken)) { return; } var allInterfacesStatus = default(CollectionsInterfaceStatus); foreach (var @interface in namedTypeSymbol.AllInterfaces) { var originalDefinition = @interface.OriginalDefinition; if (originalDefinition.Equals(iCollectionType)) { allInterfacesStatus.ICollectionPresent = true; } else if (originalDefinition.Equals(iEnumerableType)) { allInterfacesStatus.IEnumerablePresent = true; } else if (originalDefinition.Equals(iListType)) { allInterfacesStatus.IListPresent = true; } else if (originalDefinition.Equals(gCollectionType)) { allInterfacesStatus.GenericICollectionPresent = true; } else if (originalDefinition.Equals(gEnumerableType)) { allInterfacesStatus.GenericIEnumerablePresent = true; } else if (originalDefinition.Equals(gListType)) { allInterfacesStatus.GenericIListPresent = true; } } INamedTypeSymbol?missingInterface; INamedTypeSymbol?implementedInterface; if (allInterfacesStatus.GenericIListPresent) { // Implemented IList<T>, meaning has all 3 generic interfaces. Nothing can be wrong. return; } else if (allInterfacesStatus.IListPresent) { // Implemented IList but not IList<T>. missingInterface = gListType; implementedInterface = iListType; } else if (allInterfacesStatus.GenericICollectionPresent) { // Implemented ICollection<T>, and doesn't have an inherit of IList. Nothing can be wrong return; } else if (allInterfacesStatus.ICollectionPresent) { // Implemented ICollection but not ICollection<T> missingInterface = gCollectionType; implementedInterface = iCollectionType; } else if (allInterfacesStatus.GenericIEnumerablePresent) { // Implemented IEnumerable<T>, and doesn't have an inherit of ICollection. Nothing can be wrong return; } else if (allInterfacesStatus.IEnumerablePresent) { // Implemented IEnumerable, but not IEnumerable<T> missingInterface = gEnumerableType; implementedInterface = iEnumerableType; } else { // No collections implementation, nothing can be wrong. return; } RoslynDebug.Assert(missingInterface != null && implementedInterface != null); context.ReportDiagnostic(Diagnostic.Create(Rule, namedTypeSymbol.Locations.First(), namedTypeSymbol.Name, implementedInterface.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), missingInterface.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat))); }
protected override void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext symbolContext) { var namedType = (INamedTypeSymbol)symbolContext.Symbol; if (namedType.IsAbstract) { return; } // 1) MissingDiagnosticAnalyzerAttributeRule: DiagnosticAnalyzer has no DiagnosticAnalyzerAttribute. // 2) AddLanguageSupportToAnalyzerRule: For analyzer supporting only one of C# or VB languages, detect if it can support the other language. var hasAttribute = false; SyntaxNode?attributeSyntax = null; bool supportsCSharp = false; bool supportsVB = false; var namedTypeAttributes = namedType.GetApplicableAttributes(_attributeUsageAttribute); foreach (AttributeData attribute in namedTypeAttributes) { if (attribute.AttributeClass.DerivesFrom(DiagnosticAnalyzerAttribute)) { // Bail out for the case where analyzer type derives from a sub-type in different assembly, and the sub-type has the diagnostic analyzer attribute. if (attribute.ApplicationSyntaxReference == null) { return; } hasAttribute = true; // The attribute constructor's signature is "(string, params string[])", // so process both string arguments and string[] arguments. foreach (TypedConstant arg in attribute.ConstructorArguments) { CheckLanguage(arg, ref supportsCSharp, ref supportsVB); if (arg.Kind == TypedConstantKind.Array) { foreach (TypedConstant element in arg.Values) { CheckLanguage(element, ref supportsCSharp, ref supportsVB); } } } attributeSyntax = attribute.ApplicationSyntaxReference.GetSyntax(symbolContext.CancellationToken); } } if (!hasAttribute) { Diagnostic diagnostic = namedType.CreateDiagnostic(MissingDiagnosticAnalyzerAttributeRule); symbolContext.ReportDiagnostic(diagnostic); } else if (supportsCSharp ^ supportsVB) { RoslynDebug.Assert(attributeSyntax != null); // If the analyzer assembly doesn't reference either C# or VB CodeAnalysis assemblies, // then the analyzer is pretty likely a language-agnostic analyzer. Compilation compilation = symbolContext.Compilation; string compilationTypeNameToCheck = supportsCSharp ? CSharpCompilationFullName : BasicCompilationFullName; INamedTypeSymbol?compilationType = compilation.GetOrCreateTypeByMetadataName(compilationTypeNameToCheck); if (compilationType == null) { string missingLanguage = supportsCSharp ? LanguageNames.VisualBasic : LanguageNames.CSharp; Diagnostic diagnostic = attributeSyntax.CreateDiagnostic(AddLanguageSupportToAnalyzerRule, namedType.Name, missingLanguage); symbolContext.ReportDiagnostic(diagnostic); } } }
private static bool TryGetReleaseTrackingData( ImmutableArray <AdditionalText> additionalTexts, CancellationToken cancellationToken, [NotNullWhen(returnValue: true)] out ReleaseTrackingData?shippedData, [NotNullWhen(returnValue: true)] out ReleaseTrackingData?unshippedData, out List <Diagnostic>?invalidFileDiagnostics) { if (!TryGetReleaseTrackingFiles(additionalTexts, cancellationToken, out var shippedText, out var unshippedText)) { // TODO: Report a diagnostic that both must be specified if either shippedText or unshippedText is non-null. shippedData = shippedText != null ? ReleaseTrackingData.Default : null; unshippedData = unshippedText != null ? ReleaseTrackingData.Default : null; invalidFileDiagnostics = null; return(false); } var diagnostics = new List <Diagnostic>(); using var reportedInvalidLines = PooledHashSet <TextLine> .GetInstance(); shippedData = ReadReleaseTrackingData(shippedText.Path, shippedText.GetText(cancellationToken), OnDuplicateEntryInRelease, OnInvalidEntry, isShippedFile: true); unshippedData = ReadReleaseTrackingData(unshippedText.Path, unshippedText.GetText(cancellationToken), OnDuplicateEntryInRelease, OnInvalidEntry, isShippedFile: false); invalidFileDiagnostics = diagnostics; return(invalidFileDiagnostics.Count == 0); // Local functions. void OnDuplicateEntryInRelease(string ruleId, Version currentVersion, string path, SourceText sourceText, TextLine line) { if (!reportedInvalidLines.Add(line)) { // Already reported. return; } RoslynDebug.Assert(diagnostics != null); // Rule '{0}' has more then one entry for release '{1}' in analyzer release file '{2}'. string arg1 = ruleId; string arg2 = currentVersion == UnshippedVersion ? "unshipped" : currentVersion.ToString(); string arg3 = Path.GetFileName(path); LinePositionSpan linePositionSpan = sourceText.Lines.GetLinePositionSpan(line.Span); Location location = Location.Create(path, line.Span, linePositionSpan); var diagnostic = Diagnostic.Create(RemoveDuplicateEntriesForAnalyzerReleaseRule, location, arg1, arg2, arg3); diagnostics.Add(diagnostic); } void OnInvalidEntry(TextLine line, InvalidEntryKind invalidEntryKind, string path, SourceText sourceText) { RoslynDebug.Assert(diagnostics != null); RoslynDebug.Assert(reportedInvalidLines != null); if (!reportedInvalidLines.Add(line)) { // Already reported. return; } var rule = invalidEntryKind switch { // Analyzer release file '{0}' has a missing or invalid release header '{1}'. InvalidEntryKind.Header => InvalidHeaderInAnalyzerReleasesFileRule, // Analyzer release file '{0}' has an entry with one or more 'Undetected' fields that need to be manually filled in '{1}'. InvalidEntryKind.UndetectedField => InvalidUndetectedEntryInAnalyzerReleasesFileRule, // Analyzer release file '{0}' has an invalid entry '{1}'. InvalidEntryKind.Other => InvalidEntryInAnalyzerReleasesFileRule, _ => throw new NotImplementedException(), }; string arg1 = Path.GetFileName(path); string arg2 = line.ToString(); LinePositionSpan linePositionSpan = sourceText.Lines.GetLinePositionSpan(line.Span); Location location = Location.Create(path, line.Span, linePositionSpan); var diagnostic = Diagnostic.Create(rule, location, arg1, arg2); diagnostics.Add(diagnostic); } }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.RegisterCompilationStartAction(compilationContext => { compilationContext.RegisterOperationBlockAction(operationBlockContext => { var owningSymbol = operationBlockContext.OwningSymbol; if (owningSymbol.IsConfiguredToSkipAnalysis(operationBlockContext.Options, AlwaysTrueFalseOrNullRule, operationBlockContext.Compilation, operationBlockContext.CancellationToken)) { return; } var processedOperationRoots = new HashSet <IOperation>(); foreach (var operationRoot in operationBlockContext.OperationBlocks) { static bool ShouldAnalyze(IOperation op) => (op as IBinaryOperation)?.IsComparisonOperator() == true || (op as IInvocationOperation)?.TargetMethod.ReturnType.SpecialType == SpecialType.System_Boolean || op.Kind == OperationKind.Coalesce || op.Kind == OperationKind.ConditionalAccess || op.Kind == OperationKind.IsNull || op.Kind == OperationKind.IsPattern; if (operationRoot.HasAnyOperationDescendant(ShouldAnalyze)) { // Skip duplicate analysis from operation blocks for constructor initializer and body. if (!processedOperationRoots.Add(operationRoot.GetRoot())) { // Already processed. continue; } var cfg = operationBlockContext.GetControlFlowGraph(operationRoot); var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(operationBlockContext.Compilation); var valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider, operationBlockContext.Options, AlwaysTrueFalseOrNullRule, PointsToAnalysisKind.Complete, operationBlockContext.CancellationToken, out var copyAnalysisResultOpt, out var pointsToAnalysisResult); if (valueContentAnalysisResult == null || pointsToAnalysisResult == null) { continue; } foreach (var operation in cfg.DescendantOperations()) { // Skip implicit operations. // However, 'IsNull' operations are compiler generated operations corresponding to // non-implicit conditional access operations, so we should not skip them. if (operation.IsImplicit && operation.Kind != OperationKind.IsNull) { continue; } switch (operation.Kind) { case OperationKind.BinaryOperator: var binaryOperation = (IBinaryOperation)operation; PredicateValueKind predicateKind = GetPredicateKind(binaryOperation); if (predicateKind != PredicateValueKind.Unknown && (!(binaryOperation.LeftOperand is IBinaryOperation leftBinary) || GetPredicateKind(leftBinary) == PredicateValueKind.Unknown) && (!(binaryOperation.RightOperand is IBinaryOperation rightBinary) || GetPredicateKind(rightBinary) == PredicateValueKind.Unknown)) { ReportAlwaysTrueFalseOrNullDiagnostic(operation, predicateKind); } break; case OperationKind.Invocation: case OperationKind.IsPattern: predicateKind = GetPredicateKind(operation); if (predicateKind != PredicateValueKind.Unknown) { ReportAlwaysTrueFalseOrNullDiagnostic(operation, predicateKind); } break; case OperationKind.IsNull: // '{0}' is always/never '{1}'. Remove or refactor the condition(s) to avoid dead code. predicateKind = GetPredicateKind(operation); DiagnosticDescriptor rule; switch (predicateKind) { case PredicateValueKind.AlwaysTrue: rule = AlwaysTrueFalseOrNullRule; break; case PredicateValueKind.AlwaysFalse: rule = NeverNullRule; break; default: continue; } var originalOperation = operationRoot.SemanticModel.GetOperation(operation.Syntax, operationBlockContext.CancellationToken); if (originalOperation is IAssignmentOperation || originalOperation is IVariableDeclaratorOperation) { // Skip compiler generated IsNull operation for assignment/variable declaration within a using. continue; } var arg1 = operation.Syntax.ToString(); var arg2 = operation.Language == LanguageNames.VisualBasic ? "Nothing" : "null"; var diagnostic = operation.CreateDiagnostic(rule, arg1, arg2); operationBlockContext.ReportDiagnostic(diagnostic); break; } } PredicateValueKind GetPredicateKind(IOperation operation) { Debug.Assert(operation.Kind == OperationKind.BinaryOperator || operation.Kind == OperationKind.Invocation || operation.Kind == OperationKind.IsNull || operation.Kind == OperationKind.IsPattern); RoslynDebug.Assert(pointsToAnalysisResult != null); RoslynDebug.Assert(valueContentAnalysisResult != null); if (operation is IBinaryOperation binaryOperation && binaryOperation.IsComparisonOperator() || operation.Type?.SpecialType == SpecialType.System_Boolean) { PredicateValueKind predicateKind = pointsToAnalysisResult.GetPredicateKind(operation); if (predicateKind != PredicateValueKind.Unknown) { return(predicateKind); } if (copyAnalysisResultOpt != null) { predicateKind = copyAnalysisResultOpt.GetPredicateKind(operation); if (predicateKind != PredicateValueKind.Unknown) { return(predicateKind); } } predicateKind = valueContentAnalysisResult.GetPredicateKind(operation); if (predicateKind != PredicateValueKind.Unknown) { return(predicateKind); } } return(PredicateValueKind.Unknown); } void ReportAlwaysTrueFalseOrNullDiagnostic(IOperation operation, PredicateValueKind predicateKind) { Debug.Assert(predicateKind != PredicateValueKind.Unknown); // '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code. var arg1 = operation.Syntax.ToString(); var arg2 = predicateKind == PredicateValueKind.AlwaysTrue ? (operation.Language == LanguageNames.VisualBasic ? "True" : "true") : (operation.Language == LanguageNames.VisualBasic ? "False" : "false"); var diagnostic = operation.CreateDiagnostic(AlwaysTrueFalseOrNullRule, arg1, arg2); operationBlockContext.ReportDiagnostic(diagnostic); } } }
internal PEEventSymbol( PEModuleSymbol moduleSymbol, PENamedTypeSymbol containingType, EventDefinitionHandle handle, PEMethodSymbol addMethod, PEMethodSymbol removeMethod, MultiDictionary <string, PEFieldSymbol> privateFieldNameToSymbols ) { RoslynDebug.Assert((object)moduleSymbol != null); RoslynDebug.Assert((object)containingType != null); Debug.Assert(!handle.IsNil); RoslynDebug.Assert((object)addMethod != null); RoslynDebug.Assert((object)removeMethod != null); _addMethod = addMethod; _removeMethod = removeMethod; _handle = handle; _containingType = containingType; EventAttributes mdFlags = 0; EntityHandle eventType = default(EntityHandle); try { var module = moduleSymbol.Module; module.GetEventDefPropsOrThrow(handle, out _name, out mdFlags, out eventType); } catch (BadImageFormatException mrEx) { _name = _name ?? string.Empty; _lazyCachedUseSiteInfo.Initialize( new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this) ); if (eventType.IsNil) { _eventTypeWithAnnotations = TypeWithAnnotations.Create( new UnsupportedMetadataTypeSymbol(mrEx) ); } } TypeSymbol originalEventType = _eventTypeWithAnnotations.Type; if (!_eventTypeWithAnnotations.HasType) { var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType); originalEventType = metadataDecoder.GetTypeOfToken(eventType); const int targetSymbolCustomModifierCount = 0; var typeSymbol = DynamicTypeDecoder.TransformType( originalEventType, targetSymbolCustomModifierCount, handle, moduleSymbol ); typeSymbol = NativeIntegerTypeDecoder.TransformType( typeSymbol, handle, moduleSymbol ); // We start without annotation (they will be decoded below) var type = TypeWithAnnotations.Create(typeSymbol); // Decode nullable before tuple types to avoid converting between // NamedTypeSymbol and TupleTypeSymbol unnecessarily. // The containing type is passed to NullableTypeDecoder.TransformType to determine access // because the event does not have explicit accessibility in metadata. type = NullableTypeDecoder.TransformType( type, handle, moduleSymbol, accessSymbol: _containingType, nullableContext: _containingType ); type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol); _eventTypeWithAnnotations = type; } // IsWindowsRuntimeEvent checks the signatures, so we just have to check the accessors. bool isWindowsRuntimeEvent = IsWindowsRuntimeEvent; bool callMethodsDirectly = isWindowsRuntimeEvent ? !DoModifiersMatch(_addMethod, _removeMethod) : !DoSignaturesMatch(moduleSymbol, originalEventType, _addMethod, _removeMethod); if (callMethodsDirectly) { _flags |= Flags.CallMethodsDirectly; } else { _addMethod.SetAssociatedEvent(this, MethodKind.EventAdd); _removeMethod.SetAssociatedEvent(this, MethodKind.EventRemove); PEFieldSymbol?associatedField = GetAssociatedField( privateFieldNameToSymbols, isWindowsRuntimeEvent ); if ((object?)associatedField != null) { _associatedFieldOpt = associatedField; associatedField.SetAssociatedEvent(this); } } if ((mdFlags & EventAttributes.SpecialName) != 0) { _flags |= Flags.IsSpecialName; } if ((mdFlags & EventAttributes.RTSpecialName) != 0) { _flags |= Flags.IsRuntimeSpecialName; } }
internal override GreenNode SetAnnotations(SyntaxAnnotation[]?annotations) { RoslynDebug.Assert(GetType() == typeof(SyntaxToken)); return(new SyntaxToken(Kind, FullWidth, GetDiagnostics(), annotations)); }
private FloatingValueSet(IValueSet <TFloating> numbers, bool hasNaN) { RoslynDebug.Assert(numbers is NumericValueSet <TFloating, TFloatingTC>); (_numbers, _hasNaN) = (numbers, hasNaN); }
public EventSymbol(Symbols.EventSymbol underlying) { RoslynDebug.Assert(underlying is object); _underlying = underlying; }
public static void ReportNoLocationDiagnostic( this Compilation compilation, DiagnosticDescriptor rule, Action <Diagnostic> addDiagnostic, ImmutableDictionary <string, string?>?properties, params object[] args) { var effectiveSeverity = GetEffectiveSeverity(); if (!effectiveSeverity.HasValue) { // Disabled rule return; } if (effectiveSeverity.Value != rule.DefaultSeverity) { #pragma warning disable RS0030 // The symbol 'DiagnosticDescriptor.DiagnosticDescriptor.#ctor' is banned in this project: Use 'DiagnosticDescriptorHelper.Create' instead rule = new DiagnosticDescriptor(rule.Id, rule.Title, rule.MessageFormat, rule.Category, effectiveSeverity.Value, rule.IsEnabledByDefault, rule.Description, rule.HelpLinkUri, rule.CustomTags.ToArray()); #pragma warning restore RS0030 } var diagnostic = Diagnostic.Create(rule, Location.None, properties, args); addDiagnostic(diagnostic); return; DiagnosticSeverity?GetEffectiveSeverity() { // Microsoft.CodeAnalysis version >= 3.7 exposes options through 'CompilationOptions.SyntaxTreeOptionsProvider.TryGetDiagnosticValue' // Microsoft.CodeAnalysis version 3.3 - 3.7 exposes options through 'SyntaxTree.DiagnosticOptions'. This API is deprecated in 3.7. var syntaxTreeOptionsProvider = s_compilationOptionsSyntaxTreeOptionsProviderProperty?.GetValue(compilation.Options); var syntaxTreeOptionsProviderTryGetDiagnosticValueMethod = syntaxTreeOptionsProvider?.GetType().GetRuntimeMethods().FirstOrDefault(m => m.Name == "TryGetDiagnosticValue"); if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod == null && s_syntaxTreeDiagnosticOptionsProperty == null) { return(rule.DefaultSeverity); } ReportDiagnostic?overriddenSeverity = null; foreach (var tree in compilation.SyntaxTrees) { ReportDiagnostic?configuredValue = null; // Prefer 'CompilationOptions.SyntaxTreeOptionsProvider', if available. if (s_compilationOptionsSyntaxTreeOptionsProviderProperty != null) { if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod != null) { // public abstract bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, out ReportDiagnostic severity); // public abstract bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, CancellationToken cancellationToken, out ReportDiagnostic severity); object?[] parameters; if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod.GetParameters().Length == 3) { parameters = new object?[] { tree, rule.Id, null }; } else { parameters = new object?[] { tree, rule.Id, CancellationToken.None, null }; } if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod.Invoke(syntaxTreeOptionsProvider, parameters) is true && parameters.Last() is ReportDiagnostic value) { configuredValue = value; } } } else { RoslynDebug.Assert(s_syntaxTreeDiagnosticOptionsProperty != null); var options = (ImmutableDictionary <string, ReportDiagnostic>)s_syntaxTreeDiagnosticOptionsProperty.GetValue(tree) !; if (options.TryGetValue(rule.Id, out var value)) { configuredValue = value; } } if (configuredValue == null) { continue; } if (configuredValue == ReportDiagnostic.Suppress) { // Any suppression entry always wins. return(null); } if (overriddenSeverity == null) { overriddenSeverity = configuredValue; } else if (overriddenSeverity.Value.IsLessSevereThan(configuredValue.Value)) { // Choose the most severe value for conflicts. overriddenSeverity = configuredValue; } } return(overriddenSeverity.HasValue ? overriddenSeverity.Value.ToDiagnosticSeverity() : rule.DefaultSeverity); } }
protected void AdjustFlagsAndWidth(GreenNode node) { RoslynDebug.Assert(node != null, "PERF: caller must ensure that node!=null, we do not want to re-check that here."); this.flags |= (node.flags & NodeFlags.InheritMask); _fullWidth += node._fullWidth; }
public bool TryCreateForTupleElements(ITupleOperation tupleOperation, [NotNullWhen(returnValue: true)] out ImmutableArray <AnalysisEntity> elementEntities) { if (_tupleElementEntitiesMap.TryGetValue(tupleOperation, out elementEntities)) { return(!elementEntities.IsDefault); } try { elementEntities = default; if (tupleOperation.Type?.IsTupleType != true || _getPointsToAbstractValueOpt == null) { return(false); } var tupleType = (INamedTypeSymbol)tupleOperation.Type; if (tupleType.TupleElements.IsDefault) { return(false); } PointsToAbstractValue instanceLocation = _getPointsToAbstractValueOpt(tupleOperation); var underlyingValueTupleType = tupleType.GetUnderlyingValueTupleTypeOrThis(); AnalysisEntity?parentEntity = null; if (tupleOperation.TryGetParentTupleOperation(out var parentTupleOperationOpt, out var elementOfParentTupleContainingTuple) && TryCreateForTupleElements(parentTupleOperationOpt, out var parentTupleElementEntities)) { Debug.Assert(parentTupleOperationOpt.Elements.Length == parentTupleElementEntities.Length); for (int i = 0; i < parentTupleOperationOpt.Elements.Length; i++) { if (parentTupleOperationOpt.Elements[i] == elementOfParentTupleContainingTuple) { parentEntity = parentTupleElementEntities[i]; instanceLocation = parentEntity.InstanceLocation; break; } } RoslynDebug.Assert(parentEntity != null); } else { parentEntity = AnalysisEntity.Create(underlyingValueTupleType, ImmutableArray <AbstractIndex> .Empty, underlyingValueTupleType, instanceLocation, parentOpt: null); } Debug.Assert(parentEntity.InstanceLocation == instanceLocation); var builder = ArrayBuilder <AnalysisEntity> .GetInstance(tupleType.TupleElements.Length); foreach (var field in tupleType.TupleElements) { var tupleFieldName = field.CorrespondingTupleField.Name; var mappedValueTupleField = underlyingValueTupleType.GetMembers(tupleFieldName).OfType <IFieldSymbol>().FirstOrDefault(); if (mappedValueTupleField == null) { builder.Free(); return(false); } builder.Add(AnalysisEntity.Create(mappedValueTupleField, indices: ImmutableArray <AbstractIndex> .Empty, type: mappedValueTupleField.Type, instanceLocation, parentEntity)); } elementEntities = builder.ToImmutableAndFree(); return(true); }
internal static UsedNamespaceOrType CreateNamespace(INamespace @namespace, IAssemblyReference?assemblyOpt = null, string?aliasOpt = null) { RoslynDebug.Assert(@namespace != null); return(new UsedNamespaceOrType(alias: aliasOpt, targetAssembly: assemblyOpt, targetNamespace: @namespace)); }
int IVBFileCodeModelEvents.EndEdit() { try { if (_editCount == 1) { RoslynDebug.AssertNotNull(_batchElements); RoslynDebug.AssertNotNull(_invisibleEditor); List <ValueTuple <AbstractKeyedCodeElement, SyntaxPath> >?elementAndPaths = null; if (_batchElements.Count > 0) { foreach (var element in _batchElements) { var node = element.LookupNode(); if (node != null) { elementAndPaths ??= new List <ValueTuple <AbstractKeyedCodeElement, SyntaxPath> >(); elementAndPaths.Add(ValueTuple.Create(element, new SyntaxPath(node))); } } } if (_batchDocument != null) { // perform expensive operations at once var newDocument = State.ThreadingContext.JoinableTaskFactory.Run(async() => { var simplifierOptions = await _batchDocument.GetSimplifierOptionsAsync(GlobalOptions, CancellationToken.None).ConfigureAwait(false); return(await Simplifier.ReduceAsync(_batchDocument, Simplifier.Annotation, simplifierOptions, CancellationToken.None).ConfigureAwait(false)); }); _batchDocument.Project.Solution.Workspace.TryApplyChanges(newDocument.Project.Solution); // done using batch document _batchDocument = null; } // Ensure the file is prettylisted, even if we didn't make any edits CodeModelService.EnsureBufferFormatted(_invisibleEditor.TextBuffer); if (elementAndPaths != null) { foreach (var elementAndPath in elementAndPaths) { // make sure the element is there. if (_codeElementTable.TryGetValue(elementAndPath.Item1.NodeKey, out var existingElement)) { elementAndPath.Item1.ReacquireNodeKey(elementAndPath.Item2, CancellationToken.None); } // make sure existing element doesn't go away (weak reference) in the middle of // updating the node key GC.KeepAlive(existingElement); } } _batchMode = false; _batchElements = null; } return(VSConstants.S_OK); } catch (Exception ex) { return(Marshal.GetHRForException(ex)); } finally { ReleaseEditor(); } }
internal static UsedNamespaceOrType CreateXmlNamespace(string prefix, string xmlNamespace) { RoslynDebug.Assert(xmlNamespace != null); RoslynDebug.Assert(prefix != null); return(new UsedNamespaceOrType(alias: prefix, targetXmlNamespace: xmlNamespace)); }
internal ImmutableArray <TypeParameterConstraintClause> BindTypeParameterConstraintClauses( Symbol containingSymbol, ImmutableArray <TypeParameterSymbol> typeParameters, TypeParameterListSyntax typeParameterList, SyntaxList <TypeParameterConstraintClauseSyntax> clauses, ref IReadOnlyDictionary <TypeParameterSymbol, bool> isValueTypeOverride, DiagnosticBag diagnostics, bool isForOverride = false) { Debug.Assert(this.Flags.Includes(BinderFlags.GenericConstraintsClause)); RoslynDebug.Assert((object)containingSymbol != null); Debug.Assert((containingSymbol.Kind == SymbolKind.NamedType) || (containingSymbol.Kind == SymbolKind.Method)); Debug.Assert(typeParameters.Length > 0); Debug.Assert(clauses.Count > 0); int n = typeParameters.Length; // Create a map from type parameter name to ordinal. // No need to report duplicate names since duplicates // are reported when the type parameters are bound. var names = new Dictionary <string, int>(n, StringOrdinalComparer.Instance); foreach (var typeParameter in typeParameters) { var name = typeParameter.Name; if (!names.ContainsKey(name)) { names.Add(name, names.Count); } } // An array of constraint clauses, one for each type parameter, indexed by ordinal. var results = ArrayBuilder <TypeParameterConstraintClause?> .GetInstance(n, fillWithValue : null); var syntaxNodes = ArrayBuilder <ArrayBuilder <TypeConstraintSyntax>?> .GetInstance(n, fillWithValue : null); // Bind each clause and add to the results. foreach (var clause in clauses) { var name = clause.Name.Identifier.ValueText; RoslynDebug.Assert(name is object); int ordinal; if (names.TryGetValue(name, out ordinal)) { Debug.Assert(ordinal >= 0); Debug.Assert(ordinal < n); (TypeParameterConstraintClause constraintClause, ArrayBuilder <TypeConstraintSyntax>?typeConstraintNodes) = this.BindTypeParameterConstraints(typeParameterList.Parameters[ordinal], clause, isForOverride, diagnostics); if (results[ordinal] == null) { results[ordinal] = constraintClause; syntaxNodes[ordinal] = typeConstraintNodes; } else { // "A constraint clause has already been specified for type parameter '{0}'. ..." diagnostics.Add(ErrorCode.ERR_DuplicateConstraintClause, clause.Name.Location, name); typeConstraintNodes?.Free(); } } else { // Unrecognized type parameter. Don't bother binding the constraints // (the ": I<U>" in "where U : I<U>") since that will lead to additional // errors ("type or namespace 'U' could not be found") if the type // parameter is referenced in the constraints. // "'{1}' does not define type parameter '{0}'" diagnostics.Add(ErrorCode.ERR_TyVarNotFoundInConstraint, clause.Name.Location, name, containingSymbol.ConstructedFrom()); } } // Add default values for type parameters without constraint clauses. for (int i = 0; i < n; i++) { if (results[i] == null) { results[i] = GetDefaultTypeParameterConstraintClause(typeParameterList.Parameters[i], isForOverride); } } TypeParameterConstraintClause.AdjustConstraintTypes(containingSymbol, typeParameters, results, ref isValueTypeOverride); RemoveInvalidConstraints(typeParameters, results !, syntaxNodes, diagnostics); foreach (var typeConstraintsSyntaxes in syntaxNodes) { typeConstraintsSyntaxes?.Free(); } syntaxNodes.Free(); return(results.ToImmutableAndFree() !); }