private PropertyDetails GetPropertyDetails(PropertyDeclarationSyntax propertyDeclaration, SemanticModel semModel) { var propertyType = Unknown; switch (propertyDeclaration.Type) { case GenericNameSyntax gns: propertyType = gns.ToString(); // Lazy way to get generic types break; case PredefinedTypeSyntax pds: propertyType = pds.Keyword.ValueText; break; case IdentifierNameSyntax ins: propertyType = ins.Identifier.ValueText; break; case QualifiedNameSyntax qns: propertyType = qns.Right.Identifier.ValueText; if (qns.Right is GenericNameSyntax qgns) { propertyType += qgns.TypeArgumentList.ToString(); } break; case NullableTypeSyntax nts: propertyType = ((PredefinedTypeSyntax)nts.ElementType).Keyword.Text; if (!propertyType.ToLowerInvariant().Contains("nullable")) { propertyType += nts.QuestionToken.Text; } break; case ArrayTypeSyntax ats: propertyType = ats.ToString(); break; } var propertyName = this.GetIdentifier(propertyDeclaration); bool?propIsReadOnly; var setter = propertyDeclaration?.AccessorList?.Accessors .FirstOrDefault(a => a.RawKind == (ushort)SyntaxKind.SetAccessorDeclaration); if (setter == null) { propIsReadOnly = true; } else { var setterModifiers = setter.Modifiers; propIsReadOnly = setterModifiers.Any(m => m.Kind() == SyntaxKind.PrivateKeyword); } var pd = new PropertyDetails { Name = propertyName, PropertyType = propertyType, IsReadOnly = propIsReadOnly ?? false, }; foreach (var attribList in propertyDeclaration.AttributeLists) { foreach (var attrib in attribList.Attributes) { var att = new AttributeDetails { Name = attrib.Name.ToString(), }; var count = 1; foreach (var arg in attrib.ArgumentList.Arguments) { string name = null; string value = null; if (arg?.NameColon != null) { name = arg.NameColon.Name.ToString(); value = ((arg.NameColon.Parent as AttributeArgumentSyntax).Expression as IdentifierNameSyntax).Identifier.Value.ToString(); } else if (arg?.NameEquals != null) { name = arg.NameEquals.Name.ToString(); value = ((arg.NameEquals.Parent as AttributeArgumentSyntax).Expression as IdentifierNameSyntax).Identifier.Value.ToString(); } else { value = arg.ToString(); } att.Arguments.Add(new AttributeArgumentDetails { Index = count++, Name = name, Value = value, }); } pd.Attributes.Add(att); } } Logger?.RecordInfo(StringRes.Info_IdentifiedPropertySummary.WithParams(pd.Name, pd.PropertyType, pd.IsReadOnly)); ITypeSymbol typeSymbol = this.GetTypeSymbol(semModel, propertyDeclaration, pd); pd.Symbol = typeSymbol; return(pd); }
protected IEnumerable <AttributeDetails> GetAttributeDetails(SyntaxList <AttributeListSyntax> attributeList) { var result = new List <AttributeDetails>(); foreach (var attribList in attributeList) { foreach (var attrib in attribList.Attributes) { var att = new AttributeDetails { Name = attrib.Name.ToString(), }; var count = 1; if (attrib?.ArgumentList?.Arguments.Any() ?? false) { foreach (var arg in attrib?.ArgumentList.Arguments) { string name; if (arg?.NameColon != null) { name = arg.NameColon.Name.Identifier.Text; } else if (arg?.NameEquals != null) { name = arg.NameEquals.Name.ToString(); } else { name = string.Empty; } var expression = arg.Expression; string value; if (expression is IdentifierNameSyntax ins) { value = ins.Identifier.Value.ToString(); } else if (expression is LiteralExpressionSyntax les) { value = les.ToString().Replace("\"", string.Empty); } else { value = arg.ToString(); } Logger?.RecordInfo(StringRes.Info_FoundAttributeArgument.WithParams(name, value)); att.Arguments.Add(new AttributeArgumentDetails { Index = count++, Name = name, Value = value, }); } } else { Logger?.RecordInfo(StringRes.Info_NoArgumentsForAttribute); } result.Add(att); } } return(result); }