Skip to content

Commit

Permalink
add source generator with global namespace setting
Browse files Browse the repository at this point in the history
  • Loading branch information
shuebner committed Aug 22, 2021
1 parent 0141ec3 commit 3121216
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLSchema1"
targetNamespace="mysamplenamespace"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema1.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema1.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="MyRootElement">
<xs:complexType id="RootType">
<xs:all>
<xs:element name="Child1">
<xs:simpleType id="Child1Type">
<xs:restriction base="xs:boolean"/>
</xs:simpleType>
</xs:element>
<xs:element name="Child2">
<xs:simpleType id="Child2Type">
<xs:restriction base="xs:string"/>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
18 changes: 18 additions & 0 deletions XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using Xunit;

namespace XmlSchemaClassGenerator.SourceGenerator.Tests
{
public class SimpleSchemaTests
{
[Fact]
public void Compiles()
{
new Sample.Generated.MyRootElement
{
Child1 = true,
Child2 = "foo"
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<Import Project="..\XmlSchemaClassGenerator.SourceGenerator\XmlSchemaClassGenerator.SourceGenerator.props"/>

<ItemGroup>
<ProjectReference Include="..\XmlSchemaClassGenerator.SourceGenerator\XmlSchemaClassGenerator.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="Samples\simple_schema.xsd" />
</ItemGroup>

<PropertyGroup>
<xscgen_Namespace>Sample.Generated</xscgen_Namespace>
</PropertyGroup>

<ItemGroup>
<Content Update="Samples\simple_schema.xsd">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NoPackageAnalysis>true</NoPackageAnalysis>

<PackageId>XmlSchemaClassGenerator.SourceGenerator</PackageId>
<Authors>Sven Hübner</Authors>
<Description>Source generator for POCOs from XSD schema files, based on XmlSchemaClassGenerator</Description>
<PackageTags>xml;xsd;Schema;Source Generator;poco;XmlSchemaClassGenerator</PackageTags>
<PackageProjectUrl>https://github.com/mganss/XmlSchemaClassGenerator</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>git://github.com/mganss/XmlSchemaClassGenerator</RepositoryUrl>
<RootNamespace>XmlSchemaClassGenerator</RootNamespace>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\XmlSchemaClassGenerator\XmlSchemaClassGenerator.csproj" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.CodeDom" Version="5.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.4.0" GeneratePathProperty="true"/>
</ItemGroup>

<PropertyGroup>
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
</PropertyGroup>

<Target Name="GetDependencyTargetPaths">
<ItemGroup>
<TargetPathWithTargetPlatformMoniker Include="..\XmlSchemaClassGenerator\bin\$(Configuration)\$(TargetFramework)\XmlSchemaClassGenerator.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_CodeDom)\lib\netstandard2.0\System.CodeDom.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_Text_Encoding_CodePages)\lib\netstandard2.0\System.Text.Encoding.CodePages.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_ValueTuple)\lib\netstandard1.0\System.ValueTuple.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_ComponentModel_Annotations)\lib\netstandard2.0\System.ComponentModel.Annotations.dll" IncludeRuntimeDependency="false" />
<TargetPathWithTargetPlatformMoniker Include="$(PKGSystem_Runtime_CompilerServices_Unsafe)\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll" IncludeRuntimeDependency="false" />
</ItemGroup>
</Target>

<ItemGroup>
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="..\XmlSchemaClassGenerator\bin\$(Configuration)\$(TargetFramework)\XmlSchemaClassGenerator.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="$(PKGSystem_CodeDom)\lib\netstandard2.0\System.CodeDom.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
<None Include="$(PKGSystem_Text_Encoding_CodePages)\lib\netstandard2.0\System.Text.Encoding.CodePages.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
<None Include="$(PKGSystem_ValueTuple)\lib\netstandard1.0\System.ValueTuple.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
<None Include="$(PKGSystem_ComponentModel_Annotations)\lib\netstandard2.0\System.ComponentModel.Annotations.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>
<None Include="$(PKGSystem_Runtime_CompilerServices_Unsafe)\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/>

<None Include="XmlSchemaClassGenerator.SourceGenerator.props" Pack="true" PackagePath="build/$(PackageId).props" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<ItemGroup>
<CompilerVisibleProperty Include="xscgen_Namespace" />
</ItemGroup>
</Project>
81 changes: 81 additions & 0 deletions XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Schema;

namespace XmlSchemaClassGenerator
{
[Generator]
public class XsdSourceGenerator : ISourceGenerator
{
internal class MemoryOutputWriter : OutputWriter
{
public string Content { get; set; }

public override void Write(CodeNamespace cn)
{
var cu = new CodeCompileUnit();
cu.Namespaces.Add(cn);

using (var writer = new StringWriter())
{
Write(writer, cu);
Content = writer.ToString();
}
}
}

public void Execute(GeneratorExecutionContext context)
{
#if DEBUG
if (!Debugger.IsAttached)
{
//Debugger.Launch();
}
#endif
var configurations = GetConfigurations(context);

foreach (var (schemaFile, @namespace) in configurations)
{
var schemaStr = schemaFile.GetText().ToString();
var stringReader = new StringReader(schemaStr);

var schemaSet = new XmlSchemaSet();
schemaSet.Add(null, XmlReader.Create(stringReader));

var generator = new Generator();
generator.NamespaceProvider.Add(new NamespaceKey(), @namespace);
MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter();
generator.OutputWriter = memoryOutputWriter;
generator.Generate(schemaSet);
context.AddSource("Pocos", memoryOutputWriter.Content);
}
}

public void Initialize(GeneratorInitializationContext context)
{
// do nothing
}

static IEnumerable<(AdditionalText SchemaFile, string Namespace)> GetConfigurations(GeneratorExecutionContext context)
{
if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_Namespace", out var @namespace))
{
@namespace = "Generated";
}

foreach (AdditionalText file in context.AdditionalFiles)
{
if (Path.GetExtension(file.Path).Equals(".xsd", StringComparison.OrdinalIgnoreCase))
{
yield return (file, @namespace);
}
}
}
}
}
12 changes: 12 additions & 0 deletions XmlSchemaClassGenerator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xscgen-proj", "xscgen-proj\xscgen-proj.csproj", "{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlSchemaClassGenerator.SourceGenerator", "XmlSchemaClassGenerator.SourceGenerator\XmlSchemaClassGenerator.SourceGenerator.csproj", "{1A4760D7-7618-41E8-BC97-C68566B7A16C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlSchemaClassGenerator.SourceGenerator.Tests", "XmlSchemaClassGenerator.SourceGenerator.Tests\XmlSchemaClassGenerator.SourceGenerator.Tests.csproj", "{333F3108-2714-4706-ABA7-4298EFEBFCA7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -50,6 +54,14 @@ Global
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Release|Any CPU.Build.0 = Release|Any CPU
{1A4760D7-7618-41E8-BC97-C68566B7A16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A4760D7-7618-41E8-BC97-C68566B7A16C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A4760D7-7618-41E8-BC97-C68566B7A16C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A4760D7-7618-41E8-BC97-C68566B7A16C}.Release|Any CPU.Build.0 = Release|Any CPU
{333F3108-2714-4706-ABA7-4298EFEBFCA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{333F3108-2714-4706-ABA7-4298EFEBFCA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{333F3108-2714-4706-ABA7-4298EFEBFCA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{333F3108-2714-4706-ABA7-4298EFEBFCA7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 3121216

Please sign in to comment.