< Summary

Class:NanoCLang.Entities.FunctionSchema
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\FunctionSchema.cs
Covered lines:45
Uncovered lines:12
Coverable lines:57
Total lines:215
Line coverage:78.9% (45 of 57)
Covered branches:35
Total branches:54
Branch coverage:64.8% (35 of 54)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Locations()100%1100%
get_Parameters()100%1100%
get_Heap()100%1100%
get_World()50%2100%
get_HasWorld()100%10%
get_Arity()100%10%
WellFormed()83.33%690.9%
GetEnvironment()100%1100%
GetEnvironment(...)100%10%
Tokens()73.52%34100%
Equals(...)100%1100%
Equals(...)50%8100%
GetHashCode()0%40%
op_Equality(...)100%1100%
op_Inequality(...)100%1100%

File(s)

C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\FunctionSchema.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 a function schema that contains unbuilt heaps.
 9    /// </summary>
 10    public class RawFunctionSchema : Base, IEquatable<RawFunctionSchema?>, ICallable {
 11        /// <summary>
 12        /// Creates a new instance of a function schema.
 13        /// </summary>
 14        /// <param name="locations">Locations that the function operates on.</param>
 15        /// <param name="parameters">Parameters and their types that the function expects.</param>
 16        /// <param name="heap">Input heap that the function modifies.</param>
 17        /// <param name="world">World being the return type and heap of the function or null to infer the world.</param>
 18        public RawFunctionSchema(string[] locations, TypeParameter[] parameters, IHeapElement[] heap, RawWorld? world) {
 19            Locations = locations;
 20            Parameters = parameters;
 21            Heap = heap;
 22            this.world = world;
 23        }
 24        /// <summary>
 25        /// Locations that the function operates on.
 26        /// </summary>
 27        public string[] Locations { get; }
 28        /// <summary>
 29        /// Parameters and their types that the function expects.
 30        /// </summary>
 31        public TypeParameter[] Parameters { get; }
 32        /// <summary>
 33        /// Input heap that the function modifies.
 34        /// </summary>
 35        public IHeapElement[] Heap { get; }
 36        /// <summary>
 37        /// World being the return type and heap of the function.
 38        /// </summary>
 39        public RawWorld World => world ?? throw new InvalidOperationException("World of the function is unknown!");
 40        private RawWorld? world;
 41        /// <summary>
 42        /// Fix the world to the schema after inferring.
 43        /// </summary>
 44        /// <param name="world">World to set to the schema.</param>
 45        public RawWorld FixWorld(RawWorld world) {
 46            if (this.world is null)
 47                VerbConsole.WriteLine(VerbosityLevel.Default, $"Schema world was inferred as {world}!");
 48            return this.world ??= world;
 49        }
 50        /// <summary>
 51        /// Gets a boolean that shows if the schema was already assigned a world by the parser or the inferrer.
 52        /// </summary>
 53        public bool HasWorld => !(world is null);
 54        /// <summary>
 55        /// Gets the arity of the function, being the number of expected parameters.
 56        /// </summary>
 57        public int Arity => Parameters.Length;
 58        /// <summary>
 59        /// Creates the function schema represented by the raw schema by expanding structures with the environment <para
 60        /// </summary>
 61        /// <param name="phi">Global environment to expand structures with.</param>
 62        /// <param name="links">Structure location links.</param>
 63        /// <returns>Built function schema.</returns>
 64        public FunctionSchema Build(GlobalEnvironment phi, out IEnumerable<KeyValuePair<string, string>> links) => new F
 65        /// <inheritdoc cref="Build(GlobalEnvironment, out IEnumerable{KeyValuePair{string, string}})"/>
 66        public FunctionSchema Build(GlobalEnvironment phi) => new FunctionSchema(Locations, Parameters, Heap.GenerateHea
 67        /// <inheritdoc/>
 68        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 69            yield return "[";
 70            foreach (var tk in StringFormatterToken.Separated(Locations, args.ParameterListSeparator)) yield return tk;
 71            yield return "]";
 72            if (args.NewlinesBeforeFunctionParams <= 0 && args.SpaceBetweenLocationsAndFunctionParams) yield return " ";
 73            for (int i = 0; i < args.NewlinesBeforeFunctionParams; i++) yield return new NewLineToken();
 74            yield return "(";
 75            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 76            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 77            yield return ")";
 78            foreach (var tk in RawWorld.WorldOperator(args)) yield return tk;
 79            foreach (var tk in Heap.Tokens(args)) yield return tk;
 80            if (world is null) yield break;
 81            for (int i = 0; i < args.NewlinesBeforeFunctionWorld; i++) yield return new NewLineToken();
 82            if (args.NewlinesBeforeFunctionWorld <= 0 && args.SpaceBeforeFunctionWorld) yield return " ";
 83            yield return "->";
 84            for (int i = 0; i < args.NewlinesAfterFunctionWorld; i++) yield return new NewLineToken();
 85            if (args.NewlinesAfterFunctionWorld <= 0 && args.SpaceAfterFunctionWorld) yield return " ";
 86            foreach (var tk in world.Tokens(args)) yield return tk;
 87        }
 88        #region Equality checks
 89        /// <inheritdoc/>
 90        public override bool Equals(object? obj) => Equals(obj as RawFunctionSchema);
 91        /// <inheritdoc/>
 92        public bool Equals(RawFunctionSchema? other) => !(other is null) && Locations.SequenceEqual(other.Locations) && 
 93        /// <inheritdoc/>
 94        public override int GetHashCode() {
 95            var hash = new HashCode();
 96            foreach (var loc in Locations) hash.Add(loc);
 97            foreach (var param in Parameters) hash.Add(param);
 98            foreach (var heapelem in Heap) hash.Add(heapelem);
 99            hash.Add(World);
 100            return hash.ToHashCode();
 101        }
 102        /// <inheritdoc/>
 103        public static bool operator ==(RawFunctionSchema? left, RawFunctionSchema? right) => EqualityComparer<RawFunctio
 104        /// <inheritdoc/>
 105        public static bool operator !=(RawFunctionSchema? left, RawFunctionSchema? right) => !(left == right);
 106        #endregion
 107    }
 108    /// <summary>
 109    /// Provides a class for a function schema.
 110    /// </summary>
 111    public class FunctionSchema : Base, IEquatable<FunctionSchema?>, ICallable {
 112        /// <summary>
 113        /// Creates a new instance of a function schema.
 114        /// </summary>
 115        /// <param name="locations">Locations that the function operates on.</param>
 116        /// <param name="parameters">Parameters and their types that the function expects.</param>
 117        /// <param name="heap">Input heap that the function modifies.</param>
 118        /// <param name="world">World being the return type and heap of the function or null to infer the world.</param>
 92119        public FunctionSchema(string[] locations, TypeParameter[] parameters, Heap heap, World? world) {
 46120            Locations = locations;
 46121            Parameters = parameters;
 46122            Heap = heap;
 46123            this.world = world;
 46124        }
 125        /// <summary>
 126        /// Locations that the function operates on.
 127        /// </summary>
 18128        public string[] Locations { get; }
 129        /// <summary>
 130        /// Parameters and their types that the function expects.
 131        /// </summary>
 99132        public TypeParameter[] Parameters { get; }
 133        /// <summary>
 134        /// Input heap that the function modifies.
 135        /// </summary>
 115136        public Heap Heap { get; }
 137        /// <summary>
 138        /// World being the return type and heap of the function.
 139        /// </summary>
 37140        public World World => world ?? throw new InvalidOperationException("World of the function is unknown!");
 141        private readonly World? world;
 142        /// <summary>
 143        /// Gets a boolean that shows if the schema was already assigned a world by the parser or the inferrer.
 144        /// </summary>
 0145        public bool HasWorld => !(world is null);
 146        /// <summary>
 147        /// Gets the arity of the function, being the number of expected parameters.
 148        /// </summary>
 0149        public int Arity => Parameters.Length;
 150        /// <summary>
 151        /// Checks if the function schema is well-formed and raises an exception if it is ill-formed.
 152        /// </summary>
 153        /// <exception cref="IllFormedException">Function schema is ill-formed.</exception>
 21154        public void WellFormed() {
 21155            VerbConsole.WriteLine(VerbosityLevel.Default, "WF-Schema");
 21156            var gamma = new LocalEnvironment();
 141157            foreach (var param in Parameters) {
 26158                param.Type.WellFormed(gamma, Heap);
 26159                if (!gamma.TryAdd(param.Name, param.Type))
 0160                    throw new IllFormedException(param, $"Parameters must have distinct names: {param.Name} is already u
 26161            }
 21162            Heap.WellFormed(gamma);
 21163            world?.WellFormed(gamma);
 21164        }
 165        /// <inheritdoc cref="GetEnvironment(TypeParameter[])"/>
 166        public LocalEnvironment GetEnvironment()
 73167            => new LocalEnvironment(Parameters.ToDictionary(i => i.Name, i => i.Type));
 168        /// <summary>
 169        /// Creates a new local environment from the type parameters that represent the bindings in the function body.
 170        /// </summary>
 171        /// <returns>Local environment of the function parameters.</returns>
 172        internal static LocalEnvironment GetEnvironment(TypeParameter[] parameters)
 0173            => new LocalEnvironment(parameters.ToDictionary(i => i.Name, i => i.Type));
 174        /// <inheritdoc/>
 1175        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 1176            yield return "[";
 6177            foreach (var tk in StringFormatterToken.Separated(Locations, args.ParameterListSeparator)) yield return tk;
 1178            yield return "]";
 1179            if (args.NewlinesBeforeFunctionParams <= 0 && args.SpaceBetweenLocationsAndFunctionParams) yield return " ";
 5180            for (int i = 0; i < args.NewlinesBeforeFunctionParams; i++) yield return new NewLineToken();
 1181            yield return "(";
 324182            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 1183            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 1184            yield return ")";
 12185            foreach (var tk in RawWorld.WorldOperator(args)) yield return tk;
 84186            foreach (var tk in Heap.Tokens(args)) yield return tk;
 1187            if (world is null) yield break;
 5188            for (int i = 0; i < args.NewlinesBeforeFunctionWorld; i++) yield return new NewLineToken();
 1189            if (args.NewlinesBeforeFunctionWorld <= 0 && args.SpaceBeforeFunctionWorld) yield return " ";
 1190            yield return "->";
 2191            for (int i = 0; i < args.NewlinesAfterFunctionWorld; i++) yield return new NewLineToken();
 2192            if (args.NewlinesAfterFunctionWorld <= 0 && args.SpaceAfterFunctionWorld) yield return " ";
 132193            foreach (var tk in world.Tokens(args)) yield return tk;
 1194        }
 195        #region Equality Checks
 196        /// <inheritdoc/>
 1197        public override bool Equals(object? obj) => Equals(obj as FunctionSchema);
 198        /// <inheritdoc/>
 1199        public bool Equals(FunctionSchema? other) => other != null && Locations.SequenceEqual(other.Locations) && Parame
 200        /// <inheritdoc/>
 0201        public override int GetHashCode() {
 0202            var hash = new HashCode();
 0203            foreach (var i in Locations) hash.Add(i);
 0204            foreach (var i in Parameters) hash.Add(i);
 0205            hash.Add(Heap);
 0206            hash.Add(world);
 0207            return hash.ToHashCode();
 0208        }
 209        /// <inheritdoc/>
 1210        public static bool operator ==(FunctionSchema? left, FunctionSchema? right) => EqualityComparer<FunctionSchema?>
 211        /// <inheritdoc/>
 1212        public static bool operator !=(FunctionSchema? left, FunctionSchema? right) => !(left == right);
 213        #endregion
 214    }
 215}