void ReleaseDesignerOutlets() { if (CSharpFile != null) { CSharpFile.Dispose(); CSharpFile = null; } if (HTMLFile != null) { HTMLFile.Dispose(); HTMLFile = null; } if (MarkDownFile != null) { MarkDownFile.Dispose(); MarkDownFile = null; } if (XMLFile != null) { XMLFile.Dispose(); XMLFile = null; } if (ChooseButton != null) { ChooseButton.Dispose(); ChooseButton = null; } }
public static bool IsValidPMixinFile(this CSharpFile file) { //skip code behind files. if (file.FileName.FullPath.EndsWith(Constants.PMixinFileExtension, StringComparison.InvariantCultureIgnoreCase)) { return(false); } var partialClasses = file.SyntaxTree.GetPartialClasses(); var resolver = file.CreateResolver(); return(partialClasses.Any( c => { var resolvedClass = resolver.Resolve(c); if (resolvedClass.IsError) { return false; } return resolvedClass.Type.GetAttributes() .Any(x => x.AttributeType.Implements <IPMixinAttribute>()); })); }
public async Task Output() { var usings = new List <UsingDirectiveSyntax>(); var firstNS = namespaces[0]; usings.Add ( UsingDirective(IdentifierName(firstNS)) .WithGlobalKeyword ( Token ( TriviaList(Comment("// Generated Code")), SyntaxKind.GlobalKeyword, TriviaList() ) ) ); foreach (var ns in namespaces.Skip(1)) { usings.Add ( UsingDirective(IdentifierName(ns)) .WithGlobalKeyword(Token(SyntaxKind.GlobalKeyword)) ); } var code = CompilationUnit() .WithUsings ( List(usings) ); var cSharpFile = new CSharpFile(code, createStream, "DefaultGlobalUsings"); await cSharpFile.Output(); }
public void LoadExtendsTest(string className, string baseClassName) { var csFile = new CSharpFile( className.ToBasicPath(), DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); var declaration = Assert.Single(csFile.Declarations); var declarationResolver = this.SetupDeclarationResolver( declaration, baseClassName); var classDecl = Assert.IsType <ClassDeclaration>(declaration); classDecl.Load(declarationResolver); Assert.NotNull(classDecl.GenericParameters); Assert.NotNull(classDecl.Extends); var extendsSingle = Assert.Single(classDecl.Extends); var genDeclUse = Assert.IsType <GenericDeclarationUse>(extendsSingle); Assert.Equal(baseClassName, genDeclUse.Declaration.Name); }
public void LoadClassAttributes() { var className = nameof(AttributedClass); var file = className.ToBasicPath(); var csFile = new CSharpFile( file, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); var declaration = Assert.Single(csFile.Declarations); var declarationResolver = this.SetupDeclarationResolver(declaration); var decl = Assert.IsType <ClassDeclaration>(declaration); decl.Load(declarationResolver); Assert.NotEmpty(decl.Attributes); var attribute = Assert.Single(decl.Attributes); Assert.Equal(nameof(PatternAttribute), attribute.Name); Assert.NotNull(attribute.SyntaxNodeProvider); }
private IDeclarationResolver SetupDeclarationResolver(IDeclaration <SyntaxNode> contextDeclaration, params string[] classNames) { var declarationResolverMock = new Mock <IDeclarationResolver>(); foreach (var className in classNames) { var classFile = new CSharpFile( className.ToBasicPath(), DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); classFile.Load(); var classDeclarationSingle = Assert.Single(classFile.Declarations); if (classDeclarationSingle is IGenericDeclaration <SyntaxNode> genericDeclaration && genericDeclaration.TypeParameterListSyntaxProvider.SyntaxNode != null) { declarationResolverMock .Setup(dr => dr.Resolve(genericDeclaration.Name, It.IsAny <IReadOnlyList <IDeclarationUse <SyntaxNode> > >(), contextDeclaration)) .Returns(genericDeclaration); } else { declarationResolverMock .Setup(dr => dr.Resolve(classDeclarationSingle.Name, contextDeclaration)) .Returns(classDeclarationSingle); } } return(declarationResolverMock.Object); }
private void Reload(string[] filenames) { IsParsed = false; var files = new List <CSharpFile>(); for (int index = 0; index < filenames.Length; index++) { var filename = filenames[index]; var extension = Path.GetExtension(filename); // ignoring ".ammy.cs" makes it impossible to use defined properties from that type //if (extension != ".cs" || filename.EndsWith(".ammy.cs")) if (extension != ".cs") { continue; } if (!Path.IsPathRooted(filename)) { filename = filename.ToAbsolutePath(_projectDir); } if (!File.Exists(filename)) { continue; } // 10000 is CSharp file offset var file = new CSharpFile(index + 10000, filename, NitraCSharp.Instance); files.Add(file); } Files = files.Cast <Nitra.ProjectSystem.File>().ToArray(); }
public static string Preview(this AstNode node, CSharpFile file, int maxWidth) { var startLocation = node.StartLocation; var startOffset = file.Document.GetOffset(startLocation.Line, startLocation.Column); var line = file.Document.GetLineByNumber(startLocation.Line); var lineText = file.Document.GetText(line.Offset, line.Length); if (line.Length < maxWidth) { // Don't truncate return(lineText); } var endLocation = node.EndLocation; var endOffset = file.Document.GetOffset(endLocation.Line, endLocation.Column); const string ellipsis = "..."; var charactersEitherSide = (maxWidth - (ellipsis.Length * 2)); // Place the node text as close as possible to the centre of the returned text var start = Math.Max(line.Offset, startOffset - charactersEitherSide); var end = Math.Min(line.EndOffset, endOffset + charactersEitherSide); return(ellipsis + file.Document.GetText(start, end - start).Trim() + ellipsis); }
public static CSharpFile AddOrUpdateProjectItemFile(this Solution solution, RawSourceFile rawSourceFile) { Ensure.ArgumentNotNull(solution, "solution"); try { var project = solution.Projects.FirstOrDefault( p => p.FileName.Equals(rawSourceFile.ProjectFileName)); if (null == project) { _log.ErrorFormat("Failed AddOrUpdateProjectItemFile [{0}] because could not find Project [{1}]", rawSourceFile.FileName, rawSourceFile.ProjectFileName); //TODO: Should this throw an exception instead? return(null); } var csharpFile = new CSharpFile(project, rawSourceFile.FileName, rawSourceFile.FileContents); project.AddOrUpdateCSharpFile(csharpFile); solution.RecreateCompilations(); return(csharpFile); } catch (Exception e) { _log.Error("Exception in AddOrUpdateCodeGeneratorFileSource: " + e.Message, e); throw; } }
public async Task Output(AppApiTemplate appTemplate) { foreach (var group in appTemplate.GroupTemplates) { var controller = createController(appTemplate, group); var controllerClassName = getControllerClassName(group); var cSharpFile = new CSharpFile(controller, createStream, controllerClassName); await cSharpFile.Output(); } var namespaces = appTemplate.ObjectTemplates(ApiCodeGenerators.Dotnet) .Select(o => o.DataType.Namespace ?? "") .Union ( new[] { "Microsoft.AspNetCore.Authorization", "Microsoft.AspNetCore.Mvc", "XTI_App.Api", "XTI_WebApp.Api" } ) .Distinct() .OrderBy(str => str) .ToArray(); await new GlobalUsingsClass(createStream, namespaces).Output(); }
public MethodVisitor(SDRepository repository, SDMethod method, SDType type, CSharpFile file) { _repository = repository; _method = method; _type = type; _file = file; _tokenList = method.Calls; }
public void BasicCSharpFileTest() { var file = "./Resources/Workspace/BasicClass.cs"; var csFile = new CSharpFile(file, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); Assert.Equal(Path.GetFileName(file), csFile.FileName); Assert.Equal(Path.GetDirectoryName(file), csFile.FilePath); }
public static IEnumerable <IType> ResolveTypes(this CSharpFile file) { var resolver = file.CreateResolver(); return(file.SyntaxTree.GetClassDefinitions() .Select(x => resolver.Resolve(x)) .Where(x => !x.IsError) .Select(x => x.Type) .ToArray()); }
static void Main(string[] args) { if (args.Length <= 0) { Console.WriteLine(GetHelp); return; } ArgumentResult argumentResult = new ArgumentResult(args); if (argumentResult.ErrMsg.GetCountByArguments("ERR") > 0) { Console.WriteLine(argumentResult.ErrMsg["ERR"]); return; } bool isHaveBaseController = argumentResult.BaseController.GetCountByArguments("-B", "--BaseController") > 0; bool isHaveHttpGet = argumentResult.BaseController.GetCountByArguments("-G", "--HttpGet") > 0; bool isShowUI = argumentResult.ShowUI.GetCountByArguments("-ui", "--ShowUI") > 0; string apiFileName = argumentResult.APIControllerFileName["api"]; if (!File.Exists(apiFileName)) { Console.WriteLine($"檔案 {apiFileName} 不存在!請確認。"); return; } string originalContent = FileHelper.ReadTextFileToEnd(apiFileName); if (isShowUI) { frmConvertWebAPI contextForm = new frmConvertWebAPI(originalContent); CSharpFile cs = ParseApiController(apiFileName); contextForm.SetTargetCsSource(cs.ToString()); DialogResult result = contextForm.ShowDialog(); if (result == DialogResult.OK) { FileHelper.WriteTextToFile(apiFileName, cs.ToString()); Console.WriteLine($"寫入 {apiFileName} Ok!"); } else { Console.WriteLine("使用者取消..."); } } else { CSharpFile cs = ParseApiController(apiFileName); FileHelper.WriteTextToFile(apiFileName, cs.ToString()); } //Console.ReadLine(); }
private static CSharpFile ParseApiController(string apiFileName) { CSharpFile cs = new CSharpFile(apiFileName); cs.InsertNewLine(0, "using Microsoft.AspNetCore.Mvc;"); for (int count = 0; count < cs.LineCount(); count++) { if (cs[count].GetKindOfLine == KIND_OF_LINE.USING) { if (cs.GetLine(count).ToLower() == "using system.web.http;") { cs[count] = new CSharpLine(""); } } } for (int count = 0; count < cs.LineCount(); count++) { if (cs[count].GetKindOfLine == KIND_OF_LINE.CLASS) { string mvcRoute = "[Route(\"api/[controller]\")]"; cs.InsertNewLine(count, mvcRoute); string apiControllerAttr = "[ApiController]"; cs.InsertNewLine(count, apiControllerAttr); break; } } for (int count = 0; count < cs.LineCount(); count++) { if (cs[count].GetKindOfLine == KIND_OF_LINE.METHOD) { string getAttr = "[HttpGet]"; cs.InsertNewLine(count, getAttr); break; } } for (int count = 0; count < cs.LineCount(); count++) { if (cs[count].GetKindOfLine == KIND_OF_LINE.CLASS) { string procLine = cs.GetLine(count); //procLine = procLine.Replace("ApiController", "ControllerBase"); string[] classLine = procLine.Split(new char[] { ':' }); procLine = $"{classLine[0]}: {classLine[1].Replace("ApiController", "ControllerBase")}"; cs[count] = new CSharpLine(procLine); } } return(cs); }
/// <inheritdoc /> protected override CSharpFile GenerateCode(ContractDefinition contract, string implementationName, string @namespace, CSharpAccessModifier accessLevel) { // Generate the code CSharpFile file = new CSharpFile( @namespace: @namespace, usings: null, classes: this.GetClasses(contract, implementationName, accessLevel), fileHeader: this.GetFileHeader(contract) ); return(file); }
public void Generate() { CSharpFile customTypeManagerGenerator = new CSharpFile(); customTypeManagerGenerator.Name = string.Format("{0}TypeManager", name); customTypeManagerGenerator.cSharpFileElements.Add(new UsingElement(typeof(CustomTypeGenerator))); customTypeManagerGenerator.cSharpFileElements.Add(new UsingElement(typeof(CreateAssetMenuAttribute))); customTypeManagerGenerator.cSharpFileElements.Add(new UsingElement(typeof(SerializableAttribute))); customTypeManagerGenerator.cSharpFileElements.Add(new NewLineElement()); NamespaceElement namespaceElement = new NamespaceElement(string.IsNullOrEmpty(@namespace) ? "CustomType" : @namespace); customTypeManagerGenerator.cSharpFileElements.Add(namespaceElement); ClassElement managerClass = new ClassElement(string.Format("{0}TypeManager", name)); managerClass.ClassAttributes.Add(new CreateAssetMenuElement(name)); managerClass.DerivedFrom = new SingletonTypeManagerElement(string.Format("{0}TypeManager", name)); namespaceElement.cSharpFileElements.Add(managerClass); ClassElement typeClass = new ClassElement(name); typeClass.ClassAttributes.Add(new AttributeElement(typeof(SerializableAttribute))); typeClass.DerivedFrom = new CustomTypeEelemnt(); namespaceElement.cSharpFileElements.Add(typeClass); customTypeManagerGenerator.Save(string.Format("{0}/{1}", path, name)); CSharpFile propertyGenerator = new CSharpFile(); propertyGenerator.cSharpFileElements.Add(new UsingElement(typeof(CustomPropertyDrawer))); propertyGenerator.cSharpFileElements.Add(new UsingElement(typeof(CustomTypeGenerator))); propertyGenerator.cSharpFileElements.Add(new UsingElement(typeof(CreateAssetMenuAttribute))); propertyGenerator.cSharpFileElements.Add(namespaceElement); ClassElement propertyClass = new ClassElement(string.Format("{0}PropertyDrower", name)); propertyGenerator.Name = propertyClass.Name; propertyClass.DerivedFrom = new TypePropertyDrowerElement(managerClass.Name); propertyClass.ClassAttributes.Add(new WeaponModeTypePropertyDrowerAttributeElement(typeClass.Name)); namespaceElement.cSharpFileElements.Clear(); namespaceElement.cSharpFileElements.Add(propertyClass); propertyGenerator.Save(string.Format("{0}/{1}/Editor", path, name)); AssetDatabase.Refresh(); }
public void LoadCSharpFileNameSpaceDeclarationTest() { var file = "./Resources/Workspace/MultiNameSapces.cs"; var csFile = new CSharpFile(file, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); Assert.Equal(3, csFile.Declarations.Count); Assert.Single(csFile.Declarations.Where(d => string.IsNullOrEmpty(d.DeclarationNameSpace))); Assert.Single(csFile.Declarations.Where(d => d.DeclarationNameSpace == "SoloX.GeneratorTools.Core.CSharp.UTest.Resources.Workspace")); Assert.Single(csFile.Declarations.Where(d => d.DeclarationNameSpace == "SoloX.GeneratorTools.Core.CSharp.UTest.Resources.Workspace.Test")); }
public void LoadCSharpFileTest(string declarationFile, string name, Type expectedDeclarationType) { var csFile = new CSharpFile( declarationFile, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); Assert.Single(csFile.Declarations); var decl = csFile.Declarations.Single(); Assert.Equal(expectedDeclarationType, decl.GetType()); Assert.Equal(name, decl.Name); }
public void LoadMemberListTest(string className, bool isArray) { var file = className.ToBasicPath(); var csFile = new CSharpFile( file, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); var declaration = Assert.Single(csFile.Declarations); var declarationResolver = this.SetupDeclarationResolver( declaration, nameof(SimpleClass)); var decl = Assert.IsType <ClassDeclaration>(declaration); decl.Load(declarationResolver); Assert.Empty(decl.GenericParameters); Assert.Empty(decl.Extends); Assert.NotEmpty(decl.Members); Assert.Equal(2, decl.Members.Count); var mClass = Assert.Single(decl.Members.Where(m => m.Name == nameof(ClassWithProperties.PropertyClass))); var pClass = Assert.IsType <PropertyDeclaration>(mClass); Assert.IsType <GenericDeclarationUse>(pClass.PropertyType); Assert.Equal(nameof(SimpleClass), pClass.PropertyType.Declaration.Name); var mInt = Assert.Single(decl.Members.Where(m => m.Name == nameof(ClassWithProperties.PropertyInt))); var pInt = Assert.IsType <PropertyDeclaration>(mInt); Assert.IsType <PredefinedDeclarationUse>(pInt.PropertyType); Assert.Equal("int", pInt.PropertyType.Declaration.Name); if (isArray) { Assert.NotNull(pClass.PropertyType.ArraySpecification); Assert.NotNull(pInt.PropertyType.ArraySpecification); } else { Assert.Null(pClass.PropertyType.ArraySpecification); Assert.Null(pInt.PropertyType.ArraySpecification); } }
/// <summary> /// Converts a CSharpFile into a TextFile. /// </summary> /// <param name="cSharpFile">The CSharpFile</param> /// <returns>The generated TextFile.</returns> public static TextFile ToTextFile(this CSharpFile cSharpFile) { if (cSharpFile == null) { throw new ArgumentNullException(nameof(cSharpFile)); } // Generate the output string fileContents = cSharpFile.ToString(); // Create the TextFile object which will be sent back to Vipr TextFile textFile = new TextFile(cSharpFile.RelativeFilePath, fileContents); return(textFile); }
/// <summary> /// Generates factory cmdlets for creating PowerShell objects that can be serialized as types defined /// in the given ODCM model. /// </summary> /// <param name="model">The ODCM model</param> /// <param name="location">The filesystem location at which the generated files should be placed</param> /// <returns></returns> private static IEnumerable <TextFile> GenerateObjectFactoryCmdlets(OdcmModel model, string location) { // 1. Convert the types in the ODCM model into ObjectFactory objects foreach (ObjectFactoryCmdlet objectFactoryCmdlet in model.CreateObjectFactories(location)) { // 2. Convert the ObjectFactory into an abstract representation of the C# file CSharpFile cSharpFile = objectFactoryCmdlet.ToCSharpFile(); // 3. Generate the text file by converting the abstract representation of the C# file into a string TextFile outputFile = cSharpFile.ToTextFile(); // Return the generated file yield return(outputFile); } }
/// <summary> /// Converts a Resource into a CSharpFile. /// </summary> /// <param name="resource">The resource</param> /// <returns>The converted CSharpFile.</returns> public static CSharpFile ToCSharpFile(this Resource resource) { if (resource == null) { throw new ArgumentNullException(nameof(resource)); } // Get the C# file details CSharpFile cSharpFile = new CSharpFile(resource.RelativeFilePath + ".cs") { Usings = CSharpFileHelper.GetDefaultUsings(), Classes = resource.CreateClasses(), }; return(cSharpFile); }
/// <summary> /// Converts an ObjectFactoryCmdlet into a CSharpFile. /// </summary> /// <param name="cmdlet">The object factory cmdlet</param> /// <returns>The converted CSharpFile.</returns> public static CSharpFile ToCSharpFile(this ObjectFactoryCmdlet cmdlet) { if (cmdlet == null) { throw new ArgumentNullException(nameof(cmdlet)); } // Get the C# file details CSharpFile cSharpFile = new CSharpFile(cmdlet.RelativeFilePath + ".cs") { Usings = CSharpFileHelper.GetDefaultUsings(), Classes = cmdlet.ToCSharpClass().SingleObjectAsEnumerable(), }; return(cSharpFile); }
/// <summary> /// Initialize a QuickFix pointing to the first line of the /// given region in the given file. /// </summary> public static QuickFix ForFirstLineInRegion (DomRegion region, CSharpFile file) { return(new QuickFix { FileName = region.FileName , Line = region.BeginLine , Column = region.BeginColumn // Note that we could display an arbitrary amount of // context to the user: ranging from one line to tens, // hundreds.. , Text = file.Document.GetText (offset: file.Document.GetOffset(region.Begin) , length: file.Document.GetLineByNumber (region.BeginLine).Length) }); }
/// <summary> /// Generates the PowerShell SDK from the given ODCM model. /// </summary> /// <param name="model">The ODCM model</param> /// <returns>The TextFile objects representing the generated SDK.</returns> private static IEnumerable <TextFile> GeneratePowerShellSDK(OdcmModel model, string location) { // 1. Convert the ODCM model into nodes (i.e. routes) foreach (OdcmNode node in model.ConvertToOdcmNodes()) { // 2. Convert the route into an abstract representation of the PowerShell cmdlets Resource resource = node.ConvertToResource(location); // 3. Convert the resource into an abstract representation of the C# file CSharpFile cSharpFile = resource.ToCSharpFile(); // 4. Generate the text file by converting the abstract representation of the C# file into a string TextFile outputFile = cSharpFile.ToTextFile(); // Return the generated file yield return(outputFile); } }
public void LoadCSharpClassTest(string className, string typeParameterName, string baseClassName) { var location = className.ToBasicPath(); var csFile = new CSharpFile( location, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); Assert.Single(csFile.Declarations); var declaration = csFile.Declarations.Single(); Assert.Equal(location, declaration.Location); var classDecl = Assert.IsType <ClassDeclaration>(declaration); classDecl.Load(Mock.Of <IDeclarationResolver>()); Assert.NotNull(classDecl.GenericParameters); Assert.NotNull(classDecl.Extends); if (string.IsNullOrEmpty(typeParameterName)) { Assert.Empty(classDecl.GenericParameters); } else { var paramDecl = Assert.Single(classDecl.GenericParameters); Assert.Equal(typeParameterName, paramDecl.Name); } if (string.IsNullOrEmpty(baseClassName)) { Assert.Empty(classDecl.Extends); } else { var baseClass = Assert.Single(classDecl.Extends); Assert.Equal(baseClassName, baseClass.Declaration.Name); } }
/// <summary> /// Generates the transmitter class. /// </summary> /// <param name="contract">The contract for which to generate the transmitter class.</param> /// <param name="implementationName">The name of the ouput class. This will also be the name of the output file before appending the extension.</param> /// <param name="namespace">The namespace in which to put the generated classes.</param> /// <param name="accessLevel">The access level of the generated classes.</param> public string Run( ContractDefinition contract, string implementationName, string @namespace, CSharpAccessModifier accessLevel = CSharpAccessModifier.Public) { if (contract == null) { throw new ArgumentNullException(nameof(contract)); } if (implementationName == null) { throw new ArgumentNullException(nameof(implementationName)); } if (!CSharpNamingUtils.IsValidIdentifier(implementationName)) { throw new ArgumentException($"Implementation name must be a valid class name: {implementationName}", nameof(implementationName)); } if (@namespace == null) { throw new ArgumentNullException(nameof(@namespace)); } foreach (string namespacePart in @namespace.Split('.')) { if (!CSharpNamingUtils.IsValidIdentifier(namespacePart)) { throw new ArgumentException($"The provided namespace is invalid because the part '{namespacePart}' is not a valid C# identifier: {@namespace}", nameof(@namespace)); } } // Validate the contract this.ValidateContract(contract); // Generate the code CSharpFile file = this.GenerateCode(contract, implementationName, @namespace, accessLevel); string result = file.ToString(); return(result); }
public override void MainSetup() { Kernel.Get <ISolutionContext>().SolutionFileName = solutionFile; _solution = Kernel.Get <ISolutionFactory>().BuildCurrentSolution(); Assert.True(null != _solution, "Failed loading Solution from [{0}]", solutionFile); _thisFile = _solution .GetValidPMixinFiles() .FirstOrDefault(c => c.FileName.FullPath.EndsWith(filenameMatchingString)); Assert.True(null != _thisFile, "Code Generated Files did not find SampleTarget file."); _sampleTargetType = _thisFile.ResolveTypes() .FirstOrDefault(x => x.FullName.EndsWith("SampleTarget")); Assert.True(null != _sampleTargetType, "Failed to Resolve SampleTarget IType"); }
public void LoadGetterSetterPropertyTest() { var className = nameof(ClassWithGetterSetterProperties); var file = className.ToBasicPath(); var csFile = new CSharpFile( file, DeclarationHelper.CreateDeclarationFactory(this.testOutputHelper)); csFile.Load(); var declaration = Assert.Single(csFile.Declarations); var declarationResolver = this.SetupDeclarationResolver(declaration); var decl = Assert.IsType <ClassDeclaration>(declaration); decl.Load(declarationResolver); Assert.NotEmpty(decl.Properties); Assert.Equal(3, decl.Properties.Count); var rwp = Assert.Single(decl.Properties.Where(p => p.Name == nameof(ClassWithGetterSetterProperties.ReadWriteProperty))); Assert.True(rwp.HasGetter); Assert.True(rwp.HasSetter); var rop = Assert.Single(decl.Properties.Where(p => p.Name == nameof(ClassWithGetterSetterProperties.ReadOnlyProperty))); Assert.True(rop.HasGetter); Assert.False(rop.HasSetter); var wop = Assert.Single(decl.Properties.Where(p => p.Name == nameof(ClassWithGetterSetterProperties.WriteOnlyProperty))); Assert.False(wop.HasGetter); Assert.True(wop.HasSetter); }