Example #1
0
        private static void CheckCommandOptionProperties(
            SymbolAnalysisContext context,
            IReadOnlyList <IPropertySymbol> properties)
        {
            var options = properties
                          .Select(p =>
            {
                var attribute = p
                                .GetAttributes()
                                .First(a => KnownSymbols.IsCommandOptionAttribute(a.AttributeClass));

                var name = attribute
                           .ConstructorArguments
                           .Where(a => KnownSymbols.IsSystemString(a.Type))
                           .Select(a => a.Value)
                           .FirstOrDefault() as string;

                var shortName = attribute
                                .ConstructorArguments
                                .Where(a => KnownSymbols.IsSystemChar(a.Type))
                                .Select(a => a.Value)
                                .FirstOrDefault() as char?;

                var envVarName = attribute
                                 .NamedArguments
                                 .Where(a => a.Key == "EnvironmentVariableName")
                                 .Select(a => a.Value.Value)
                                 .FirstOrDefault() as string;

                var converter = attribute
                                .NamedArguments
                                .Where(a => a.Key == "Converter")
                                .Select(a => a.Value.Value)
                                .Cast <ITypeSymbol>()
                                .FirstOrDefault();

                var validators = attribute
                                 .NamedArguments
                                 .Where(a => a.Key == "Validators")
                                 .SelectMany(a => a.Value.Values)
                                 .Select(c => c.Value)
                                 .Cast <ITypeSymbol>()
                                 .ToArray();

                return(new
                {
                    Property = p,
                    Name = name,
                    ShortName = shortName,
                    EnvironmentVariableName = envVarName,
                    Converter = converter,
                    Validators = validators
                });
            })
                          .ToArray();

            // No name
            var noNameOptions = options
                                .Where(o => string.IsNullOrWhiteSpace(o.Name) && o.ShortName == null)
                                .ToArray();

            foreach (var option in noNameOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0041, option.Property.Locations.First()
                                             ));
            }

            // Too short name
            var invalidNameLengthOptions = options
                                           .Where(o => !string.IsNullOrWhiteSpace(o.Name) && o.Name.Length <= 1)
                                           .ToArray();

            foreach (var option in invalidNameLengthOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0042, option.Property.Locations.First()
                                             ));
            }

            // Duplicate name
            var duplicateNameOptions = options
                                       .Where(p => !string.IsNullOrWhiteSpace(p.Name))
                                       .GroupBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
                                       .Where(g => g.Count() > 1)
                                       .SelectMany(g => g.AsEnumerable())
                                       .ToArray();

            foreach (var option in duplicateNameOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0043, option.Property.Locations.First()
                                             ));
            }

            // Duplicate name
            var duplicateShortNameOptions = options
                                            .Where(p => p.ShortName != null)
                                            .GroupBy(p => p.ShortName)
                                            .Where(g => g.Count() > 1)
                                            .SelectMany(g => g.AsEnumerable())
                                            .ToArray();

            foreach (var option in duplicateShortNameOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0044, option.Property.Locations.First()
                                             ));
            }

            // Duplicate environment variable name
            var duplicateEnvironmentVariableNameOptions = options
                                                          .Where(p => !string.IsNullOrWhiteSpace(p.EnvironmentVariableName))
                                                          .GroupBy(p => p.EnvironmentVariableName, StringComparer.Ordinal)
                                                          .Where(g => g.Count() > 1)
                                                          .SelectMany(g => g.AsEnumerable())
                                                          .ToArray();

            foreach (var option in duplicateEnvironmentVariableNameOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0045, option.Property.Locations.First()
                                             ));
            }

            // Invalid converter
            var invalidConverterOptions = options
                                          .Where(o =>
                                                 o.Converter != null &&
                                                 !o.Converter.AllInterfaces.Any(KnownSymbols.IsArgumentValueConverterInterface))
                                          .ToArray();

            foreach (var option in invalidConverterOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0046, option.Property.Locations.First()
                                             ));
            }

            // Invalid validators
            var invalidValidatorsOptions = options
                                           .Where(o => !o.Validators.All(v => v.AllInterfaces.Any(KnownSymbols.IsArgumentValueValidatorInterface)))
                                           .ToArray();

            foreach (var option in invalidValidatorsOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0047, option.Property.Locations.First()
                                             ));
            }

            // Non-letter first character in name
            var nonLetterFirstCharacterInNameOptions = options
                                                       .Where(o => !string.IsNullOrWhiteSpace(o.Name) && !char.IsLetter(o.Name[0]))
                                                       .ToArray();

            foreach (var option in nonLetterFirstCharacterInNameOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0048, option.Property.Locations.First()
                                             ));
            }

            // Non-letter short name
            var nonLetterShortNameOptions = options
                                            .Where(o => o.ShortName != null && !char.IsLetter(o.ShortName.Value))
                                            .ToArray();

            foreach (var option in nonLetterShortNameOptions)
            {
                context.ReportDiagnostic(Diagnostic.Create(
                                             DiagnosticDescriptors.CliFx0049, option.Property.Locations.First()
                                             ));
            }
        }
        private static void CheckCommandOptionProperties(
            SymbolAnalysisContext context,
            IReadOnlyList <IPropertySymbol> properties)
        {
            var options = properties
                          .Select(p =>
            {
                var attribute = p
                                .GetAttributes()
                                .First(a => KnownSymbols.IsCommandOptionAttribute(a.AttributeClass));

                var name = attribute
                           .ConstructorArguments
                           .Where(a => KnownSymbols.IsSystemString(a.Type))
                           .Select(a => a.Value)
                           .FirstOrDefault() as string;

                var shortName = attribute
                                .ConstructorArguments
                                .Where(a => KnownSymbols.IsSystemChar(a.Type))
                                .Select(a => a.Value)
                                .FirstOrDefault() as char?;

                var envVarName = attribute
                                 .NamedArguments
                                 .Where(a => a.Key == "EnvironmentVariableName")
                                 .Select(a => a.Value.Value)
                                 .FirstOrDefault() as string;

                return(new
                {
                    Property = p,
                    Name = name,
                    ShortName = shortName,
                    EnvironmentVariableName = envVarName
                });
            })
                          .ToArray();

            // No name
            var noNameOptions = options
                                .Where(o => string.IsNullOrWhiteSpace(o.Name) && o.ShortName == null)
                                .ToArray();

            foreach (var option in noNameOptions)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(DiagnosticDescriptors.CliFx0041, option.Property.Locations.First()));
            }

            // Too short name
            var invalidNameLengthOptions = options
                                           .Where(o => !string.IsNullOrWhiteSpace(o.Name) && o.Name.Length <= 1)
                                           .ToArray();

            foreach (var option in invalidNameLengthOptions)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(DiagnosticDescriptors.CliFx0042, option.Property.Locations.First()));
            }

            // Duplicate name
            var duplicateNameOptions = options
                                       .Where(p => !string.IsNullOrWhiteSpace(p.Name))
                                       .GroupBy(p => p.Name, StringComparer.OrdinalIgnoreCase)
                                       .Where(g => g.Count() > 1)
                                       .SelectMany(g => g.AsEnumerable())
                                       .ToArray();

            foreach (var option in duplicateNameOptions)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(DiagnosticDescriptors.CliFx0043, option.Property.Locations.First()));
            }

            // Duplicate name
            var duplicateShortNameOptions = options
                                            .Where(p => p.ShortName != null)
                                            .GroupBy(p => p.ShortName)
                                            .Where(g => g.Count() > 1)
                                            .SelectMany(g => g.AsEnumerable())
                                            .ToArray();

            foreach (var option in duplicateShortNameOptions)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(DiagnosticDescriptors.CliFx0044, option.Property.Locations.First()));
            }

            // Duplicate environment variable name
            var duplicateEnvironmentVariableNameOptions = options
                                                          .Where(p => !string.IsNullOrWhiteSpace(p.EnvironmentVariableName))
                                                          .GroupBy(p => p.EnvironmentVariableName, StringComparer.Ordinal)
                                                          .Where(g => g.Count() > 1)
                                                          .SelectMany(g => g.AsEnumerable())
                                                          .ToArray();

            foreach (var option in duplicateEnvironmentVariableNameOptions)
            {
                context.ReportDiagnostic(
                    Diagnostic.Create(DiagnosticDescriptors.CliFx0045, option.Property.Locations.First()));
            }
        }