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