< Summary

Class:NanoCLang.Entities.RawFunctionSchema
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\FunctionSchema.cs
Covered lines:41
Uncovered lines:10
Coverable lines:51
Total lines:215
Line coverage:80.3% (41 of 51)
Covered branches:37
Total branches:58
Branch coverage:63.7% (37 of 58)

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%
FixWorld(...)100%4100%
get_HasWorld()100%1100%
get_Arity()100%1100%
Build(...)100%2100%
Build(...)50%2100%
Tokens()73.52%34100%
Equals(...)100%1100%
Equals(...)50%8100%
GetHashCode()0%60%
op_Equality(...)100%10%
op_Inequality(...)100%10%

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>
 12818        public RawFunctionSchema(string[] locations, TypeParameter[] parameters, IHeapElement[] heap, RawWorld? world) {
 6419            Locations = locations;
 6420            Parameters = parameters;
 6421            Heap = heap;
 6422            this.world = world;
 6423        }
 24        /// <summary>
 25        /// Locations that the function operates on.
 26        /// </summary>
 11127        public string[] Locations { get; }
 28        /// <summary>
 29        /// Parameters and their types that the function expects.
 30        /// </summary>
 15731        public TypeParameter[] Parameters { get; }
 32        /// <summary>
 33        /// Input heap that the function modifies.
 34        /// </summary>
 11135        public IHeapElement[] Heap { get; }
 36        /// <summary>
 37        /// World being the return type and heap of the function.
 38        /// </summary>
 6939        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>
 2145        public RawWorld FixWorld(RawWorld world) {
 2146            if (this.world is null)
 347                VerbConsole.WriteLine(VerbosityLevel.Default, $"Schema world was inferred as {world}!");
 2148            return this.world ??= world;
 2149        }
 50        /// <summary>
 51        /// Gets a boolean that shows if the schema was already assigned a world by the parser or the inferrer.
 52        /// </summary>
 2253        public bool HasWorld => !(world is null);
 54        /// <summary>
 55        /// Gets the arity of the function, being the number of expected parameters.
 56        /// </summary>
 157        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>
 2164        public FunctionSchema Build(GlobalEnvironment phi, out IEnumerable<KeyValuePair<string, string>> links) => new F
 65        /// <inheritdoc cref="Build(GlobalEnvironment, out IEnumerable{KeyValuePair{string, string}})"/>
 2566        public FunctionSchema Build(GlobalEnvironment phi) => new FunctionSchema(Locations, Parameters, Heap.GenerateHea
 67        /// <inheritdoc/>
 2168        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 2169            yield return "[";
 14770            foreach (var tk in StringFormatterToken.Separated(Locations, args.ParameterListSeparator)) yield return tk;
 2171            yield return "]";
 2172            if (args.NewlinesBeforeFunctionParams <= 0 && args.SpaceBetweenLocationsAndFunctionParams) yield return " ";
 10573            for (int i = 0; i < args.NewlinesBeforeFunctionParams; i++) yield return new NewLineToken();
 2174            yield return "(";
 226575            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 2176            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 2177            yield return ")";
 25278            foreach (var tk in RawWorld.WorldOperator(args)) yield return tk;
 119779            foreach (var tk in Heap.Tokens(args)) yield return tk;
 2180            if (world is null) yield break;
 10581            for (int i = 0; i < args.NewlinesBeforeFunctionWorld; i++) yield return new NewLineToken();
 2182            if (args.NewlinesBeforeFunctionWorld <= 0 && args.SpaceBeforeFunctionWorld) yield return " ";
 2183            yield return "->";
 4284            for (int i = 0; i < args.NewlinesAfterFunctionWorld; i++) yield return new NewLineToken();
 4285            if (args.NewlinesAfterFunctionWorld <= 0 && args.SpaceAfterFunctionWorld) yield return " ";
 299486            foreach (var tk in world.Tokens(args)) yield return tk;
 2187        }
 88        #region Equality checks
 89        /// <inheritdoc/>
 190        public override bool Equals(object? obj) => Equals(obj as RawFunctionSchema);
 91        /// <inheritdoc/>
 2292        public bool Equals(RawFunctionSchema? other) => !(other is null) && Locations.SequenceEqual(other.Locations) && 
 93        /// <inheritdoc/>
 094        public override int GetHashCode() {
 095            var hash = new HashCode();
 096            foreach (var loc in Locations) hash.Add(loc);
 097            foreach (var param in Parameters) hash.Add(param);
 098            foreach (var heapelem in Heap) hash.Add(heapelem);
 099            hash.Add(World);
 0100            return hash.ToHashCode();
 0101        }
 102        /// <inheritdoc/>
 0103        public static bool operator ==(RawFunctionSchema? left, RawFunctionSchema? right) => EqualityComparer<RawFunctio
 104        /// <inheritdoc/>
 0105        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>
 119        public FunctionSchema(string[] locations, TypeParameter[] parameters, Heap heap, World? world) {
 120            Locations = locations;
 121            Parameters = parameters;
 122            Heap = heap;
 123            this.world = world;
 124        }
 125        /// <summary>
 126        /// Locations that the function operates on.
 127        /// </summary>
 128        public string[] Locations { get; }
 129        /// <summary>
 130        /// Parameters and their types that the function expects.
 131        /// </summary>
 132        public TypeParameter[] Parameters { get; }
 133        /// <summary>
 134        /// Input heap that the function modifies.
 135        /// </summary>
 136        public Heap Heap { get; }
 137        /// <summary>
 138        /// World being the return type and heap of the function.
 139        /// </summary>
 140        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>
 145        public bool HasWorld => !(world is null);
 146        /// <summary>
 147        /// Gets the arity of the function, being the number of expected parameters.
 148        /// </summary>
 149        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>
 154        public void WellFormed() {
 155            VerbConsole.WriteLine(VerbosityLevel.Default, "WF-Schema");
 156            var gamma = new LocalEnvironment();
 157            foreach (var param in Parameters) {
 158                param.Type.WellFormed(gamma, Heap);
 159                if (!gamma.TryAdd(param.Name, param.Type))
 160                    throw new IllFormedException(param, $"Parameters must have distinct names: {param.Name} is already u
 161            }
 162            Heap.WellFormed(gamma);
 163            world?.WellFormed(gamma);
 164        }
 165        /// <inheritdoc cref="GetEnvironment(TypeParameter[])"/>
 166        public LocalEnvironment GetEnvironment()
 167            => 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)
 173            => new LocalEnvironment(parameters.ToDictionary(i => i.Name, i => i.Type));
 174        /// <inheritdoc/>
 175        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 176            yield return "[";
 177            foreach (var tk in StringFormatterToken.Separated(Locations, args.ParameterListSeparator)) yield return tk;
 178            yield return "]";
 179            if (args.NewlinesBeforeFunctionParams <= 0 && args.SpaceBetweenLocationsAndFunctionParams) yield return " ";
 180            for (int i = 0; i < args.NewlinesBeforeFunctionParams; i++) yield return new NewLineToken();
 181            yield return "(";
 182            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 183            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 184            yield return ")";
 185            foreach (var tk in RawWorld.WorldOperator(args)) yield return tk;
 186            foreach (var tk in Heap.Tokens(args)) yield return tk;
 187            if (world is null) yield break;
 188            for (int i = 0; i < args.NewlinesBeforeFunctionWorld; i++) yield return new NewLineToken();
 189            if (args.NewlinesBeforeFunctionWorld <= 0 && args.SpaceBeforeFunctionWorld) yield return " ";
 190            yield return "->";
 191            for (int i = 0; i < args.NewlinesAfterFunctionWorld; i++) yield return new NewLineToken();
 192            if (args.NewlinesAfterFunctionWorld <= 0 && args.SpaceAfterFunctionWorld) yield return " ";
 193            foreach (var tk in world.Tokens(args)) yield return tk;
 194        }
 195        #region Equality Checks
 196        /// <inheritdoc/>
 197        public override bool Equals(object? obj) => Equals(obj as FunctionSchema);
 198        /// <inheritdoc/>
 199        public bool Equals(FunctionSchema? other) => other != null && Locations.SequenceEqual(other.Locations) && Parame
 200        /// <inheritdoc/>
 201        public override int GetHashCode() {
 202            var hash = new HashCode();
 203            foreach (var i in Locations) hash.Add(i);
 204            foreach (var i in Parameters) hash.Add(i);
 205            hash.Add(Heap);
 206            hash.Add(world);
 207            return hash.ToHashCode();
 208        }
 209        /// <inheritdoc/>
 210        public static bool operator ==(FunctionSchema? left, FunctionSchema? right) => EqualityComparer<FunctionSchema?>
 211        /// <inheritdoc/>
 212        public static bool operator !=(FunctionSchema? left, FunctionSchema? right) => !(left == right);
 213        #endregion
 214    }
 215}