]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
(refs #6924) Support for record field access syntax.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / compilation / Elaboration.java
index c36564eda59981fef0d800fc1d4492556f7817cd..9dbd94691a82cd27bab16a4a7be498e39fee2852 100644 (file)
@@ -7,6 +7,7 @@ import java.util.List;
 import org.cojen.classfile.TypeDesc;
 import org.simantics.scl.compiler.common.datatypes.Constructor;
 import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.Constant;
 import org.simantics.scl.compiler.constants.JavaTypeInstanceConstructor;
 import org.simantics.scl.compiler.constants.SCLConstructor;
 import org.simantics.scl.compiler.constants.StringConstant;
@@ -14,12 +15,14 @@ import org.simantics.scl.compiler.constants.generic.CallJava;
 import org.simantics.scl.compiler.constants.generic.ClassRef;
 import org.simantics.scl.compiler.constants.generic.ConvertToListFilter;
 import org.simantics.scl.compiler.constants.generic.MethodRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
 import org.simantics.scl.compiler.constants.generic.OutputFilter;
 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
 import org.simantics.scl.compiler.constants.generic.Pop2OutputFilter;
 import org.simantics.scl.compiler.constants.generic.PopOutputFilter;
 import org.simantics.scl.compiler.constants.generic.StackItem;
 import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
+import org.simantics.scl.compiler.constants.singletons.SafeCoerce;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
@@ -316,6 +319,7 @@ public class Elaboration {
     }
     
     public void processDataTypes(ArrayList<DDataAst> dataTypesAst) {
+        ArrayList<Runnable> fieldAccessorGenerators = new ArrayList<Runnable>(); 
         for(DDataAst dataTypeAst : dataTypesAst) {
             TypeTranslationContext context = createTypeTranslationContext();
             TVar[] typeParameters = new TVar[dataTypeAst.parameters.length];
@@ -395,7 +399,34 @@ public class Elaboration {
                 constructors[j].fieldNames = fieldNames;
                 constructors[j].recordFieldNames = constructor.fieldNames;
             }
+            if(constructors.length == 1) {
+                Constructor constructor = constructors[0];
+                if(constructor.recordFieldNames != null) {
+                    fieldAccessorGenerators.add(new Runnable() {
+                        @Override
+                        public void run() {
+                            Type in = Types.apply(dataType.name, dataType.parameters);
+                            for(int i=0;i<constructor.recordFieldNames.length;++i) {
+                                Type out = constructor.parameterTypes[i];
+                                Constant accessor;
+                                if(trivialDataType)
+                                    accessor = new SafeCoerce(dataType.parameters, in, out);
+                                else
+                                    accessor = new CallJava(dataType.parameters, Types.NO_EFFECTS, out,
+                                            new Type[] {in}, new StackItem[] {new ParameterStackItem(0, in)},
+                                            new FieldRef(constructor.javaName, constructor.fieldNames != null ? constructor.fieldNames[i] : "c" + i,
+                                                    javaTypeTranslator.toTypeDesc(out)),
+                                            null);
+                                module.addFieldAccessor(constructor.recordFieldNames[i], accessor);
+                            }
+                        }
+                    });
+                }
+            }
         }
+        
+        for(Runnable fieldAccessorGenerator : fieldAccessorGenerators)
+            fieldAccessorGenerator.run();
     }
     
     public void processTypeClasses(ArrayList<ProcessedDClassAst> typeClassesAst) {