From 1557b73959defd6e9a647b011b5caaf9709db6e4 Mon Sep 17 00:00:00 2001 From: mertcandav Date: Sun, 27 Oct 2024 20:10:40 +0300 Subject: [PATCH] sema: minor fixes and improvements --- std/comptime/type.jule | 2 ++ std/comptime/value.jule | 2 ++ std/jule/sema/comptime.jule | 13 +++++++------ std/jule/sema/eval.jule | 19 +++++++++++++++++++ std/jule/sema/sema.jule | 32 ++++++++++++++++++++++---------- std/jule/sema/type.jule | 20 +++++++++++++++----- std/time/time.jule | 2 +- 7 files changed, 68 insertions(+), 22 deletions(-) diff --git a/std/comptime/type.jule b/std/comptime/type.jule index 5b49c8897..854d8c497 100644 --- a/std/comptime/type.jule +++ b/std/comptime/type.jule @@ -85,6 +85,8 @@ impl comptimeTypeInfo { // Returns declaration information for type. // Supports only structs, traits, enums, type enums, and functions. + // For structures that constructed by the strict type alias, + // it returns declaration information for the relevant implicit struct declaration. fn Decl(self): comptimeDecl // Returns bitsize of type. diff --git a/std/comptime/value.jule b/std/comptime/value.jule index 39bb14246..d5af79a9c 100644 --- a/std/comptime/value.jule +++ b/std/comptime/value.jule @@ -37,6 +37,8 @@ impl comptimeValue { // Supports only structure types. // Parameter ident should be constant. // It allows access to private methods. + // It will not use the actual kind, so this method an provide + // access to methods of the any strict type alias. fn Method(self, ident: str): comptimeValue // Unwraps expression for runtime execution. diff --git a/std/jule/sema/comptime.jule b/std/jule/sema/comptime.jule index c78f1252b..062b9386c 100644 --- a/std/jule/sema/comptime.jule +++ b/std/jule/sema/comptime.jule @@ -560,8 +560,8 @@ impl comptimeTypeInfo { } mut decl := comptimeDeclType(nil) match { - | self.base.Struct() != nil: - decl = self.base.Struct().Decl + | self.base.softStruct() != nil: + decl = self.base.softStruct().Decl | self.base.Trait() != nil: decl = self.base.Trait() | self.base.Enum() != nil: @@ -1216,11 +1216,12 @@ impl comptimeValue { } mut ref := false mut s := (&StructIns)(nil) - if self.data.Type.Sptr() != nil { - s = self.data.Type.Sptr().Elem.Struct() + match type self.data.Type.Kind { + | &Sptr: + s = (&Sptr)(self.data.Type.Kind).Elem.softStruct() ref = true - } else { - s = self.data.Type.Struct() + | &StructIns: + s = (&StructIns)(self.data.Type.Kind) } if s == nil { e.pushErr(fc.Token, build::LogMsg.InvalidTypeForFn, self.data.Type.Str(), "Method") diff --git a/std/jule/sema/eval.jule b/std/jule/sema/eval.jule index 63f78c6ee..100d7ddd2 100644 --- a/std/jule/sema/eval.jule +++ b/std/jule/sema/eval.jule @@ -677,6 +677,25 @@ impl eval { // Eval structure instance directly. // No risk for instantiation because type aliases always points to // valid instance even with generics. + // + // For strict type aliases, their type structure may be not checked. + // So, there is possible risk for type analysis and other semantics. + // For example: + // The "std/comptime" package provides the TypeOf function, + // which is returns type information. This function may take + // type alias as argument. Like: comptime::TypeOf(Type) + // In this case, any method examination may cause crash or + // something like that. Because methods are may not be checked yet. + // But, comptime type information structure do not provides + // method interface directly. So, to examine types of method, + // developer should use the comptime::ValueOf function for the + // Method method to get a type information for a method. + // And comptime::ValueOf always takes checked type alias structs, + // So there is no way to occur such a fatal analysis issue, + // as far as tested. + // + // But, as far as tested, there is no risk for current implementation. + // Future implementations should pay attention for here. d = self._evalStruct((&StructIns)(kind)) | &Enum: d = self._evalEnum((&Enum)(kind)) diff --git a/std/jule/sema/sema.jule b/std/jule/sema/sema.jule index c1c7ece38..0ee2feb13 100644 --- a/std/jule/sema/sema.jule +++ b/std/jule/sema/sema.jule @@ -220,6 +220,12 @@ impl commonSemaMeta { } } +enum stepFlag { + NA: 0, + DeclsChecked: 1 << 0, + Done: 1 << 1, +} + // Semantic analyzer for tables. // Accepts tables as files of package. struct sema { @@ -228,6 +234,7 @@ struct sema { file: &SymTab // Current package file. flags: Flag meta: &commonSemaMeta + step: stepFlag } impl Lookup for sema { @@ -1099,7 +1106,6 @@ impl sema { // Type alias is strict, make strict type alias analysis. // See developer reference (11). mut s := initNewStructType(ta.Ident, ta.TypeSym.Type) - s.Checked = true s.Decl.sema = self s.Decl.Binded = ta.Binded s.Decl.Token = ta.Token @@ -2405,15 +2411,6 @@ impl sema { for (_, mut s) in self.file.Structs { self.checkTypeStruct(s) } - for (_, mut ta) in self.file.TypeAliases { - if ta.Strict { - mut s := (&StructIns)(ta.TypeSym.Type.Kind) - ok := self.precheckStructIns(s, nil) - if ok { - self.checkStructIns(s) - } - } - } } fn checkRets(mut self, mut &f: &FnIns) { @@ -2569,6 +2566,19 @@ impl sema { if len(self.errors) > 0 { ret } + + // Check + for (_, mut ta) in self.file.TypeAliases { + if ta.Strict { + mut s := (&StructIns)(ta.TypeSym.Type.Kind) + s.Checked = true + ok := self.precheckStructIns(s, nil) + if ok { + self.checkStructIns(s) + } + } + } + for (_, mut f) in self.files { self.setCurrentFile(f) self.checkFuncs() @@ -2624,7 +2634,9 @@ impl sema { ret } + self.step |= stepFlag.DeclsChecked self.checkPackageTypes() + self.step |= stepFlag.Done } } diff --git a/std/jule/sema/type.jule b/std/jule/sema/type.jule index b9149a3c0..36dc37fb3 100644 --- a/std/jule/sema/type.jule +++ b/std/jule/sema/type.jule @@ -41,9 +41,9 @@ trait Kind { // Evaluated type declaration. struct Type { - Generic: bool - Variadic: bool - Kind: Kind + Generic: bool + Variadic: bool + Kind: Kind } impl Kind for Type { @@ -735,7 +735,6 @@ impl Kind for Map { | &Map: m := (&Map)(other.Kind) ret self.Key.Equal(m.Key) && self.Val.Equal(m.Val) - } ret false } @@ -1018,7 +1017,7 @@ impl typeChecker { ret true } - fn fromTypeAlias(mut self, &decl: &ast::IdentTypeDecl, mut &ta: &TypeAlias): Kind { + fn fromTypeAlias(mut self, mut &decl: &ast::IdentTypeDecl, mut &ta: &TypeAlias): Kind { if !self.s.isAccessibleDefine(ta.Public, ta.Token) { self.pushErr(decl.Token, build::LogMsg.IdentNotExist, decl.Ident) ret nil @@ -1068,6 +1067,17 @@ impl typeChecker { } } + if ta.Strict && self.s.step&stepFlag.DeclsChecked == stepFlag.DeclsChecked { + // Check strict type structure if impl statements are implemented. + mut s := ta.TypeSym.Type.softStruct() + if !s.Checked { + ok := self.checkStructIns(s, decl.Token) + if !ok { + ret nil + } + } + } + { mut s := ta.TypeSym.Type.Struct() if s != nil { diff --git a/std/time/time.jule b/std/time/time.jule index 5914143c5..5f02face5 100644 --- a/std/time/time.jule +++ b/std/time/time.jule @@ -67,7 +67,7 @@ impl AbsTime { } mut t := unixYearToSeconds(y, leap) t += unixMonthToSeconds(m, leap) - t += day * UnixTime(self.Day - 1) + t += day * UnixTime(self.Day-1) t += hour * UnixTime(self.Hour) t += 60 * UnixTime(self.Minute) t += UnixTime(self.Second)