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); } }
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); } }
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); } }
/// <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); }
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()); }
/// <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)); }
/// <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()); }
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"); }
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)); }
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)
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); } }
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); } }
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)); }
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}\";")); } }
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)); }
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); } }
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>())); } }
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; } }
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))); }
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 }); }
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); }
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); }
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); } }
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 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")); }