[Laszlo-checkins] r10645 - openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc
dda@openlaszlo.org
dda at openlaszlo.org
Sat Aug 9 07:05:18 PDT 2008
Author: dda
Date: 2008-08-09 07:05:13 -0700 (Sat, 09 Aug 2008)
New Revision: 10645
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
Log:
Change 20080808-dda-K by dda at lester.local on 2008-08-08 14:28:43 EDT
in /Users/dda/laszlo/src/svn/openlaszlo/trunk
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: SWF9: allow class and global var names to differ only in case.
New Features:
Bugs Fixed: LPP-6792 (class 'Foo' and top level var 'foo' cannot coexist in SWF9 programs)
Technical Reviewer: ptw (pending)
QA Reviewer: (pending)
Doc Reviewer: (pending)
Documentation:
Release Notes:
Details:
Use subdirectory naming as discussed in LPP-6792 to distinguish class names and variable names.
We also allow classes and variable names to be the same (var foo = new foo()), as flex seems to accept this.
More details on the implementation contained in javadoc for the changed files.
Tests:
Regression: smokecheck (swf8+dhtml), (lzpix+weather)(swf8+swf9+dhtml)
Temporarily added the following test code to LzNode.lzs, and verified that produced output files
end up in the right subdirectories:
========
class Global1 {
public function x() {}
}
class GLOBAL2 {
}
class GLOBAL3 {
}
class global2 {
}
var Global1 = 6;
var GloBal1 = -1;
var global1 = 7;
//var global1 = 8; // should give an error
class global1 {
public function y() {}
}
//class global1 {} // should give an error
var foo = new global1();
foo.y();
class global3 {
}
class Global1 {
========
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java 2008-08-09 08:30:05 UTC (rev 10644)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/ParseTreePrinter.java 2008-08-09 14:05:13 UTC (rev 10645)
@@ -1333,6 +1333,7 @@
case ANNOTATE_OP_CLASSNAME:
curtu = new TranslationUnit();
curtu.setName(operand);
+ curtu.setIsClass(true);
tunits.add(curtu);
return "";
case ANNOTATE_OP_INSERTSTREAM:
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java 2008-08-09 08:30:05 UTC (rev 10644)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9External.java 2008-08-09 14:05:13 UTC (rev 10645)
@@ -53,11 +53,21 @@
private File workdir = createCompilationWorkDir();
private Compiler.OptionMap options;
- /**
- * The key is the 'tolower' name, the value is the actual name.
+ /*
+ * Used by getFileNameForClassName to prevent filename conflicts.
+ * The key is the 'tolower' name, the value is an ArrayList of
+ * UniqueGlobalName objects.
*/
private HashMap uniqueFileNames = new HashMap();
+ public class UniqueGlobalName {
+ String globalName;
+ boolean isClass;
+ int subdirnum; // subdirector number, 0 means top level
+ }
+
+ private int maxSubdirnum = 0;
+
public SWF9External(Compiler.OptionMap options) {
this.options = options;
}
@@ -619,6 +629,9 @@
}
cmd.add("-compiler.source-path+=" + workdir.getPath());
+ for (int i=1; i<=maxSubdirnum; i++) {
+ cmd.add("-compiler.source-path+=" + workdir.getPath() + File.separator + i);
+ }
if (options.getBoolean(Compiler.DEBUG_SWF9)) {
cmd.add("-debug=true");
}
@@ -656,23 +669,69 @@
}
/**
- * Checks for unique file names for files written.
- * We do not allow files to match, or even to be differing
- * only by case. The latter will cause problems on
- * file systems that merge upper/lower case names.
- * @throw CompilerError for file name conflicts
+ * Get a unique file name for the class or global variable. Flex
+ * requires that classes and global variables must be defined
+ * within matching file names. For example 'var FooBar' must be in
+ * FooBar.as, and 'class foobar' must be in foobar.as. But some
+ * file systems (like FAT32 and AFS+) do not allow file names in the
+ * same directory that only differ by case. In order to allow
+ * names that differ by case, we use subdirectories on an as needed
+ * basis. For example, if we see names in the order:
+ * "foo" "fOO" "BAR" "Foo" "bar"
+ * the file/directory names will be used:
+ * <pre>
+ * "./foo.as"
+ * "./1/fOO.as"
+ * "./bar.as"
+ * "./2/Foo.as"
+ * "./1/bar.as"
+ * </pre>
+ * This system guarantees usable file names on all systems,
+ * normally keeping all files in the top level directory, and
+ * minimizes the number of subdirectories. Each subdirectory
+ * requires an additional '-compiler.source-path+=...' argument
+ * to flex, and we'd rather not test whether there is a limit.
+ *
+ * This method also checks for class/global var names that have been
+ * used before and throws an error.
+ *
+ * A side effect of this method is to set the maxSubdirnum to the
+ * maximum of the subdirectory numbers used.
+ *
+ * @throw CompilerError for class/var names used previously.
*/
- void checkFileNameForClassName(String name) {
+ private String getFileNameForClassName(String name, boolean isClass) {
String lower = name.toLowerCase();
- String existing;
- if ((existing = (String)uniqueFileNames.get(lower)) != null) {
- if (existing.equals(name)) {
- throw new CompilerError("cannot declare class name more than once: \"" + name + "\"");
- } else {
- throw new CompilerError("class names only differ by upper/lower case: \"" + existing + "\" versus \"" + name + "\"");
+ List list = (List)uniqueFileNames.get(lower);
+
+ if (list == null) {
+ list = new ArrayList();
+ uniqueFileNames.put(lower, list);
+ } else {
+ for (Iterator iter = list.iterator(); iter.hasNext(); ) {
+ UniqueGlobalName unique = (UniqueGlobalName)iter.next();
+ if (name.equals(unique.globalName) && isClass == unique.isClass) {
+ String what = isClass ? "class" : "global var";
+ throw new CompilerError("cannot declare " + what +
+ " name more than once: \"" + name + "\"");
+ }
}
}
- uniqueFileNames.put(lower, name);
+ int dirnum = list.size();
+ UniqueGlobalName unique = new UniqueGlobalName();
+ unique.globalName = name;
+ unique.isClass = isClass;
+ unique.subdirnum = dirnum;
+ list.add(unique);
+ String subdirname = workdir.getPath();
+ if (dirnum > 0) {
+ subdirname += File.separator + dirnum;
+ }
+ if (dirnum > maxSubdirnum) {
+ (new File(subdirname)).mkdirs();
+ maxSubdirnum = dirnum;
+ }
+ return subdirname + File.separator + name + ".as";
}
/**
@@ -695,8 +754,7 @@
public void writeFile(TranslationUnit tunit, String pre, String post) {
String name = tunit.getName();
String body = tunit.getContents();
- checkFileNameForClassName(name);
- String infilename = workdir.getPath() + File.separator + name + ".as";
+ String infilename = getFileNameForClassName(name, tunit.isClass());
tunit.setSourceFileName(infilename);
tunit.setLineOffset(countLines(pre));
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java 2008-08-09 08:30:05 UTC (rev 10644)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/SWF9Generator.java 2008-08-09 14:05:13 UTC (rev 10645)
@@ -699,6 +699,7 @@
TranslationUnit tunit = new TranslationUnit();
tunit.setName(varname);
+ tunit.setIsClass(false);
String decl = "public var " + varname;
if (glovar.type != null)
decl += ":" + glovar.type;
Modified: openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java 2008-08-09 08:30:05 UTC (rev 10644)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/TranslationUnit.java 2008-08-09 14:05:13 UTC (rev 10645)
@@ -28,6 +28,7 @@
private boolean isMain = false; // designated classes, like LFCApplication
private Map streams = new HashMap(); // alternate streams, indexed by number
private int maxInserts = 0; // bound the number of stream insert replacements
+ private boolean isClass = true;
// When these appear in the contents they will be replaced
// by the indicated stream whenever contents is retrieved.
@@ -88,6 +89,14 @@
isMain = value;
}
+ public boolean isClass() {
+ return isClass;
+ }
+
+ public void setIsClass(boolean isClass) {
+ this.isClass = isClass;
+ }
+
public void addText(String s) {
text.append(s);
linenum += countOccurence(s, '\n');
More information about the Laszlo-checkins
mailing list