Skip to content

Commit

Permalink
Extensions mostly working
Browse files Browse the repository at this point in the history
  • Loading branch information
carl-andersson-at-westermo committed May 29, 2024
1 parent b8af89d commit 321d269
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 49 deletions.
24 changes: 24 additions & 0 deletions YangParser/SemanticModel/BelongsTo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using YangParser.Parser;

namespace YangParser.SemanticModel;

public class BelongsTo : Statement
{
public BelongsTo(YangStatement statement) : base(statement)
{
if (statement.Keyword != Keyword)
throw new SemanticError($"Non-matching Keyword '{statement.Keyword}', expected {Keyword}", statement);
}

public const string Keyword = "belongs-to";

public override ChildRule[] PermittedChildren { get; } =
[
new ChildRule(Prefix.Keyword, Cardinality.Required)
];

public override string ToCode()
{
return string.Empty;
}
}
27 changes: 17 additions & 10 deletions YangParser/SemanticModel/DefaultValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public override string ToCode()
return GetTypeSpecification(prefix, value, type);
}

private string GetTypeSpecification(string prefix, string value, Type type)
private string GetTypeSpecification(string prefix, string value, Type type, bool chained = false)
{
if (string.IsNullOrEmpty(value))
{
Expand Down Expand Up @@ -54,10 +54,10 @@ private string GetTypeSpecification(string prefix, string value, Type type)
case "decimal64":
return Argument;
case "union":
if (onlyNumbers.Match(Argument).Success)
{
return $"new({Argument})";
}
// if (onlyNumbers.Match(Argument).Success)
// {
// return $"new({Argument})";
// }

var enumeration = type.SearchDownwards<Enum>(Argument);
if (enumeration != null)
Expand All @@ -73,15 +73,22 @@ private string GetTypeSpecification(string prefix, string value, Type type)

foreach (var subType in type.Children.OfType<Type>())
{
var possible = GetTypeSpecification(prefix, value, subType);
var possible = GetTypeSpecification(prefix, value, subType, true);
if (possible != $"new(\"{Argument}\")")
{
if (possible == $"\"{Argument}\"")
{
return $"new(\"{Argument}\")";
}

return possible == Argument ? $"new({Argument})" : possible;
if (BuiltinTypeReference.IsBuiltin(subType, out var typeName, out _))
{
return chained
? "new(" + possible + $"/*{typeName}*/" + ")"
: possible + $"/*{typeName}*/";
}

return "new(new " + MakeName(subType.Argument) + "(" + possible + "))";
}
}

Expand All @@ -96,16 +103,16 @@ private string GetTypeSpecification(string prefix, string value, Type type)
prefix = type.Argument.Prefix(out _);
}

return GetTypeSpecification(prefix, value, source.GetChild<Type>());
return GetTypeSpecification(prefix, value, source.GetChild<Type>(), true);
}

if (onlyNumbers.Match(Argument).Success)
{
return $"new({Argument})";
return $"new(/*{type.Argument}*/{Argument})";
}

Log.Write($"Fallback for 'default {Argument}' to type {type}");
return $"new(\"{Argument}\")";
return $"new(/*{type.Argument}*/\"{Argument}\")";
}
}

Expand Down
18 changes: 12 additions & 6 deletions YangParser/SemanticModel/Extension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,24 @@ public Extension(YangStatement statement) : base(statement)
public override string ToCode()
{
var arg = Children.FirstOrDefault(child => child is Argument);
var argStr = arg is null
var vargName = arg?.Argument;
if (vargName == Argument)
{
if (Argument != "value") vargName = "value";
else vargName = "_" + vargName;
}

var argStr = vargName is null
? string.Empty
: $$"""
public string {{MakeName(arg.Argument)}} { get; set; }
public {{MakeName(Argument)}}Attribute(string {{MakeName(arg.Argument)}})
public string {{MakeName(vargName)}} { get; set; }
public {{MakeName(Argument)}}(string {{MakeName(vargName)}})
{
this.{{MakeName(arg.Argument)}} = {{MakeName(arg.Argument)}};
this.{{MakeName(vargName)}} = {{MakeName(vargName)}};
}
""";
return $$"""
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class {{MakeName(Argument)}}Attribute : Attribute
public class {{MakeName(Argument)}}
{
{{Indent(argStr)}}
}
Expand Down
59 changes: 59 additions & 0 deletions YangParser/SemanticModel/ExtensionReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Linq;
using YangParser.Parser;

namespace YangParser.SemanticModel;

public class ExtensionReference : Statement
{
public ExtensionReference(YangStatement statement) : base(statement, false)
{
SourceModulePrefix = statement.Prefix;
ExtensionName = statement.Keyword;
Argument = statement.Argument?.ToString() ?? string.Empty;
}

public string ExtensionName { get; }

public string SourceModulePrefix { get; }

public override string ToCode()
{
var sourceModule = this.FindSourceFor(SourceModulePrefix);
var source = sourceModule?.Extensions.FirstOrDefault(e => e.Argument == ExtensionName);
if (source is null)
{
throw new SemanticError(
$"Could not find source extension for {SourceModulePrefix}:{ExtensionName} in module {sourceModule}",
Source);
}

var children = Children.Select(c => c.ToCode()).ToArray();
var inheritance = string.IsNullOrWhiteSpace(SourceModulePrefix)
? MakeName(ExtensionName)
: SourceModulePrefix + ':' + MakeName(ExtensionName);
var classNameSource = Argument.Contains('/') ? ExtensionName + Argument.GetHashCode() : Argument;
if (source.TryGetChild<Argument>(out _))
{
return $$"""
public {{MakeName(classNameSource)}}Extension {{MakeName(classNameSource)}}ExtensionValue { get; }
{{DescriptionString}}{{AttributeString}}
public class {{MakeName(classNameSource)}}Extension : {{inheritance}}
{
public {{MakeName(classNameSource)}}Extension() : base("{{SingleLine(Argument).Replace("\n", "\\\n")}}")
{
}
{{Indent(string.Join("\n", children))}}
}
""";
}

return $$"""
public {{MakeName(classNameSource)}}Extension {{MakeName(classNameSource)}}ExtensionValue { get; }
{{DescriptionString}}{{AttributeString}}
public class {{MakeName(classNameSource)}}Extension : {{inheritance}}
{
{{Indent(string.Join("\n", children))}}
}
""";
}
}
7 changes: 7 additions & 0 deletions YangParser/SemanticModel/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public Module(YangStatement statement) : base(statement)
typeDefinition.Parent?.Replace(typeDefinition, []);
}
}

if (child is Extension extension)
{
Extensions.Add(extension);
}
}
}

Expand Down Expand Up @@ -187,6 +192,7 @@ private void ExpandPrefixes(IStatement statement)
public List<Grouping> Groupings { get; } = [];
public List<Augment> Augments { get; } = [];
public List<Import> Imports { get; } = [];
public List<Extension> Extensions { get; } = [];
public List<TypeDefinition> HiddenDefinitions { get; } = [];

// public string Capability
Expand All @@ -213,5 +219,6 @@ public interface ITopLevelStatement : IStatement
public List<Grouping> Groupings { get; }
public List<Augment> Augments { get; }
public List<Import> Imports { get; }
public List<Extension> Extensions { get; }
Dictionary<string, string> ImportedModules { get; }
}
2 changes: 1 addition & 1 deletion YangParser/SemanticModel/Statement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static string MakeName(string argument)

var prefix = argument.Prefix(out var value);
var addColon = !prefix.Contains('.') && !string.IsNullOrWhiteSpace(prefix);
foreach (var section in value.Split('-', ' ', '/', '.'))
foreach (var section in value.Split('-', ' ', '/', '.','^'))
{
output.Append(Capitalize(section));
}
Expand Down
13 changes: 1 addition & 12 deletions YangParser/SemanticModel/StatementFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,13 @@

namespace YangParser.SemanticModel;

public class KeywordReference : Statement
{
public KeywordReference(YangStatement statement) : base(statement, false)
{
ReferenceNamespace = statement.Prefix;
Argument = statement.Argument?.ToString() ?? string.Empty;
}

public string ReferenceNamespace { get; set; }
}

public static class StatementFactory
{
public static IStatement Create(YangStatement source)
{
if (!string.IsNullOrWhiteSpace(source.Prefix))
{
return new KeywordReference(source);
return new ExtensionReference(source);
}

return source.Keyword switch
Expand Down
38 changes: 18 additions & 20 deletions YangParser/SemanticModel/Submodule.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using YangParser.Generator;
Expand All @@ -9,6 +8,7 @@ namespace YangParser.SemanticModel;
public class Submodule : Statement, ITopLevelStatement
{
public Dictionary<string, string> ImportedModules { get; } = [];

public Submodule(YangStatement statement) : base(statement)
{
if (statement.Keyword != Keyword)
Expand All @@ -20,14 +20,17 @@ public Submodule(YangStatement statement) : base(statement)
{
Uses.Add(use);
}

if (child is Grouping grouping)
{
Groupings.Add(grouping);
}

if (child is Augment augment)
{
Augments.Add(augment);
}

if (child is Import import)
{
Imports.Add(import);
Expand All @@ -36,6 +39,7 @@ public Submodule(YangStatement statement) : base(statement)
Usings[prefix] = reference;
ImportedModules[prefix] = import.Argument;
}

if (child is TypeDefinition typeDefinition)
{
if (typeDefinition.IsUnderGrouping())
Expand All @@ -44,18 +48,25 @@ public Submodule(YangStatement statement) : base(statement)
typeDefinition.Parent?.Replace(typeDefinition, []);
}
}

if (child is Extension extension)
{
Extensions.Add(extension);
}
}
}

public List<TypeDefinition> HiddenDefinitions { get; } = [];
private bool IsExpanded = false;

public void Expand()
{
if (IsExpanded) return;
foreach (var child in Children)
{
ExpandPrefixes(child);
}

IsExpanded = true;
}

Expand Down Expand Up @@ -100,11 +111,12 @@ public override string ToCode()

private void ExpandPrefixes(IStatement statement)
{

if (!statement.Argument.Contains(" "))
{
var argPrefix = statement.Argument.Split(':');
if (argPrefix.Length > 1 && argPrefix.Length < 3) //ignore cases where there are multiple colons, since that's an XML-namespace reference
if (argPrefix.Length > 1 &&
argPrefix.Length <
3) //ignore cases where there are multiple colons, since that's an XML-namespace reference
{
if (Usings.ContainsKey(argPrefix[0]))
{
Expand All @@ -116,30 +128,16 @@ private void ExpandPrefixes(IStatement statement)
}
}
}

foreach (var child in statement.Children)
{
ExpandPrefixes(child);
}
}

public List<Uses> Uses { get; } = [];
public List<Grouping> Groupings { get; } = [];
public List<Augment> Augments { get; } = [];
public List<Extension> Extensions { get; } = [];
public List<Import> Imports { get; } = [];

}

public class BelongsTo : Statement
{
public BelongsTo(YangStatement statement) : base(statement)
{
if (statement.Keyword != Keyword)
throw new SemanticError($"Non-matching Keyword '{statement.Keyword}', expected {Keyword}", statement);
}

public const string Keyword = "belongs-to";

public override ChildRule[] PermittedChildren { get; } =
[
new ChildRule(Prefix.Keyword, Cardinality.Required)
];
}

0 comments on commit 321d269

Please sign in to comment.