Fixed record constructor resolving from namespaces 71/1771/1
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Sun, 13 May 2018 08:34:33 +0000 (11:34 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Sun, 13 May 2018 08:34:33 +0000 (11:34 +0300)
Change-Id: Ib8b40c416672bcc97ec7ec24c97e1a0df08a8730

bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record4.scl [new file with mode: 0644]

index 757aca8b5e272880e7c6526048f1b20837709f82..d8346f41f5e889fbc66437a1f9be10a1a3ad803c 100644 (file)
@@ -192,16 +192,23 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         return -1;
     }
     
+    public SCLValue resolveSCLValue(long location, Namespace namespace, String name) throws AmbiguousNameException {
+        SCLValue value = namespace.getValue(name);
+        if(value == null)
+            return null;
+        String deprecatedDescription = value.isDeprecated();
+        if(deprecatedDescription != null)
+            errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription));
+        if(moduleDebugInfo != null)
+            moduleDebugInfo.symbolReferences.add(new SymbolReference(value.getName(), Name.create(compilationContext.module.getName(), definitionName), location));
+        return value;
+    }
+    
     public Expression resolveValue(long location, Namespace namespace, String name) {
         try {
-            SCLValue value = namespace.getValue(name);
+            SCLValue value = resolveSCLValue(location, namespace, name);
             if(value == null)
                 return null;
-            String deprecatedDescription = value.isDeprecated();
-            if(deprecatedDescription != null)
-                errorLog.logWarning(location, "Deprecated value " + value.getName().name + "." + (deprecatedDescription.isEmpty() ? "" : " " + deprecatedDescription));
-            if(moduleDebugInfo != null)
-                moduleDebugInfo.symbolReferences.add(new SymbolReference(value.getName(), Name.create(compilationContext.module.getName(), definitionName), location));
             return new EConstant(location, value);
         } catch (AmbiguousNameException e) {
             if(SCLCompilerConfiguration.ALLOW_OVERLOADING)
@@ -288,6 +295,25 @@ public class TranslationContext extends TypeTranslationContext implements Enviro
         return new EError(location);
     }
     
+    public SCLValue resolveRecordConstructor(long location, String name) throws AmbiguousNameException {
+        return resolveRecordConstructor(location, getEnvironment().getLocalNamespace(), name, 0);
+    }
+    
+    public SCLValue resolveRecordConstructor(long location, Namespace namespace, String name, int begin) throws AmbiguousNameException {
+        int end = findSeparator(name, begin);
+        String part = end == -1 ? (begin == 0 ? name : name.substring(begin)) : name.substring(begin, end);
+
+        if(end != -1 && name.charAt(end) == '.') {
+            Namespace childNamespace = namespace.getNamespace(part);
+            if(childNamespace == null)
+                return null;
+            else
+                return resolveRecordConstructor(location, childNamespace, name, end+1);
+        }
+        else
+            return resolveSCLValue(location, namespace, part);
+    }
+    
     private void reportResolveFailure(long location, Namespace namespace, String name) {
         StringBuilder message = new StringBuilder();
         message.append("Couldn't resolve ").append(name).append(".");
index a859782239caac40c50cf91e34935b43aa303b7e..8c8180a66299d7fa1f33a5c85e5ad13d77137ec3 100644 (file)
@@ -37,7 +37,7 @@ public class ERecord extends ASTExpression {
     public Expression resolve(TranslationContext context, boolean asPattern) {
         SCLValue constructorValue; 
         try {
-            constructorValue = context.getEnvironment().getLocalNamespace().getValue(constructor.name);
+            constructorValue = context.resolveRecordConstructor(location, constructor.name);
         } catch (AmbiguousNameException e) {
             context.getErrorLog().log(constructor.location, e.getMessage());
             return new EError(constructor.location);
index 8c2053e6f3db2cea06b8b9b19e6a558810aa595e..6a416687d1ba7d280a93f1a7c30976f1ba957b9f 100644 (file)
@@ -223,6 +223,7 @@ public class ModuleRegressionTests extends TestBase {
     @Test public void Record1() { test(); }
     @Test public void Record2() { test(); }
     @Test public void Record3() { test(); }
+    @Test public void Record4() { test(); }
     @Test public void RecordShorthand() { test(); }
     @Test public void RecordWildcards() { test(); }
     @Test public void RecursionBug() { test(); }
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record4.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record4.scl
new file mode 100644 (file)
index 0000000..7b37012
--- /dev/null
@@ -0,0 +1,11 @@
+// module Module
+data Foo = Foo { x :: Integer }
+--
+import "Prelude"
+import "Module" as M
+
+f = M.Foo { x = 3 }
+main = match f with
+    M.Foo { x } -> x
+-- 
+3
\ No newline at end of file