This repository has been archived by the owner on Oct 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ben Clive
committed
Jul 23, 2019
0 parents
commit 457cc8b
Showing
108 changed files
with
7,481 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
agent_queue_id: trigger-pipelines | ||
description: Dotnet worker. | ||
github: | ||
branch_configuration: [] | ||
default_branch: master | ||
pull_request_branch_filter_configuration: [] | ||
teams: | ||
- name: Everyone | ||
permission: BUILD_AND_READ | ||
- name: gbu/ecosystems/online-services | ||
permission: MANAGE_BUILD_AND_READ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
linux: &linux | ||
agents: | ||
- "capable_of_building=online-services" | ||
- "environment=production" | ||
- "permission_set=builder" | ||
- "platform=linux" # if you need a different platform, configure this: macos|linux|windows. | ||
- "queue=v3-1561728034-9178d5adb4ab9963-------z" | ||
timeout_in_minutes: 60 # TODO(ENG-548): reduce timeout once agent-cold-start is optimised. | ||
retry: | ||
automatic: | ||
# This is designed to trap and retry failures because agent lost connection. Agent exits with -1 in this case. | ||
- exit_status: -1 | ||
limit: 3 | ||
|
||
windows: &windows | ||
agents: | ||
- "capable_of_building=online-services" | ||
- "environment=production" | ||
- "permission_set=builder" | ||
- "platform=windows" # if you need a different platform, configure this: macos|linux|windows. | ||
- "queue=v3-1559053399-f2c8651809a877b4-------z" | ||
- "scaler_version=2" | ||
timeout_in_minutes: 60 # TODO(ENG-548): reduce timeout once agent-cold-start is optimised. | ||
retry: | ||
automatic: | ||
# This is designed to trap and retry failures because agent lost connection. Agent exits with -1 in this case. | ||
- exit_status: -1 | ||
limit: 3 | ||
# Workaround for flaky Git clones, likely due to - https://github.com/PowerShell/Win32-OpenSSH/issues/1322 | ||
- exit_status: 128 | ||
limit: 3 | ||
|
||
# NOTE: step labels turn into commit-status names like {org}/{repo}/{pipeline}/{step-label}, lower-case and hyphenated. | ||
# These are then relied on to have stable names by other things, so once named, please beware renaming has consequences. | ||
|
||
steps: | ||
- label: "build-linux" | ||
command: "ci/bk/build-linux.sh" | ||
artifact_paths: | ||
- "/tmp/${BUILDKITE_BUILD_ID}/**/*" | ||
<<: *linux | ||
|
||
- label: "test-linux" | ||
command: "ci/bk/test-linux.sh" | ||
artifact_paths: | ||
- "/tmp/${BUILDKITE_BUILD_ID}/**/*" | ||
<<: *linux | ||
|
||
- label: "build-windows" | ||
command: "powershell -NoProfile -NonInteractive -File ci/bk/build-win.ps1" | ||
artifact_paths: | ||
- "/tmp/${BUILDKITE_BUILD_ID}/**/*" | ||
<<: *windows |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 4 | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.json] | ||
indent_size = 2 | ||
|
||
[*.schema] | ||
indent_size = 2 | ||
|
||
[*.{targets,props,csproj}] | ||
indent_size = 2 | ||
|
||
# CSharp formatting settings: | ||
[*.cs] | ||
csharp_space_after_cast = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Tools and IDEs | ||
bin/ | ||
obj/ | ||
logs/ | ||
.vs/ | ||
.vscode/ | ||
.idea/ | ||
_ReSharper.Caches/ | ||
*.pubxml | ||
*.user | ||
launchSettings.json | ||
|
||
# Generated code | ||
GeneratedCode/gen/ | ||
CSharpCodeGenerator/CSharpCodeGenerator.Test/gen/ | ||
|
||
# Ignore Worker SDK files that are downloaded in place in order to create Nuget packages. | ||
Improbable/WorkerSdkInterop/Improbable.WorkerSdkInterop/lib | ||
Improbable/WorkerSdkInterop/Improbable.WorkerSdkInterop/runtimes | ||
Improbable/Schema/Improbable.Schema.Compiler/tools | ||
Improbable/Stdlib/Improbable.Stdlib.Schema/schema | ||
Improbable/Test/Improbable.Test.Schema/schema | ||
|
||
# Local nuget packages source | ||
nupkgs/ |
32 changes: 32 additions & 0 deletions
32
CSharpCodeGenerator/CSharpCodeGenerator.Test/CSharpCodeGenerator.Test.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<Platforms>x64</Platforms> | ||
<Platform Condition="'$(Platform)' == ''">x64</Platform> | ||
<LangVersion>latest</LangVersion> | ||
<SelfContained>false</SelfContained> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Remove="gen\**" /> | ||
<EmbeddedResource Remove="gen\**" /> | ||
<None Remove="gen\**" /> | ||
</ItemGroup> | ||
|
||
<!-- Input items for Improbable.Schema.Compiler --> | ||
<ItemGroup> | ||
<SchemaInputDir Include="$(MSBuildProjectDirectory)\schema" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Improbable.Stdlib" Version="0.0.1-preview" /> | ||
<PackageReference Include="Improbable.Stdlib.Schema" Version="13.8.2" /> | ||
<PackageReference Include="Improbable.Test.Schema" Version="13.8.2" /> | ||
<PackageReference Include="Improbable.WorkerSdkInterop" Version="13.8.2" /> | ||
<PackageReference Include="Improbable.Schema.Compiler" Version="13.8.2" /> | ||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> | ||
<PackageReference Include="Npgsql" Version="4.0.7" /> | ||
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" /> | ||
</ItemGroup> | ||
</Project> |
25 changes: 25 additions & 0 deletions
25
CSharpCodeGenerator/CSharpCodeGenerator.Test/schema/csharp.schema
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package improbable.test.csharp; | ||
|
||
// This file exists to ensure the C# code generators handle fields and events that | ||
// overlap with reserved C# keywords. | ||
|
||
type KeywordsReservedType { | ||
int64 while = 1; | ||
string for = 2; | ||
} | ||
|
||
component KeywordsReservedComponent { | ||
id = 200001; | ||
|
||
int64 var = 1; | ||
string do = 2; | ||
|
||
KeywordsReservedType private = 3; | ||
list<KeywordsReservedType> protected = 4; | ||
map<KeywordsReservedType, KeywordsReservedType> public = 5; | ||
option<KeywordsReservedType> static = 6; | ||
|
||
event KeywordsReservedType while; | ||
|
||
command KeywordsReservedType volatile(KeywordsReservedType); | ||
} |
20 changes: 20 additions & 0 deletions
20
CSharpCodeGenerator/CSharpCodeGenerator/CSharpCodeGenerator.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.2</TargetFramework> | ||
<ApplicationIcon /> | ||
<OutputType>Exe</OutputType> | ||
<StartupObject /> | ||
<LangVersion>latest</LangVersion> | ||
<SelfContained>false</SelfContained> | ||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="CommandLineParser" Version="2.4.3" /> | ||
<PackageReference Include="Improbable.CSharpCodeGen" Version="0.0.1-preview" /> | ||
<PackageReference Include="Improbable.Stdlib.CSharpCodeGen" Version="0.0.1-preview" /> | ||
<PackageReference Include="Improbable.WorkerSdkInterop.CSharpCodeGen" Version="0.0.1-preview" /> | ||
<PackageReference Include="Improbable.Schema.Bundle" Version="0.0.1-preview" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using CommandLine; | ||
using Improbable.CSharpCodeGen; | ||
using Improbable.Schema.Bundle; | ||
using Improbable.Stdlib.CSharpCodeGen; | ||
using Improbable.WorkerSdkInterop.CSharpCodeGen; | ||
using static Improbable.CSharpCodeGen.Case; | ||
using Types = Improbable.CSharpCodeGen.Types; | ||
|
||
namespace CodeGenerator | ||
{ | ||
public class Options | ||
{ | ||
[Option("input-bundle", Required = true, | ||
HelpText = "The path to the JSON Bundle file output by the SpatialOS schema_compiler.")] | ||
public string InputBundle { get; set; } | ||
|
||
[Option("output-marker", | ||
HelpText = "The path to a file that is written when code is successfully generated. Useful for timestamp checking in build systems.")] | ||
public string OutputMarker { get; set; } | ||
|
||
[Option("output-dir", Required = true, | ||
HelpText = "The path to write the generated code to.")] | ||
public string OutputDir { get; set; } | ||
} | ||
|
||
internal class Program | ||
{ | ||
private static void Main(string[] args) | ||
{ | ||
Parser.Default.ParseArguments<Options>(args) | ||
.WithParsed(Run) | ||
.WithNotParsed(errors => | ||
{ | ||
foreach (var error in errors) | ||
{ | ||
Console.Error.WriteLine(error); | ||
} | ||
|
||
Environment.ExitCode = 1; | ||
}); | ||
} | ||
|
||
private static void Run(Options options) | ||
{ | ||
Console.WriteLine(Parser.Default.FormatCommandLine(options)); | ||
|
||
var timer = new Stopwatch(); | ||
timer.Start(); | ||
|
||
try | ||
{ | ||
try | ||
{ | ||
File.Delete(options.OutputMarker); | ||
} | ||
catch | ||
{ | ||
// Nothing interesting to do here. | ||
} | ||
|
||
var bundle = SchemaBundleLoader.LoadBundle(options.InputBundle); | ||
|
||
// Sort the types by the depth of their declaration, so that nested types are generated first so they can be used by their declaring type. | ||
var types = bundle.Types.Select(kv => new TypeDescription(kv.Key, bundle)) | ||
.Union(bundle.Components.Select(kv => new TypeDescription(kv.Key, bundle))) | ||
.OrderByDescending(t => t.QualifiedName.Count(c => c == '.')) | ||
.ToList(); | ||
|
||
var baseGenerator = new Generator(bundle); | ||
var generators = new List<ICodeGenerator> | ||
{ | ||
baseGenerator, | ||
new StdlibGenerator(bundle), | ||
new SchemaObjectGenerator(bundle), | ||
}; | ||
|
||
var allContent = new Dictionary<string, StringBuilder>(); | ||
var nestedTypes = new HashSet<string>(); | ||
|
||
// Pass 1: generate all type content. | ||
foreach (var t in types) | ||
{ | ||
if (!allContent.TryGetValue(t.QualifiedName, out var builder)) | ||
{ | ||
builder = allContent[t.QualifiedName] = new StringBuilder(); | ||
} | ||
|
||
// Embed nested enums. | ||
builder.AppendJoin(Environment.NewLine, t.NestedEnums.Select(e => GenerateEnum(e, bundle).TrimEnd())); | ||
|
||
// Class implementation. | ||
builder.AppendJoin(Environment.NewLine, generators.Select(g => | ||
{ | ||
var result = g.Generate(t).TrimEnd(); | ||
if (string.IsNullOrWhiteSpace(result)) | ||
{ | ||
return string.Empty; | ||
} | ||
|
||
return $@" | ||
#region {g.GetType().FullName} | ||
{result} | ||
#endregion {g.GetType().FullName} | ||
"; | ||
|
||
}).Where(s => !string.IsNullOrEmpty(s))); | ||
|
||
// Nested types. | ||
builder.AppendJoin(Environment.NewLine, t.NestedTypes.Select(e => GenerateType(e, allContent[e.QualifiedName].ToString(), bundle))); | ||
|
||
nestedTypes.UnionWith(t.NestedTypes.Select(type => type.QualifiedName)); | ||
nestedTypes.UnionWith(t.NestedEnums.Select(type => type.QualifiedName)); | ||
} | ||
|
||
// Pass 2: Generate final content. | ||
foreach (var t in types.Where(type => !nestedTypes.Contains(type.QualifiedName))) | ||
{ | ||
var content = allContent[t.QualifiedName]; | ||
|
||
WriteFile(options, Types.TypeToFilename(t.QualifiedName), $@" | ||
namespace {GetPascalCaseNamespaceFromTypeName(t.QualifiedName)} | ||
{{ | ||
{Indent(1, GenerateType(t, content.ToString().TrimEnd(), bundle))} | ||
}}"); | ||
} | ||
|
||
// Enums. | ||
foreach (var (key, value) in bundle.Enums.Where(type => !nestedTypes.Contains(type.Key))) | ||
{ | ||
WriteFile(options, Types.TypeToFilename(key), $@" | ||
namespace {GetPascalCaseNamespaceFromTypeName(key)} | ||
{{ | ||
{Indent(1, GenerateEnum(value, bundle))} | ||
}}"); | ||
} | ||
|
||
File.WriteAllText(options.OutputMarker, string.Empty); | ||
} | ||
catch (Exception exception) | ||
{ | ||
Console.Error.WriteLine(exception); | ||
Environment.ExitCode = 1; | ||
} | ||
finally | ||
{ | ||
timer.Stop(); | ||
|
||
Console.WriteLine($"Processed schema bundle in {timer.Elapsed}."); | ||
} | ||
} | ||
|
||
private static void WriteFile(Options options, string filename, string text) | ||
{ | ||
var outputPath = Path.Combine(options.OutputDir, filename); | ||
var folder = Path.GetDirectoryName(outputPath); | ||
if (!Directory.Exists(folder)) | ||
{ | ||
Directory.CreateDirectory(folder); | ||
} | ||
|
||
// Normalize line endings so editors don't complain. | ||
text = "// Generated by SpatialOS C# CodeGen.\n" + text.Trim() + "\n"; | ||
text = text.Replace("\r\n", "\n").Replace("\n", Environment.NewLine); | ||
|
||
File.WriteAllText(outputPath, text, Encoding.UTF8); | ||
} | ||
|
||
private static string GenerateEnum(EnumDefinition enumDef, Bundle bundle) | ||
{ | ||
var values = new StringBuilder(); | ||
foreach (var v in enumDef.Values) | ||
{ | ||
values.AppendLine($"{AllCapsSnakeCaseToPascalCase(v.Name)} = {v.Value},"); | ||
} | ||
|
||
return $@"// Generated from {bundle.TypeToFile[enumDef.QualifiedName].CanonicalPath}({enumDef.SourceReference.Line},{enumDef.SourceReference.Column}) | ||
public enum {enumDef.Name} | ||
{{ | ||
{Indent(1, values.ToString().TrimEnd())} | ||
}}"; | ||
} | ||
|
||
private static string GenerateType(TypeDescription type, string content, Bundle bundle) | ||
{ | ||
var typeName = GetPascalCaseNameFromTypeName(type.QualifiedName); | ||
|
||
|
||
return $@"// Generated from {bundle.TypeToFile[type.QualifiedName].CanonicalPath}({type.SourceReference.Line},{type.SourceReference.Column}) | ||
public readonly struct {typeName} : global::System.IEquatable<{typeName}> | ||
{{ | ||
{Indent(1, content)} | ||
}}"; | ||
} | ||
} | ||
} |
Oops, something went wrong.