From cee889b33477e753ff26f56a05f6ae27cdb43cb1 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Tue, 27 Oct 2026 16:06:06 -0700 Subject: Bugfix escapes not-coded --- .../src/main/java/com/seaofnodes/simple/Parser.java | 10 ++++------ .../java/com/seaofnodes/simple/Chapter25Test.java | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java b/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java index 8410bf5c..83bef882 100644 --- a/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter28b/src/main/java/com/seaofnodes/simple/Parser.java @@ -1486,11 +1486,6 @@ public class Parser { return TypeFunPtr.make1((byte)2, true, targs, tret, _code.fidx(clzBare,order)); } - // A class type carries the constructor function as a required final field. - private TypeStruct classStruct( String typeName, TypeFunPtr init, boolean open ) { - return TypeStruct.make(addClzPrefix(typeName),open,Field.make(initFieldName(typeName),init,_code.alias(_ref._cname),true)); - } - private static String initFieldName( String typeName ) { if( startsClzPrefix(typeName) ) typeName = typeName.substring(clzPrefix.length()); @@ -1702,7 +1697,10 @@ public class Parser { private TypeMemPtr forwardRefType( String tname, TypeStruct tself ) { TYPES.put(tname,tself); String clzName = addClzPrefix( tname ); - TYPES.put(clzName, classStruct(tname,structInitSig(false,tself),true)); + // Only a struct declaration publishes an instance initializer. A + // forward type may name a file with just , so do not invent + // a constructor field (or overwrite an already parsed class). + TYPES.putIfAbsent(clzName,TypeStruct.make(clzName,true)); return TypeMemPtr.make(tself); } diff --git a/chapter28b/src/test/java/com/seaofnodes/simple/Chapter25Test.java b/chapter28b/src/test/java/com/seaofnodes/simple/Chapter25Test.java index dbb2a5ca..f94f641b 100644 --- a/chapter28b/src/test/java/com/seaofnodes/simple/Chapter25Test.java +++ b/chapter28b/src/test/java/com/seaofnodes/simple/Chapter25Test.java @@ -218,6 +218,25 @@ public class Chapter25Test { code.driver(CodeGen.Phase.TypeCheck); } + @Test public void testTypeOnlyFileReference() throws IOException { + Path base = Path.of("build/objs"); + Files.createDirectories(base); + Path root = Files.createTempDirectory(base,"type-only-"); + Files.createDirectory(root.resolve("A")); + Files.writeString(root.resolve("A/B.smp"),"int x = 0;"); + // B declares only a class initializer. Using its name as a type + // must not publish a nonexistent instance initializer during Opto. + for( String src : new String[]{ + "B? b = null; return 0;", + "val readB = { B b -> 0; }; return 0;" + } ) { + Files.writeString(root.resolve("A.smp"),src); + CodeGen code = new CodeGen(root.toString(),root.resolve("obj").toString(),null, + "A",null,123,true,TypeInteger.BOT).driver(CodeGen.Phase.TypeCheck); + assertEquals("0",Eval2.eval(code,0)); + } + } + @Test public void testPostfixFieldUpdate() { -- cgit v1.2.3