From d9ce5c1b14f563eca4ff8796b847b9caf6575fc1 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Sat, 25 Feb 2023 12:37:47 +0100 Subject: [PATCH] add Validate() method to SourceNode --- kscr-compiler/NodeCompiler.cs | 56 +++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/kscr-compiler/NodeCompiler.cs b/kscr-compiler/NodeCompiler.cs index d664b1b..706ff08 100644 --- a/kscr-compiler/NodeCompiler.cs +++ b/kscr-compiler/NodeCompiler.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -57,6 +58,8 @@ public static int RevisitRec(IEnumerable nodes, bool rec = false) Log.At(LogLevel.Debug, $"Revisited {c} members"); return c; } + + public abstract void Validate(); } public class PackageNode : SourceNode @@ -103,7 +106,9 @@ public int ReadPackages() try { var dir = new DirectoryInfo(sub); - Nodes.Add(ForPackage(vm, ctx, dir, Package)); + var node = ForPackage(vm, ctx, dir, Package); + node.Validate(); + Nodes.Add(node); c++; } catch (CompilerException cex) @@ -134,7 +139,9 @@ public int ReadFiles() try { var file = new FileInfo(sub); - Nodes.Add(new FileNode(vm, ctx, this, file)); + var node = new FileNode(vm, ctx, this, file); + node.Validate(); + Nodes.Add(node); c++; } catch (CompilerException cex) @@ -154,6 +161,7 @@ public static int ReadClassesRec(IEnumerable nodes) if (node is FileNode fn) c += fn.ReadClass(); c += ReadClassesRec(node.Nodes); + node.Validate(); } catch (CompilerException cex) { @@ -162,6 +170,13 @@ public static int ReadClassesRec(IEnumerable nodes) return c; } + + public override void Validate() + { + if (!Package.FullName.All(c => !char.IsLetter(c) || char.IsLower(c))) + throw new CompilerException(RuntimeBase.SystemSrcPos, CompilerErrorMessage.InvalidName, + "package", Package.FullName, "must be lowercase"); + } } public class FileNode : SourceNode @@ -224,6 +239,32 @@ public MemberNode CreateClassNode() Member = Cls }; } + + public override void Validate() + { + // 1 validate constructors using all superconstructors + if (Cls.DeclaredMembers.ContainsKey(Method.ConstructorName)) + { + var ctor = (Cls.DeclaredMembers[Method.ConstructorName] as Method)!; + foreach (var error in Cls.Superclasses + .Where(cls => cls.Name is not "object" and not "void") + .Where(cls => !ctor.SuperCalls.Any(spr => spr.Arg.StartsWith(cls.CanonicalName))) + .Select(missing => new CompilerException(ctor.SourceLocation, + CompilerErrorMessage.ClassSuperTypeNotCalled, Cls, missing))) + vm.CompilerErrors.Add(error); + } + + // 2 validate class abstract or all abstract members implemented + if (!Cls.IsAbstract()) + foreach (var error in ((IClass)Cls).InheritedMembers + .Where(ModifierMethods.IsAbstract) + .Where(mem => ((IClass)Cls).ClassMembers.All(x => x.Name != mem.Name)) + .Select(missing => new CompilerException(Cls.SourceLocation, + CompilerErrorMessage.ClassAbstractMemberNotImplemented, Cls, missing))) + vm.CompilerErrors.Add(error); + + // 3 validate used type parameters + } } public class MemberNode : SourceNode @@ -250,7 +291,9 @@ public int ReadMembers() foreach (var mem in cls.member()) try { - Nodes.Add(Visit(mem)); + var node = Visit(mem); + node.Validate(); + Nodes.Add(node); c++; } catch (CompilerException cex) @@ -412,4 +455,11 @@ private Core.System.Class ContainingClass() return cls; return Parent!.ContainingClass(); } + + public override void Validate() + { + // 1 validate overriding member is constructor or matches supermember footprint + + // 2 validate used type parameters + } } \ No newline at end of file