Author: dda
Date: 2008-01-18 13:37:38 -0800 (Fri, 18 Jan 2008)
New Revision: 7856

Modified:
   openlaszlo/branches/devildog/WEB-INF/lps/config/lps.properties
   
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
Log:
Change 20080118-dda-a by [EMAIL PROTECTED] on 2008-01-18 16:04:16 EST
    in /Users/dda/laszlo/src/svn/openlaszlo/branches/devildog
    for http://svn.openlaszlo.org/openlaszlo/branches/devildog

Summary: SWF9: show compiler errors, fix compatibility for flex 3.0 release

New Features:

Bugs Fixed: LPP-5234

Technical Reviewer: ptw (pending)
QA Reviewer: hminsky (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:

 *** NOTE: with this change the file lps.properties must be changed so that
     both compiler.swf9.lib.builder and compiler.swf9.app.builder use 'compc'.
     'mxmlc' is no longer used.  The lps.properties file has changed with this
     commit, but developers may have already changed it locally.

 1)   In testing with the 3.0 flex sdk release, a couple issues came up:
     - the default directory for installation has spaces in the filename,
       some code that built a simple command string for Runtime.exec
       had to be changed to use an array of arguments.  Presumably this
       will also work for Windows without changes.
     - the (somewhat convoluted) steps for building an application in two
       steps did not work as before.  Now we use a single step with the
       -include-classes flag (rather than using -- followed by a list of 
classes).
       This caused some small rework, but is cleaner and should be faster than 
before.
     - We no longer use mxmlc, but use compc for all steps in compiling a 
library and an app.
       There is a temporary error message if we detect this is mis-set.

    One result of the second item above is that references that aren't really 
used
    may not be flagged as an error.  For example this code listed at the 'top 
level',
    for example with a <view><handler> tag::

       var myvar:non_existing_type = 23;

    does not give any error (non_existing_type does not refer to an existing 
class).
    myvar is made into a global variable, put into its own file, and since 
never refered
    to, is not even compiled.  However, adding 'myvar = 123;' will cause a 
reference
    to that class and will make it compile.  Likewise, a user class with errors 
that is
    never referenced will also not give an error.  If this seems odd, we may 
want to add
    a reference to each variable and class - this could be put into a stub top 
level function
    in the 'main' class that is never called.

  2) The Errors in a browser are improved somewhat, though probably need some 
more.
   Instead of getting a generic 'compile failed' error, you now get the actual 
compiler error.
   The problem is that the error display is not really set up for more than one 
error,
   and there may be many compiler errors, which may all helpful.  For the 
moment, they
   are just appended together to a maximum of 50.  But the browser formatting 
ignores
   line breaks, and any more than a few errors will start to look like a big 
mass.

   We really want to approach errors like warnings - for some reason multiple 
warnings
   can be generated, but not multiple errors.  The warning mechanism uses 
'CompilationEnvironment'
   class, and there is special code in the template to show a list of warnings, 
but not errors
   (see lps/templates/app-console.xslt).

Tests:
   Sadly - henry's hello test gives me a blank screen, but that has happened 
before when
   I first started testing.  I do have an app that *compiles* cleanly with the 
new setup,
   as does the LFC.  All these statements apply to both the old flex 2.x sdk 
tested with
   this code base, as well as the flex 3.0.0 sdk as installed in the default 
location.

   Smokecheck for DHTML and SWF8.



Modified: openlaszlo/branches/devildog/WEB-INF/lps/config/lps.properties
===================================================================
--- openlaszlo/branches/devildog/WEB-INF/lps/config/lps.properties      
2008-01-18 21:34:59 UTC (rev 7855)
+++ openlaszlo/branches/devildog/WEB-INF/lps/config/lps.properties      
2008-01-18 21:37:38 UTC (rev 7856)
@@ -2,7 +2,7 @@
 # LPS properties file for development
 
#===============================================================================
 # * P_LZ_COPYRIGHT_BEGIN ******************************************************
-# * Copyright 2001-2004, 2008 Laszlo Systems, Inc.  All Rights Reserved.       
     *
+# * Copyright 2001-2008 Laszlo Systems, Inc.  All Rights Reserved.            *
 # * Use is subject to license terms.                                          *
 # * P_LZ_COPYRIGHT_END ********************************************************
 
@@ -164,7 +164,7 @@
 # Where the SWF9 external library compiler lives (relative to HOME, or 
absolute)
 compiler.swf9.lib.builder=../../flex2/bin/compc
 # Where the SWF9 external application compiler lives (relative to HOME, or 
absolute)
-compiler.swf9.app.builder=../../flex2/bin/mxmlc
+compiler.swf9.app.builder=../../flex2/bin/compc
 # Tell extern compiler to issue warnings.
 compiler.swf9.warnings=false
 

Modified: 
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
===================================================================
--- 
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
    2008-01-18 21:34:59 UTC (rev 7855)
+++ 
openlaszlo/branches/devildog/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
    2008-01-18 21:37:38 UTC (rev 7856)
@@ -52,6 +52,9 @@
   /** The LFC 'main' class, which extends nothing */
   public final static String MAIN_LIB_CLASSNAME = "LFCApplication";
 
+  /** Number of errors shown before truncating */
+  static public final int MAX_ERRORS_SHOWN = 50;
+
   /**
    * Saved program node, to show during debugging
    */
@@ -452,6 +455,7 @@
     private int colnum;
     private String error;
     private String code = "";
+    private String cleanedCode = "";
     private String orig = "";
     private TranslationUnit tunit;
 
@@ -476,18 +480,58 @@
       return linenum;
     }
 
+    // returns just the compiler error: e.g.
+    //  Error:  variable 'x' undefined
     public String getErrorString() {
       return error;
     }
 
+    // returns the complete the compiler error: e.g.
+    //   Error: variable 'x' undefined
+    //       result = x + 4;
+    //                ^
     public String originalErrorString() {
       return orig + "\n" + code;
     }
 
+    // returns the complete the compiler error,
+    // but without the positional 'caret', and
+    // an indication of where the code starts,
+    // other than just a newline.  This is
+    // meant to be read in the browser.
+    //   Error: variable 'x' undefined, in line: result = x + 4;
+    // Compare this with originalErrorString().
+    public String cleanedErrorString() {
+      String result = orig.trim();
+      if (result.endsWith("."))
+        result = result.substring(0, orig.length() - 1);
+      result += ", in line: " + cleanedCode;
+      return result;
+    }
+
+    public void addCodeLine(String str) {
+      if (code.length() > 0) {
+        code += "\n";
+      }
+      code += str;
+
+      // In cleanedCode, don't keep lines with just spaces and caret (^)
+      if (!str.matches("^[ ^]*$")) {
+        if (cleanedCode.length() > 0) {
+          cleanedCode += "\n";
+        }
+        cleanedCode += str;
+      }
+    }
+
     public String getCode() {
       return code;
     }
 
+    public String getCleanedCode() {
+      return cleanedCode;
+    }
+
     public TranslationUnit getTranslationUnit() {
       return tunit;
     }
@@ -572,9 +616,7 @@
           // Capture it in an error message not tied to a particular line
           lastError = new ExternalGeneratorError();
         }
-        if (lastError.code.length() > 0)
-          lastError.code += "\n";
-        lastError.code += str;
+        lastError.addCodeLine(str);
       }
     }
     
@@ -583,27 +625,55 @@
     }
   }
 
+  public static boolean useUnixQuoting() {
+    String osname = System.getProperty("os.name");
+    return !osname.startsWith("Windows");
+  }
+
   /**
    * Return a more nicely formatted command line.
    * On UNIX systems, we change '$' to \$' so the
    * output line can be cut and pasted into a shell.
    */
-  public String prettyCommand(String cmd)
+  public String prettyCommand(List cmd)
   {
-    String osname = System.getProperty("os.name");
-    if (!osname.startsWith("Windows")) {
-      // goodness, both $ and \ are special characters for regex.
-      cmd = cmd.replaceAll("[$]", "\\\\\\$");
+    String cmdstr = "";
+    for (Iterator iter = cmd.iterator(); iter.hasNext(); ) {
+      if (cmdstr.length() > 0)
+        cmdstr += " ";
+
+      String arg = (String)iter.next();
+      if (useUnixQuoting()) {
+      
+        // goodness, both $ and \ are special characters for regex.
+        arg = arg.replaceAll("[$]", "\\\\\\$");
+        if (arg.indexOf(' ') >= 0) {
+          arg = "\"" + arg + "\"";
+        }
+      }
+      cmdstr += arg;
     }
-    return cmd;
+    return cmdstr;
   }
 
-  public void execCompileCommand(String cmd, String dir, List tunits,
+  public void execCompileCommand(List cmd, String dir, List tunits,
                                  String outfileName)
     throws IOException          // TODO: [2007-11-20 dda] clean up, why catch 
only some exceptions?
   {
-    System.err.println("Executing compiler: (cd " + dir + "; " + 
prettyCommand(cmd) + ")");
-    Process proc = Runtime.getRuntime().exec(cmd, null, new File(dir));
+    String[] cmdstr = (String[])cmd.toArray(new String[0]);
+    String prettycmd = prettyCommand(cmd);
+    System.err.println("Executing compiuler: (cd " + dir + "; " + prettycmd + 
")");
+    String bigErrorString = "";
+    int bigErrorCount = 0;
+
+    if (DEBUG_OUTPUT) {
+      String buildsh = "#!/bin/sh\n";
+      buildsh += "cd " + dir + "\n";
+      buildsh += prettycmd + "\n";
+      emitFile(tempdir + File.separator + "build.sh", buildsh);
+    }
+
+    Process proc = Runtime.getRuntime().exec(cmdstr, null, new File(dir));
     try {
       OutputStream os = proc.getOutputStream();
       OutputCollector outcollect = new OutputCollector(proc.getInputStream());
@@ -651,30 +721,52 @@
           String actualSrcLine = actualSrcFile + ": " + err.getLineNumber();
           if (tunit == null || 
               ((srcLine = tunit.originalLineNumber(err.getLineNumber())) <= 
0)) {
-            srcLineStr = "unknown";
+            srcLineStr = "[" + actualSrcLine + "]";
           }
           else {
             // For now, we also show the actual source file/line
-            srcLineStr = String.valueOf(srcLine);
+            srcLineStr = String.valueOf(srcLine) +
+              " [" + actualSrcLine + "]";
           }
-          System.err.println("Compiler error: at " + srcLineStr +
-                             " [" + actualSrcLine + "]: " + 
-                             err.getErrorString() +
-                             "\n   " + err.originalErrorString());
+          String errorSummary = srcLineStr +
+            ": " + err.getErrorString() +
+            "\n   " + err.originalErrorString();
+          System.err.println("Compiler error: at " + srcLineStr + ": " +
+                             err.getErrorString() + "\n   " +
+                             err.originalErrorString());
+          bigErrorCount++;
+          if (bigErrorCount < MAX_ERRORS_SHOWN) {
+            bigErrorString += srcLineStr + ": " +
+              err.getErrorString() + "\n   " +
+              err.cleanedErrorString();
+          }
+          else if (bigErrorCount == 50) {
+            bigErrorString += ".... more than " + MAX_ERRORS_SHOWN +
+              " errors, additional errors not shown.\n";
+          }
         }
       }
 
       if (exitval != 0) {
-        System.err.println("FAIL: compc returned " + exitval);
+        System.err.println("FAIL: compiler returned " + exitval);
       }
     }
     catch (InterruptedException ie) {
-      throw new CompilerError("Interrupted compc");
+      throw new CompilerError("Interrupted compiler");
     }
     System.err.println("Done executing compiler");
     if (!new File(outfileName).exists()) {
       System.err.println("Intermediate file " + outfileName + ": does not 
exist");
-      throw new CompilerError("Errors from compc, output file not created");
+      // TODO: [2008-1-17 dda] remove this transitional code in a couple months
+      if (((String)cmd.get(0)).indexOf("mxmlc") >= 0) {
+        throw new CompilerError("Errors from compiler - change 
compiler.swf9.lib.builder property in lps.properties to use compc rather than 
mxmlc?");
+      }
+      if (bigErrorString.length() > 0) {
+        throw new CompilerError(bigErrorString);
+      }
+      else {
+        throw new CompilerError("Errors from compiler, output file not 
created");
+      }
     }
   }
 
@@ -703,60 +795,47 @@
   public byte[] flexCompile(List tunits, String tempdir, String apptype)
     throws IOException
   {
-    TranslationUnit appTunit = null;
     boolean buildSharedLibrary = 
options.getBoolean(Compiler.BUILD_SHARED_LIBRARY);
     assert (apptype != null && !buildSharedLibrary) : "application class type 
never set";
 
-    String outfilebase = "app.swf";
+    String builderCmd;
+    String outfilebase;
+
+    if (buildSharedLibrary) {
+      outfilebase = "app.swc";
+      builderCmd = getLPSPathname("compiler.swf9.lib.builder");
+    }
+    else {
+      outfilebase = "app.swf";
+      builderCmd = getLPSPathname("compiler.swf9.app.builder");
+    }
     String outfilename = tempdir + File.separator + outfilebase;
-    String swcfilebase = "app.swc";
-    String swcfilename = tempdir + File.separator + swcfilebase;
-
-    String libBuilderCmd = getLPSPathname("compiler.swf9.lib.builder");
     boolean swf9Warnings = getLPSBoolean("compiler.swf9.warnings", true);
 
-    String cmd = libBuilderCmd;
+    List cmd = new ArrayList();
+    cmd.add(builderCmd);
     if (!swf9Warnings)
-      cmd += " -compiler.show-actionscript-warnings=false";
-    cmd += " -compiler.source-path+=.";
-    if (!buildSharedLibrary)
-      cmd += " -library-path+=" + getLFCLibrary();
+      cmd.add("-compiler.show-actionscript-warnings=false");
+    if (!buildSharedLibrary) {
+      cmd.add("-default-size");
+      cmd.add(options.get(Compiler.CANVAS_WIDTH, "800"));
+      cmd.add(options.get(Compiler.CANVAS_HEIGHT));
+      cmd.add("-library-path+=" + getLFCLibrary());
+    }
+    cmd.add("-compiler.source-path+=.");
     if (USE_COMPILER_DEBUG_FLAG)
-      cmd += " -debug=true";
-    cmd += " -output " + swcfilebase;
-    cmd += " --";
+      cmd.add("-debug=true");
+    cmd.add("-output");
+    cmd.add(outfilebase);
+    cmd.add("-include-classes");
     for (Iterator iter = tunits.iterator(); iter.hasNext(); ) {
       TranslationUnit tunit = (TranslationUnit)iter.next();
       // The application main is built in a final step after this.
-      if (buildSharedLibrary || !tunit.isMainTranslationUnit()) {
-        cmd += " " + tunit.getName();
+      if (buildSharedLibrary || tunit.isMainTranslationUnit()) {
+        cmd.add(tunit.getName());
       }
-      else {
-        appTunit = tunit;
-      }
     }
 
-    execCompileCommand(cmd, tempdir, tunits, swcfilename);
-
-    if (buildSharedLibrary) {
-      return getBytes(swcfilename);
-    }
-
-    assert(appTunit != null);
-
-    String appBuilderCmd = getLPSPathname("compiler.swf9.app.builder");
-    cmd = appBuilderCmd;
-    if (!swf9Warnings)
-      cmd += " -compiler.show-actionscript-warnings=false";
-    cmd += " -default-size "+options.get(Compiler.CANVAS_WIDTH, "800") + " " + 
options.get(Compiler.CANVAS_HEIGHT);
-    cmd += " -compiler.source-path+=.";
-    cmd += " -library-path+=" + getLFCLibrary();
-    cmd += " -library-path+=" + swcfilename;
-    if (USE_COMPILER_DEBUG_FLAG)
-      cmd += " -debug=true";
-    cmd += " -output " + outfilebase;
-    cmd += " " + appTunit.getName()+".as";
-
     execCompileCommand(cmd, tempdir, tunits, outfilename);
     return getBytes(outfilename);
   }


_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins

Reply via email to