[Laszlo-checkins] r8551 - openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler

ptw@openlaszlo.org ptw at openlaszlo.org
Fri Apr 4 10:17:32 PDT 2008


Author: ptw
Date: 2008-04-04 10:17:28 -0700 (Fri, 04 Apr 2008)
New Revision: 8551

Modified:
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java
   openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ViewSchema.java
Log:
Change 20080403-ptw-X by ptw at dueling-banjos.local on 2008-04-03 07:58:34 EDT
    in /Users/ptw/OpenLaszlo/ringding-clean
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: More tweaks to instance classes

Bugs Fixed:
LPP-5625 'Implement instances with methods as singleton classes' (partial)

Technical Reviewer: henry.minsky at gmail.com (Message-ID: <8c61fad60804040706u1ac5b5a7pea2dde0104a874fb at mail.gmail.com>)
QA Reviewer: dda at ddanderson.com (pending)

Details:
    ClassCompiler, ClassModel:  Move compling of class to ClassModel
    so that in can be invoked on demand (e.g., when a class is
    referenced).

    ViewSchema:  Fix annotation of built-in classes to actually work.

    NodeModel:  Leave non-method attributes of instance classes as
    init args so they can be processed by construct methods.

Tests:
    Amazon working a little better, smokecheck has one error



Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java	2008-04-04 14:30:47 UTC (rev 8550)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassCompiler.java	2008-04-04 17:17:28 UTC (rev 8551)
@@ -236,33 +236,12 @@
     }
     
     public void compile(Element elt) {
-        String tagName = elt.getAttributeValue("name");
-        ViewSchema schema = mEnv.getSchema();
-        if (schema.enforceValidIdentifier) {
-            try {
-                tagName = requireIdentifierAttributeValue(elt, "name");
-            } catch (MissingAttributeException e) {
-                throw new CompilationError(
-                    /* (non-Javadoc)
-                     * @i18n.test
-                     * @org-mes="'name' is a required attribute of <" + p[0] + "> and must be a valid identifier"
-                     */
-                    org.openlaszlo.i18n.LaszloMessages.getMessage(
-                        ClassCompiler.class.getName(),"051018-193", new Object[] {elt.getName()})
-                    , elt);
-            }
-        }
-        // We compile a class declaration just like a view, and then
-        // add attribute declarations and perhaps some other stuff that
-        // the runtime wants.
-        ClassModel classModel = schema.getClassModel(tagName);
-        ViewCompiler.preprocess(elt, mEnv);
-        NodeModel model = NodeModel.elementAsModel(elt, schema, mEnv);
-        model = model.expandClassDefinitions();
-        // Establish class root
-        model.assignClassRoot(0);
-        classModel.setNodeModel(model);
-        classModel.emitClassDeclaration(mEnv);
+      String tagName = elt.getAttributeValue("name");
+      ClassModel classModel = mEnv.getSchema().getClassModel(tagName);
+      // May have already been compiled by a forward reference
+      if (! classModel.isCompiled()) {
+        classModel.compile(mEnv);
+      }
     }
 
   protected void compileClass(Element elt, ClassModel classModel, String initobj) {

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java	2008-04-04 14:30:47 UTC (rev 8550)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ClassModel.java	2008-04-04 17:17:28 UTC (rev 8551)
@@ -15,9 +15,10 @@
     protected final ViewSchema schema;
     /** This is really the LZX tag name */
     protected final String className;
-    // This is null for builtin classes
+    protected boolean builtin = false;
+    // This is null for the root class
     protected final ClassModel superclass;
-    // This is null for builtin classes
+    // This is null for the root class
     protected final Element definition;
     protected NodeModel nodeModel;
     
@@ -62,11 +63,6 @@
         }
     }
 
-    // Construct a builtin class
-    ClassModel(String className, ViewSchema schema) {
-        this(className, null, schema, null);
-    }
-
   public int compareTo(Object other) throws ClassCastException {
     ClassModel o = (ClassModel)other;
     int order = this.sortkey.startsWith(o.sortkey) ? +1 : this.sortkey.compareTo(o.sortkey);
@@ -139,6 +135,10 @@
     // model store class and tagname separately?
     ClassModel superclassModel = getSuperclassModel();
     String superTagName = superclassModel.getClassName();
+    // Allow forward references
+    if (! superclassModel.isCompiled()) {
+      superclassModel.compile(env);
+    }
     String superclassName = LZXTag2JSClass(superTagName);
 
     // Build the constructor
@@ -246,6 +246,25 @@
     env.compileScript("ConstructorMap[" + ScriptCompiler.quote(tagName) + "] = " + className + ";\n");
   }
 
+  /**
+   * Output a class.  Called after schema processing, but may be
+   * compiled out of order, so that forward references to classes work
+   */
+  public void compile(CompilationEnvironment env) {
+    if (! isBuiltin()) {
+      // We compile a class declaration just like a view, and then
+      // add attribute declarations and perhaps some other stuff that
+      // the runtime wants.
+      ViewCompiler.preprocess(definition, env);
+      NodeModel model = NodeModel.elementAsModel(definition, schema, env);
+      model = model.expandClassDefinitions();
+      // Establish class root
+      model.assignClassRoot(0);
+      setNodeModel(model);
+      emitClassDeclaration(env);
+    }
+  }
+
     /** Returns true if this is equal to or a subclass of
      * superclass. */
     boolean isSubclassOf(ClassModel superclass) {
@@ -254,8 +273,12 @@
         return this.superclass.isSubclassOf(superclass);
     }
     
+  void setIsBuiltin(boolean value) {
+    builtin = value;
+  }
+
     boolean isBuiltin() {
-        return superclass == null;
+      return builtin;
     }
     
     boolean hasNodeModel() {
@@ -263,6 +286,11 @@
         return nodeModel != null;
     }
 
+  boolean isCompiled() {
+    // Classes that are builtin or have been compiled
+    return isBuiltin() || hasNodeModel();
+  }
+
     ClassModel getSuperclassModel() {
       return superclass;
     }

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java	2008-04-04 14:30:47 UTC (rev 8550)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/NodeModel.java	2008-04-04 17:17:28 UTC (rev 8551)
@@ -1835,43 +1835,62 @@
 
     Map asMap() {
         updateAttrs();
+        assert classAttrs.isEmpty();
         Map map = new LinkedHashMap();
         String tagName = className;
-        if (hasMethods()) {
-            // Emit a class declaration to hold the methods
+        // Emit a class declaration to hold the methods, but for
+        // compatibility with many construct methods, leave all
+        // the non-methods in the attrs list...
+        // TODO: [2008-04-02 ptw] Someday clean this up so that we
+        // don't have to send so damn many Object's just to cons
+        // up a view.
+        boolean hasMethods = false;
+        Map inits = new LinkedHashMap();
+        // Node as map just wants to see all the attrs, so clean out
+        // the binding markers
+        for (Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) {
+            Map.Entry entry = (Map.Entry) i.next();
+            String key = (String) entry.getKey();
+            Object value = entry.getValue();
+            if (value instanceof NodeModel.BindingExpr) {
+                inits.put(key, ((NodeModel.BindingExpr)value).getExpr());
+            } else if (! (value instanceof Function)) {
+                inits.put(key, value);
+            } else {
+                hasMethods = true;
+            }
+        }
+        if (hasMethods) {
+            // We have to remove the attributes that have been
+            // converted to inits so things like constraints don't get
+            // installed twice.
+            // TODO: [2008-04-03 ptw] This is a descructive operation
+            // on the model, so the model is invalid after this.  This
+            // should be ok, since it should not be consulted once the
+            // code is generated; but it would be safer to make this
+            // non-destructive.
+            for (Iterator i = inits.keySet().iterator(); i.hasNext(); ) {
+                attrs.remove(i.next());
+            }
             String name = id;
             if (name == null) {
                 name = CompilerUtils.attributeUniqueName(element, "class");
             }
+            // Update tagname to our custom class
             tagName = className + "_" + name;
             ClassModel classModel = new ClassModel(tagName, parentClassModel, schema, element);
             classModel.setNodeModel(this);
             classModel.emitClassDeclaration(env);
         } else {
-            Map inits = new LinkedHashMap();
-            // Node as map just wants to see all the attrs, so clean out
-            // the binding markers
-            for (Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) {
-                Map.Entry entry = (Map.Entry) i.next();
-                String key = (String) entry.getKey();
-                Object value = entry.getValue();
-                if (! (value instanceof NodeModel.BindingExpr)) {
-                    inits.put(key, value);
-                } else {
-                    inits.put(key, ((NodeModel.BindingExpr)value).getExpr());
-                }
-            }
-            if (!attrs.isEmpty()) {
-                map.put("attrs", inits);
-            }
-            if (!classAttrs.isEmpty()) {
-                map.put("classAttrs", classAttrs);
-            }
             if (!children.isEmpty()) {
                 map.put("children", childrenMaps());
             }
         }
 
+        if (!attrs.isEmpty()) {
+            map.put("attrs", inits);
+        }
+
         // The tag to instantiate
         // TODO: [2008-04-01 ptw] we could have a flag day and put the
         // class here, eliminating having to go through the

Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ViewSchema.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ViewSchema.java	2008-04-04 14:30:47 UTC (rev 8550)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/compiler/ViewSchema.java	2008-04-04 17:17:28 UTC (rev 8551)
@@ -446,7 +446,7 @@
 
     /** Adds a ClassModel entry into the class table for CLASSNAME. */
     private void makeNewStaticClass (String classname) {
-        ClassModel info = new ClassModel(classname, this);
+        ClassModel info = new ClassModel(classname, null, this, null);
         if (sInputTextElements.contains(classname)) {
             info.isInputText = true;
             info.hasInputText = true;
@@ -611,6 +611,10 @@
         ec.updateSchema(docroot, this, visited);
         /** From here on, user-defined classes must not use reserved javascript identifiers */
         this.enforceValidIdentifier = true;
+        // Note that these classes are all built in
+        for (Iterator i = mClassMap.values().iterator(); i.hasNext(); ) {
+          ((ClassModel)i.next()).setIsBuiltin(true);
+        }
     }
     
 



More information about the Laszlo-checkins mailing list