< Summary

Class:NanoCLang.Entities.StructDefinition
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\StructDefinition.cs
Covered lines:69
Uncovered lines:16
Coverable lines:85
Total lines:137
Line coverage:81.1% (69 of 85)
Covered branches:44
Total branches:72
Branch coverage:61.1% (44 of 72)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Locations()100%1100%
get_Parameters()100%1100%
get_Dependencies()100%1100%
get_Fields()100%1100%
WellFormed(...)100%10100%
GetSubstitutor()83.33%690%
Tokens()64.28%4283.33%
Equals(...)100%10%
Equals(...)50%8100%
GetHashCode()0%80%
op_Equality(...)100%1100%
op_Inequality(...)100%1100%

File(s)

C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\StructDefinition.cs

#LineLine coverage
 1using NanoCLang.Environemnts;
 2using System;
 3using System.Collections.Generic;
 4using System.Linq;
 5
 6namespace NanoCLang.Entities {
 7    /// <summary>
 8    /// Provides a class for structure definitions.
 9    /// </summary>
 10    public class StructDefinition : Base, IEquatable<StructDefinition?>, ICallable {
 11        /// <summary>
 12        /// Creates a new instance of a structure definition from a list of structure fields.
 13        /// </summary>
 14        /// <param name="locations">Additional locations that the structure operates on.</param>
 15        /// <param name="args">Parameters that the structure invariant depends on.</param>
 16        /// <param name="dependencies">Calls to other structs that the structure depends on.</param>
 17        /// <param name="fields">Fields of the structure.</param>
 5218        public StructDefinition(string[] locations, TypeParameter[] args, FunctionCallExpression[] dependencies, StructF
 2619            Locations = locations;
 2620            Parameters = args;
 2621            Dependencies = dependencies;
 2622            Fields = fields;
 2623        }
 24        /// <summary>
 25        /// Additional locations that the struct operates on.
 26        /// </summary>
 6927        public string[] Locations { get; }
 28        /// <summary>
 29        /// Parameters that the structure invariant depends on.
 30        /// </summary>
 8831        public TypeParameter[] Parameters { get; }
 32        /// <summary>
 33        /// List of structs that the struct depends on.
 34        /// </summary>
 7835        public FunctionCallExpression[] Dependencies { get; }
 36        /// <summary>
 37        /// Member fields of the structure.
 38        /// </summary>
 16839        public StructField[] Fields { get; }
 40        /// <summary>
 41        /// Checks if the structure definition is well-formed and raises an exception if it is ill-formed.
 42        /// </summary>
 43        /// <param name="phi">Environemt to check the structure definition with.</param>
 44        /// <exception cref="IllFormedException">structure definition is ill-formed.</exception>
 1045        public void WellFormed(GlobalEnvironment phi) {
 1046            var gamma = new LocalEnvironment();
 1047            var emptyHeap = new Heap();
 4448            foreach (var param in Parameters) {
 49                // check with empty heap because structures cannot depend on heaps that are external
 550                param.Type.WellFormed(gamma, emptyHeap);
 551                if (!gamma.TryAdd(param.Name, param.Type))
 152                    throw new IllFormedException(param, $"Structure parameters must have distinct names: {param.Name} is
 453            }
 2454            var collision = Fields.Select(i => i.Name).Intersect(Parameters.Select(i => i.Name)).ToList();
 955            if (collision.Any())
 156                throw new IllFormedException(this, $"Cannot declare fields with name(s) {string.Join(", ", collision)}, 
 3057            var fieldcollision = Fields.GroupBy(i => i.Name).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
 858            if (fieldcollision.Any())
 159                throw new IllFormedException(this, $"Cannot declare fields with name(s) {string.Join(", ", fieldcollisio
 60
 3261            foreach (var dep in Dependencies) dep.GetBindings(phi, out _);
 662        }
 63        /// <summary>
 64        /// Gets a substitutor object that replaces variables that refer to struct members in the heap with their block 
 65        /// </summary>
 66        /// <returns>Heap substitutor.</returns>
 7167        public Substitutor GetSubstitutor() {
 7168            var theta = new Substitutor();
 51069            foreach (var field in Fields) {
 9970                if (theta.Variables.ContainsKey(field.Name))
 071                    throw new IllFormedException(field, $"Cannot use field name {field.Name} twice in one structure!");
 9972                else if (field.Binding.Index is SingletonIndex i)
 5973                    theta.Variables[field.Name] = new VariableExpression(Heap.OffsetVar(i.Offset));
 9974            }
 7175            return theta;
 7176        }
 77
 78        /// <inheritdoc/>
 479        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 80            // LBC (fields += structField)+ RBC COLON LBA locations = identifierList RBA
 481            yield return "struct";
 482            if (args.SpaceAfterFunKeyword) yield return " ";
 483            yield return "(";
 15084            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 485            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 486            yield return ")";
 687            if (Dependencies.Length > 0) {
 288                yield return " ";
 289                yield return ":";
 290                yield return " ";
 4291                foreach (var tk in StringFormatterToken.Separated(Dependencies, args, args.ParameterListSeparator)) yiel
 292            }
 493            if (args.NewlineBeforeFunctionBody) {
 094                yield return new NewLineToken();
 095                if (args.IndentFunctionBodyOpenBrace) yield return new string(' ', args.FunctionBodyIndent);
 896            } else if (args.SpaceBeforeFunctionBody) yield return " ";
 497            yield return "{";
 52698            foreach (var tk in StringFormatterToken.Indented(args.FunctionBodyIndent, () => Fields.SelectMany(i => i.Tok
 899            if (args.NewlineBeforeFunctionBodyCloseBrace) {
 4100                yield return new NewLineToken();
 4101                if (args.IndentFunctionBodyCloseBrace) yield return new string(' ', args.FunctionBodyIndent);
 4102            } else if (args.SpaceBeforeFunctionBodyCloseBrace) yield return " ";
 4103            yield return "}";
 4104            if (args.NewlineBeforeFunctionSchemaColon) {
 0105                yield return new NewLineToken();
 0106                if (args.IndentFunctionSchemaColon) yield return new string(' ', args.FunctionSchemaIndent);
 8107            } else if (args.SpaceBeforeFunctionSchemaColon) yield return " ";
 4108            yield return ":";
 4109            if (args.NewlineAfterFunctionSchemaColon) {
 0110                yield return new NewLineToken();
 0111                if (args.IndentFunctionSchema) yield return new string(' ', args.FunctionSchemaIndent);
 8112            } else if (args.SpaceAfterFunctionSchemaColon) yield return " ";
 4113            yield return "[";
 36114            foreach (var tk in StringFormatterToken.Separated(Locations, args.ParameterListSeparator)) yield return tk;
 4115            yield return "]";
 4116        }
 117        #region Equality checks
 118        /// <inheritdoc/>
 0119        public override bool Equals(object? obj) => Equals(obj as StructDefinition);
 120        /// <inheritdoc/>
 4121        public bool Equals(StructDefinition? other) => other != null && Locations.SequenceEqual(other.Locations) && Para
 122        /// <inheritdoc/>
 0123        public override int GetHashCode() {
 0124            var hash = new HashCode();
 0125            foreach (var i in Locations) hash.Add(i);
 0126            foreach (var i in Parameters) hash.Add(i);
 0127            foreach (var i in Dependencies) hash.Add(i);
 0128            foreach (var i in Fields) hash.Add(i);
 0129            return hash.ToHashCode();
 0130        }
 131        /// <inheritdoc/>
 4132        public static bool operator ==(StructDefinition? left, StructDefinition? right) => EqualityComparer<StructDefini
 133        /// <inheritdoc/>
 4134        public static bool operator !=(StructDefinition? left, StructDefinition? right) => !(left == right);
 135        #endregion
 136    }
 137}