From: Hannu Niemistö Date: Mon, 14 May 2018 10:06:03 +0000 (+0000) Subject: Merge "Fixed record constructor resolving from namespaces" X-Git-Tag: v1.43.0~136^2~483 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=138667b7aae3a7984a8d0bb2a39461ce342b08e7;hp=2790c2eced1ae3e229972ede7173dc6831834760 Merge "Fixed record constructor resolving from namespaces" --- diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java index 757aca8b5..d8346f41f 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/TranslationContext.java @@ -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("."); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java index a85978223..8c8180a66 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java @@ -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); diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java index 8c2053e6f..6a416687d 100644 --- a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java @@ -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 index 000000000..7b370124c --- /dev/null +++ b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Record4.scl @@ -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