Пример #1
0
        public void DefaultNamespaceCombinesRelativeInputFilePathWithRootNamespace()
        {
            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            using (var template = new TestClrTemplate())
            {
                template.Context = context;
                transformation.Host.TemplateFile = Path.Combine(Environment.CurrentDirectory, "SubFolder\\Template.tt");
                transformation.Host.GetMetadataValue = (hierarhcy, inputFile, metadataName) => string.Empty;
                transformation.Host.GetPropertyValue = (hierarchy, propertyName) =>
                {
                    switch (propertyName)
                    {
                        case "RootNamespace":
                            return "TestNamespace";
                        case "MSBuildProjectFullPath":
                            return Path.Combine(Environment.CurrentDirectory, "Project.proj");
                        default:
                            return string.Empty;
                    }
                };

                Assert.AreEqual("TestNamespace.SubFolder", template.DefaultNamespace);
            }
        }
Пример #2
0
 public void ContextCanBeSet()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         this.generator.Context = context;
         Assert.AreSame(context, this.generator.Context);
     }
 }
Пример #3
0
 public void TransformTextGeneratesFileHeader()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         this.template.Context = context;
         transformation.Host.TemplateFile = Path.GetRandomFileName();
         string output = this.template.TransformText();
         StringAssert.Contains(output, "<autogenerated>");                
         StringAssert.Contains(output, transformation.Host.TemplateFile);
     }
 }
Пример #4
0
        /// <summary>
        /// Generates the proxy class.
        /// </summary>
        /// <param name="context">The transformation context.</param>
        /// <param name="sourceClassDeclaration">The source class declaration.</param>
        /// <returns>A partial class declaration.</returns>
        private ClassDeclarationSyntax GenerateProxy(TransformationContext context, ClassDeclarationSyntax sourceClassDeclaration)
        {
            var result = ClassDeclaration($"Proxy{sourceClassDeclaration.Identifier}")
                         .WithModifiers(sourceClassDeclaration.Modifiers)
                         .WithAttributeLists(
                SingletonList <AttributeListSyntax>(
                    AttributeList(
                        SingletonSeparatedList <AttributeSyntax>(
                            Attribute(
                                IdentifierName("ExcludeFromCodeCoverage"))))
                    .WithOpenBracketToken(
                        Token(
                            GenerateXmlDoc($"Proxy Implementation of <see cref=\"{sourceClassDeclaration.Identifier}\"/>."),
                            SyntaxKind.OpenBracketToken,
                            TriviaList()))))
                         .AddBaseListTypes(
                SimpleBaseType(ParseTypeName(sourceClassDeclaration.Identifier.Text)),
                SimpleBaseType(ParseTypeName($"IDraft<{sourceClassDeclaration.Identifier.Text}>")));

            result = result.AddMembers(
                GetPublicInstanceProperties(this.interfaceType)
                .Select(p =>
            {
                return(CreateProxyProperty(context, p));
            }).ToArray());

            if (sourceClassDeclaration.Members.Any(x => x is ConstructorDeclarationSyntax))
            {
                result = result.WithMembers(List(
                                                sourceClassDeclaration.Members.
                                                Where(x => x is ConstructorDeclarationSyntax).
                                                Cast <ConstructorDeclarationSyntax>().
                                                Select(c => this.GenerateProxyConstructor(sourceClassDeclaration, c))));
            }

            result = result.AddMembers(
                this.GenerateDraftStateField(),
                this.GenerateDraftStateProperty(),
                this.GenerateOriginalProperty(sourceClassDeclaration),
                this.GenerateImmutableOriginalProperty(),
                this.GenerateCloneMethod(context, GetPublicInstanceProperties(this.interfaceType)));

            return(result);
        }
Пример #5
0
        public void WriteCombinesTextWrittenToTheSameOutputMultipleTimes()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
                using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
                {
                    transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                    var outputInfo = new OutputItem {
                        File = TestFile
                    };
                    context.Write(outputInfo, TestText);
                    context.Write(outputInfo, TestText);
                }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);

            Assert.AreEqual(TestText + TestText, outputFile.Content.ToString());
        }
Пример #6
0
        /// <summary>Try to resolve the destination instance.</summary>
        /// <param name="context">Transformation context.</param>
        /// <param name="destination">Existing destination instance or NULL.</param>
        /// <returns>Destination instance or NULL if some of transformers will create it manually.</returns>
        protected internal virtual TDestination GetDestinationInstance(TransformationContext context, TDestination destination)
        {
            // Note: if destination object is isolated just created new instance. Otherwise, reuse the existing instance or created new.

            // keep existing destination for transformers with NON-isolated destinations.
            if (destination != null && !IsIsolatedDestination())
            {
                return(destination);
            }
            if (Builder?.InitialDestinationFactory != null)
            {
                return(Builder.InitialDestinationFactory(context));
            }
            if (Builder?.Configuration?.AutoCreateDestination == true)
            {
                return(Builder.Configuration.CreateInstanceSafe <TDestination>());
            }

            return(default);
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var targetClass = (ClassDeclarationSyntax)context.ProcessingNode;

            var equatableContext = EquatableGenerationContext.Create(targetClass, context.Compilation, context.SemanticModel);

            var resultClass = targetClass
                              .WithBaseList(GetBaseList(equatableContext))
                              .WithAttributeLists(List(new AttributeListSyntax[0]))
                              .WithModifiers(TokenList(Token(SyntaxKind.PartialKeyword)))
                              .WithMembers(List(new MemberDeclarationSyntax[]
            {
                EqualsImplementation(equatableContext),
                EquatableImplementation(equatableContext),
                GetHashCode(equatableContext)
            }));

            return(Task.FromResult(List <MemberDeclarationSyntax>().Add(resultClass)));
        }
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            TransformationResult result = declaration;

            if (declaration.Name == "DebugCheckVersionAndDataLayout")
            {
                if (IMGUI_VERSION is not null)
                {
                    result.Add(IMGUI_VERSION);
                }

                if (IMGUI_VERSION_NUM is not null)
                {
                    result.Add(IMGUI_VERSION_NUM);
                }
            }

            return(result);
        }
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            // Private/protected functions are always stripped
            if (declaration.Accessibility is AccessModifier.Private or AccessModifier.Protected)
            {
                return(null);
            }

            // Check if any parents are private/protected
            foreach (TranslatedDeclaration parent in context.Parents)
            {
                if (parent.Accessibility is AccessModifier.Private or AccessModifier.Protected)
                {
                    return(null);
                }
            }

            return(base.TransformFunction(context, declaration));
        }
Пример #10
0
        /// <summary>
        /// Generates the clone method.
        /// </summary>
        /// <param name="context">The transformation context.</param>
        /// <param name="properties">The properties to generate the clone method for.</param>
        /// <returns>The Member Declaration syntax.</returns>
        private MemberDeclarationSyntax GenerateCloneMethod(TransformationContext context, IEnumerable <IPropertySymbol> properties)
        {
            string methodStart = $@"
        /// <summary>
        /// Clones the object from the original.
        /// </summary>
        void IDraft.Clone()
        {{
            if (this.draftState == null)
            {{
                throw new DraftException(this, ""Draft state not set."");
            }}

            if (((ILockable)this).Locked)
            {{
                throw new ImmutableException(this, ""This instance is immutable and cannot be the destination of a clone operation."");
            }}
";

            var stringBuilder = new StringBuilder(methodStart);

            foreach (var property in properties)
            {
                var baseType = GetMutableType(context, property.Type);

                if (SymbolEqualityComparer.Default.Equals(baseType, property.Type))
                {
                    stringBuilder.AppendLine($@"this.{property.Name} = this.Original.{property.Name};");
                }
                else
                {
                    stringBuilder.AppendLine($@"
                        if (!this.{property.Name}.IsDraft())
                        {{
                            this.{property.Name} = this.Original.{property.Name};
                        }}");
                }
            }

            stringBuilder.AppendLine("}");
            return(ParseMemberDeclaration(stringBuilder.ToString())
                   .NormalizeWhitespace());
        }
Пример #11
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(
            TransformationContext context,
            IProgress <Diagnostic> progress,
            CancellationToken cancellationToken)
        {
            var compilation   = context.Compilation;
            var applyTo       = context.ProcessingNode as MemberDeclarationSyntax;
            var semanticModel = context.SemanticModel;

            if (applyTo is ClassDeclarationSyntax applyToClass)
            {
                return(GenerateForClass(applyTo, semanticModel, applyToClass));
            }
            if (applyTo is StructDeclarationSyntax applyToStruct)
            {
                return(GenerateForStructs(semanticModel, applyToStruct));
            }
            throw new InvalidOperationException("applyTo is not a ClassDeclarationSyntax nor a StructDeclarationSyntax");
        }
Пример #12
0
        public void WriteCombinesTextOfDifferentOutputsWithTheSameFileName()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
                using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
                {
                    transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                    context.Write(new OutputItem {
                        File = TestFile
                    }, TestText);
                    context.Write(new OutputItem {
                        File = TestFile
                    }, TestText);
                }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);

            Assert.AreEqual(TestText + TestText, outputFile.Content.ToString());
        }
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var results = SyntaxFactory.List <MemberDeclarationSyntax>();

            MemberDeclarationSyntax copy = null;
            var applyToClass             = context.ProcessingNode as ClassDeclarationSyntax;

            if (applyToClass != null)
            {
                copy = applyToClass
                       .WithIdentifier(SyntaxFactory.Identifier(applyToClass.Identifier.ValueText + this.suffix));
            }

            if (copy != null)
            {
                results = results.Add(copy);
            }

            return(Task.FromResult(results));
        }
Пример #14
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(
            TransformationContext context,
            IProgress <Diagnostic> progress,
            CancellationToken cancellationToken)
        {
            var results = SyntaxFactory.List <MemberDeclarationSyntax>();

            //get the current method
            var method = (MethodDeclarationSyntax)context.ProcessingNode;
            //get the containing class
            var parentClass = (ClassDeclarationSyntax)context.ProcessingNode.Parent;

            var autoMethod    = new AutoMethodGenerator(Settings).Generate(method);
            var wrapperMethod = new WrapperMethodGenerator(Settings).Generate(method);

            results = results.Add(wrapperMethod);
            results = results.Add(autoMethod);

            return(Task.FromResult(results));
        }
        // This transformation is an opt-out heuristic
        // It'd be not-ideal if it was wrong, but it's expected that the user will be smart enough to avoid calling the nonsense overload
        // In the long term we'll rely on a parameter being explicitly marked as a string once https://github.com/ocornut/imgui/pull/3038 is merged
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            // Opt out of specific functions that shouldn't get overloads
            if (ShouldOptOut(declaration))
            {
                return(declaration);
            }

            // Check if this function has a string parameter
            ImmutableArray <int> .Builder?stringParameters = null;
            bool firstParameterHasEnd = false;

            for (int i = 0; i < declaration.Parameters.Length; i++)
            {
                TranslatedParameter parameter = declaration.Parameters[i];

                // If the parameter is a `byte*`, it's a string parameter
                if (parameter.Type is PointerTypeReference {
                    Inner: CSharpBuiltinTypeReference cSharpPointee
                } && cSharpPointee == CSharpBuiltinType.Byte)
Пример #16
0
        public void Transform(TransformationContext context)
        {
            var gen = new OracleScriptGenerator();
            gen.TargetSystem = context.TargetSystem;
            gen.DataSchema = context.DataSchema;

            var accessor = new SimpleXmlValueAccessor(context.TransformationElement, DataSchemaProject.TargetNamespace);
            gen.DatabaseSchemaName = accessor.GetString("DatabaseSchemaName");
            var docGenName = accessor.GetStringOrDefault("ScriptDocumentGenerator");
            if (!string.IsNullOrEmpty(docGenName))
            {
                gen.ScriptDocumentGenerator = context.DocGenFactory.Create(docGenName);
            }

            var outputFilePath = accessor.GetStringOrDefault("OutputFile");
            using (FileStream stream = new FileStream(outputFilePath, FileMode.Create))
            {
                gen.Generate(stream);
            }
        }
Пример #17
0
        public void RootNamespaceReturnsPropertyValueSuppliedByProvider()
        {
            using (var transformation = new FakeTransformation())
                using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
                    using (var template = new TestClrTemplate())
                    {
                        template.Context = context;

                        const string ExpectedValue      = "TestNamespace";
                        string       actualPropertyName = null;
                        transformation.Host.GetPropertyValue = (hierarchy, propertyName) =>
                        {
                            actualPropertyName = propertyName;
                            return(ExpectedValue);
                        };

                        Assert.AreEqual(ExpectedValue, template.RootNamespace);
                        Assert.AreEqual("RootNamespace", actualPropertyName);
                    }
        }
Пример #18
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var results = SyntaxFactory.List <MemberDeclarationSyntax>();
            // Our generator is applied to any class that our attribute is applied to.
            var applyToClass  = context.ProcessingNode as ClassDeclarationSyntax;
            var applyToStruct = context.ProcessingNode as StructDeclarationSyntax;
            var model         = context.Compilation.GetSemanticModel(applyToClass?.SyntaxTree ?? applyToStruct.SyntaxTree);

            if (applyToClass != null)
            {
                var symbol = model.GetDeclaredSymbol(applyToClass);
                if (InheritsFrom("NetworkEngine.NetworkEntity", symbol))
                {
                    results = results.AddRange(GenerateSyncEntityClass(model, applyToClass));
                    results = GenerateMessages(model, applyToClass, results);
                }
                else if (InheritsFrom("NetworkEngine.SyncObject", symbol))
                {
                    results = results.AddRange(GenerateSyncObjClass(model, applyToClass));
                    results = GenerateObjMessages(model, applyToClass, results);
                }
                else if (applyToClass.Identifier.Text == SchemaGenerator.SchemaGenClassName)
                {
                    List <INamedTypeSymbol> allTypesModel = new List <INamedTypeSymbol>();
                    GetAllSymbolsVisitor    visitor       = new GetAllSymbolsVisitor(allTypesModel);
                    visitor.Visit(context.Compilation.GlobalNamespace);
                    //results = results.Add(SyntaxFactory.ClassDeclaration("OUTPUT" + Path.Combine(context.ProjectDirectory, "DEFS_SCHEMA.json")));
                    SchemaGenerator.GenerateSchema(context.ProjectDirectory, allTypesModel);
                }
                else
                {
                    results = results.Add(GenerateStaticSyncObj(model, applyToClass));
                }
            }
            else if (applyToStruct != null)
            {
                var symbol = model.GetDeclaredSymbol(applyToStruct);
                results = results.Add(GenerateStaticSyncObj(model, applyToStruct));
            }
            return(Task.FromResult <SyntaxList <MemberDeclarationSyntax> >(results));
        }
Пример #19
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var partialType = CreatePartialType();

            return(Task.FromResult(SyntaxFactory.List(partialType)));

            IEnumerable <MemberDeclarationSyntax> CreatePartialType()
            {
                var newPartialType =
                    context.ProcessingNode is ClassDeclarationSyntax classDeclaration
                        ? SyntaxFactory.ClassDeclaration(classDeclaration.Identifier.ValueText)
                        : context.ProcessingNode is StructDeclarationSyntax structDeclaration
                            ? SyntaxFactory.StructDeclaration(structDeclaration.Identifier.ValueText)
                            : default(TypeDeclarationSyntax);

                if (newPartialType is null)
                {
                    yield break;
                }
                yield return(newPartialType
                             ?.AddModifiers(SyntaxFactory.Token(SyntaxKind.PartialKeyword))
                             .AddMembers(CreateTargetFrameworkListProperty(), CreateCurrentTargetFrameworkProperty()));
            }

            MemberDeclarationSyntax CreateTargetFrameworkListProperty()
            {
                var collectionType           = "System.Collections.Generic.List<string>";
                var frameworks               = context.BuildProperties["TargetFrameworks"];
                var quotedFrameworks         = frameworks.Split(";").Select(framework => $"\"{framework}\"");
                var commaDelimitedFrameworks = string.Join(',', quotedFrameworks.ToArray());

                return(SyntaxFactory.ParseMemberDeclaration($"public {collectionType} TargetFrameworks {{ get; }} = new {collectionType} {{ {commaDelimitedFrameworks} }};"));
            }

            MemberDeclarationSyntax CreateCurrentTargetFrameworkProperty()
            {
                var framework = context.BuildProperties["TargetFramework"];

                return(SyntaxFactory.ParseMemberDeclaration($"public string CurrentTargetFramework {{ get; }} = \"{framework}\";"));
            }
        }
Пример #20
0
        public async Task <RichGenerationResult> GenerateRichAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var results = new List <ChangeMember>();

            MemberDeclarationSyntax copy = null;
            var applyToClass             = context.ProcessingNode as ClassDeclarationSyntax;

            if (applyToClass != null)
            {
                copy = applyToClass
                       .WithIdentifier(SyntaxFactory.Identifier(applyToClass.Identifier.ValueText + this.suffix));
                results.Add(ChangeMember.AddMember(context.ProcessingNode, copy));
                //results.Add(ChangeMember.ReplaceMember(context.ProcessingNode, copy));
            }

            var applyToField = context.ProcessingNode as FieldDeclarationSyntax;

            if (applyToField != null)
            {
                var oldDeclaration = applyToField.Declaration;
                copy = applyToField.WithDeclaration(SyntaxFactory.VariableDeclaration(oldDeclaration.Type).WithVariables(SyntaxFactory.SeparatedList <VariableDeclaratorSyntax>(
                                                                                                                             oldDeclaration.Variables.Select(v =>
                {
                    if (v is VariableDeclaratorSyntax variableDeclaratorSyntax)
                    {
                        return(SyntaxFactory.VariableDeclarator(variableDeclaratorSyntax.Identifier.Text + suffix));
                    }
                    return(v);
                })
                                                                                                                             )));
                results.Add(ChangeMember.AddMember(context.ProcessingNode, copy));
            }

            return(new RichGenerationResult
            {
                Members = results,
                Usings = SyntaxFactory.List <UsingDirectiveSyntax>(),
                AttributeLists = SyntaxFactory.List <AttributeListSyntax>(),
                Externs = SyntaxFactory.List <ExternAliasDirectiveSyntax>()
            });
        }
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var partialClass = GeneratePartialClass();

            return(Task.FromResult(SyntaxFactory.List(partialClass)));

            IEnumerable <MemberDeclarationSyntax> GeneratePartialClass()
            {
                var classDeclaration = context.ProcessingNode as ClassDeclarationSyntax;

                yield return(classDeclaration
                             .AddMembers(CreateExampleBuildProperty()));
            }

            MemberDeclarationSyntax CreateExampleBuildProperty()
            {
                var value = context.BuildProperties["ExampleBuildProperty"];

                return(SyntaxFactory.ParseMemberDeclaration($"public string ExampleBuildProperty {{ get; }} = \"{value}\";"));
            }
        }
 protected override TransformationResult TransformNormalField(TransformationContext context, TranslatedNormalField declaration)
 {
     //TODO: Ideally this should not need to touch Clang stuff so much
     //TODO: Can the new Desugar function added to unreleased versions of ClangSharp help here?
     // Look for fields of type PxPadding and delete them (somewhat involved since the information we need isn't exposed on ClangSharp as cleanly as we'd like.)
     return(declaration.Declaration switch
     {
         FieldDecl
         {
             Type : TemplateSpecializationType
             {
                 Handle :
                 {
                     Declaration :
                     {
                         IsNull : false,
                         DeclKind : CX_DeclKind.CX_DeclKind_ClassTemplateSpecialization,
                     } fieldTypeDeclaration
                 }
             }
         } => fieldTypeDeclaration.Spelling.ToString() == "PxPadding" ? null : declaration,
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var results = SyntaxFactory.List <MemberDeclarationSyntax>();

            MemberDeclarationSyntax copy = null;
            var applyToClass             = context.ProcessingNode as MethodDeclarationSyntax;

            if (applyToClass != null)
            {
                copy = applyToClass
                       .WithIdentifier(SyntaxFactory.Identifier(NameGenerator.Combine(applyToClass.Identifier.ValueText, this.suffix)))
                       .WithLeadingTrivia(SyntaxFactory.Comment($"// Bogus content: {new Bogus.Faker().Hacker.Phrase()}"));
            }

            if (copy != null)
            {
                results = results.Add(copy);
            }

            return(Task.FromResult(results));
        }
Пример #24
0
        public void DefaultNamespaceUsesProjectItemLinkPathInsteadOfPhysicalFilePath()
        {
            using (var transformation = new FakeTransformation())
                using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
                    using (var template = new TestClrTemplate())
                    {
                        template.Context = context;

                        transformation.Host.TemplateFile = Path.Combine(Environment.CurrentDirectory, "Template.tt");

                        transformation.Host.GetMetadataValue = (hierarhcy, inputFile, metadataName) =>
                        {
                            switch (metadataName)
                            {
                            case "Link":
                                return("SubFolder\\Template.tt");

                            default:
                                return(string.Empty);
                            }
                        };

                        transformation.Host.GetPropertyValue = (hierarchy, propertyName) =>
                        {
                            switch (propertyName)
                            {
                            case "RootNamespace":
                                return("TestNamespace");

                            case "MSBuildProjectFullPath":
                                return(Path.Combine(Environment.CurrentDirectory, "Project.proj"));

                            default:
                                return(string.Empty);
                            }
                        };

                        Assert.AreEqual("TestNamespace.SubFolder", template.DefaultNamespace);
                    }
        }
Пример #25
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(
            TransformationContext context,
            IProgress <Diagnostic> progress,
            CancellationToken cancellationToken)
        {
            if (context.ProcessingNode is InterfaceDeclarationSyntax applyTo)
            {
                var cases = applyTo.Members
                            .Where(m => m is MethodDeclarationSyntax)
                            .Select(m => m as MethodDeclarationSyntax)
                            .Select(m => MakeCaseClass(applyTo, m))
                            .ToList();

                var staticCtorClass = MakeStaticConstructorClass(applyTo);

                return(Task.FromResult(SyntaxFactory.List <MemberDeclarationSyntax>().AddRange(cases).Add(staticCtorClass)));
            }
            else
            {
                return(Task.FromResult(SyntaxFactory.List <MemberDeclarationSyntax>()));
            }
        }
Пример #26
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var generatedMembers = SyntaxFactory.List <MemberDeclarationSyntax>();

            if (context.ProcessingNode is ClassDeclarationSyntax classDeclaration)
            {
                var descriptor = classDeclaration.ToRecordDescriptor();
                generatedMembers = generatedMembers.AddRange(GenerateRecordPartials(descriptor));
            }
            return(Task.FromResult(generatedMembers));

            IEnumerable <MemberDeclarationSyntax> GenerateRecordPartials(RecordDescriptor descriptor)
            {
                yield return(RecordPartialGenerator.Generate(descriptor, cancellationToken));

                yield return(BuilderPartialGenerator.Generate(descriptor, cancellationToken));

                yield return(DeconstructPartialGenerator.Generate(descriptor, cancellationToken));

                yield break;
            }
        }
Пример #27
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            var results = SyntaxFactory.List <MemberDeclarationSyntax>();

            // Our generator is applied to any class that our attribute is applied to.
            var applyToClass = (ClassDeclarationSyntax)context.ProcessingNode;

            // Apply a suffix to the name of a copy of the class.
            var partialClass = SyntaxFactory.ClassDeclaration($"{applyToClass.Identifier}")
                               .WithModifiers(
                SyntaxFactory.TokenList(
                    SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                    SyntaxFactory.Token(SyntaxKind.PartialKeyword)));

            if (applyToClass.TypeParameterList != null)
            {
                partialClass = partialClass.WithTypeParameterList(applyToClass.TypeParameterList);
            }

            if (applyToClass.ConstraintClauses != null)
            {
                partialClass = partialClass.WithConstraintClauses(applyToClass.ConstraintClauses);
            }

            var returnType = CodeGenUtil.TypeFromClass(applyToClass);

            var fields = applyToClass.Members.Where(m => m is FieldDeclarationSyntax)
                         .Select(m => m as FieldDeclarationSyntax)
                         .Where(m => m.Modifiers.Any(SyntaxKind.PublicKeyword))
                         .Where(m => m.Modifiers.Any(SyntaxKind.ReadOnlyKeyword))
                         .Where(m => !m.Modifiers.Any(SyntaxKind.StaticKeyword))
                         .ToList();

            partialClass = CodeGenUtil.AddWith(context, partialClass, returnType, fields);
            partialClass = CodeGenUtil.AddLenses(partialClass, returnType, fields);

            return(Task.FromResult <SyntaxList <MemberDeclarationSyntax> >(results.Add(partialClass)));
        }
Пример #28
0
        public List <Instance> TryTransform(Instance instance, TransformationContext context)
        {
            if (!instance.ModuleIdentifier.Contains("dffeas"))
            {
                return(null);
            }

            var fdc = new Instance("FDC", "fdc_" + context.GetNextInstanceNumber(this));

            var clock      = instance.Ports.First(p => p.Identifier == "clk").ConnectedNet.Identifier;
            var clr        = instance.Ports.First(p => p.Identifier == "clrn").ConnectedNet.Identifier;
            var dataInput  = instance.Ports.First(p => p.Identifier == "d").ConnectedNet.Identifier;
            var dataOutput = instance.Ports.First(p => p.Identifier == "q").ConnectedNet.Identifier;

            fdc.Ports.Add(new Net("C", NetType.Input, new Net("clock", NetType.Wire)));
            fdc.Ports.Add(new Net("CLR", NetType.Input, new Net(clr, NetType.Wire)));
            fdc.Ports.Add(new Net("D", NetType.Input, new Net(dataInput, NetType.Wire)));
            fdc.Ports.Add(new Net("Q", NetType.Output, new Net(dataOutput, NetType.Wire)));

            return(new List <Instance> {
                fdc
            });
        }
Пример #29
0
        private static void WriteThrowsInvalidOperationException(OutputItem first, OutputItem second, params string[] keywords)
        {
            using (var transformation = new FakeTransformation())
                using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
                {
                    first.File = TestFile;
                    context.Write(first, string.Empty);

                    try
                    {
                        second.File = TestFile;
                        context.Write(second, string.Empty);
                    }
                    catch (InvalidOperationException e)
                    {
                        Assert.AreNotEqual(typeof(TransformationException), e.GetType());
                        foreach (string keyword in keywords)
                        {
                            StringAssert.Contains(e.Message, keyword);
                        }
                    }
                }
        }
 protected void IntroduceEvent(TransformationContext context, TypeDefDeclaration type, EventDeclaration theEvent)
 {
     var fieldRef = type.FindField(theEvent.Name);
     FieldDefDeclaration field;
     if(fieldRef == null) {
         field = new FieldDefDeclaration {
             Attributes = FieldAttributes.Private,
             Name = theEvent.Name,
             FieldType = theEvent.EventType,
         };
         type.Fields.Add(field);
     } else {
         field = fieldRef.Field;
     }
     var addOn = theEvent.GetAccessor(MethodSemantics.AddOn);
     if (addOn == null) {
         theEvent.ImplementAddOn(type, field, AspectInfrastructureTask.WeavingHelper);
     }
     var removeOn = theEvent.GetAccessor(MethodSemantics.RemoveOn);
     if (removeOn == null) {
         theEvent.ImplementRemoveOn(type, field, AspectInfrastructureTask.WeavingHelper);
     }
 }
        private async Task <GeneratedDocument> GenerateDocumentFrom(CSharpCompilation compilation, Document document, CancellationToken cancellationToken)
        {
            var inputSyntaxTree = await document.GetSyntaxTreeAsync(cancellationToken);

            var inputSemanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var inputCompilationUnit = inputSyntaxTree.GetCompilationUnitRoot();
            var generatedDocument    = new GeneratedDocument(inputCompilationUnit, document);
            var context            = new TransformationContext(document, inputSemanticModel, compilation, _errorReporter);
            var assemblyAttributes = compilation.Assembly.GetAttributes();

            foreach (var memberNode in GetMemberDeclarations(inputSyntaxTree))
            {
                var attributeData = GetAttributeData(inputSemanticModel, memberNode, assemblyAttributes);
                if (attributeData.Count == 0)
                {
                    continue;
                }

                foreach (var(markerAttribute, generator) in _generatorPluginProvider.FindCodeGenerators(attributeData))
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    try
                    {
                        var emitted = await generator.GenerateAsync(memberNode, markerAttribute, context, cancellationToken);

                        generatedDocument.Append(emitted, generator);
                    }
                    catch (Exception exception)
                    {
                        _errorReporter.ReportError(document, exception);
                    }
                }
            }

            return(generatedDocument);
        }
Пример #32
0
        public RichGenerationResult Generate(TransformationContext context)
        {
            _context = context;
            var classSyntax = (ClassDeclarationSyntax)context.ProcessingNode;
            var model       = context.SemanticModel;
            ClassDeclarationSyntax classDeclaration = null;

            var classSemantic = model.GetDeclaredSymbol(classSyntax);
            var className     = $"{classSemantic.Name}Proxy";

            try
            {
                classDeclaration = GenerateClass(classSemantic, className);

                classDeclaration = AddReciveMapMethod(classSyntax, model, classDeclaration);

                classDeclaration = AddConstructor(classDeclaration, classSemantic, className);

                classDeclaration = AddSubscriptions(classSyntax, model, classDeclaration);
            }
            catch (Exception e)
            {
                Logger.Error(e.ToString(), "");
                classDeclaration = ClassDeclaration(className).WithCloseBraceToken(Token(TriviaList(Comment($"//{e}")), SyntaxKind.CloseBraceToken, TriviaList()));
            }

            var namespaveDeclaration = AddNamespace(classSyntax, classDeclaration);

            var result = new RichGenerationResult
            {
                Members = List <MemberDeclarationSyntax>().Add(namespaveDeclaration)
            };

            result.Usings = GenerateUsingStatements();

            return(result);
        }
Пример #33
0
        public Task <RichGenerationResult> GenerateRichAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            SyntaxList <MemberDeclarationSyntax> derive;

            switch (context.ProcessingNode)
            {
            case ClassDeclarationSyntax classDeclaration:
                derive = SumTypeClassGenerator.CreateSyntax(context, _discriminantName, _options);
                break;

            case StructDeclarationSyntax structDeclaration:
                derive = SumTypeStructGenerator.CreateSyntax(context, _discriminantName);
                break;

            default:
                throw new NotSupportedException();
            }

            // Figure out ancestry for the generated type, including nesting types and namespaces.
            var wrappedMembers = SyntaxFactory.List(derive.WrapWithAncestors(context.ProcessingNode).Select(n => n.NormalizeWhitespace()));

            var usings = _options.HasFlag(SumTypeOptions.EnableJsonConverter)
                ? SyntaxFactory.List(new[]
            {
                SyntaxFactory.UsingDirective(
                    SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName("System"),
                        SyntaxFactory.IdentifierName("Reflection"))),
            })
                : SyntaxFactory.List <UsingDirectiveSyntax>();

            return(Task.FromResult(new RichGenerationResult
            {
                Members = wrappedMembers,
                Usings = usings
            }));
        }
        IEnumerable <MemberDeclarationSyntax> GenerateRequestHandler(TransformationContext context)
        {
            if (context.ProcessingNode is ClassDeclarationSyntax classDeclaration && IsMediatorRequest(classDeclaration, out var details))
            {
                var handlerClassName = classDeclaration.Identifier.ValueText + "Handler_Generated";
                var typeInfo         = context.SemanticModel.GetDeclaredSymbol(classDeclaration);
                var walker           = new RequestHandlerCSharpWalker(context.SemanticModel);

                classDeclaration.Accept(walker);

                var fields             = walker.HandleMethodParameters.Select(ToFieldSyntax).ToArray();
                var constructor        = GenerateConstructor(handlerClassName, walker.HandleMethodParameters);
                var handleMethod       = GenerateHandleMethod(classDeclaration.Identifier.ValueText, walker.HandleMethodCancellationTokenParameterIndex, walker.HandleMethodParameters.ToArray(), details);
                var newClassDefinition = ClassDeclaration(handlerClassName);

                var requestHandlerType = ClassDeclaration(handlerClassName)
                                         .AddMembers(fields)
                                         .AddMembers(constructor, handleMethod);

                var tResponse = details.IsGeneric
                    ? $", {details.ReturnTypeName}"
                    : "";
                requestHandlerType = requestHandlerType
                                     .AddBaseListTypes(SimpleBaseType(ParseName($"global::MediatR.IRequestHandler<{classDeclaration.Identifier.ValueText}{tResponse}>")));
                yield return(requestHandlerType);
            }

            MemberDeclarationSyntax ToFieldSyntax((string ParamName, string TypeName) field)
            {
                return(ParseMemberDeclaration($@"private readonly {field.TypeName} _{field.ParamName};
"));
            }

            MemberDeclarationSyntax GenerateHandleMethod(
                string className,
                int?cancellationTokenIndex,
                (string ParamName, string TypeName)[] parameters,
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="progress"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public Task<SyntaxList<MemberDeclarationSyntax>> GenerateAsync(TransformationContext context
            , IProgress<Diagnostic> progress, CancellationToken cancellationToken)
        {
            // TODO: TBD: well, it did in fact report the result, didn't it?
            progress.Report(Create(X2000_FlagsEnumerationBitwiseOperatorsCodeGen
                , context.ProcessingNode.GetLocation()));

            // We do not just expect a Member, but the Type, returned here.
            MemberDeclarationSyntax GenerateFlagsEnumerationPartial(FlagsEnumerationDescriptor d) => Generate(d, cancellationToken);

            return Task.Run(() =>
            {
                var generatedMembers = List<MemberDeclarationSyntax>();

                // ReSharper disable once InvertIf
                if (context.ProcessingNode is ClassDeclarationSyntax classDecl)
                {
                    var descriptor = classDecl.ToFlagsEnumerationDescriptor();
                    generatedMembers = generatedMembers.Add(GenerateFlagsEnumerationPartial(descriptor));
                }

                return generatedMembers;
            }, cancellationToken);
        }
        public void WriteSetsFileProject()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                context.Write(new OutputItem { File = TestFile, Project = "Test.proj" }, string.Empty);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.AreEqual("Test.proj", outputFile.Project);
        }
        public void WriteSetsFileItemTypeForDefaultOutput()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                context.Write(new OutputItem { ItemType = ItemType.Compile }, string.Empty);
            }

            OutputFile outputFile = outputFiles.Single(output => string.IsNullOrEmpty(output.File));
            Assert.AreEqual(ItemType.Compile, outputFile.ItemType);
        }
        public void WriteSetsFileCustomToolNamespace()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                context.Write(new OutputItem { File = TestFile, CustomToolNamespace = "Microsoft" }, string.Empty);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.AreEqual("Microsoft", outputFile.CustomToolNamespace);
        }
        public void WriteSetsFileCopyToOutputDirectory()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                context.Write(new OutputItem { File = TestFile, CopyToOutputDirectory = CopyToOutputDirectory.CopyAlways }, string.Empty);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.AreEqual(CopyToOutputDirectory.CopyAlways, outputFile.CopyToOutputDirectory);
        }
 public void WriteRespectsTransformationIndentationForSingleLineText()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         transformation.PushIndent("\t");
         context.Write(new OutputItem(), TestText);
         Assert.AreEqual("\t" + TestText, transformation.TransformText());
     }
 }
 public void WriteRespectsTransformationIndentationForMultilineText()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         transformation.PushIndent("\t");
         string text = TestText + Environment.NewLine + TestText;
         context.Write(new OutputItem(), text);
         string expectedOutput = "\t" + TestText + Environment.NewLine + "\t" + TestText;
         Assert.AreEqual(expectedOutput, transformation.TransformText());
     }
 }
 public void GetPropertyValueThrowsArgumentNullExceptionWhenNameIsNull()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         context.GetPropertyValue(null);
     }
 }
 public void WriteThrowsInvalidOperationExceptionWhenProjectIsSpecifiedWithoutFile()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         context.Write(new OutputItem { Project = "Test.proj" }, string.Empty);
     }
 }
 public void WriteThrowsArgumentNullExceptionWhenOutputIsNull()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         context.Write(null, string.Empty);
     }
 }
 public void WriteAppendsToTransformationWhenOutputFileIsNotSpecified()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         transformation.Write("TransformationOutput");
         context.Write(new OutputItem(), "TemplateOutput");
         Assert.AreEqual("TransformationOutput" + "TemplateOutput", transformation.TransformText());
     }
 }
 public void WriteAppendsToPreviousTemplateOutput()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         context.Write(new OutputItem(), "TemplateOutput");
         transformation.Write("TransformationOutput");
         Assert.AreEqual("TemplateOutput" + "TransformationOutput", transformation.TransformText());
     }
 }
 public void TransformationReturnsTransformationPassedToConstructor()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         Assert.AreSame(transformation, context.Transformation);
     }
 }
 public void HostReturnsHostOfTransformation()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         Assert.IsNotNull(context.Host);
         Assert.AreSame(transformation.Host, context.Host);
     }
 }
 public void GetServiceReturnsNullWhenServiceIsNotAvailable()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         Assert.IsNull(context.GetService(typeof(ICloneable))); // Bogus service
     }
 }
 public void GetServiceDelegatesToHost()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         var expected = ((IServiceProvider)transformation.Host).GetService(typeof(ITransformationContextProvider));
         var actual = context.GetService(typeof(ITransformationContextProvider));
         Assert.AreSame(expected, actual);
     }
 }
 public void WriteThrowsInvalidOperationExceptionWhenDirectoryIsSpecifiedWithoutFile()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         context.Write(new OutputItem { Directory = "SubFolder" }, string.Empty);
     }
 }
        public void GetPropertyValuePassesHostHierarchyToProvider()
        {
            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.Hierarchy = new object();

                object actualHierarchy = null;
                transformation.Host.GetPropertyValue = (hierarchy, propertyName) =>
                {
                    actualHierarchy = hierarchy;
                    return string.Empty;
                };

                context.GetPropertyValue("Irrelevant");
                Assert.AreSame(transformation.Host.Hierarchy, actualHierarchy);
            }
        }
        private static void WriteThrowsInvalidOperationException(OutputItem first, OutputItem second, params string[] keywords)
        {
            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                first.File = TestFile;
                context.Write(first, string.Empty);

                try
                {
                    second.File = TestFile;
                    context.Write(second, string.Empty);
                }
                catch (InvalidOperationException e)
                {
                    Assert.AreNotEqual(typeof(TransformationException), e.GetType());
                    foreach (string keyword in keywords)
                    {
                        StringAssert.Contains(e.Message, keyword);
                    }
                }
            }
        }
 public void GetPropertyValueReturnsValueSuppliedByProvider()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         const string ExpectedValue = "TestValue";
         transformation.Host.GetPropertyValue = (hierarchy, propertyName) => ExpectedValue;
         Assert.AreEqual(ExpectedValue, context.GetPropertyValue("TestProperty"));
     }
 }
        public void WriteCombinesTextOfDifferentOutputsWithTheSameFileName()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                context.Write(new OutputItem { File = TestFile }, TestText);
                context.Write(new OutputItem { File = TestFile }, TestText);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.AreEqual(TestText + TestText, outputFile.Content.ToString());
        }
        public void WriteCombinesTextWrittenToTheSameOutputMultipleTimes()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;
                var outputInfo = new OutputItem { File = TestFile };
                context.Write(outputInfo, TestText);
                context.Write(outputInfo, TestText);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.AreEqual(TestText + TestText, outputFile.Content.ToString());
        }
        public void WriteCombinesFileMetadata()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;

                var outputInfo = new OutputItem { File = TestFile };
                outputInfo.Metadata["Generator"] = "TextTemplatingFileGenerator";
                context.Write(outputInfo, string.Empty);

                outputInfo.Metadata.Clear();
                outputInfo.Metadata["LastGenOutput"] = "Test.txt";
                context.Write(outputInfo, string.Empty);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.AreEqual("TextTemplatingFileGenerator", outputFile.Metadata["Generator"]);
            Assert.AreEqual("Test.txt", outputFile.Metadata["LastGenOutput"]);
        }
        public void GetMetadataValuePassesInputFileToProvider()
        {
            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.TemplateFile = Path.GetRandomFileName();

                string actualFileName = null;
                transformation.Host.GetMetadataValue = (hierarchy, fileName, metadataName) =>
                {
                    actualFileName = fileName;
                    return string.Empty;
                };

                context.GetMetadataValue("Irrelevant");
                Assert.AreSame(transformation.Host.TemplateFile, actualFileName);
            }
        }
 public void GetMetadataValueThrowsArgumentExceptionWhenNameIsEmpty()
 {
     using (var transformation = new FakeTransformation())
     using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
     {
         context.GetMetadataValue(" \t\r\n");
     }
 }
        public void WriteCombinesFileReferences()
        {
            OutputFile[] outputFiles = null;

            using (var transformation = new FakeTransformation())
            using (var context = new TransformationContext(transformation, transformation.GenerationEnvironment))
            {
                transformation.Host.UpdatedOutputFiles = (input, outputs) => outputFiles = outputs;

                var outputInfo = new OutputItem { File = TestFile };
                outputInfo.References.Add("System");
                context.Write(outputInfo, string.Empty);

                outputInfo.Metadata.Clear();
                outputInfo.References.Add("System.Xml");
                context.Write(outputInfo, string.Empty);
            }

            OutputFile outputFile = outputFiles.Single(output => output.File == TestFile);
            Assert.IsTrue(outputFile.References.Contains("System"));
            Assert.IsTrue(outputFile.References.Contains("System.Xml"));
        }