src/extensions/default/analyzers/Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers/TypeUpgradeAnalyzer.cs
/// <summary>
/// Analyzes an identifier syntax node to determine if it likely represents any of the types present
/// in <see cref="IdentifierMappings"/>.
/// </summary>
/// <param name="context">The syntax node analysis context including the identifier node to analyze.</param>
/// <param name="mappings">Type mappings to use when upgrading types.</param>
/// <param name="simpleName">The simple name of the identifier being analyzed.</param>
Analyzes an identifier syntax node to determine if it likely represents any of the types present
in .
Analyzes an identifier syntax node to determine if it likely represents any of the types present in .
private static void AnalyzeIdentifier(SyntaxNodeAnalysisContext context, IEnumerable<TypeMapping> mappings, string simpleName)
        {
            var mapping = mappings.FirstOrDefault(m => m.SimpleName?.Equals(simpleName, StringComparison.Ordinal) ?? false);
            if (mapping is null)
            {
                return;
            }
            if (mapping.NewName is null)
            {
                return;
            }
            var fullyQualifiedNameNode = context.Node.GetQualifiedName();
            if (fullyQualifiedNameNode.IsQualifiedName()
                && !mapping.OldName.EndsWith(fullyQualifiedNameNode.ToString(), StringComparison.Ordinal))
            {
                return;
            }
            var symbolInfo = context.SemanticModel.GetSymbolInfo(context.Node);
            if (symbolInfo.Symbol is ISymbol symbol)
            {
                if (symbol is INamedTypeSymbol typeSymbol)
                {
                    if (typeSymbol is not IErrorTypeSymbol
                    && !typeSymbol.ToDisplayString(NullableFlowState.NotNull).Equals(mapping.OldName, StringComparison.Ordinal))
                    {
                        return;
                    }
                    else
                    {
                    }
                }
                else
                {
                    return;
                }
            }
            if (symbolInfo.CandidateSymbols.OfType<INamedTypeSymbol>().Any(s => s.ToDisplayString(NullableFlowState.NotNull).Equals(mapping.NewName, StringComparison.Ordinal)))
            {
                return;
            }
            if (!fullyQualifiedNameNode.IsTypeSyntax())
            {
                return;
            }
            var properties = ImmutableDictionary.Create<string, string?>().Add(NewIdentifierKey, mapping.NewName);
            var diagnostic = CreateDiagnostic(fullyQualifiedNameNode.GetLocation(), properties, simpleName, mapping.NewName);
            context.ReportDiagnostic(diagnostic);
        }
private static void AnalyzeIdentifier ( SyntaxNodeAnalysisContext context , IEnumerable < TypeMapping > mappings , string simpleName ) { var mapping = mappings . FirstOrDefault ( m => m . SimpleName ? . Equals ( simpleName , StringComparison . Ordinal ) ?? false ) ; if ( mapping is null ) { return ; } if ( mapping . NewName is null ) { return ; } var fullyQualifiedNameNode = context . Node . GetQualifiedName ( ) ; if ( fullyQualifiedNameNode . IsQualifiedName ( ) && ! mapping . OldName . EndsWith ( fullyQualifiedNameNode . ToString ( ) , StringComparison . Ordinal ) ) { return ; } var symbolInfo = context . SemanticModel . GetSymbolInfo ( context . Node ) ; if ( symbolInfo . Symbol is ISymbol symbol ) { if ( symbol is INamedTypeSymbol typeSymbol ) { if ( typeSymbol is not IErrorTypeSymbol && ! typeSymbol . ToDisplayString ( NullableFlowState . NotNull ) . Equals ( mapping . OldName , StringComparison . Ordinal ) ) { return ; } else { } } else { return ; } } if ( symbolInfo . CandidateSymbols . OfType < INamedTypeSymbol > ( ) . Any ( s => s . ToDisplayString ( NullableFlowState . NotNull ) . Equals ( mapping . NewName , StringComparison . Ordinal ) ) ) { return ; } if ( ! fullyQualifiedNameNode . IsTypeSyntax ( ) ) { return ; } var properties = ImmutableDictionary . Create < string , string ? > ( ) . Add ( NewIdentifierKey , mapping . NewName ) ; var diagnostic = CreateDiagnostic ( fullyQualifiedNameNode . GetLocation ( ) , properties , simpleName , mapping . NewName ) ; context . ReportDiagnostic ( diagnostic ) ; }
Analyzes an identifier syntax node to determine if it likely represents any of the types present
in .
Analyzes an identifier syntax node to determine if it likely represents any of the types present in .
// If the identifier isn't one of the mapped identifiers, bail out // This analyzer requires a new type // If the identifier is part of a fully qualified name and the qualified name does not match // the old name, then bail out because it is not referring to that type // If symbol information is available, then attempt to use that to determine // whether the syntax node corresponds to a type that needs flagged. // Bail out if the node corresponds to a type symbol that isn't the old type. // This case is intentionally not handled. // A type symbol that is either an error type symbol or that correctly matches the old type name // may warrant reporting a diagnostic. // If the identifier resolves to a symbol that isn't a type symbol (property symbol, for example), // then bail out because this analyzer should only flag type usage. // Bail out if the symbol might correspond to a symbol that is the new type. // If the symbol cannot be determined, bail out if the syntax is not used in // a way that a type symbol would typically be used. This avoids incorrectly // reporting diagnostics in cases where an interesting simple name is used // for a property name that doesn't resolve to a symbol, for example. // Store the new identifier name that this identifier should be replaced with for use // by the code fix provider. // Create and report the diagnostic. Note that the fully qualified name's location is used so // that the code fix provider can directly replace the node without needing to consider its parents.
context
SyntaxNodeAnalysisContext
The syntax node analysis context including the identifier node to analyze.
The syntax node analysis context including the identifier node to analyze .
mappings
IEnumerable<TypeMapping>
Type mappings to use when upgrading types.
Type mappings to use when upgrading types .
simpleName
string
The simple name of the identifier being analyzed.
The simple name of the identifier being analyzed .