void AppendNamespace(INamedTypeSymbol classSymbol, CsharpCodeBuilder codeBuilder) { if (!classSymbol.ContainingNamespace.IsGlobalNamespace) { codeBuilder.AppendCodeLines($"namespace {classSymbol.ContainingNamespace.ToDisplayString()}"); codeBuilder.BeginSegment(); } }
private void AppendClassDefinition(INamedTypeSymbol classSymbol, CsharpCodeBuilder codeBuilder) { var classSymbols = classSymbol.GetContainerClassChains(); for (int i = 0; i < classSymbols.Count; i++) { var parentClass = classSymbols[i]; if (i == classSymbols.Count - 1) { codeBuilder.AppendCodeLines($@"static partial class {parentClass.GetClassSymbolDisplayText()}"); } else { codeBuilder.AppendCodeLines($@"partial class {parentClass.GetClassSymbolDisplayText()}"); } codeBuilder.BeginSegment(); } }
void AppendClassDefinition(INamedTypeSymbol classSymbol, CsharpCodeBuilder codeBuilder) { var classSymbols = classSymbol.GetContainerClassChains(); foreach (var parentClass in classSymbols) { codeBuilder.AppendCodeLines($@"partial class {parentClass.GetClassSymbolDisplayText()}"); codeBuilder.BeginSegment(); } }
void AppendPublicCtor(INamedTypeSymbol classSymbol, IDictionary <string, ArgumentInfo> nameMapper, bool isDependencyInjection, bool nullCheck, CsharpCodeBuilder codeBuilder) { if (isDependencyInjection) { codeBuilder.AppendCodeLines("[Microsoft.Extensions.DependencyInjection.ActivatorUtilitiesConstructor]"); } string args = string.Join(", ", nameMapper.Select(p => p.Value.GetCtorMethodArgumentItem())); codeBuilder.AppendCodeLines($"public {classSymbol.Name}({args})"); var baseCtorArgs = nameMapper.Values.Where(p => p.Source == ArgumentSource.BaseCtor); if (baseCtorArgs.Any()) { string baseArgs = string.Join(", ", baseCtorArgs.Select(p => $"{p.MemberName}: {p.ArgName}")); codeBuilder.AppendCodeLines($" : base({baseArgs})"); } codeBuilder.BeginSegment(); // lines foreach (var member in nameMapper.Values.Where(p => p.Source != ArgumentSource.BaseCtor)) { codeBuilder.AppendCodeLines(BuildCtorAssignLine(member)); } codeBuilder.EndSegment(); string BuildCtorAssignLine(ArgumentInfo argumentInfo) { if (nullCheck && !argumentInfo.ArgTypeSymbol.IsValueType) { return($"this.{argumentInfo.MemberName} = {argumentInfo.ArgName} ?? throw new System.ArgumentNullException(nameof({argumentInfo.ArgName}));"); } else { return($"this.{argumentInfo.MemberName} = {argumentInfo.ArgName};"); } } }
void AppendSingletonBody(INamedTypeSymbol classSymbol, CsharpCodeBuilder codeBuilder) { var instanceName = classSymbol.GetAttributes().Where(p => p.AttributeClass.SafeEquals(typeof(SingletonPatternAttribute))) .Select(p => p.NamedArguments.Where(t => t.Key == nameof(SingletonPatternAttribute.InstancePropertyName)).Where(t => !t.Value.IsNull).Select(t => (string)t.Value.Value).FirstOrDefault()) .FirstOrDefault(); instanceName = string.IsNullOrEmpty(instanceName) ? SingletonPatternAttribute.DefaultInstanceName : instanceName; var content = $@"private static readonly Lazy<{classSymbol.GetClassSymbolDisplayText()}> LazyInstance = new Lazy<{classSymbol.GetClassSymbolDisplayText()}>(() => new {classSymbol.GetClassSymbolDisplayText()}(), true); private {classSymbol.Name}() {{ }} public static {classSymbol.GetClassSymbolDisplayText()} {instanceName} => LazyInstance.Value;"; codeBuilder.AppendCodeLines(content); }
void AppendUsingLines(INamedTypeSymbol _, CsharpCodeBuilder codeBuilder) { codeBuilder.AppendCodeLines("using System;"); }
private CodeFile ProcessClass(INamedTypeSymbol classSymbol, List <IFieldSymbol> fields, CodeWriter codeWriter) { var compilation = codeWriter.Compilation; INamedTypeSymbol notifySymbol = compilation.GetTypeByMetadataName("System.ComponentModel.INotifyPropertyChanged"); var classSymbols = classSymbol.GetContainerClassChains(); CsharpCodeBuilder codeBuilder = new CsharpCodeBuilder(); var allNamespaces = new HashSet <string>(); allNamespaces.Add("System.ComponentModel"); foreach (var usingNamespace in allNamespaces.OrderBy(p => p)) { codeBuilder.AppendCodeLines($"using {usingNamespace};"); } //codeBuilder.AppendCodeLines($@"using System.ComponentModel;"); if (!classSymbol.ContainingNamespace.IsGlobalNamespace) { codeBuilder.AppendCodeLines($"namespace {classSymbol.ContainingNamespace.ToDisplayString()}"); codeBuilder.BeginSegment(); } foreach (var parentClass in classSymbols) { if (parentClass != classSymbol) { codeBuilder.AppendCodeLines($@"partial class {parentClass.GetClassSymbolDisplayText()}"); codeBuilder.BeginSegment(); } } if (!classSymbol.AllInterfaces.Contains(notifySymbol)) { codeBuilder.AppendCodeLines( $@"partial class {classSymbol.GetClassSymbolDisplayText()} : {notifySymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)}"); codeBuilder.BeginSegment(); codeBuilder.AppendCodeLines("public event PropertyChangedEventHandler PropertyChanged;"); } else { codeBuilder.AppendCodeLines($@"partial class {classSymbol.Name}"); codeBuilder.BeginSegment(); } // create properties for each field foreach (IFieldSymbol fieldSymbol in fields) { ProcessField(codeBuilder, fieldSymbol, codeWriter); } codeBuilder.EndAllSegments(); return(new CodeFile { BasicName = classSymbol.GetCodeFileBasicName(), Content = codeBuilder.ToString(), }); }
private static void ProcessField(CsharpCodeBuilder source, IFieldSymbol fieldSymbol, CodeWriter codeWriter) { // get the name and type of the field string fieldName = fieldSymbol.Name; ITypeSymbol fieldType = fieldSymbol.Type; AttributeData attributeData = fieldSymbol.GetAttributes() .Single(p => p.AttributeClass.SafeEquals(typeof(AutoNotifyAttribute))); // get the AutoNotify attribute from the field, and any associated data TypedConstant overridenNameOpt = attributeData.NamedArguments.SingleOrDefault(kvp => kvp.Key == nameof(AutoNotifyAttribute.PropertyName)).Value; string propertyName = chooseName(fieldName, overridenNameOpt); if (!System.Text.RegularExpressions.Regex.IsMatch(propertyName, "^[_a-zA-Z][_a-zA-Z0-9]*$")) { codeWriter.Context.ReportDiagnostic(KnifeDiagnostic.AutoNotify.InvalidPropertyName(propertyName)); } if (propertyName == fieldName) { codeWriter.Context.ReportDiagnostic(KnifeDiagnostic.AutoNotify.PropertyNameEqualFieldName(propertyName)); } source.AppendCodeLines($@" public {fieldType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)} {propertyName} {{ get {{ return this.{fieldName}; }} set {{ if(this.{fieldName} != value) {{ this.{fieldName} = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof({propertyName}))); }} }} }} "); string chooseName(string field, TypedConstant overridenNameOption) { if (!overridenNameOption.IsNull) { return(overridenNameOption.Value.ToString()); } field = field.TrimStart('_'); if (field.Length == 0) { return(string.Empty); } if (field.Length == 1) { return(field.ToUpperInvariant()); } return(field.Substring(0, 1).ToUpperInvariant() + field.Substring(1)); } }
private void AppendUsingLines(INamedTypeSymbol _, CsharpCodeBuilder codeBuilder) { codeBuilder.AppendCodeLines("using System.Collections.Generic;"); codeBuilder.AppendCodeLines("using System.Linq;"); }