Skip to content

Commit

Permalink
globalとlocalのinterfaceの区別を作成した
Browse files Browse the repository at this point in the history
  • Loading branch information
KurisuJuha committed Jan 8, 2025
1 parent e40561e commit fd616d7
Show file tree
Hide file tree
Showing 3 changed files with 448 additions and 423 deletions.
29 changes: 15 additions & 14 deletions mooresmaster.Generator/Semantic/Semantics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,73 +17,73 @@ public class Semantics
public readonly List<(SwitchId switchId, ClassId typeId)> SwitchInheritList = new();
public readonly Dictionary<SwitchId, SwitchSemantics> SwitchSemanticsTable = new();
public readonly Dictionary<ClassId, TypeSemantics> TypeSemanticsTable = new();

public SwitchId AddSwitchSemantics(SwitchSemantics switchSemantics)
{
var id = SwitchId.New();
SwitchSemanticsTable.Add(id, switchSemantics);
return id;
}

public InterfaceId AddInterfaceSemantics(InterfaceSemantics interfaceSemantics)
{
var id = InterfaceId.New();
InterfaceSemanticsTable.Add(id, interfaceSemantics);
return id;
}

public ClassId AddTypeSemantics(TypeSemantics typeSemantics)
{
var id = ClassId.New();
TypeSemanticsTable.Add(id, typeSemantics);
SchemaTypeSemanticsTable.Add(typeSemantics.Schema, id);
return id;
}

public RootId AddRootSemantics(RootSemantics rootSemantics)
{
var id = RootId.New();
RootSemanticsTable.Add(id, rootSemantics);
return id;
}

public PropertyId AddPropertySemantics(PropertySemantics propertySemantics)
{
var id = PropertyId.New();
PropertySemanticsTable.Add(id, propertySemantics);
return id;
}

public InterfacePropertyId AddInterfacePropertySemantics(InterfacePropertySemantics interfacePropertySemantics)
{
var id = InterfacePropertyId.New();
InterfacePropertySemanticsTable.Add(id, interfacePropertySemantics);
InterfacePropertyIdTable.Add(interfacePropertySemantics, id);
return id;
}

public void AddInterfaceInterfaceImplementation(InterfaceId target, InterfaceId other)
{
if (!InterfaceInterfaceImplementationTable.TryGetValue(target, out var list))
{
list = new List<InterfaceId>();
InterfaceInterfaceImplementationTable[target] = list;
}

list.Add(other);
}

public void AddClassInterfaceImplementation(ClassId target, InterfaceId other)
{
if (!ClassInterfaceImplementationTable.TryGetValue(target, out var list))
{
list = new List<InterfaceId>();
ClassInterfaceImplementationTable[target] = list;
}

list.Add(other);
}

public Semantics Merge(Semantics other)
{
foreach (var inherit in other.SwitchInheritList) SwitchInheritList.Add(inherit);
Expand All @@ -97,10 +97,10 @@ public Semantics Merge(Semantics other)
foreach (var kvp in other.InterfacePropertyIdTable) InterfacePropertyIdTable.Add(kvp.Key, kvp.Value);
foreach (var kvp in other.InterfaceInterfaceImplementationTable) InterfaceInterfaceImplementationTable.Add(kvp.Key, kvp.Value);
foreach (var kvp in other.ClassInterfaceImplementationTable) ClassInterfaceImplementationTable.Add(kvp.Key, kvp.Value);

return this;
}

public Semantics AddTo(Semantics other)
{
return other.Merge(this);
Expand All @@ -121,9 +121,10 @@ public record RootSemantics(Schema Root, ClassId ClassId)
/// 親要素がinterfaceになることはない
/// </param>
/// <param name="Schema"></param>
public record TypeSemantics(PropertyId[] Properties, ISchema Schema)
public record TypeSemantics(PropertyId[] Properties, ISchema Schema, RootId RootId)
{
public PropertyId[] Properties = Properties;
public RootId RootId = RootId;
public ISchema Schema = Schema;
}

Expand Down
134 changes: 79 additions & 55 deletions mooresmaster.Generator/Semantic/SemanticsGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,109 +11,133 @@ public static class SemanticsGenerator
public static Semantics Generate(ImmutableArray<Schema> schemaArray, SchemaTable table)
{
var semantics = new Semantics();

foreach (var schema in schemaArray)
{
// ファイルに分けられているルートの要素はclassになる
// ただし、objectSchemaだった場合のちのGenerateで生成されるため、ここでは生成しない
if (table.Table[schema.InnerSchema] is ObjectSchema objectSchema)
{
var (innerSemantics, id) = Generate(objectSchema, table);
semantics.AddRootSemantics(new RootSemantics(schema, id));
var rootId = RootId.New();
var (innerSemantics, id) = Generate(objectSchema, table, rootId);
semantics.RootSemanticsTable.Add(rootId, new RootSemantics(schema, id));
innerSemantics.AddTo(semantics);
}
else
{
var typeSemantics = new TypeSemantics([], table.Table[schema.InnerSchema]);
var rootId = RootId.New();
var typeSemantics = new TypeSemantics([], table.Table[schema.InnerSchema], rootId);
var typeId = semantics.AddTypeSemantics(typeSemantics);
semantics.AddRootSemantics(new RootSemantics(schema, typeId));

Generate(table.Table[schema.InnerSchema], table).AddTo(semantics);
semantics.RootSemanticsTable.Add(rootId, new RootSemantics(schema, typeId));
Generate(table.Table[schema.InnerSchema], table, rootId).AddTo(semantics);
}

foreach (var defineInterface in schema.Interfaces)
GenerateInterfaceSemantics(defineInterface, schema, table).AddTo(semantics);
}

ResolveInterfaceInterfaceImplementations(semantics);
ResolveClassInterfaceImplementations(semantics);

return semantics;
}

private static void ResolveInterfaceInterfaceImplementations(Semantics semantics)
{
var interfaceTable = semantics.InterfaceSemanticsTable.ToDictionary(kvp => kvp.Value.Interface.InterfaceName, kvp => kvp.Key);

var globalInterfaceTable = semantics.InterfaceSemanticsTable
.Where(i => i.Value.Interface.IsGlobal)
.ToDictionary(kvp => kvp.Value.Interface.InterfaceName, kvp => kvp.Key);

foreach (var kvp in semantics.InterfaceSemanticsTable)
{
var target = kvp.Key;

var localInterfaceTable = semantics.InterfaceSemanticsTable
.Where(i => i.Value.Schema.SchemaId == kvp.Value.Schema.SchemaId)
.Where(i => !i.Value.Interface.IsGlobal)
.ToDictionary(kvp => kvp.Value.Interface.InterfaceName, kvp => kvp.Key);

foreach (var interfaceId in kvp.Value.Interface.ImplementationInterfaces)
{
var other = interfaceTable[interfaceId];
semantics.AddInterfaceInterfaceImplementation(target, other);
}
if (localInterfaceTable.TryGetValue(interfaceId, out var localOther))
{
semantics.AddInterfaceInterfaceImplementation(target, localOther);
}
else
{
var globalOther = globalInterfaceTable[interfaceId];
semantics.AddInterfaceInterfaceImplementation(target, globalOther);
}
}
}

private static void ResolveClassInterfaceImplementations(Semantics semantics)
{
var interfaceTable = semantics.InterfaceSemanticsTable.ToDictionary(kvp => kvp.Value.Interface.InterfaceName, kvp => kvp.Key);

var globalInterfaceTable = semantics.InterfaceSemanticsTable
.Where(i => i.Value.Interface.IsGlobal)
.ToDictionary(kvp => kvp.Value.Interface.InterfaceName, kvp => kvp.Key);

foreach (var kvp in semantics.TypeSemanticsTable)
{
if (kvp.Value.Schema is not ObjectSchema objectSchema) continue;

var localInterfaceTable = semantics.InterfaceSemanticsTable
.Where(i => i.Value.Schema.SchemaId == semantics.RootSemanticsTable[kvp.Value.RootId].Root.SchemaId)
.Where(i => !i.Value.Interface.IsGlobal)
.ToDictionary(kvp => kvp.Value.Interface.InterfaceName, kvp => kvp.Key);

var target = kvp.Key;

foreach (var interfaceName in objectSchema.InterfaceImplementations)
{
var interfaceId = interfaceTable[interfaceName];
semantics.AddClassInterfaceImplementation(target, interfaceId);
}
if (localInterfaceTable.TryGetValue(interfaceName, out var localOther))
{
semantics.AddClassInterfaceImplementation(target, localOther);
}
else
{
var globalOther = globalInterfaceTable[interfaceName];
semantics.AddClassInterfaceImplementation(target, globalOther);
}
}
}

private static Semantics GenerateInterfaceSemantics(DefineInterface defineInterface, Schema schema, SchemaTable table)
{
var semantics = new Semantics();

var interfaceId = InterfaceId.New();

List<InterfacePropertyId> propertyIds = new();
foreach (var property in defineInterface.Properties)
{
var propertySchema = property.Value;

var propertyId = semantics.AddInterfacePropertySemantics(new InterfacePropertySemantics(propertySchema, interfaceId));
propertyIds.Add(propertyId);
}

semantics.InterfaceSemanticsTable[interfaceId] = new InterfaceSemantics(
schema,
defineInterface,
propertyIds.ToArray()
);

return semantics;
}

private static Semantics Generate(ISchema schema, SchemaTable table)
private static Semantics Generate(ISchema schema, SchemaTable table, RootId rootId)
{
var semantics = new Semantics();

switch (schema)
{
case ArraySchema arraySchema:
Generate(table.Table[arraySchema.Items], table).AddTo(semantics);
Generate(table.Table[arraySchema.Items], table, rootId).AddTo(semantics);
break;
case ObjectSchema objectSchema:
var (innerSemantics, _) = Generate(objectSchema, table);
var (innerSemantics, _) = Generate(objectSchema, table, rootId);
innerSemantics.AddTo(semantics);
break;
case SwitchSchema oneOfSchema:
var (oneOfInnerSemantics, _) = Generate(oneOfSchema, table);
var (oneOfInnerSemantics, _) = Generate(oneOfSchema, table, rootId);
oneOfInnerSemantics.AddTo(semantics);
break;
case RefSchema:
Expand All @@ -131,31 +155,31 @@ private static Semantics Generate(ISchema schema, SchemaTable table)
default:
throw new ArgumentOutOfRangeException(nameof(schema));
}

return semantics;
}

private static (Semantics, SwitchId) Generate(SwitchSchema switchSchema, SchemaTable table)
private static (Semantics, SwitchId) Generate(SwitchSchema switchSchema, SchemaTable table, RootId rootId)
{
var semantics = new Semantics();

var interfaceId = SwitchId.New();
List<(SwitchPath, string, ClassId)> thenList = new();
foreach (var ifThen in switchSchema.IfThenArray)
{
Generate(table.Table[ifThen.Schema], table).AddTo(semantics);

Generate(table.Table[ifThen.Schema], table, rootId).AddTo(semantics);
var then = semantics.SchemaTypeSemanticsTable[table.Table[ifThen.Schema]];
semantics.SwitchInheritList.Add((interfaceId, then));
thenList.Add((ifThen.SwitchReferencePath, ifThen.When, then));
}

semantics.SwitchSemanticsTable.Add(interfaceId, new SwitchSemantics(switchSchema, thenList.ToArray()));

return (semantics, interfaceId);
}

private static (Semantics, ClassId) Generate(ObjectSchema objectSchema, SchemaTable table)
private static (Semantics, ClassId) Generate(ObjectSchema objectSchema, SchemaTable table, RootId rootId)
{
var semantics = new Semantics();
var typeId = ClassId.New();
Expand All @@ -166,7 +190,7 @@ private static (Semantics, ClassId) Generate(ObjectSchema objectSchema, SchemaTa
switch (schema)
{
case ObjectSchema innerObjectSchema:
var (objectInnerSemantics, objectInnerTypeId) = Generate(innerObjectSchema, table);
var (objectInnerSemantics, objectInnerTypeId) = Generate(innerObjectSchema, table, rootId);
objectInnerSemantics.AddTo(semantics);
properties.Add(semantics.AddPropertySemantics(
new PropertySemantics(
Expand All @@ -179,7 +203,7 @@ private static (Semantics, ClassId) Generate(ObjectSchema objectSchema, SchemaTa
));
break;
case SwitchSchema oneOfSchema:
var (oneOfInnerSemantics, oneOfInnerTypeId) = Generate(oneOfSchema, table);
var (oneOfInnerSemantics, oneOfInnerTypeId) = Generate(oneOfSchema, table, rootId);
oneOfInnerSemantics.AddTo(semantics);
properties.Add(semantics.AddPropertySemantics(
new PropertySemantics(
Expand All @@ -192,7 +216,7 @@ private static (Semantics, ClassId) Generate(ObjectSchema objectSchema, SchemaTa
));
break;
default:
Generate(table.Table[property.Value], table).AddTo(semantics);
Generate(table.Table[property.Value], table, rootId).AddTo(semantics);
properties.Add(semantics.AddPropertySemantics(
new PropertySemantics(
typeId,
Expand All @@ -205,11 +229,11 @@ private static (Semantics, ClassId) Generate(ObjectSchema objectSchema, SchemaTa
break;
}
}

var typeSemantics = new TypeSemantics(properties.ToArray(), objectSchema);
var typeSemantics = new TypeSemantics(properties.ToArray(), objectSchema, rootId);
semantics.TypeSemanticsTable[typeId] = typeSemantics;
semantics.SchemaTypeSemanticsTable[typeSemantics.Schema] = typeId;

return (semantics, typeId);
}
}
Loading

0 comments on commit fd616d7

Please sign in to comment.