]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merge "SCL-compiler should activate installed bundles"
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Tue, 11 Sep 2018 05:12:03 +0000 (05:12 +0000)
committerGerrit Code Review <gerrit2@simantics>
Tue, 11 Sep 2018 05:12:03 +0000 (05:12 +0000)
16 files changed:
bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java
bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/AWTChassis.java
bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/impl/ElementDiagram.java
bundles/org.simantics.g2d/src/org/simantics/g2d/participant/MouseUtil.java
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/G2DSceneGraph.java
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/NodeEventHandler.java
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/adapter/AWTMouseEventAdapter.java
bundles/org.simantics.scl.compiler/META-INF/MANIFEST.MF
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/common/datatypes/Constructor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/compilation/Elaboration.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/SCLConstructor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/ComponentAccess.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/FieldComponentAccess.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/MethodComponentAccess.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ERecord.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/modules/SCLValue.java

index 4fe3b51d898183c882b81b1feb14d7abd665ad44..43653cbd0930abc7da98159406c44a71122ed235 100644 (file)
@@ -1806,7 +1806,6 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L
     protected boolean mouseDragged(MouseDragBegin e) {
         if (isHovering()
                 && (isControlDown(e) || isShiftDown(e))
-                && e.context instanceof NodeEventHandler
                 && (dataRVI != null || text != null))
         {
             List<Transferable> trs = new ArrayList<>(2);
index 2679ef620ac5c87b65de2337c9a188219895a88e..06b3ca22044dbb9ddfe808fe75ab2a8c94241532 100644 (file)
@@ -16,6 +16,7 @@ import java.awt.Container;
 import java.awt.Cursor;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
 import java.awt.Rectangle;
 import java.awt.image.VolatileImage;
 import java.lang.reflect.Method;
@@ -31,6 +32,7 @@ import org.simantics.g2d.canvas.IMouseCursorListener;
 import org.simantics.g2d.dnd.DragInteractor;
 import org.simantics.g2d.dnd.DropInteractor;
 import org.simantics.g2d.internal.DebugPolicy;
+import org.simantics.g2d.participant.TransformUtil;
 import org.simantics.scenegraph.g2d.G2DRenderingHints;
 import org.simantics.scenegraph.g2d.events.Event;
 import org.simantics.scenegraph.g2d.events.IEventQueue;
@@ -239,6 +241,12 @@ public class AWTChassis extends JComponent implements ICanvasChassis {
                     holder.addMouseMotionListener(mouseAdapter);
                     holder.addMouseWheelListener(mouseAdapter);
                     holder.addFocusListener(focusAdapter);
+
+                    TransformUtil util = canvasContext.getAtMostOneItemOfClass(TransformUtil.class);
+                    if (util != null) {
+                        mouseAdapter.initDragGestureListener(holder, (control) -> util.controlToCanvas(control, null));
+                    }
+
                 }
             };
             if (AWTThread.getThreadAccess().currentThreadAccess())
index 7bec43780df1bb9904e943a347b6b98fedeeb624..07ffe5436d7d67fd9aa5ee5119f71d65b98fb35a 100644 (file)
@@ -670,20 +670,6 @@ public class ElementDiagram implements IDiagram {
                 if (deltaDistance > 0)
                     mi.addDistanceForButtons(deltaDistance);
 
-                // Send mouse drag events.
-                for (ButtonInfo bi : mi.buttonPressInfo.values()) {
-                    if (!bi.down)
-                        continue;
-                    if (bi.deltaMotion <= profile.movementTolerance)
-                        continue;
-                    if (bi.drag)
-                        continue;
-                    bi.drag = true;
-                    MouseDragBegin db = new MouseDragBegin(this, e.time, e.mouseId, e.buttons, e.stateMask, bi.button,
-                            bi.canvasPosition, bi.controlPosition, e.controlPosition, e.screenPosition);
-                    getContext().getEventQueue().queueFirst(db);
-                }
-
             } else if (e instanceof MouseButtonPressedEvent) {
                 Point2D canvasPosition = util.controlToCanvas(e.controlPosition, null);
                 MouseButtonPressedEvent me = (MouseButtonPressedEvent) e;
index 44ded472960a1686f100d1cc69f8fed9bd8137a6..d5fbdc12b2a84a29493d5c0a1ee017b4a0ee02ff 100644 (file)
@@ -111,21 +111,6 @@ public class MouseUtil extends AbstractCanvasParticipant {
                     if (deltaDistance>0)
                         mi.addDistanceForButtons(deltaDistance);
 
-                    // Send mouse drag events.
-                    for (ButtonInfo bi : mi.buttonPressInfo.values())
-                    {
-                        if (!bi.down) continue;
-                        if (bi.deltaMotion<=profile.movementTolerance) continue;
-                        if (bi.drag) continue;
-                        bi.drag = true;
-                        MouseDragBegin db = new MouseDragBegin(
-                                this, e.time, e.mouseId, e.buttons, e.stateMask, bi.button,
-                                bi.canvasPosition, bi.controlPosition,
-                                e.controlPosition, e.screenPosition
-                                );
-                        getContext().getEventQueue().queueFirst(db);
-                    }
-
                 } else
                     if (e instanceof MouseButtonPressedEvent)
                     {
index 885b8c3a049aae024848250847310d78853f6a16..204181c3786fe01631e4b333cce06a7e681bdfd3 100644 (file)
@@ -158,7 +158,6 @@ public class G2DSceneGraph extends G2DParentNode implements ILookupService, INod
             RepaintManager.setCurrentManager(repaintManager);
         }
         this.rootPane = rootPane;
-        eventHandler.setRootPane(rootPane);
     }
 
     private RepaintManager findProperRepaintManager(RepaintManager old) {
index 1c1ac8a37a7b523ace66705188f148c1972ed763..8d3ba3a94482e3405382ea4817faa90c0c107441 100644 (file)
  *******************************************************************************/
 package org.simantics.scenegraph.g2d.events;
 
-import java.awt.Component;
-import java.awt.GraphicsEnvironment;
-import java.awt.dnd.DnDConstants;
-import java.awt.dnd.DragGestureEvent;
-import java.awt.dnd.DragGestureListener;
-import java.awt.dnd.DragSource;
-import java.awt.dnd.DragSourceDragEvent;
-import java.awt.dnd.DragSourceDropEvent;
-import java.awt.dnd.DragSourceEvent;
-import java.awt.dnd.DragSourceListener;
-import java.awt.event.InputEvent;
-import java.awt.geom.Point2D;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -34,7 +22,6 @@ import org.simantics.scenegraph.g2d.G2DSceneGraph;
 import org.simantics.scenegraph.g2d.IG2DNode;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;
-import org.simantics.scenegraph.g2d.events.adapter.AWTMouseEventAdapter;
 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -220,65 +207,6 @@ public class NodeEventHandler implements IEventHandler {
         return sort;
     }
 
-    public void setRootPane(Component rootPane) {
-        if (GraphicsEnvironment.isHeadless()) {
-            LOGGER.info("Disabling DragSource in headless environments");
-            return;
-        }
-        final DragSource ds = new DragSource();
-        final DragSourceListener dsl = new DragSourceListener() {
-            @Override
-            public void dropActionChanged(DragSourceDragEvent dsde) {
-            }
-            @Override
-            public void dragOver(DragSourceDragEvent dsde) {
-            }
-            @Override
-            public void dragExit(DragSourceEvent dse) {
-            }
-            @Override
-            public void dragEnter(DragSourceDragEvent dsde) {
-            }
-            @Override
-            public void dragDropEnd(DragSourceDropEvent dsde) {
-            }
-        };
-        DragGestureListener dgl = new DragGestureListener() {
-            @Override
-            public void dragGestureRecognized(DragGestureEvent dge) {
-                InputEvent ie = dge.getTriggerEvent();
-                if (ie instanceof java.awt.event.MouseEvent) {
-                    java.awt.event.MouseEvent e = (java.awt.event.MouseEvent) ie;
-                    Point2D controlPos = AWTMouseEventAdapter.getControlPosition(e);
-                    MouseDragBegin event = new MouseDragBegin(NodeEventHandler.this,
-                            e.getWhen(), 0,
-                            AWTMouseEventAdapter.getButtonStatus(e),
-                            AWTMouseEventAdapter.getStateMask(e),
-                            AWTMouseEventAdapter.getMouseButton(e),
-                            // TODO: fix canvas position if necessary
-                            new Point2D.Double(),
-                            controlPos,
-                            controlPos,
-                            AWTMouseEventAdapter.getScreenPosition(e));
-
-                    // Send MouseDragBegin to the scenegraph and see
-                    // if anyone sets event.transferable to start DnD.
-                    handleMouseDragBeginEvent(event, EventTypes.MouseDragBegin);
-                    if (event.transferable != null) {
-                        ds.startDrag(dge, null, event.transferable, dsl);
-                        if (DEBUG_EVENTS)
-                            debug("dragGestureRecognized: startDrag " + event.transferable);
-                    }
-                }
-            }
-        };
-        ds.createDefaultDragGestureRecognizer(
-                rootPane,
-                DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK,
-                dgl);
-        ds.addDragSourceListener(dsl);
-    }
-
     public boolean mousePressed(MouseButtonPressedEvent event) {
         G2DFocusManager.INSTANCE.clearFocus();
         try {
index bad131312a337ce33195346fde1d1a6c4888b145..e01876c6d0000dfa1049631cf9d766cf8fbc4713 100644 (file)
  */
 package org.simantics.scenegraph.g2d.events.adapter;
 
+import java.awt.Component;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragSource;
 import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
@@ -22,6 +27,7 @@ import java.awt.event.MouseMotionListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.awt.geom.Point2D;
+import java.util.function.UnaryOperator;
 
 import org.simantics.scenegraph.g2d.events.EventDebugPolicy;
 import org.simantics.scenegraph.g2d.events.IEventHandler;
@@ -29,6 +35,7 @@ import org.simantics.scenegraph.g2d.events.IEventQueue;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
@@ -289,4 +296,38 @@ public class AWTMouseEventAdapter extends AbstractEventAdapter implements MouseL
             System.out.println("AWT mouse clicked: " + e);
     }
 
+    public void initDragGestureListener(Component rootPane, UnaryOperator<Point2D> controlToCanvas) {
+        final DragSource ds = new DragSource();
+        DragGestureListener dgl = new DragGestureListener() {
+            @Override
+            public void dragGestureRecognized(DragGestureEvent dge) {
+                InputEvent ie = dge.getTriggerEvent();
+                if (ie instanceof java.awt.event.MouseEvent) {
+                    java.awt.event.MouseEvent e = (java.awt.event.MouseEvent) ie;
+                    Point2D controlPos = getControlPosition(e);
+                    Point2D canvasPos = controlToCanvas.apply(controlPos);
+
+                    MouseDragBegin event = new MouseDragBegin(this,
+                            e.getWhen(), 0,
+                            getButtonStatus(e),
+                            getStateMask(e),
+                            getMouseButton(e),
+                            canvasPos,
+                            controlPos,
+                            controlPos,
+                            getScreenPosition(e));
+
+                    handleEvent(event);
+
+                    if (event.transferable != null) {
+                        ds.startDrag(dge, null, event.transferable, null);
+                    }
+                }
+            }
+        };
+        ds.createDefaultDragGestureRecognizer(
+                rootPane,
+                DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK,
+                dgl);
+    }
 }
index 7bfc9da61812996e1eb9eb035b1b6e74bc33c174..b5f2e0fc005c78d639399ec160c0f5f985b4cd97 100644 (file)
@@ -49,6 +49,7 @@ Export-Package: org.cojen.classfile,
  org.simantics.scl.compiler.environment.specification,
  org.simantics.scl.compiler.errors,
  org.simantics.scl.compiler.internal.codegen.chr;x-friends:="org.simantics.scl.compiler.tests",
+ org.simantics.scl.compiler.internal.codegen.continuations,
  org.simantics.scl.compiler.internal.codegen.references,
  org.simantics.scl.compiler.internal.codegen.types;x-friends:="org.simantics.scl.compiler.tests",
  org.simantics.scl.compiler.internal.codegen.utils;x-friends:="org.simantics.scl.compiler.tests",
index 88a45558f55658a4feb55c995753556674c1f8b5..7e57d3d145cc2e958457e466eaff611b5c9f6c61 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.scl.compiler.common.datatypes;
 
 import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.componentaccess.ComponentAccess;
 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
 import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder;
 import org.simantics.scl.compiler.types.TVar;
@@ -21,7 +22,7 @@ public class Constructor implements Typed {
     public final TVar[] typeVariables;
     public final Type type;
 
-    public String[] fieldNames;
+    public ComponentAccess[] componentAccesses;
 
     public String[] recordFieldNames;
     
index c59df828d93a852cf6c5b03d848f8cad9b3f3792..56e8eb3b66cc0cecaed1d4aa647e57ee7d180b1c 100644 (file)
@@ -12,11 +12,12 @@ 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;
+import org.simantics.scl.compiler.constants.componentaccess.ComponentAccess;
+import org.simantics.scl.compiler.constants.componentaccess.FieldComponentAccess;
 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;
@@ -79,7 +80,6 @@ import org.simantics.scl.compiler.internal.deriving.InstanceDerivers;
 import org.simantics.scl.compiler.internal.elaboration.profiling.BranchPointInjector;
 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
 import org.simantics.scl.compiler.internal.header.ModuleHeader;
-import org.simantics.scl.compiler.internal.parsing.Token;
 import org.simantics.scl.compiler.internal.parsing.declarations.ConstructorAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DAnnotationAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DClassAst;
@@ -96,7 +96,6 @@ import org.simantics.scl.compiler.internal.parsing.declarations.DTypeAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DValueAst;
 import org.simantics.scl.compiler.internal.parsing.declarations.DValueTypeAst;
 import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException;
-import org.simantics.scl.compiler.internal.parsing.parser.SCLTerminals;
 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDClassAst;
 import org.simantics.scl.compiler.internal.parsing.translation.ProcessedDInstanceAst;
 import org.simantics.scl.compiler.internal.parsing.translation.RelationRepository;
@@ -109,7 +108,6 @@ import org.simantics.scl.compiler.module.ModuleUtils;
 import org.simantics.scl.compiler.module.debug.ModuleDebugInfo;
 import org.simantics.scl.compiler.module.repository.ImportFailure;
 import org.simantics.scl.compiler.module.repository.ImportFailureException;
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
 import org.simantics.scl.compiler.types.TCon;
 import org.simantics.scl.compiler.types.TForAll;
 import org.simantics.scl.compiler.types.TFun;
@@ -399,7 +397,7 @@ public class Elaboration {
                     parameterTypes[i] = context.toType(constructor.parameters[i]);
                 String javaName = constructors.length == 1 ? className 
                         : compilationContext.namingPolicy.getConstructorClassName(name);
-                String[] fieldNames = null;
+                ComponentAccess[] componentAccesses = null;
                 for(DAnnotationAst annotation : constructor.annotations)
                     if(annotation.id.text.equals("@JavaType")) {
                         try {
@@ -412,24 +410,24 @@ public class Elaboration {
                     else if(annotation.id.text.equals("@FieldNames")) {
                         try {
                             EListLiteral literal = (EListLiteral)annotation.parameters[0];
-                            fieldNames = new String[literal.getComponents().length];
-                            for(int i=0;i<fieldNames.length;++i) {
+                            componentAccesses = new ComponentAccess[literal.getComponents().length];
+                            for(int i=0;i<componentAccesses.length;++i) {
                                 Expression component = literal.getComponents()[i];
                                 if(component instanceof EVar)
-                                    fieldNames[i] = ((EVar)component).name;
+                                    componentAccesses[i] = new FieldComponentAccess(((EVar)component).name);
                                 else if(component instanceof ELiteral)
-                                    fieldNames[i] = ((StringConstant)((ELiteral)component).getValue()).getValue();
+                                    componentAccesses[i] = new FieldComponentAccess(((StringConstant)((ELiteral)component).getValue()).getValue());
                             }
                         } catch(Exception e) {
                             errorLog.log(annotation.parameters[0].location, "Invalid annotation parameter.");
-                            fieldNames = null;
+                            componentAccesses = null;
                         }
                     }   
                 
                 constructors[j] = new Constructor(constructor.location, dataType,
                         Name.create(moduleName, name), 
                         parameterTypes, javaName);
-                constructors[j].fieldNames = fieldNames;
+                constructors[j].componentAccesses = componentAccesses;
                 constructors[j].recordFieldNames = constructor.fieldNames;
             }
             if(constructors.length == 1) {
@@ -439,16 +437,19 @@ public class Elaboration {
                         @Override
                         public void run() {
                             Type in = Types.apply(dataType.name, dataType.parameters);
+                            
+                            ComponentAccess[] componentAccesses = constructor.componentAccesses != null
+                                       ? constructor.componentAccesses
+                                   : SCLConstructor.DEFAULT_FIELD_NAMES[constructor.recordFieldNames.length];
                             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
+                                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)),
+                                            componentAccesses[i].toMethodRef(constructor.javaName, javaTypeTranslator.toTypeDesc(out)),
                                             null);
                                 module.addFieldAccessor(constructor.recordFieldNames[i], accessor);
                             }
@@ -1131,6 +1132,7 @@ public class Elaboration {
             int constructorTag = 0;
             for(Constructor constructor : dataType.constructors) {
                 SCLValue value = new SCLValue(constructor.name);
+                value.parameterNames = constructor.recordFieldNames;
                 value.definitionLocation = constructor.loc;
                 SCLConstructor sclConstructor = 
                         new SCLConstructor(
@@ -1139,10 +1141,9 @@ public class Elaboration {
                                 constructor.getTypeVariables(),
                                 constructorTag++,
                                 constructor.getReturnType(),
-                                constructor.fieldNames == null 
+                                constructor.componentAccesses == null 
                                         ? SCLConstructor.DEFAULT_FIELD_NAMES[constructor.getParameterTypes().length] 
-                                        : constructor.fieldNames,
-                                constructor.recordFieldNames,
+                                        : constructor.componentAccesses,
                                 constructor.getParameterTypes());
                 if(dataType.constructors.length == 1 && (
                         dataType.getTypeDesc() == null ||
index 9e8c7a0f2310c79b0bc28c26fc505bdb07ae394c..1491c71bd6582cb90c9154f4e478846c3e5f119a 100644 (file)
@@ -2,6 +2,8 @@ package org.simantics.scl.compiler.constants;
 
 import org.cojen.classfile.TypeDesc;
 import org.objectweb.asm.Label;
+import org.simantics.scl.compiler.constants.componentaccess.ComponentAccess;
+import org.simantics.scl.compiler.constants.componentaccess.FieldComponentAccess;
 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
@@ -18,40 +20,38 @@ import org.simantics.scl.compiler.types.Types;
 public class SCLConstructor extends FunctionValue {
     
     private static int MAX_FIELD_COUNT = Constants.MAX_TUPLE_LENGTH;
-    public static String[][] DEFAULT_FIELD_NAMES = new String[MAX_FIELD_COUNT+1][];
+    public static ComponentAccess[][] DEFAULT_FIELD_NAMES = new ComponentAccess[MAX_FIELD_COUNT+1][];
     
     static {
         for(int i=0;i<=MAX_FIELD_COUNT;++i) {
-            String[] fieldNames = new String[i];
+               ComponentAccess[] fieldNames = new ComponentAccess[i];
             for(int j=0;j<i;++j)
-                fieldNames[j] = "c" + j;
+                fieldNames[j] = new FieldComponentAccess("c" + j);
             DEFAULT_FIELD_NAMES[i] = fieldNames;
         }
     }
     
-    String name; // For debugging
-    String className;
-    String[] fieldNames;
+    private final String name; // For debugging
+    private final String className;
+    private final ComponentAccess[] componentAccesses;
     boolean onlyConstructor;
-    int constructorTag;
-    public final String[] recordFieldNames;
+    private final int constructorTag;
        
     public SCLConstructor(String name, String className, TVar[] typeParameters, int constructorTag,
-            Type returnType, String[] fieldNames, String[] recordFieldNames, Type... parameterTypes) {
+            Type returnType, ComponentAccess[] componentAccesses, Type... parameterTypes) {
         super(typeParameters, Types.NO_EFFECTS, returnType, parameterTypes);
         ClassBuilder.checkClassName(className);
         this.name = name;
         this.className = className;
-        this.fieldNames = fieldNames;
+        this.componentAccesses = componentAccesses;
         this.constructorTag = constructorTag;
-        this.recordFieldNames = recordFieldNames;
     }    
     
     public SCLConstructor(String name, String className, TVar[] typeParameters, int constructorTag,
             Type returnType,
             Type ... parameterTypes) {     
         this(name, className, typeParameters, constructorTag, returnType,
-                DEFAULT_FIELD_NAMES[parameterTypes.length], null, parameterTypes);
+                DEFAULT_FIELD_NAMES[parameterTypes.length], parameterTypes);
     }
     
     public void setOnlyConstructor(boolean onlyConstructor) {
@@ -118,7 +118,7 @@ public class SCLConstructor extends FunctionValue {
             
             if(!typeDesc.equals(TypeDesc.VOID)) {
                 mb.dup();
-                mb.loadField(MethodBuilder.getClassName(constructorType), fieldNames[i], typeDesc);                
+                componentAccesses[i].load(mb, MethodBuilder.getClassName(constructorType), typeDesc);
                 if(typeDesc == TypeDesc.OBJECT)
                     mb.unbox(contType);      
             }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/ComponentAccess.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/ComponentAccess.java
new file mode 100644 (file)
index 0000000..95757e8
--- /dev/null
@@ -0,0 +1,12 @@
+package org.simantics.scl.compiler.constants.componentaccess;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.constants.generic.MethodRef;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+
+public interface ComponentAccess {
+
+       MethodRef toMethodRef(String baseClass, TypeDesc returnType);
+       void load(MethodBuilder mb, String baseClass, TypeDesc returnType);
+
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/FieldComponentAccess.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/FieldComponentAccess.java
new file mode 100644 (file)
index 0000000..ca0b229
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.scl.compiler.constants.componentaccess;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.constants.generic.MethodRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.FieldRef;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+
+public class FieldComponentAccess implements ComponentAccess {
+       public final String fieldName;
+
+       public FieldComponentAccess(String fieldName) {
+               this.fieldName = fieldName;
+       }
+
+       @Override
+       public void load(MethodBuilder mb, String baseClass, TypeDesc returnType) {
+               mb.loadField(baseClass, fieldName, returnType);
+       }
+
+       @Override
+       public MethodRef toMethodRef(String baseClass, TypeDesc returnType) {
+               return new FieldRef(baseClass, fieldName, returnType);
+       }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/MethodComponentAccess.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/componentaccess/MethodComponentAccess.java
new file mode 100644 (file)
index 0000000..7283266
--- /dev/null
@@ -0,0 +1,30 @@
+package org.simantics.scl.compiler.constants.componentaccess;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.constants.generic.MethodRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.ObjectMethodRef;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+
+public class MethodComponentAccess implements ComponentAccess {
+       public final String methodName;
+       public final boolean isInterface;
+
+       public MethodComponentAccess(String fieldName, boolean isInterface) {
+               this.methodName = fieldName;
+               this.isInterface = isInterface;
+       }
+
+       @Override
+       public void load(MethodBuilder mb, String baseClass, TypeDesc returnType) {
+               if(isInterface)
+                       mb.invokeInterface(baseClass, methodName, returnType, Constants.EMPTY_TYPEDESC_ARRAY);
+               else
+                       mb.invokeVirtual(baseClass, methodName, returnType, Constants.EMPTY_TYPEDESC_ARRAY);
+       }
+
+       @Override
+       public MethodRef toMethodRef(String baseClass, TypeDesc returnType) {
+               return new ObjectMethodRef(isInterface, baseClass, methodName, returnType, Constants.EMPTY_TYPEDESC_ARRAY);
+       }
+}
index 8c8180a66299d7fa1f33a5c85e5ad13d77137ec3..47ef205df17cbce0d9ff1d74dd8f1154adc1bcfa 100644 (file)
@@ -46,16 +46,12 @@ public class ERecord extends ASTExpression {
             context.getErrorLog().log(constructor.location, "Couldn't resolve the record constructor " + constructor.name + ".");
             return new EError(constructor.location);
         }
-        if(!(constructorValue.getValue() instanceof SCLConstructor)) {
+        String[] parameterNames = constructorValue.parameterNames;
+        if(parameterNames == null) {
             context.getErrorLog().log(constructor.location, "Value " + constructor.name + " is not a record constructor.");
             return new EError(constructor.location);
         }
-        String[] fieldNames = ((SCLConstructor)constructorValue.getValue()).recordFieldNames;
-        if(fieldNames == null) {
-            context.getErrorLog().log(constructor.location, "Value " + constructor.name + " is not a record constructor.");
-            return new EError(constructor.location);
-        }
-        Expression[] parameters = translateFieldsToFunctionParameters(context, fields, fieldNames, false);
+        Expression[] parameters = translateFieldsToFunctionParameters(context, fields, parameterNames, false);
         if(parameters == null)
             return new EError(location);
         if(asPattern)
@@ -73,7 +69,7 @@ public class ERecord extends ASTExpression {
                 if(parameter == null) {
                     ExistentialFrame frame = context.getCurrentExistentialFrame();
                     if(frame == null || frame.disallowNewExistentials) {
-                        context.getErrorLog().log(location, "Field " + fieldNames[i] + " not defined.");
+                        context.getErrorLog().log(location, "Field " + parameterNames[i] + " not defined.");
                         error = true;
                     }
                     else
index 0d4651d4852530452959897f87aca2a2f1b7f01d..08b03d04feddc900ae1994bbbe6597ab09b1f1f9 100644 (file)
@@ -35,6 +35,7 @@ public final class SCLValue implements Typed {
     private ArrayList<SCLValueProperty> properties = new ArrayList<SCLValueProperty>(2);
     public String documentation;
     public long definitionLocation = Locations.NO_LOCATION;
+    public String[] parameterNames;
     
     public SCLValue(Name name) {
         this.name = name;