private void ShowFormattedSummary(IndentingTextWriter writer, string summary, int?columns) { _env.AssertValue(writer); if (string.IsNullOrWhiteSpace(summary)) { return; } // REVIEW: should we replace consecutive spaces with a single space as a preprocessing step? int screenWidth = (columns ?? Console.BufferWidth) - 1; // Console.BufferWidth returns 0 if command redirection operator is used if (screenWidth <= 0) { screenWidth = 80; } const int indentLen = 3; string indent = new string(' ', indentLen); var builder = new StringBuilder(); // REVIEW: is using StringSplitOptions.RemoveEmptyEntries the right thing to do here? var blocks = summary.Split(new[] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < blocks.Length; i++) { AppendFormattedText(builder, blocks[i], indent, screenWidth); } writer.WriteLine("Summary:"); writer.WriteLine(builder); }
protected void GenerateMethodSignature(IndentingTextWriter w, CmdParser.ArgInfo.Arg arg, string parent, string parentType, string parentValue, ref string linePrefix, string argSuffix) { if (Exclude.Contains(arg.LongName)) { return; } if (arg.IsSubComponentItemType) { // We need to create a tree with all the subcomponents, unless the subcomponent is a Trainer. Contracts.Assert(arg.ItemType.GetGenericTypeDefinition() == typeof(SubComponent <,>)); var types = arg.ItemType.GetGenericArguments(); var baseType = types[0]; var sigType = types[1]; if (sigType == typeof(SignatureDataLoader)) { return; } w.WriteLine(linePrefix); linePrefix = ","; if (IsTrainer(sigType)) { w.WriteLine("[DataLabInputPort(FriendlyName = \"Untrained model\", DisplayName = \"Untrained model\", IsOptional = false, DataTypes = WellKnownDataTypeIds.ILearnerDotNet, Description = \"An untrained model\")]"); GenerateParameter(w, "ILearner", arg.LongName + argSuffix); return; } var typeName = EnumName(arg, sigType); GenerateDataLabParameterAttribute(w, arg.LongName, false, arg.LongName, arg.DefaultValue != null ? typeName + "." + arg.DefaultValue : null, arg.HelpText, parent, parentType, parentValue); GenerateParameter(w, typeName, arg.LongName + argSuffix); var infos = ComponentCatalog.GetAllDerivedClasses(baseType, sigType); foreach (var info in infos) { var args = info.CreateArguments(); if (args == null) { continue; } var argInfo = CmdParser.GetArgInfo(args.GetType(), args); foreach (var a in argInfo.Args) { GenerateMethodSignature(w, a, arg.LongName, typeName, info.LoadNames[0], ref linePrefix, argSuffix + info.LoadNames[0]); } } } else { w.WriteLine(linePrefix); linePrefix = ","; if (IsColumnType(arg)) { GenerateDataLabParameterAttribute(w, arg.LongName, false, arg.LongName, null, arg.HelpText, parent, parentType, parentValue); GenerateParameter(w, "string", arg.LongName + argSuffix); } else { GenerateDataLabParameterAttribute(w, arg.LongName, IsOptional(arg), arg.LongName, Stringify(arg.DefaultValue), arg.HelpText, parent, parentType, parentValue); GenerateParameter(w, GetCSharpTypeName(arg.ItemType), arg.LongName + argSuffix); } } }
protected void GenerateImplBody(IndentingTextWriter w, CmdParser.ArgInfo.Arg arg, string argSuffix) { if (Exclude.Contains(arg.LongName)) { return; } if (arg.IsCollection) { if (IsColumnType(arg)) { w.WriteLine("args{0}.{1} = {1}.Select({2}.Parse).ToArray();", argSuffix, arg.LongName, GetCSharpTypeName(arg.ItemType)); } else if (IsStringColumnType(arg)) { w.WriteLine("args{0}.{1} = {2};", argSuffix, arg.LongName, arg.LongName + argSuffix); } else { w.WriteLine("args{0}.{1} = new[] {{ {2} }};", argSuffix, arg.LongName, arg.LongName + argSuffix); } } else { w.WriteLine("args{0}.{1} = {2};", argSuffix, arg.LongName, arg.LongName + argSuffix); } }
/// <summary> /// Called at the beginning of a test - it dumps the usage of the Arguments class(es). /// </summary> private static void Init(IndentingTextWriter wrt, object defaults) { var env = new TlcEnvironment(seed: 42); wrt.WriteLine("Usage:"); wrt.WriteLine(CmdParser.ArgumentsUsage(env, defaults.GetType(), defaults, false, 200)); }
protected override void GenerateOutputPort(IndentingTextWriter w) { w.WriteLine( "[DataLabOutputPort(FriendlyName = \"Transformed IDataView\", DisplayName = \"Transformed IDataView\", Position = 0, DataType = WellKnownDataTypeIds.IDataViewDotNet, Description = \"Transformed data (IDataView)\")]"); w.WriteLine( "[DataLabOutputPort(FriendlyName = \"Transformed data model\", DisplayName = \"Transformed data model\", Position = 1, DataType = WellKnownDataTypeIds.ITransformDotNet, Description = \"Transformed data model (ITransform)\")]"); }
private void GenerateImplCall(IndentingTextWriter w, CmdParser.ArgInfo.Arg arg, string parent, string parentType, string parentValue, string argSuffix) { if (Exclude.Contains(arg.LongName)) { return; } if (arg.IsSubComponentItemType) { // We need to create a tree with all the subcomponents, unless the subcomponent is a Trainer. Contracts.Assert(arg.ItemType.GetGenericTypeDefinition() == typeof(SubComponent <,>)); var types = arg.ItemType.GetGenericArguments(); var baseType = types[0]; var sigType = types[1]; if (sigType == typeof(SignatureDataLoader)) { return; } if (IsTrainer(sigType)) { return; } var typeName = EnumName(arg, sigType); GenerateImplCall(w, typeName, arg.LongName + argSuffix); var infos = ComponentCatalog.GetAllDerivedClasses(baseType, sigType); foreach (var info in infos) { var args = info.CreateArguments(); if (args == null) { continue; } var argInfo = CmdParser.GetArgInfo(args.GetType(), args); foreach (var a in argInfo.Args) { GenerateImplCall(w, a, arg.LongName, typeName, info.LoadNames[0], argSuffix + info.LoadNames[0]); } } } else { if (IsColumnType(arg) || IsStringColumnType(arg)) { string name = arg.LongName + argSuffix; if (arg.IsCollection) { w.WriteLine("builder.{0} = ((string)parameters[\"{1}\"]).Split('|');", Capitalize(name), name); } else { w.WriteLine("builder.{0} = (string)parameters[\"{1}\"];", Capitalize(name), name); } } else { GenerateImplCall(w, GetCSharpTypeName(arg.ItemType), arg.LongName + argSuffix); } } }
protected override void GenerateMethodSignature(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.WriteLine("/// <summary>"); w.WriteLine("/// Creates a {0}", component.LoadNames[0]); w.WriteLine("/// </summary>"); w.WriteLine("/// <returns>A tuple containing learner name and settings.</returns>"); w.WriteLine("public Tuple<string, string> GetTlcSettings()"); }
protected override void GenerateClassName(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.WriteLine(); var className = prefix + component.LoadNames[0]; w.WriteLine("/// <summary>Module: {0}</summary>", className); w.WriteLine("public static class {0}EntryPoint", className); w.WriteLine("{"); }
protected virtual void GenerateClassName(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.WriteLine(); var className = prefix + component.LoadNames[0]; w.WriteLine("/// <summary>Module: {0}</summary>", className); w.WriteLine("public partial class {0}", className); w.WriteLine("{"); }
private void GenerateInputOutput(IndentingTextWriter writer, ModuleCatalog.EntryPointInfo entryPointInfo, ModuleCatalog catalog) { var classAndMethod = CSharpGeneratorUtils.GetEntryPointMetadata(entryPointInfo); writer.WriteLine($"namespace {classAndMethod.Namespace}"); writer.WriteLine("{"); writer.Indent(); GenerateInput(writer, entryPointInfo, catalog); writer.Outdent(); writer.WriteLine("}"); writer.WriteLine(); }
public static void GenerateSummary(IndentingTextWriter writer, string summary) { if (string.IsNullOrEmpty(summary)) { return; } writer.WriteLine("/// <summary>"); foreach (var line in summary.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) { writer.WriteLine($"/// {line}"); } writer.WriteLine("/// </summary>"); }
protected void GenerateImplCall(IndentingTextWriter w, CmdParser.ArgInfo.Arg arg, string argSuffix) { if (Exclude.Contains(arg.LongName)) { return; } if (arg.IsSubComponentItemType) { Contracts.Assert(arg.ItemType.GetGenericTypeDefinition() == typeof(SubComponent <,>)); var types = arg.ItemType.GetGenericArguments(); var baseType = types[0]; var sigType = types[1]; if (sigType == typeof(SignatureDataLoader)) { return; } if (IsTrainer(sigType)) { w.WriteLine("builder.{0} = {1};", Capitalize(arg.LongName + argSuffix), arg.LongName + argSuffix); return; } w.WriteLine("builder.{0} = {1};", Capitalize(arg.LongName + argSuffix), arg.LongName + argSuffix); var infos = ComponentCatalog.GetAllDerivedClasses(baseType, sigType); foreach (var info in infos) { var args = info.CreateArguments(); if (args == null) { continue; } var argInfo = CmdParser.GetArgInfo(args.GetType(), args); foreach (var a in argInfo.Args) { GenerateImplCall(w, a, argSuffix + info.LoadNames[0]); } } } else { if (IsColumnType(arg)) { w.WriteLine("builder.{0} = {1}.Split('|');", Capitalize(arg.LongName + argSuffix), arg.LongName + argSuffix); } else { w.WriteLine("builder.{0} = {1}{2};", Capitalize(arg.LongName + argSuffix), CastIfNeeded(arg), arg.LongName + argSuffix); } } }
private void GenerateParameterAttribute(IndentingTextWriter w, string displayName, object defaultValue, string description, string parent = null, string parentType = null, string parentValue = null) { w.WriteLine("[Help(Display = @\"{0}\", ToolTip = \"{1}\")]", PrettyPrintDisplayName(displayName), description); if (parent != null) { w.WriteLine("[Relevancy(Key = \"{0}\", Values = new object[] {{ {1}.{2} }})]", parent, parentType, parentValue); } if (defaultValue != null) { w.WriteLine("[Domain(DefaultValue = {0})]", defaultValue); } w.WriteLine("[ModuleParameter]"); }
private void ListKinds(IndentingTextWriter writer) { var sigs = _env.ComponentCatalog.GetAllSignatureTypes() .Select(ComponentCatalog.SignatureToString) .OrderBy(x => x); writer.WriteLine("Available component kinds:"); using (writer.Nest()) { foreach (var sig in sigs) { writer.WriteLine(sig); } } }
protected override void GenerateUsings(IndentingTextWriter w) { w.WriteLine("using System;"); w.WriteLine("using System.Diagnostics.CodeAnalysis;"); w.WriteLine("using System.Linq;"); w.WriteLine("using Microsoft.Analytics.MachineLearning;"); w.WriteLine("using Microsoft.Analytics.Modules;"); w.WriteLine("using Microsoft.ML.Runtime;"); w.WriteLine("using Microsoft.ML.Runtime.CommandLine;"); w.WriteLine("using Microsoft.ML.Runtime.Data;"); w.WriteLine("using Microsoft.ML.Runtime.Internal.Internallearn;"); }
protected void GenerateImplCall(IndentingTextWriter w, CmdParser.ArgInfo.Arg arg, string argSuffix) { if (Exclude.Contains(arg.LongName)) { return; } if (IsColumnType(arg)) { w.WriteLine("builder.{0} = {1}.Split('|');", Capitalize(arg.LongName + argSuffix), arg.LongName + argSuffix); } else { w.WriteLine("builder.{0} = {1}{2};", Capitalize(arg.LongName + argSuffix), CastIfNeeded(arg), arg.LongName + argSuffix); } }
protected override void GenerateEnumValue(IndentingTextWriter w, ComponentCatalog.LoadableClassInfo info) { var name = info != null ? info.LoadNames[0] : "None"; w.WriteLine("/// <summary> {0} option </summary>", name); w.Write("{0}", name); }
private static void ShowMetadata(IndentingTextWriter itw, ISchema schema, int col, bool showVals) { Contracts.AssertValue(itw); Contracts.AssertValue(schema); Contracts.Assert(0 <= col && col < schema.ColumnCount); using (itw.Nest()) { foreach (var kvp in schema.GetMetadataTypes(col).OrderBy(p => p.Key)) { Contracts.AssertNonEmpty(kvp.Key); Contracts.AssertValue(kvp.Value); var type = kvp.Value; itw.Write("Metadata '{0}': {1}", kvp.Key, type); if (showVals) { if (!type.IsVector) { ShowMetadataValue(itw, schema, col, kvp.Key, type); } else { ShowMetadataValueVec(itw, schema, col, kvp.Key, type); } } itw.WriteLine(); } } }
protected void GenerateModuleType(IndentingTextWriter w, ComponentCatalog.LoadableClassInfo component) { string cat; if (component.IsOfType(typeof(SignatureBinaryClassifierTrainer))) { cat = "BinaryClassifier"; } else if (component.IsOfType(typeof(SignatureMultiClassClassifierTrainer))) { cat = "MultiClassClassifier"; } else if (component.IsOfType(typeof(SignatureRegressorTrainer))) { cat = "Regression"; } else if (component.IsOfType(typeof(SignatureAnomalyDetectorTrainer))) { cat = "AnomalyDetector"; } else { cat = "None"; } w.WriteLine("[DataLabModuleType(Type = ModuleType.{0})]", cat); }
protected override void GenerateUsings(IndentingTextWriter w) { var allNamespaces = new HashSet <string>(); foreach (var ns in Namespaces) { allNamespaces.Add(ns); } allNamespaces.Add("System.Collections.Generic"); allNamespaces.Add("Microsoft.Analytics.Modules.Common"); allNamespaces.Add("Microsoft.Analytics.Platform.ML.Models"); allNamespaces.Add("Microsoft.ML.Runtime.Data"); allNamespaces.Add("Microsoft.ML.Runtime.Modules.Contracts"); allNamespaces.Add("Microsoft.ML.Runtime.Modules.Contracts.Attributes"); allNamespaces.Add("Microsoft.ML.Runtime.Modules.Contracts.Types"); var namespaces = allNamespaces.ToArray(); Array.Sort(namespaces, (a, b) => a.StartsWith("System") && !b.StartsWith("System") ? -1 : !a.StartsWith("System") && b.StartsWith("System") ? 1 : string.CompareOrdinal(a, b)); foreach (var ns in namespaces) { w.WriteLine("using {0};", ns); } }
protected override void GenerateMethodSignature(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.WriteLine("public static Tuple<IDataView, DataTransform> Create{0}{1}(", prefix, component.LoadNames[0]); using (w.Nest()) { var argumentInfo = CmdParser.GetArgInfo(component.ArgType, component.CreateArguments()); w.WriteLine("[DataLabInputPort(FriendlyName = \"IDataView\", DisplayName = \"IDataView\", IsOptional = false, DataTypes = WellKnownDataTypeIds.IDataViewDotNet, Description = \"Input data (IDataView)\")]"); w.Write("IDataView data"); var pre = ","; foreach (var arg in argumentInfo.Args.Where(a => !a.IsHidden)) { GenerateMethodSignature(w, arg, null, null, null, ref pre, ""); } w.WriteLine(")"); } }
protected override void GenerateImplBody(IndentingTextWriter w, ComponentCatalog.LoadableClassInfo component) { w.WriteLine("{"); using (w.Nest()) { w.WriteLine("var args = new {0}();", GetCSharpTypeName(component.ArgType)); w.WriteLine("var defs = new {0}();", GetCSharpTypeName(component.ArgType)); var argumentInfo = CmdParser.GetArgInfo(component.ArgType, component.CreateArguments()); var arguments = argumentInfo.Args.Where(a => !a.IsHidden).ToArray(); foreach (var arg in arguments) { GenerateImplBody(w, arg, ""); } w.WriteLine("return new Tuple<string, string>(\"{0}\", CmdParser.GetSettings(args, defs));", component.LoadNames[0]); } w.WriteLine("}"); }
protected override void GenerateImplCall(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.WriteLine("{"); using (w.Nest()) { var className = prefix + component.LoadNames[0]; w.WriteLine("var builder = new {0}();", className); var argumentInfo = CmdParser.GetArgInfo(component.ArgType, component.CreateArguments()); var arguments = argumentInfo.Args.Where(a => !a.IsHidden).ToArray(); foreach (var arg in arguments) { GenerateImplCall(w, arg, ""); } w.WriteLine("var learner = builder.GetTlcSettings();"); w.WriteLine("return new TlcTrainer(learner.Item1, learner.Item2);"); } w.WriteLine("}"); }
protected override void GenerateEnumValue(IndentingTextWriter w, ComponentCatalog.LoadableClassInfo info) { var userName = info != null ? info.UserName : "******"; var name = info != null ? info.LoadNames[0] : "None"; w.WriteLine("[ItemInfo(FriendlyName = \"{0}\", DisplayValue = \"{1}\")]", userName, userName); w.Write("{0}", name); }
protected override void GenerateMethodSignature(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.WriteLine("/// <summary>"); w.WriteLine("/// Creates a {0}", component.LoadNames[0]); w.WriteLine("/// </summary>"); w.WriteLine("/// <param name=\"env\">The environment</param>"); w.WriteLine("/// <param name=\"data\">The data set</param>"); w.WriteLine("/// <returns>The transformed data.</returns>"); w.WriteLine("public IDataView Create{0}{1}Impl(", prefix, component.LoadNames[0]); using (w.Nest()) { w.WriteLine("IHostEnvironment env,"); w.WriteLine("IDataView data)"); } }
private void ShowUsage(IndentingTextWriter writer, string kind, string summary, string loadName, IReadOnlyList <string> loadNames, object args, int?columns) { _env.Assert(loadName == loadNames[0]); writer.WriteLine("Help for {0}: '{1}'", kind, loadName); using (writer.Nest()) ShowAliases(writer, loadNames); writer.WriteLine(); ShowFormattedSummary(writer, summary, columns); if (args == null) { writer.WriteLine("Component '{0}' is not configurable", loadName); writer.WriteLine(); } else { writer.WriteLine(CmdParser.ArgumentsUsage(_env, args.GetType(), args, false, columns)); } }
protected override void GenerateSummaryComment(IndentingTextWriter w, ComponentCatalog.LoadableClassInfo component) { w.WriteLine("/// <summary>"); var desc = component.Summary ?? component.LoadNames[0]; using (var sr = new StringReader(desc)) { string line; while ((line = sr.ReadLine()) != null) { w.WriteLine("/// {0}", line); } } w.WriteLine("/// </summary>"); var argumentInfo = CmdParser.GetArgInfo(component.ArgType, component.CreateArguments()); var arguments = argumentInfo.Args.Where(a => !a.IsHidden).ToArray(); foreach (var arg in arguments) { GenerateSummaryComment(w, arg, ""); } }
private void GenerateOutput(IndentingTextWriter writer, ModuleCatalog.EntryPointInfo entryPointInfo, out HashSet <string> outputVariableNames) { outputVariableNames = new HashSet <string>(); string classBase = ""; if (entryPointInfo.OutputKinds != null) { classBase = $" : {string.Join(", ", entryPointInfo.OutputKinds.Select(CSharpGeneratorUtils.GetCSharpTypeName))}"; } writer.WriteLine($"public sealed class Output{classBase}"); writer.WriteLine("{"); writer.Indent(); var outputType = entryPointInfo.OutputType; if (outputType.IsGenericType && outputType.GetGenericTypeDefinition() == typeof(CommonOutputs.MacroOutput <>)) { outputType = outputType.GetGenericTypeArgumentsEx()[0]; } foreach (var fieldInfo in outputType.GetFields()) { var outputAttr = fieldInfo.GetCustomAttributes(typeof(TlcModule.OutputAttribute), false) .FirstOrDefault() as TlcModule.OutputAttribute; if (outputAttr == null) { continue; } CSharpGeneratorUtils.GenerateSummary(writer, outputAttr.Desc); var outputTypeString = CSharpGeneratorUtils.GetOutputType(fieldInfo.FieldType); outputVariableNames.Add(CSharpGeneratorUtils.Capitalize(outputAttr.Name ?? fieldInfo.Name)); writer.WriteLine($"public {outputTypeString} {CSharpGeneratorUtils.Capitalize(outputAttr.Name ?? fieldInfo.Name)} {{ get; set; }} = new {outputTypeString}();"); writer.WriteLine(); } writer.Outdent(); writer.WriteLine("}"); }
protected override void GenerateUsings(IndentingTextWriter w) { w.WriteLine("using System;"); w.WriteLine("using System.Linq;"); w.WriteLine("using Microsoft.ML.Runtime;"); w.WriteLine("using Microsoft.ML.Runtime.CommandLine;"); w.WriteLine("using Microsoft.ML.Runtime.Data;"); w.WriteLine("using Microsoft.ML.Runtime.Internal.Internallearn;"); }
protected override void GenerateMethodSignature(IndentingTextWriter w, string prefix, ComponentCatalog.LoadableClassInfo component) { w.Write("public static Tuple<ITrainer> Create{0}{1}(", prefix, component.LoadNames[0]); using (w.Nest()) { var argumentInfo = CmdParser.GetArgInfo(component.ArgType, component.CreateArguments()); var arguments = argumentInfo.Args.Where(a => !a.IsHidden).ToArray(); var pre = ""; foreach (var arg in arguments) { GenerateMethodSignature(w, arg, null, null, null, ref pre, ""); } w.WriteLine(")"); } }
private static bool WriteUnitOfWork( IndentingTextWriter writer, InterfaceDeclaration declaration, ICollection<string> implementedInterfaces ) { Contract.Requires( writer != null ); Contract.Requires( declaration != null ); Contract.Requires( implementedInterfaces != null ); if ( implementedInterfaces.Contains( declaration.TypeName ) ) return false; implementedInterfaces.Add( declaration.TypeName ); writer.WriteLine( "bool {0}.HasPendingChanges", declaration.TypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "get" ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "return ChangeTracker.HasChanges();" ); writer.Unindent(); writer.WriteLine( "}" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "void {0}.RegisterNew( {1} item )", declaration.TypeName, declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "Set<{0}>().Add( item );", declaration.ArgumentTypeName ); writer.WriteLine( "OnPropertyChanged( new PropertyChangedEventArgs( \"HasPendingChanges\" ) );" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "void {0}.RegisterRemoved( {1} item )", declaration.TypeName, declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "Set<{0}>().Remove( item );", declaration.ArgumentTypeName ); writer.WriteLine( "OnPropertyChanged( new PropertyChangedEventArgs( \"HasPendingChanges\" ) );" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "void {0}.RegisterChanged( {1} item )", declaration.TypeName, declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "if ( Entry( item ).State != EntityState.Detached )" ); writer.Indent(); writer.WriteLine( "return;" ); writer.Unindent(); writer.WriteLine(); writer.WriteLine( "Set<{0}>().Attach( item );", declaration.ArgumentTypeName ); writer.WriteLine( "Entry( item ).State = EntityState.Modified;" ); writer.WriteLine( "OnPropertyChanged( new PropertyChangedEventArgs( \"HasPendingChanges\" ) );" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "void {0}.Unregister( {1} item )", declaration.TypeName, declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "Entry( item ).State = EntityState.Detached;" ); writer.WriteLine( "OnPropertyChanged( new PropertyChangedEventArgs( \"HasPendingChanges\" ) );" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "void {0}.Rollback()", declaration.TypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "foreach ( var entry in ChangeTracker.Entries<{0}>() )", declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "switch ( entry.State )" ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "case EntityState.Modified:" ); writer.WriteLine( "case EntityState.Deleted:" ); writer.Indent(); writer.WriteLine( "entry.CurrentValues.SetValues( entry.OriginalValues );" ); writer.WriteLine( "entry.State = EntityState.Unchanged;" ); writer.WriteLine( "break;" ); writer.Unindent(); writer.WriteLine( "case EntityState.Added:" ); writer.Indent(); writer.WriteLine( "entry.State = EntityState.Detached;" ); writer.WriteLine( "break;" ); writer.Unindent(); writer.Unindent(); writer.WriteLine( "}" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "OnPropertyChanged( new PropertyChangedEventArgs( \"HasPendingChanges\" ) );" ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "async Task {0}.CommitAsync( CancellationToken cancellationToken )", declaration.TypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "await SaveChangesAsync( cancellationToken ).ConfigureAwait( false );" ); writer.WriteLine( "OnPropertyChanged( new PropertyChangedEventArgs( \"HasPendingChanges\" ) );" ); writer.Unindent(); writer.WriteLine( "}" ); return true; }
private static bool WriteReadOnlyRepository( IndentingTextWriter writer, InterfaceDeclaration declaration, ICollection<string> implementedInterfaces ) { Contract.Requires( writer != null ); Contract.Requires( implementedInterfaces != null ); if ( implementedInterfaces.Contains( declaration.TypeName ) ) return false; implementedInterfaces.Add( declaration.TypeName ); writer.WriteLine( "async Task<IEnumerable<{1}>> {0}.GetAsync( Func<IQueryable<{1}>, IQueryable<{1}>> queryShaper, CancellationToken cancellationToken )", declaration.TypeName, declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "return await queryShaper( Set<{0}>() ).ToArrayAsync( cancellationToken ).ConfigureAwait( false );", declaration.ArgumentTypeName ); writer.Unindent(); writer.WriteLine( "}" ); writer.WriteLine(); writer.WriteLine( "async Task<TResult> {0}.GetAsync<TResult>( Func<IQueryable<{1}>, TResult> queryShaper, CancellationToken cancellationToken )", declaration.TypeName, declaration.ArgumentTypeName ); writer.WriteLine( "{" ); writer.Indent(); writer.WriteLine( "return await Task<TResult>.Factory.StartNew( () => queryShaper( Set<{0}>() ), cancellationToken ).ConfigureAwait( false );", declaration.ArgumentTypeName ); writer.Unindent(); writer.WriteLine( "}" ); return true; }
private static bool WritePropertyChangedImplementation( IndentingTextWriter writer, ICollection<string> implementedInterfaces ) { Contract.Requires( writer != null ); Contract.Requires( implementedInterfaces != null ); if ( implementedInterfaces.Contains( INotifyPropertyChanged ) ) return false; implementedInterfaces.Add( INotifyPropertyChanged ); writer.WriteLine( "public event PropertyChangedEventHandler PropertyChanged;" ); writer.WriteLine(); writer.WriteLine( "private void OnPropertyChanged( PropertyChangedEventArgs e ) => PropertyChanged?.Invoke( this, e );" ); return true; }
private static void ImplementInterface( IndentingTextWriter writer, InterfaceDeclaration declaration, ICollection<string> implementedInterfaces ) { Contract.Requires( writer != null ); Contract.Requires( declaration != null ); Contract.Requires( implementedInterfaces != null ); switch ( declaration.Key ) { case IReadOnlyRepository: WriteReadOnlyRepository( writer, declaration, implementedInterfaces ); break; case IRepository: var inheritedDeclaration = new InterfaceDeclaration( IReadOnlyRepository, declaration ); if ( WritePropertyChangedImplementation( writer, implementedInterfaces ) ) writer.WriteLine(); if ( WriteReadOnlyRepository( writer, inheritedDeclaration, implementedInterfaces ) ) writer.WriteLine(); WriteRepository( writer, declaration, implementedInterfaces ); break; case IUnitOfWork: if ( WritePropertyChangedImplementation( writer, implementedInterfaces ) ) writer.WriteLine(); WriteUnitOfWork( writer, declaration, implementedInterfaces ); break; } }
private static void WriteEndClass( IndentingTextWriter writer, bool hasNamespace ) { Contract.Requires( writer != null ); if ( hasNamespace ) { writer.Unindent(); writer.WriteLine( "}" ); } writer.Unindent(); writer.Write( "}" ); }
private static bool WriteStartClass( IndentingTextWriter writer, string defaultNamespace, IReadOnlyList<UsingDirectiveSyntax> usings, ClassDeclarationSyntax @class ) { Contract.Requires( writer != null ); Contract.Requires( defaultNamespace != null ); Contract.Requires( usings != null ); Contract.Requires( @class != null ); var @namespace = ResolveNamespace( @class, defaultNamespace ); var hasNamespace = !string.IsNullOrEmpty( @namespace ); var className = @class.Identifier.Text; if ( hasNamespace ) { writer.WriteLine( "namespace {0}", @namespace ); writer.WriteLine( "{" ); writer.Indent(); } WriteUsings( writer, usings ); writer.WriteLine(); writer.WriteLine( "/// <content>" ); writer.WriteLine( "/// Provides auto-generated interfaces for the <see cref=\"{0}\" /> class. To add addition interfaces,", className ); writer.WriteLine( "/// implement the interface in the main source file." ); writer.WriteLine( "/// <seealso cref=\"IReadOnlyRepository{T}\" />" ); writer.WriteLine( "/// <seealso cref=\"IRepository{T}\" />" ); writer.WriteLine( "/// <seealso cref=\"IUnitOfWork{T}\" />." ); writer.WriteLine( "/// <content>" ); writer.WriteLine( "[GeneratedCode( \"More Framework\", \"1.0\" )]" ); writer.WriteLine( "{0}partial class {1}", ResolveScopeModifier( @class ), className ); writer.WriteLine( "{" ); writer.Indent(); return hasNamespace; }
private static void WriteUsings( IndentingTextWriter writer, IReadOnlyList<UsingDirectiveSyntax> declaredUsings ) { Contract.Requires( writer != null ); Contract.Requires( declaredUsings != null ); var usings = new SortedSet<UsingDirectiveSyntax>( UsingDirectiveComparer.Instance ); // merge sorted, distinct list of required and declared usings usings.AddRange( RequiredUsings ); usings.AddRange( declaredUsings ); // write out required usings foreach ( var @using in usings ) writer.WriteLine( @using ); }