Merging from releases/1.6@3944:4025
svn merge -r3944:4025 https://google-web-toolkit.googlecode.com/svn/releases/1.6 .
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@4032 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/build.xml b/build.xml
index 4efa2f8..6b8bcc9 100755
--- a/build.xml
+++ b/build.xml
@@ -7,9 +7,9 @@
<property name="target" value="build" />
<property name="gwt.apicheck.config"
- location="tools/api-checker/config/gwt14_15userApi.conf"/>
+ location="tools/api-checker/config/gwt15_16userApi.conf"/>
<property name="gwt.apicheck.oldroot"
- location="../gwt-1.4"/>
+ location="../gwt-1.5"/>
<target name="dist" depends="dev, user, servlet, tools, jni, doc, samples" description="Run the distributions">
<gwt.ant dir="distro-source" />
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java
index 23ea00f..5db5a59 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPackage.java
@@ -28,7 +28,7 @@
private final Annotations annotations = new Annotations();
- private final Map<String, JClassType> types = new HashMap<String, JClassType>();
+ private final Map<String, JRealClassType> types = new HashMap<String, JRealClassType>();
JPackage(String name) {
this.name = name;
@@ -81,7 +81,7 @@
return "package " + name;
}
- void addType(JClassType type) {
+ void addType(JRealClassType type) {
types.put(type.getSimpleSourceName(), type);
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
index 955146f..e326756 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
@@ -87,6 +87,7 @@
} while (enclosing != null);
nestedName = nn;
}
+ oracle.addNewType(this);
}
public void addAnnotations(
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
index e217ce2..75e8e2e 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
@@ -167,10 +167,14 @@
}
}
- private Set<JClassType> allTypes = null;
+ private final Set<JRealClassType> allTypes = new HashSet<JRealClassType>();
private final Map<JType, JArrayType> arrayTypes = new IdentityHashMap<JType, JArrayType>();
+ /**
+ * A set of invalidated types queued up to be removed on the next
+ * {@link #reset()}.
+ */
private final Set<JRealClassType> invalidatedTypes = new HashSet<JRealClassType>();
private JClassType javaLangObject;
@@ -179,6 +183,12 @@
private final Map<String, List<JParameterizedType>> parameterizedTypes = new HashMap<String, List<JParameterizedType>>();
+ /**
+ * A list of recently-added types that will be fully initialized on the next
+ * call to {@link #finish(TreeLogger)}.
+ */
+ private final List<JRealClassType> recentTypes = new ArrayList<JRealClassType>();
+
private int reloadCount = 0;
private final Map<String, List<JWildcardType>> wildcardTypes = new HashMap<String, List<JWildcardType>>();
@@ -248,6 +258,18 @@
}
/**
+ * Called after a block of new types are added.
+ *
+ * TODO: make not public?
+ */
+ public void finish(TreeLogger logger) {
+ JClassType[] newTypes = recentTypes.toArray(NO_JCLASSES);
+ computeHierarchyRelationships(newTypes);
+ consumeTypeArgMetaData(logger, newTypes);
+ recentTypes.clear();
+ }
+
+ /**
* Gets the type object that represents an array of the specified type. The
* returned type always has a stable identity so as to guarantee that all
* calls to this method with the same argument return the same object.
@@ -270,7 +292,10 @@
* <code>java.lang.Object</code>.
*/
public JClassType getJavaLangObject() {
- assert javaLangObject != null;
+ if (javaLangObject == null) {
+ javaLangObject = findType("java.lang.Object");
+ assert javaLangObject != null;
+ }
return javaLangObject;
}
@@ -457,18 +482,6 @@
* @return an array of types, possibly of zero length
*/
public JClassType[] getTypes() {
- if (allTypes == null) {
- allTypes = new HashSet<JClassType>();
- JPackage[] pkgs = getPackages();
- for (int i = 0; i < pkgs.length; i++) {
- JPackage pkg = pkgs[i];
- JClassType[] types = pkg.getTypes();
- for (int j = 0; j < types.length; j++) {
- JRealClassType type = (JRealClassType) types[j];
- buildAllTypesImpl(allTypes, type);
- }
- }
- }
return allTypes.toArray(NO_JCLASSES);
}
@@ -525,35 +538,12 @@
}
/**
- * Updates relationships within this type oracle. Should be called after any
- * changes are made.
- *
- * <p>
- * Throws <code>TypeOracleException</code> thrown if fundamental baseline
- * correctness criteria are violated, most notably the absence of
- * "java.lang.Object"
- * </p>
+ * Reset this type oracle for rebuild.
*
* TODO: make this not public.
*/
- public void refresh(TreeLogger logger) throws NotFoundException {
- allTypes = null;
- if (javaLangObject == null) {
- javaLangObject = findType("java.lang.Object");
- if (javaLangObject == null) {
- throw new NotFoundException("java.lang.Object");
- }
- }
- computeHierarchyRelationships();
- consumeTypeArgMetaData(logger);
- }
-
- /**
- * Removes all types that are no longer valid.
- *
- * TODO: make not public?
- */
- public void removeInvalidatedTypes() {
+ public void reset() {
+ recentTypes.clear();
if (!invalidatedTypes.isEmpty()) {
invalidateTypes(invalidatedTypes);
invalidatedTypes.clear();
@@ -620,32 +610,25 @@
});
}
+ void addNewType(JRealClassType newType) {
+ allTypes.add(newType);
+ recentTypes.add(newType);
+ }
+
void invalidate(JRealClassType realClassType) {
invalidatedTypes.add(realClassType);
}
- private void buildAllTypesImpl(Set<JClassType> allTypes, JRealClassType type) {
- boolean didAdd = allTypes.add(type);
- assert (didAdd);
- JClassType[] nestedTypes = type.getNestedTypes();
- for (int i = 0; i < nestedTypes.length; i++) {
- JRealClassType nestedType = (JRealClassType) nestedTypes[i];
- buildAllTypesImpl(allTypes, nestedType);
- }
- }
-
- private void computeHierarchyRelationships() {
+ private void computeHierarchyRelationships(JClassType[] types) {
// For each type, walk up its hierarchy chain and tell each supertype
// about its subtype.
- //
- JClassType[] types = getTypes();
for (int i = 0; i < types.length; i++) {
JClassType type = types[i];
type.notifySuperTypes();
}
}
- private void consumeTypeArgMetaData(TreeLogger logger) {
+ private void consumeTypeArgMetaData(TreeLogger logger, JClassType[] types) {
if (GenUtil.warnAboutMetadata()) {
logger = logger.branch(
TreeLogger.DEBUG,
@@ -654,10 +637,6 @@
+ " javadoc annotation; please use Java parameterized types instead",
null);
}
- consumeTypeArgMetaData(logger, getTypes());
- }
-
- private void consumeTypeArgMetaData(TreeLogger logger, JClassType[] types) {
for (int i = 0; i < types.length; i++) {
JClassType type = types[i];
// CTORS not supported yet
@@ -1012,12 +991,16 @@
private void removeTypes(Set<JRealClassType> invalidTypes) {
for (Iterator<JRealClassType> iter = invalidTypes.iterator(); iter.hasNext();) {
JClassType classType = iter.next();
+
+ allTypes.remove(classType);
+
JPackage pkg = classType.getPackage();
if (pkg != null) {
pkg.remove(classType);
}
classType.removeFromSupertypes();
+
iter.remove();
}
}
diff --git a/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java b/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java
index d19ae45..14047e5 100644
--- a/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java
+++ b/dev/core/src/com/google/gwt/dev/CompileArgProcessor.java
@@ -17,15 +17,15 @@
import com.google.gwt.dev.util.arg.ArgHandlerLogLevel;
import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
-import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
import com.google.gwt.dev.util.arg.ArgHandlerTreeLoggerFlag;
+import com.google.gwt.dev.util.arg.ArgHandlerWorkDir;
import com.google.gwt.util.tools.ToolBase;
abstract class CompileArgProcessor extends ToolBase {
public CompileArgProcessor(CompileTaskOptions options) {
registerHandler(new ArgHandlerLogLevel(options));
registerHandler(new ArgHandlerTreeLoggerFlag(options));
- registerHandler(new ArgHandlerOutDir(options));
+ registerHandler(new ArgHandlerWorkDir(options));
registerHandler(new ArgHandlerModuleName(options));
}
diff --git a/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java b/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
index dd345fc..82965c9 100644
--- a/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
+++ b/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
@@ -18,11 +18,11 @@
import com.google.gwt.dev.util.arg.OptionGuiLogger;
import com.google.gwt.dev.util.arg.OptionLogLevel;
import com.google.gwt.dev.util.arg.OptionModuleName;
-import com.google.gwt.dev.util.arg.OptionOutDir;
+import com.google.gwt.dev.util.arg.OptionWorkDir;
/**
* A common set of options for all compile tasks.
*/
public interface CompileTaskOptions extends OptionGuiLogger, OptionModuleName,
- OptionLogLevel, OptionOutDir {
+ OptionLogLevel, OptionWorkDir {
}
diff --git a/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java b/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
index 9c093c0..e0b7ead 100644
--- a/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
+++ b/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
@@ -28,7 +28,6 @@
private Type logLevel;
private String moduleName;
- private File outDir;
private boolean useGuiLogger;
private File workDir;
@@ -42,8 +41,8 @@
public void copyFrom(CompileTaskOptions other) {
setLogLevel(other.getLogLevel());
setModuleName(other.getModuleName());
- setOutDir(other.getOutDir());
setUseGuiLogger(other.isUseGuiLogger());
+ setWorkDir(other.getWorkDir());
}
public File getCompilerWorkDir() {
@@ -58,8 +57,8 @@
return moduleName;
}
- public File getOutDir() {
- return outDir;
+ public File getWorkDir() {
+ return workDir;
}
public boolean isUseGuiLogger() {
@@ -74,22 +73,11 @@
this.moduleName = moduleName;
}
- public void setOutDir(File outDir) {
- this.outDir = outDir;
- }
-
public void setUseGuiLogger(boolean useGuiLogger) {
this.useGuiLogger = useGuiLogger;
}
- /**
- * TODO: add a command line option to pass files between compile phases?
- */
- protected File getWorkDir() {
- if (workDir == null) {
- workDir = new File(System.getProperty("java.io.tmpdir"), GWT_TMP_DIR);
- workDir.mkdirs();
- }
- return workDir;
+ public void setWorkDir(File workDir) {
+ this.workDir = workDir;
}
}
diff --git a/dev/core/src/com/google/gwt/dev/GWTCompiler.java b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
index fd4786a..9a85324 100644
--- a/dev/core/src/com/google/gwt/dev/GWTCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
@@ -19,9 +19,11 @@
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompilePerms.CompilePermsOptionsImpl;
import com.google.gwt.dev.CompileTaskRunner.CompileTask;
+import com.google.gwt.dev.Link.LinkOptionsImpl;
import com.google.gwt.dev.Precompile.PrecompileOptionsImpl;
import com.google.gwt.dev.util.PerfLogger;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
+import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
import java.io.File;
@@ -34,6 +36,7 @@
public ArgProcessor(CompilerOptions options) {
super(options);
registerHandler(new ArgHandlerExtraDir(options));
+ registerHandler(new ArgHandlerOutDir(options));
}
@Override
@@ -45,7 +48,7 @@
static class GWTCompilerOptionsImpl extends PrecompileOptionsImpl implements
CompilerOptions {
- private File extraDir;
+ private LinkOptionsImpl linkOptions = new LinkOptionsImpl();
public GWTCompilerOptionsImpl() {
}
@@ -56,15 +59,23 @@
public void copyFrom(CompilerOptions other) {
super.copyFrom(other);
- setExtraDir(other.getExtraDir());
+ linkOptions.copyFrom(other);
}
public File getExtraDir() {
- return extraDir;
+ return linkOptions.getExtraDir();
+ }
+
+ public File getOutDir() {
+ return linkOptions.getOutDir();
}
public void setExtraDir(File extraDir) {
- this.extraDir = extraDir;
+ linkOptions.setExtraDir(extraDir);
+ }
+
+ public void setOutDir(File outDir) {
+ linkOptions.setOutDir(outDir);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/GWTHosted.java b/dev/core/src/com/google/gwt/dev/GWTHosted.java
index f81cb76..87bd0d4 100644
--- a/dev/core/src/com/google/gwt/dev/GWTHosted.java
+++ b/dev/core/src/com/google/gwt/dev/GWTHosted.java
@@ -23,6 +23,7 @@
import com.google.gwt.dev.shell.ArtifactAcceptor;
import com.google.gwt.dev.shell.GWTShellServletFilter;
import com.google.gwt.dev.shell.ServletContainer;
+import com.google.gwt.dev.shell.ServletContainerLauncher;
import com.google.gwt.dev.shell.jetty.JettyLauncher;
import com.google.gwt.dev.util.PerfLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
@@ -30,6 +31,7 @@
import com.google.gwt.util.tools.ArgHandlerString;
import java.io.PrintWriter;
+import java.net.BindException;
import java.util.HashSet;
import java.util.Set;
@@ -44,12 +46,6 @@
*/
protected class ArgHandlerModulesExtra extends ArgHandlerExtra {
- private final PrintWriterTreeLogger console = new PrintWriterTreeLogger(
- new PrintWriter(System.err));
- {
- console.setMaxDetail(TreeLogger.WARN);
- }
-
@Override
public boolean addExtraArg(String arg) {
return addModule(console, arg);
@@ -65,6 +61,32 @@
return new String[] {"module"};
}
}
+ /**
+ * Handles the -server command line flag.
+ */
+ protected class ArgHandlerServer extends ArgHandlerString {
+ @Override
+ public String getPurpose() {
+ return "Prevents the embedded Tomcat server from running, even if a port is specified";
+ }
+
+ @Override
+ public String getTag() {
+ return "-server";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[] {"serverLauncherClass"};
+ }
+
+ @Override
+ public boolean setString(String arg) {
+ // Supercedes -noserver.
+ setRunTomcat(true);
+ return setServer(console, arg);
+ }
+ }
/**
* Handles a startup url that can be passed on the command line.
@@ -100,7 +122,6 @@
* shutdown AWT related threads, since the contract for their termination is
* still implementation-dependent.
*/
- BootStrapPlatform.init();
GWTHosted shellMain = new GWTHosted();
if (shellMain.processArgs(args)) {
shellMain.run();
@@ -108,14 +129,37 @@
System.exit(0);
}
+ protected final PrintWriterTreeLogger console = new PrintWriterTreeLogger(
+ new PrintWriter(System.err, true));
+
+ /**
+ * The servlet launcher to use (defaults to embedded Jetty).
+ */
+ private ServletContainerLauncher launcher = new JettyLauncher();
+
+ /**
+ * The set of modules this hosted mode instance can run.
+ */
private Set<ModuleDef> modules = new HashSet<ModuleDef>();
+ /**
+ * The server that was started.
+ */
private ServletContainer server;
+ /**
+ * Our servlet filter, embedded into the server, which autogenerates GWT
+ * modules when the selection script is requested.
+ */
private GWTShellServletFilter servletFilter;
+ {
+ console.setMaxDetail(TreeLogger.WARN);
+ }
+
public GWTHosted() {
super(false, true);
+ registerHandler(new ArgHandlerServer());
registerHandler(new ArgHandlerStartupURLs());
registerHandler(new ArgHandlerModulesExtra());
}
@@ -127,11 +171,33 @@
modules.add(moduleDef);
return true;
} catch (UnableToCompleteException e) {
- System.err.println("Unable to load module '" + moduleName + "'");
+ logger.log(TreeLogger.ERROR, "Unable to load module '" + moduleName + "'");
return false;
}
}
+ public boolean setServer(TreeLogger logger, String serverClassName) {
+ Throwable t;
+ try {
+ Class<?> clazz = Class.forName(serverClassName, true,
+ Thread.currentThread().getContextClassLoader());
+ Class<? extends ServletContainerLauncher> sclClass = clazz.asSubclass(ServletContainerLauncher.class);
+ launcher = sclClass.newInstance();
+ return true;
+ } catch (ClassCastException e) {
+ t = e;
+ } catch (ClassNotFoundException e) {
+ t = e;
+ } catch (InstantiationException e) {
+ t = e;
+ } catch (IllegalAccessException e) {
+ t = e;
+ }
+ logger.log(TreeLogger.ERROR, "Unable to load server class '"
+ + serverClassName + "'", t);
+ return false;
+ }
+
@Override
protected ArtifactAcceptor doCreateArtifactAcceptor(final ModuleDef module) {
return new ArtifactAcceptor() {
@@ -156,8 +222,7 @@
@Override
protected int startUpServer() {
- PerfLogger.start("GWTShell.startup (Jetty launch)");
- JettyLauncher launcher = new JettyLauncher();
+ PerfLogger.start("GWTHosted.startUpServer");
try {
TreeLogger serverLogger = getTopLogger().branch(TreeLogger.INFO,
"Starting HTTP on port " + getPort(), null);
@@ -175,14 +240,18 @@
moduleArray);
server = launcher.start(serverLogger, getPort(), options.getOutDir(),
servletFilter);
- } catch (UnableToCompleteException e) {
+ assert (server != null);
+ return server.getPort();
+ } catch (BindException e) {
+ System.err.println("Port "
+ + getPort()
+ + " is already is use; you probably still have another session active");
+ } catch (Exception e) {
+ System.err.println("Unable to start embedded HTTP server");
+ e.printStackTrace();
+ } finally {
PerfLogger.end();
- return -1;
}
- assert (server != null);
-
- PerfLogger.end();
- return server.getPort();
+ return -1;
}
-
}
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
index 2da8519..460ec3f 100644
--- a/dev/core/src/com/google/gwt/dev/GWTShell.java
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -43,6 +43,7 @@
import com.google.gwt.dev.util.arg.ArgHandlerLogLevel;
import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
+import com.google.gwt.dev.util.arg.ArgHandlerWorkDir;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerFlag;
@@ -103,7 +104,7 @@
}
/**
- * handles the -noserver command line flag.
+ * Handles the -noserver command line flag.
*/
protected class ArgHandlerNoServerFlag extends ArgHandlerFlag {
@Override
@@ -378,7 +379,6 @@
* shutdown AWT related threads, since the contract for their termination is
* still implementation-dependent.
*/
- BootStrapPlatform.init();
GWTShell shellMain = new GWTShell();
if (shellMain.processArgs(args)) {
shellMain.run();
@@ -423,6 +423,10 @@
}
protected GWTShell(boolean forceServer, boolean noURLs) {
+ // Set any platform specific system properties.
+ BootStrapPlatform.init();
+ BootStrapPlatform.applyPlatformHacks();
+
registerHandler(getArgHandlerPort());
if (!forceServer) {
@@ -435,12 +439,13 @@
registerHandler(new ArgHandlerLogLevel(options));
registerHandler(new ArgHandlerGenDir(options));
- registerHandler(new ArgHandlerExtraDir(options));
+ registerHandler(new ArgHandlerWorkDir(options));
if (!noURLs) {
registerHandler(new ArgHandlerStartupURLsExtra());
}
+ registerHandler(new ArgHandlerExtraDir(options));
registerHandler(new ArgHandlerOutDir(options));
registerHandler(new ArgHandlerScriptStyle(options));
@@ -562,9 +567,6 @@
*/
public void run() {
try {
- // Set any platform specific system properties.
- BootStrapPlatform.applyPlatformHacks();
-
if (!startUp()) {
// Failed to initalize.
return;
diff --git a/dev/core/src/com/google/gwt/dev/Link.java b/dev/core/src/com/google/gwt/dev/Link.java
index d458108..97968b0 100644
--- a/dev/core/src/com/google/gwt/dev/Link.java
+++ b/dev/core/src/com/google/gwt/dev/Link.java
@@ -28,7 +28,9 @@
import com.google.gwt.dev.cfg.StaticPropertyOracle;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
+import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
import com.google.gwt.dev.util.arg.OptionExtraDir;
+import com.google.gwt.dev.util.arg.OptionOutDir;
import java.io.File;
import java.util.HashMap;
@@ -42,13 +44,15 @@
/**
* Options for Link.
*/
- public interface LinkOptions extends CompileTaskOptions, OptionExtraDir {
+ public interface LinkOptions extends CompileTaskOptions, OptionExtraDir,
+ OptionOutDir {
}
static class ArgProcessor extends CompileArgProcessor {
public ArgProcessor(LinkOptions options) {
super(options);
registerHandler(new ArgHandlerExtraDir(options));
+ registerHandler(new ArgHandlerOutDir(options));
}
@Override
@@ -64,6 +68,7 @@
LinkOptions {
private File extraDir;
+ private File outDir;
public LinkOptionsImpl() {
}
@@ -75,15 +80,24 @@
public void copyFrom(LinkOptions other) {
super.copyFrom(other);
setExtraDir(other.getExtraDir());
+ setOutDir(other.getOutDir());
}
public File getExtraDir() {
return extraDir;
}
+ public File getOutDir() {
+ return outDir;
+ }
+
public void setExtraDir(File extraDir) {
this.extraDir = extraDir;
}
+
+ public void setOutDir(File outDir) {
+ this.outDir = outDir;
+ }
}
public static ArtifactSet link(TreeLogger logger, ModuleDef module,
diff --git a/dev/core/src/com/google/gwt/dev/Precompile.java b/dev/core/src/com/google/gwt/dev/Precompile.java
index 627ef1e..a7e8bf0 100644
--- a/dev/core/src/com/google/gwt/dev/Precompile.java
+++ b/dev/core/src/com/google/gwt/dev/Precompile.java
@@ -26,6 +26,7 @@
import com.google.gwt.dev.cfg.PropertyPermutations;
import com.google.gwt.dev.cfg.Rules;
import com.google.gwt.dev.cfg.StaticPropertyOracle;
+import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationUnit;
import com.google.gwt.dev.jdt.RebindOracle;
import com.google.gwt.dev.jdt.RebindPermutationOracle;
@@ -37,6 +38,7 @@
import com.google.gwt.dev.jjs.UnifiedAst;
import com.google.gwt.dev.jjs.impl.FragmentLoaderCreator;
import com.google.gwt.dev.shell.StandardRebindOracle;
+import com.google.gwt.dev.util.PerfLogger;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.ArgHandlerDisableAggressiveOptimization;
import com.google.gwt.dev.util.arg.ArgHandlerEnableAssertions;
@@ -153,8 +155,8 @@
private RebindOracle[] rebindOracles;
public DistillerRebindPermutationOracle(ModuleDef module,
- ArtifactSet generatorArtifacts, PropertyPermutations perms,
- File genDir, File generatorResourcesDir) {
+ CompilationState compilationState, ArtifactSet generatorArtifacts,
+ PropertyPermutations perms, File genDir, File generatorResourcesDir) {
permutations = new Permutation[perms.size()];
propertyOracles = new StaticPropertyOracle[perms.size()];
rebindOracles = new RebindOracle[perms.size()];
@@ -166,9 +168,9 @@
String[] orderedPropValues = perms.getOrderedPropertyValues(i);
propertyOracles[i] = new StaticPropertyOracle(orderedProps,
orderedPropValues, configProps);
- rebindOracles[i] = new StandardRebindOracle(
- module.getCompilationState(), propertyOracles[i], module, rules,
- genDir, generatorResourcesDir, generatorArtifacts);
+ rebindOracles[i] = new StandardRebindOracle(compilationState,
+ propertyOracles[i], module, rules, genDir, generatorResourcesDir,
+ generatorArtifacts);
permutations[i] = new Permutation(propertyOracles[i]);
}
}
@@ -253,6 +255,8 @@
JJSOptions jjsOptions, ModuleDef module, File genDir,
File generatorResourcesDir) {
try {
+ CompilationState compilationState = module.getCompilationState(logger);
+
String[] declEntryPts = module.getEntryPointTypeNames();
if (declEntryPts.length == 0) {
logger.log(TreeLogger.ERROR, "Module has no entry points defined", null);
@@ -261,14 +265,18 @@
ArtifactSet generatedArtifacts = new ArtifactSet();
DistillerRebindPermutationOracle rpo = new DistillerRebindPermutationOracle(
- module, generatedArtifacts, new PropertyPermutations(
- module.getProperties()), genDir, generatorResourcesDir);
+ module, compilationState, generatedArtifacts,
+ new PropertyPermutations(module.getProperties()), genDir,
+ generatorResourcesDir);
FragmentLoaderCreator fragmentLoaderCreator = new FragmentLoaderCreator(
- module.getCompilationState(), module, genDir, generatorResourcesDir, generatedArtifacts);
+ compilationState, module, genDir, generatorResourcesDir,
+ generatedArtifacts);
WebModeCompilerFrontEnd frontEnd = new WebModeCompilerFrontEnd(
- module.getCompilationState(), rpo, fragmentLoaderCreator);
+ compilationState, rpo, fragmentLoaderCreator);
+ PerfLogger.start("Precompile");
UnifiedAst unifiedAst = JavaToJavaScriptCompiler.precompile(logger,
frontEnd, declEntryPts, jjsOptions, rpo.getPermuationCount() == 1);
+ PerfLogger.end();
// Merge all identical permutations together.
Permutation[] permutations = rpo.getPermutations();
@@ -307,10 +315,12 @@
public static boolean validate(TreeLogger logger, JJSOptions jjsOptions,
ModuleDef module, File genDir, File generatorResourcesDir) {
try {
+ CompilationState compilationState = module.getCompilationState(logger);
+
String[] declEntryPts = module.getEntryPointTypeNames();
if (declEntryPts.length == 0) {
// Pretend that every single compilation unit is an entry point.
- Set<CompilationUnit> compilationUnits = module.getCompilationState().getCompilationUnits();
+ Set<CompilationUnit> compilationUnits = compilationState.getCompilationUnits();
declEntryPts = new String[compilationUnits.size()];
int i = 0;
for (CompilationUnit unit : compilationUnits) {
@@ -320,12 +330,14 @@
ArtifactSet generatorArtifacts = new ArtifactSet();
DistillerRebindPermutationOracle rpo = new DistillerRebindPermutationOracle(
- module, generatorArtifacts, new PropertyPermutations(
- module.getProperties()), genDir, generatorResourcesDir);
+ module, compilationState, generatorArtifacts,
+ new PropertyPermutations(module.getProperties()), genDir,
+ generatorResourcesDir);
FragmentLoaderCreator fragmentLoaderCreator = new FragmentLoaderCreator(
- module.getCompilationState(), module, genDir, generatorResourcesDir, generatorArtifacts);
+ compilationState, module, genDir, generatorResourcesDir,
+ generatorArtifacts);
WebModeCompilerFrontEnd frontEnd = new WebModeCompilerFrontEnd(
- module.getCompilationState(), rpo, fragmentLoaderCreator);
+ compilationState, rpo, fragmentLoaderCreator);
JavaToJavaScriptCompiler.precompile(logger, frontEnd, declEntryPts,
jjsOptions, true);
return true;
@@ -388,6 +400,6 @@
options.getModuleName());
// TODO: All JDT checks now before even building TypeOracle?
- module.getCompilationState().compile(logger);
+ module.getCompilationState(logger);
}
}
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
index b4e4b1e..cbc3e39 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
@@ -85,14 +85,14 @@
private Class<? extends Linker> activePrimaryLinker;
- private CompilationState compilationState;
-
private String deployTo;
private final List<String> entryPointTypeNames = new ArrayList<String>();
private final Set<File> gwtXmlFiles = new HashSet<File>();
+ private CompilationState lazyCompilationState;
+
private JavaSourceOracle lazyJavaSourceOracle;
private ResourceOracleImpl lazyPublicOracle;
@@ -262,8 +262,11 @@
return name;
}
- public CompilationState getCompilationState() {
- return compilationState;
+ public CompilationState getCompilationState(TreeLogger logger) {
+ if (lazyCompilationState == null) {
+ lazyCompilationState = new CompilationState(logger, lazyJavaSourceOracle);
+ }
+ return lazyCompilationState;
}
/**
@@ -333,8 +336,29 @@
public synchronized TypeOracle getTypeOracle(TreeLogger logger)
throws UnableToCompleteException {
if (lazyTypeOracle == null) {
- lazyTypeOracle = compilationState.getTypeOracle();
- updateTypeOracle(logger);
+ lazyTypeOracle = getCompilationState(logger).getTypeOracle();
+
+ // Sanity check the seed types and don't even start it they're missing.
+ boolean seedTypesMissing = false;
+ if (lazyTypeOracle.findType("java.lang.Object") == null) {
+ Util.logMissingTypeErrorWithHints(logger, "java.lang.Object");
+ seedTypesMissing = true;
+ } else {
+ TreeLogger branch = logger.branch(TreeLogger.TRACE,
+ "Finding entry point classes", null);
+ String[] typeNames = getEntryPointTypeNames();
+ for (int i = 0; i < typeNames.length; i++) {
+ String typeName = typeNames[i];
+ if (lazyTypeOracle.findType(typeName) == null) {
+ Util.logMissingTypeErrorWithHints(branch, typeName);
+ seedTypesMissing = true;
+ }
+ }
+ }
+
+ if (seedTypesMissing) {
+ throw new UnableToCompleteException();
+ }
}
return lazyTypeOracle;
}
@@ -371,11 +395,13 @@
lazySourceOracle.refresh(logger);
// Update the compilation state to reflect the resource oracle changes.
- compilationState.refresh();
+ if (lazyCompilationState != null) {
+ lazyCompilationState.refresh(logger);
+ }
// Refresh type oracle if needed.
if (lazyTypeOracle != null) {
- updateTypeOracle(logger);
+ getTypeOracle(logger);
}
PerfLogger.end();
}
@@ -470,9 +496,6 @@
}
lazyJavaSourceOracle = new JavaSourceOracleImpl(lazySourceOracle);
- // Create the compilation state.
- compilationState = new CompilationState(lazyJavaSourceOracle);
-
PerfLogger.end();
}
@@ -499,37 +522,4 @@
return scanner;
}
- private void updateTypeOracle(TreeLogger logger)
- throws UnableToCompleteException {
- PerfLogger.start("ModuleDef.updateTypeOracle");
- TreeLogger branch = logger.branch(TreeLogger.TRACE,
- "Compiling Java source files in module '" + getName() + "'");
- compilationState.compile(branch);
- PerfLogger.end();
-
- TypeOracle typeOracle = compilationState.getTypeOracle();
-
- // Sanity check the seed types and don't even start it they're missing.
- boolean seedTypesMissing = false;
- if (typeOracle.findType("java.lang.Object") == null) {
- Util.logMissingTypeErrorWithHints(logger, "java.lang.Object");
- seedTypesMissing = true;
- } else {
- branch = logger.branch(TreeLogger.TRACE, "Finding entry point classes",
- null);
- String[] typeNames = getEntryPointTypeNames();
- for (int i = 0; i < typeNames.length; i++) {
- String typeName = typeNames[i];
- if (typeOracle.findType(typeName) == null) {
- Util.logMissingTypeErrorWithHints(branch, typeName);
- seedTypesMissing = true;
- }
- }
- }
-
- if (seedTypesMissing) {
- throw new UnableToCompleteException();
- }
- }
-
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
index 1af9a10..a63ae7b 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
@@ -16,7 +16,6 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.CompilationUnit.State;
import com.google.gwt.dev.javac.impl.SourceFileCompilationUnit;
@@ -40,34 +39,17 @@
*/
public class CompilationState {
- /**
- * Compute the set of all valid binary type names (for
- * {@link BinaryTypeReferenceRestrictionsChecker}.
- */
- private static Set<String> getValidBinaryTypeNames(Set<CompilationUnit> units) {
- Set<String> validBinaryTypeNames = new HashSet<String>();
+ private static void markSurvivorsChecked(Set<CompilationUnit> units) {
for (CompilationUnit unit : units) {
- switch (unit.getState()) {
- case COMPILED:
- for (ClassFile classFile : unit.getJdtCud().compilationResult().getClassFiles()) {
- char[] binaryName = CharOperation.concatWith(
- classFile.getCompoundName(), '/');
- validBinaryTypeNames.add(String.valueOf(binaryName));
- }
- break;
- case CHECKED:
- for (CompiledClass compiledClass : unit.getCompiledClasses()) {
- validBinaryTypeNames.add(compiledClass.getBinaryName());
- }
- break;
+ if (unit.getState() == State.COMPILED) {
+ unit.setState(State.CHECKED);
}
}
- return validBinaryTypeNames;
}
protected final Map<String, CompilationUnit> unitMap = new HashMap<String, CompilationUnit>();
- private Set<JavaSourceFile> cachedSourceFiles = Collections.emptySet();
+ private Set<JavaSourceFile> cachedSourceFiles = Collections.emptySet();
/**
* Classes mapped by binary name.
*/
@@ -83,68 +65,55 @@
*/
private final Map<String, CompilationUnit> exposedUnitMap = Collections.unmodifiableMap(unitMap);
+ /**
+ * Unmodifiable view of all units.
+ */
private Set<CompilationUnit> exposedUnits = Collections.emptySet();
+
+ /**
+ * Recreated on refresh, allows incremental compiles.
+ */
+ private JdtCompiler jdtCompiler;
+
+ /**
+ * Controls our type oracle.
+ */
private final TypeOracleMediator mediator = new TypeOracleMediator();
+
+ /**
+ * Our source file inputs.
+ */
private final JavaSourceOracle sourceOracle;
/**
+ * Tracks the set of valid binary type names for
+ * {@link BinaryTypeReferenceRestrictionsChecker}.
+ */
+ private final Set<String> validBinaryTypeNames = new HashSet<String>();
+
+ /**
* Construct a new {@link CompilationState}.
*
* @param sourceOracle an oracle used to retrieve source code and check for
* changes in the underlying source code base
*/
- public CompilationState(JavaSourceOracle sourceOracle) {
+ public CompilationState(TreeLogger logger, JavaSourceOracle sourceOracle) {
this.sourceOracle = sourceOracle;
- refresh();
+ refresh(logger);
}
- public void addGeneratedCompilationUnit(CompilationUnit unit) {
- String typeName = unit.getTypeName();
- assert (!unitMap.containsKey(typeName));
- unitMap.put(typeName, unit);
- updateExposedUnits();
- }
-
- /**
- * Compile all units and updates all internal state. Invalidate any units with
- * compile errors.
- */
- public void compile(TreeLogger logger) throws UnableToCompleteException {
- PerfLogger.start("CompilationState.compile");
- Set<CompilationUnit> units = getCompilationUnits();
- if (JdtCompiler.compile(units)) {
- Set<String> validBinaryTypeNames = getValidBinaryTypeNames(units);
-
- // Dump all units with direct errors; we cannot safely check them.
- boolean anyErrors = CompilationUnitInvalidator.invalidateUnitsWithErrors(
- logger, units);
-
- // Check all units using our custom checks.
- CompilationUnitInvalidator.validateCompilationUnits(units,
- validBinaryTypeNames);
-
- // More units may have errors now.
- anyErrors |= CompilationUnitInvalidator.invalidateUnitsWithErrors(logger,
- units);
-
- if (anyErrors) {
- CompilationUnitInvalidator.invalidateUnitsWithInvalidRefs(logger, units);
- }
-
- JsniCollector.collectJsniMethods(logger, units, new JsProgram());
+ @SuppressWarnings("unchecked")
+ public void addGeneratedCompilationUnits(TreeLogger logger,
+ Set<? extends CompilationUnit> generatedCups) {
+ for (CompilationUnit unit : generatedCups) {
+ String typeName = unit.getTypeName();
+ assert (!unitMap.containsKey(typeName));
+ unitMap.put(typeName, unit);
}
-
- mediator.refresh(logger, units);
-
- // Any surviving units are now considered CHECKED.
- for (CompilationUnit unit : units) {
- if (unit.getState() == State.COMPILED) {
- unit.setState(State.CHECKED);
- }
- }
-
updateExposedUnits();
- PerfLogger.end();
+ compile(logger, (Set<CompilationUnit>) generatedCups);
+ mediator.addNewUnits(logger, (Set<CompilationUnit>) generatedCups);
+ markSurvivorsChecked((Set<CompilationUnit>) generatedCups);
}
/**
@@ -193,7 +162,7 @@
*
* TODO: something more optimal with generated files?
*/
- public void refresh() {
+ public void refresh(TreeLogger logger) {
// Always remove all generated compilation units.
for (Iterator<CompilationUnit> it = unitMap.values().iterator(); it.hasNext();) {
CompilationUnit unit = it.next();
@@ -204,10 +173,49 @@
}
refreshFromSourceOracle();
+ updateExposedUnits();
+
// Don't log about invalidated units via refresh.
CompilationUnitInvalidator.invalidateUnitsWithInvalidRefs(TreeLogger.NULL,
getCompilationUnits());
- updateExposedUnits();
+
+ jdtCompiler = new JdtCompiler();
+ validBinaryTypeNames.clear();
+ compile(logger, getCompilationUnits());
+ mediator.refresh(logger, getCompilationUnits());
+ markSurvivorsChecked(getCompilationUnits());
+ }
+
+ /**
+ * Compile units and update their internal state. Invalidate any units with
+ * compile errors.
+ */
+ private void compile(TreeLogger logger, Set<CompilationUnit> newUnits) {
+ PerfLogger.start("CompilationState.compile");
+ if (jdtCompiler.doCompile(newUnits)) {
+ // Dump all units with direct errors; we cannot safely check them.
+ boolean anyErrors = CompilationUnitInvalidator.invalidateUnitsWithErrors(
+ logger, newUnits);
+
+ // Check all units using our custom checks.
+ CompilationUnitInvalidator.validateCompilationUnits(newUnits,
+ validBinaryTypeNames);
+
+ // More units may have errors now.
+ anyErrors |= CompilationUnitInvalidator.invalidateUnitsWithErrors(logger,
+ newUnits);
+
+ if (anyErrors) {
+ CompilationUnitInvalidator.invalidateUnitsWithInvalidRefs(logger,
+ newUnits);
+ }
+
+ recordValidBinaryTypeNames(newUnits);
+
+ JsniCollector.collectJsniMethods(logger, newUnits, new JsProgram());
+ }
+
+ PerfLogger.end();
}
private void rebuildClassMaps() {
@@ -225,6 +233,18 @@
exposedClassFileMapBySource = Collections.unmodifiableMap(classFileMapBySource);
}
+ private void recordValidBinaryTypeNames(Set<CompilationUnit> units) {
+ for (CompilationUnit unit : units) {
+ if (unit.getState() == State.COMPILED) {
+ for (ClassFile classFile : unit.getJdtCud().compilationResult().getClassFiles()) {
+ char[] binaryName = CharOperation.concatWith(
+ classFile.getCompoundName(), '/');
+ validBinaryTypeNames.add(String.valueOf(binaryName));
+ }
+ }
+ }
+ }
+
private void refreshFromSourceOracle() {
// See if the source oracle has changed.
Set<JavaSourceFile> newSourceFiles = sourceOracle.getSourceFiles();
diff --git a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
index f9e19a7..b02a342 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
@@ -98,11 +98,12 @@
@Override
public void process(CompilationUnitDeclaration cud, int i) {
- // TODO: not always generate bytecode eagerly?
super.process(cud, i);
ICompilationUnit icu = cud.compilationResult().compilationUnit;
CompilationUnitAdapter adapter = (CompilationUnitAdapter) icu;
- adapter.getUnit().setJdtCud(cud);
+ CompilationUnit unit = adapter.getUnit();
+ unit.setJdtCud(cud);
+ recordBinaryTypes(unit.getCompiledClasses());
}
}
@@ -228,8 +229,6 @@
return new CompilerOptions(settings);
}
- private final List<CompilationUnit> activeUnits = new ArrayList<CompilationUnit>();
-
/**
* Maps dotted binary names to compiled classes.
*/
@@ -244,7 +243,29 @@
/**
* Not externally instantiable.
*/
- private JdtCompiler() {
+ public JdtCompiler() {
+ }
+
+ public boolean doCompile(Collection<CompilationUnit> units) {
+ List<ICompilationUnit> icus = new ArrayList<ICompilationUnit>();
+ for (CompilationUnit unit : units) {
+ String packageName = Shared.getPackageName(unit.getTypeName());
+ addPackages(packageName);
+ Set<CompiledClass> compiledClasses = unit.getCompiledClasses();
+ if (compiledClasses == null) {
+ icus.add(new CompilationUnitAdapter(unit));
+ } else {
+ recordBinaryTypes(compiledClasses);
+ }
+ }
+ if (icus.isEmpty()) {
+ return false;
+ }
+
+ PerfLogger.start("JdtCompiler.compile");
+ compiler.compile(icus.toArray(new ICompilationUnit[icus.size()]));
+ PerfLogger.end();
+ return true;
}
private void addPackages(String packageName) {
@@ -260,30 +281,11 @@
}
}
- private boolean doCompile(Collection<CompilationUnit> units) {
- List<ICompilationUnit> icus = new ArrayList<ICompilationUnit>();
- for (CompilationUnit unit : units) {
- String packageName = Shared.getPackageName(unit.getTypeName());
- addPackages(packageName);
- Set<CompiledClass> compiledClasses = unit.getCompiledClasses();
- if (compiledClasses == null) {
- icus.add(new CompilationUnitAdapter(unit));
- activeUnits.add(unit);
- } else {
- for (CompiledClass compiledClass : compiledClasses) {
- binaryTypes.put(compiledClass.getBinaryName().replace('/', '.'),
- compiledClass);
- }
- }
+ private void recordBinaryTypes(Set<CompiledClass> compiledClasses) {
+ for (CompiledClass compiledClass : compiledClasses) {
+ binaryTypes.put(compiledClass.getBinaryName().replace('/', '.'),
+ compiledClass);
}
- if (icus.isEmpty()) {
- return false;
- }
-
- PerfLogger.start("JdtCompiler.compile");
- compiler.compile(icus.toArray(new ICompilationUnit[icus.size()]));
- PerfLogger.end();
- return true;
}
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java b/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
index 885f0d4..63e4a4e 100644
--- a/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
+++ b/dev/core/src/com/google/gwt/dev/javac/TypeOracleMediator.java
@@ -16,7 +16,6 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.HasMetaData;
import com.google.gwt.core.ext.typeinfo.HasTypeParameters;
import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
@@ -37,12 +36,10 @@
import com.google.gwt.core.ext.typeinfo.JRealClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
-import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.core.ext.typeinfo.JWildcardType.BoundType;
import com.google.gwt.dev.javac.impl.Shared;
import com.google.gwt.dev.util.Empty;
-import com.google.gwt.dev.util.PerfLogger;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
@@ -336,22 +333,28 @@
private final Map<String, JRealClassType> binaryMapper = new HashMap<String, JRealClassType>();
private final Map<SourceTypeBinding, JRealClassType> sourceMapper = new IdentityHashMap<SourceTypeBinding, JRealClassType>();
- private final Map<TypeVariableBinding, JTypeParameter> tvMapper = new IdentityHashMap<TypeVariableBinding, JTypeParameter>();
+
+ /**
+ * Mapping of type variable bindings; transient because compilation units are
+ * processed monolithically, and a tv binding is only valid within a single
+ * unit.
+ */
+ private final transient Map<TypeVariableBinding, JTypeParameter> tvMapper = new IdentityHashMap<TypeVariableBinding, JTypeParameter>();
+
private final TypeOracle typeOracle = new TypeOracle();
- private final Set<JRealClassType> unresolvedTypes = new HashSet<JRealClassType>();
- public TypeOracle getTypeOracle() {
- return typeOracle;
- }
+ /**
+ * Set of unresolved types to process, generated from the first phase of type
+ * oracle resolution. Transient because they all get resolved in the second
+ * phase.
+ */
+ private final transient Set<JRealClassType> unresolvedTypes = new HashSet<JRealClassType>();
- public void refresh(TreeLogger logger, Set<CompilationUnit> units)
- throws UnableToCompleteException {
- PerfLogger.start("TypeOracleMediator.refresh");
- typeOracle.removeInvalidatedTypes();
- clear();
-
+ /**
+ * Adds new units to an existing TypeOracle.
+ */
+ public void addNewUnits(TreeLogger logger, Set<CompilationUnit> units) {
// Perform a shallow pass to establish identity for new and old types.
- PerfLogger.start("TypeOracleMediator.refresh (shallow)");
for (CompilationUnit unit : units) {
if (!unit.isCompiled()) {
continue;
@@ -365,10 +368,8 @@
binaryMapper.put(compiledClass.getBinaryName(), type);
}
}
- PerfLogger.end();
// Perform a deep pass to resolve all new types in terms of our types.
- PerfLogger.start("TypeOracleMediator.refresh (deep)");
for (CompilationUnit unit : units) {
if (!unit.isCompiled()) {
continue;
@@ -377,9 +378,10 @@
"Processing types in compilation unit: " + unit.getDisplayLocation());
Set<CompiledClass> compiledClasses = unit.getCompiledClasses();
for (CompiledClass compiledClass : compiledClasses) {
- if (unresolvedTypes.contains(compiledClass.getRealClassType())) {
+ if (unresolvedTypes.remove(compiledClass.getRealClassType())) {
TypeDeclaration typeDeclaration = compiledClass.getTypeDeclaration();
- if (!resolveTypeDeclaration(cudLogger, unit.getSource(), typeDeclaration)) {
+ if (!resolveTypeDeclaration(cudLogger, unit.getSource(),
+ typeDeclaration)) {
logger.log(TreeLogger.WARN,
"Unexpectedly unable to fully resolve type "
+ compiledClass.getSourceName());
@@ -387,24 +389,25 @@
}
}
}
- clear();
- PerfLogger.end();
+ // Clean transient state.
+ assert unresolvedTypes.size() == 0;
+ tvMapper.clear();
- try {
- typeOracle.refresh(logger);
- } catch (NotFoundException e) {
- // TODO
- e.printStackTrace();
- }
-
- PerfLogger.end();
+ typeOracle.finish(logger);
}
- private void clear() {
+ public TypeOracle getTypeOracle() {
+ return typeOracle;
+ }
+
+ /**
+ * Full refresh based on new units.
+ */
+ public void refresh(TreeLogger logger, Set<CompilationUnit> units) {
binaryMapper.clear();
sourceMapper.clear();
- tvMapper.clear();
- unresolvedTypes.clear();
+ typeOracle.reset();
+ addNewUnits(logger, units);
}
private Object createAnnotationInstance(TreeLogger logger,
diff --git a/dev/core/src/com/google/gwt/dev/shell/ServletContainerLauncher.java b/dev/core/src/com/google/gwt/dev/shell/ServletContainerLauncher.java
index e3896e2..d9ef731 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ServletContainerLauncher.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ServletContainerLauncher.java
@@ -16,9 +16,9 @@
package com.google.gwt.dev.shell;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import java.io.File;
+import java.net.BindException;
import javax.servlet.Filter;
@@ -28,6 +28,18 @@
*/
public interface ServletContainerLauncher {
- ServletContainer start(TreeLogger topLogger, int port, File appRootDir,
- Filter shellServletFilter) throws UnableToCompleteException;
+ /**
+ * Start an embedded HTTP server.
+ *
+ * @param logger the server logger
+ * @param port the TCP port to serve on
+ * @param appRootDir the base WAR directory
+ * @param filter a servlet filter that must be installed on the root path to
+ * serve generated files
+ * @return the launch servlet contained
+ * @throws BindException if the requested port is already in use
+ * @throws Exception if the server fails to start for any other reason
+ */
+ ServletContainer start(TreeLogger logger, int port, File appRootDir,
+ Filter filter) throws BindException, Exception;
}
diff --git a/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java b/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java
index 38f106f..0a526c3 100644
--- a/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java
+++ b/dev/core/src/com/google/gwt/dev/shell/ShellModuleSpaceHost.java
@@ -90,7 +90,7 @@
// It has to wait until now because we need to inject javascript.
//
Rules rules = module.getRules();
- rebindOracle = new StandardRebindOracle(module.getCompilationState(),
+ rebindOracle = new StandardRebindOracle(module.getCompilationState(logger),
propOracle, module, rules, genDir, shellDir, new ArtifactSet());
// Create a completely isolated class loader which owns all classes
@@ -105,7 +105,7 @@
// class loader (the one that loaded the shell itself).
//
classLoader = new CompilingClassLoader(logger,
- module.getCompilationState(), readySpace);
+ module.getCompilationState(logger), readySpace);
}
public String rebind(TreeLogger logger, String sourceTypeName)
diff --git a/dev/core/src/com/google/gwt/dev/shell/StandardGeneratorContext.java b/dev/core/src/com/google/gwt/dev/shell/StandardGeneratorContext.java
index 64687f5..06ba50e 100644
--- a/dev/core/src/com/google/gwt/dev/shell/StandardGeneratorContext.java
+++ b/dev/core/src/com/google/gwt/dev/shell/StandardGeneratorContext.java
@@ -308,14 +308,14 @@
String qualifiedTypeName = gcup.getTypeName();
genTypeNames.add(qualifiedTypeName);
maybeWriteSource(gcup, qualifiedTypeName);
- compilationState.addGeneratedCompilationUnit(gcup);
if (subBranch != null) {
subBranch.log(TreeLogger.DEBUG, gcup.getDisplayLocation(), null);
}
}
- compilationState.compile(logger);
+ compilationState.addGeneratedCompilationUnits(logger,
+ committedGeneratedCups);
}
// Make sure all generated types can be found in TypeOracle.
diff --git a/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java b/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
index 9a6b12b..832311d 100644
--- a/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
+++ b/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java
@@ -191,7 +191,7 @@
@SuppressWarnings("unchecked")
public ServletContainer start(TreeLogger logger, int port, File appRootDir,
- Filter shellServletFilter) throws UnableToCompleteException {
+ Filter shellServletFilter) throws Exception {
checkStartParams(logger, port, appRootDir);
// The dance we do with Jetty's logging system.
@@ -210,6 +210,9 @@
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(port);
connector.setHost("127.0.0.1");
+ // Don't steal ports from an existing proc.
+ connector.setReuseAddress(false);
+
server.addConnector(connector);
// Create a new web app in the war directory.
@@ -227,15 +230,10 @@
server.setHandler(wac);
server.setStopAtShutdown(true);
+ server.start();
- try {
- server.start();
- int actualPort = connector.getPort();
- return new JettyServletContainer(logger, wac, actualPort, appRootDir);
- } catch (Exception e) {
- logger.log(TreeLogger.ERROR, "Unable to start embedded Jetty server", e);
- throw new UnableToCompleteException();
- }
+ return new JettyServletContainer(logger, wac, connector.getLocalPort(),
+ appRootDir);
}
private void checkStartParams(TreeLogger logger, int port, File appRootDir) {
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerWorkDir.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerWorkDir.java
new file mode 100644
index 0000000..c08130f
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerWorkDir.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.util.arg;
+
+import com.google.gwt.util.tools.ArgHandlerDir;
+
+import java.io.File;
+
+/**
+ * Argument handler for processing the output directory flag.
+ */
+public final class ArgHandlerWorkDir extends ArgHandlerDir {
+
+ public static final String GWT_TMP_DIR = "gwt-tmp";
+
+ private final OptionWorkDir option;
+
+ public ArgHandlerWorkDir(OptionWorkDir option) {
+ this.option = option;
+ }
+
+ public String[] getDefaultArgs() {
+ return new String[] {
+ "-workDir",
+ new File(System.getProperty("java.io.tmpdir"), GWT_TMP_DIR).getAbsolutePath()};
+ }
+
+ public String getPurpose() {
+ return "The compiler work directory (must be writeable; defaults to system temp dir)";
+ }
+
+ public String getTag() {
+ return "-workDir";
+ }
+
+ @Override
+ public void setDir(File dir) {
+ option.setWorkDir(dir);
+ }
+
+}
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/OptionWorkDir.java b/dev/core/src/com/google/gwt/dev/util/arg/OptionWorkDir.java
new file mode 100644
index 0000000..acd8539
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/OptionWorkDir.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.util.arg;
+
+import java.io.File;
+
+/**
+ * Option to set the compiler working directory.
+ */
+public interface OptionWorkDir {
+
+ /**
+ * Returns the compiler work directory.
+ */
+ File getWorkDir();
+
+ /**
+ * Sets the compiler work directory.
+ */
+ void setWorkDir(File dir);
+}
diff --git a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java
index 23cdb49..6c1a9ad 100644
--- a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java
@@ -16,7 +16,6 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.CompilationUnit.State;
import com.google.gwt.dev.javac.impl.MockJavaSourceFile;
import com.google.gwt.dev.javac.impl.SourceFileCompilationUnit;
@@ -38,23 +37,6 @@
*/
public class CompilationStateTest extends TestCase {
- private MockJavaSourceOracle oracle = new MockJavaSourceOracle(
- JavaSourceCodeBase.getStandardResources());
-
- private CompilationState state = new CompilationState(oracle);
-
- public void testAddGeneratedCompilationUnit() {
- validateCompilationState();
-
- // Add a unit and ensure it shows up.
- addGeneratedUnit(JavaSourceCodeBase.FOO);
- validateCompilationState(JavaSourceCodeBase.FOO.getTypeName());
-
- // Ensure it disappears after a refresh.
- state.refresh();
- validateCompilationState();
- }
-
static void assertUnitsChecked(Collection<CompilationUnit> units) {
for (CompilationUnit unit : units) {
assertSame(State.CHECKED, unit.getState());
@@ -63,17 +45,41 @@
}
}
- public void testCompile() throws UnableToCompleteException {
- validateUncompiled();
- state.compile(createTreeLogger());
- assertUnitsChecked(state.getCompilationUnits());
+ /**
+ * Tweak this if you want to see the log output.
+ */
+ private static TreeLogger createTreeLogger() {
+ boolean reallyLog = false;
+ if (reallyLog) {
+ AbstractTreeLogger logger = new PrintWriterTreeLogger();
+ logger.setMaxDetail(TreeLogger.ALL);
+ return logger;
+ } else {
+ return TreeLogger.NULL;
+ }
}
- public void testCompileError() throws UnableToCompleteException {
+ private MockJavaSourceOracle oracle = new MockJavaSourceOracle(
+ JavaSourceCodeBase.getStandardResources());
+
+ private CompilationState state = new CompilationState(createTreeLogger(),
+ oracle);
+
+ public void testAddGeneratedCompilationUnit() {
+ validateCompilationState();
+
+ // Add a unit and ensure it shows up.
+ addGeneratedUnits(JavaSourceCodeBase.FOO);
+ validateCompilationState(JavaSourceCodeBase.FOO.getTypeName());
+
+ // Ensure it disappears after a refresh.
+ state.refresh(createTreeLogger());
+ validateCompilationState();
+ }
+
+ public void testCompileError() {
oracle.add(JavaSourceCodeBase.BAR);
- state.refresh();
- validateUncompiled();
- state.compile(createTreeLogger());
+ state.refresh(createTreeLogger());
CompilationUnit badUnit = state.getCompilationUnitMap().get(
JavaSourceCodeBase.BAR.getTypeName());
@@ -85,22 +91,15 @@
assertUnitsChecked(goodUnits);
}
- public void testCompileWithGeneratedUnits() throws UnableToCompleteException {
- validateUncompiled();
- state.compile(createTreeLogger());
+ public void testCompileWithGeneratedUnits() {
assertUnitsChecked(state.getCompilationUnits());
- addGeneratedUnit(JavaSourceCodeBase.FOO);
- state.compile(createTreeLogger());
+ addGeneratedUnits(JavaSourceCodeBase.FOO);
assertUnitsChecked(state.getCompilationUnits());
}
- public void testCompileWithGeneratedUnitsError()
- throws UnableToCompleteException {
- validateUncompiled();
- state.compile(createTreeLogger());
+ public void testCompileWithGeneratedUnitsError() {
assertUnitsChecked(state.getCompilationUnits());
- addGeneratedUnit(JavaSourceCodeBase.BAR);
- state.compile(createTreeLogger());
+ addGeneratedUnits(JavaSourceCodeBase.BAR);
CompilationUnit badUnit = state.getCompilationUnitMap().get(
JavaSourceCodeBase.BAR.getTypeName());
@@ -112,12 +111,16 @@
assertUnitsChecked(goodUnits);
}
+ public void testInitialization() {
+ assertUnitsChecked(state.getCompilationUnits());
+ }
+
public void testSourceOracleAdd() {
validateCompilationState();
int size = state.getCompilationUnits().size();
oracle.add(JavaSourceCodeBase.FOO);
- state.refresh();
+ state.refresh(createTreeLogger());
assertEquals(size + 1, state.getCompilationUnits().size());
validateCompilationState();
}
@@ -128,7 +131,7 @@
public void testSourceOracleEmpty() {
oracle = new MockJavaSourceOracle();
- state = new CompilationState(oracle);
+ state = new CompilationState(createTreeLogger(), oracle);
validateCompilationState();
}
@@ -137,7 +140,7 @@
int size = state.getCompilationUnits().size();
oracle.remove(JavaSourceCodeBase.OBJECT.getTypeName());
- state.refresh();
+ state.refresh(createTreeLogger());
assertEquals(size - 1, state.getCompilationUnits().size());
validateCompilationState();
}
@@ -147,7 +150,7 @@
int size = state.getCompilationUnits().size();
oracle.replace(new MockJavaSourceFile(JavaSourceCodeBase.OBJECT));
- state.refresh();
+ state.refresh(createTreeLogger());
assertEquals(size, state.getCompilationUnits().size());
validateCompilationState();
}
@@ -157,18 +160,22 @@
int size = state.getCompilationUnits().size();
oracle.replace(JavaSourceCodeBase.OBJECT);
- state.refresh();
+ state.refresh(createTreeLogger());
assertEquals(size, state.getCompilationUnits().size());
validateCompilationState();
}
- private void addGeneratedUnit(JavaSourceFile sourceFile) {
- state.addGeneratedCompilationUnit(new SourceFileCompilationUnit(sourceFile) {
- @Override
- public boolean isGenerated() {
- return true;
- }
- });
+ private void addGeneratedUnits(JavaSourceFile... sourceFiles) {
+ Set<CompilationUnit> units = new HashSet<CompilationUnit>();
+ for (JavaSourceFile sourceFile : sourceFiles) {
+ units.add(new SourceFileCompilationUnit(sourceFile) {
+ @Override
+ public boolean isGenerated() {
+ return true;
+ }
+ });
+ }
+ state.addGeneratedCompilationUnits(createTreeLogger(), units);
}
private void validateCompilationState(String... generatedTypeNames) {
@@ -205,24 +212,4 @@
assertEquals(0, sourceMap.size());
assertEquals(0, generatedTypes.size());
}
-
- private void validateUncompiled() {
- for (CompilationUnit unit : state.getCompilationUnits()) {
- assertNull(unit.getJdtCud());
- }
- }
-
- /**
- * Tweak this if you want to see the log output.
- */
- private TreeLogger createTreeLogger() {
- boolean reallyLog = false;
- if (reallyLog) {
- AbstractTreeLogger logger = new PrintWriterTreeLogger();
- logger.setMaxDetail(TreeLogger.ALL);
- return logger;
- } else {
- return TreeLogger.NULL;
- }
- }
}
diff --git a/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java b/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java
index ce0305d..b8eb521 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JSORestrictionsTest.java
@@ -16,14 +16,13 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.util.UnitTestTreeLogger;
import junit.framework.TestCase;
public class JSORestrictionsTest extends TestCase {
- public void testFinalClass() throws UnableToCompleteException {
+ public void testFinalClass() {
StringBuffer code = new StringBuffer();
code.append("import com.google.gwt.core.client.JavaScriptObject;\n");
code.append("final public class Buggy extends JavaScriptObject {\n");
@@ -34,7 +33,7 @@
shouldGenerateNoError(code);
}
- public void testInstanceField() throws UnableToCompleteException {
+ public void testInstanceField() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy extends JavaScriptObject {\n");
@@ -46,7 +45,7 @@
+ JSORestrictionsChecker.ERR_INSTANCE_FIELD);
}
- public void testMultiArgConstructor() throws UnableToCompleteException {
+ public void testMultiArgConstructor() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public final class Buggy extends JavaScriptObject {\n");
@@ -57,7 +56,7 @@
+ JSORestrictionsChecker.ERR_CONSTRUCTOR_WITH_PARAMETERS);
}
- public void testNew() throws UnableToCompleteException {
+ public void testNew() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy {\n");
@@ -71,7 +70,7 @@
+ JSORestrictionsChecker.ERR_NEW_JSO);
}
- public void testNoConstructor() throws UnableToCompleteException {
+ public void testNoConstructor() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy extends JavaScriptObject {\n");
@@ -82,7 +81,7 @@
+ JSORestrictionsChecker.ERR_NONPROTECTED_CONSTRUCTOR);
}
- public void testNoInterfaces() throws UnableToCompleteException {
+ public void testNoInterfaces() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy {\n");
@@ -99,7 +98,7 @@
+ JSORestrictionsChecker.errInterfaceWithMethods("Buggy.Squeaks"));
}
- public void testNonEmptyConstructor() throws UnableToCompleteException {
+ public void testNonEmptyConstructor() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy extends JavaScriptObject {\n");
@@ -110,7 +109,7 @@
+ JSORestrictionsChecker.ERR_NONEMPTY_CONSTRUCTOR);
}
- public void testNonFinalMethod() throws UnableToCompleteException {
+ public void testNonFinalMethod() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy extends JavaScriptObject {\n");
@@ -122,7 +121,7 @@
+ JSORestrictionsChecker.ERR_INSTANCE_METHOD_NONFINAL);
}
- public void testNonProtectedConstructor() throws UnableToCompleteException {
+ public void testNonProtectedConstructor() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy extends JavaScriptObject {\n");
@@ -133,7 +132,7 @@
+ JSORestrictionsChecker.ERR_NONPROTECTED_CONSTRUCTOR);
}
- public void testNonStaticInner() throws UnableToCompleteException {
+ public void testNonStaticInner() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy {\n");
@@ -146,7 +145,7 @@
+ JSORestrictionsChecker.ERR_IS_NONSTATIC_NESTED);
}
- public void testNoOverride() throws UnableToCompleteException {
+ public void testNoOverride() {
StringBuffer buggyCode = new StringBuffer();
buggyCode.append("import com.google.gwt.core.client.JavaScriptObject;\n");
buggyCode.append("public class Buggy extends JavaScriptObject {\n");
@@ -158,7 +157,7 @@
+ JSORestrictionsChecker.ERR_OVERRIDDEN_METHOD);
}
- public void testPrivateMethod() throws UnableToCompleteException {
+ public void testPrivateMethod() {
StringBuffer code = new StringBuffer();
code.append("import com.google.gwt.core.client.JavaScriptObject;\n");
code.append("public class Buggy extends JavaScriptObject {\n");
@@ -175,7 +174,7 @@
* Buggy.
*/
private void shouldGenerateError(CharSequence buggyCode,
- final String expectedError) throws UnableToCompleteException {
+ final String expectedError) {
UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
builder.setLowestLogLevel(TreeLogger.ERROR);
if (expectedError != null) {
@@ -189,8 +188,7 @@
logger.assertCorrectLogEntries();
}
- private void shouldGenerateNoError(StringBuffer buggyCode)
- throws UnableToCompleteException {
+ private void shouldGenerateNoError(StringBuffer buggyCode) {
shouldGenerateError(buggyCode, null);
}
}
diff --git a/dev/core/test/com/google/gwt/dev/javac/LongFromJSNITest.java b/dev/core/test/com/google/gwt/dev/javac/LongFromJSNITest.java
index 0269e7b..7528d2a 100644
--- a/dev/core/test/com/google/gwt/dev/javac/LongFromJSNITest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/LongFromJSNITest.java
@@ -16,9 +16,7 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.dev.javac.CompilationUnit;
import com.google.gwt.dev.util.UnitTestTreeLogger;
import junit.framework.TestCase;
@@ -30,7 +28,7 @@
* Test access to longs from JSNI.
*/
public class LongFromJSNITest extends TestCase {
- public void testCyclicReferences() throws UnableToCompleteException {
+ public void testCyclicReferences() {
{
StringBuffer buggy = new StringBuffer();
buggy.append("class Buggy {\n");
@@ -76,7 +74,7 @@
}
}
- public void testFieldAccess() throws UnableToCompleteException {
+ public void testFieldAccess() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append("volatile long x = -1;\n");
@@ -88,7 +86,7 @@
"Referencing field 'Buggy.x': type 'long' is not safe to access in JSNI code");
}
- public void testInnerClass() throws UnableToCompleteException {
+ public void testInnerClass() {
StringBuffer code = new StringBuffer();
code.append("public class Buggy {\n");
code.append(" static class Inner {\n");
@@ -108,7 +106,7 @@
* completely unusable in JavaScript, so the current reasoning is to allow
* them.
*/
- public void testLongArray() throws UnableToCompleteException {
+ public void testLongArray() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" long[] m() { return new long[] { -1 }; }\n");
@@ -119,7 +117,7 @@
shouldGenerateNoError(code);
}
- public void testLongParameter() throws UnableToCompleteException {
+ public void testLongParameter() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" native void jsniMeth(long x) /*-{ return; }-*/;\n");
@@ -129,7 +127,7 @@
"Parameter 'x': type 'long' is not safe to access in JSNI code");
}
- public void testLongReturn() throws UnableToCompleteException {
+ public void testLongReturn() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" native long jsniMeth() /*-{ return 0; }-*/;\n");
@@ -139,7 +137,7 @@
"Type 'long' may not be returned from a JSNI method");
}
- public void testMethodArgument() throws UnableToCompleteException {
+ public void testMethodArgument() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" void print(long x) { }\n");
@@ -152,7 +150,7 @@
"Parameter 1 of method \'Buggy.print\': type 'long' may not be passed out of JSNI code");
}
- public void testMethodReturn() throws UnableToCompleteException {
+ public void testMethodReturn() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" long m() { return -1; }\n");
@@ -166,8 +164,7 @@
"Referencing method 'Buggy.m': return type 'long' is not safe to access in JSNI code");
}
- public void testOverloadedMethodWithNoWarning()
- throws UnableToCompleteException {
+ public void testOverloadedMethodWithNoWarning() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" long m(int x) { return -1; }\n");
@@ -179,8 +176,7 @@
shouldGenerateNoError(code);
}
- public void testOverloadedMethodWithWarning()
- throws UnableToCompleteException {
+ public void testOverloadedMethodWithWarning() {
StringBuffer code = new StringBuffer();
code.append("class Buggy {\n");
code.append(" long m(int x) { return -1; }\n");
@@ -195,7 +191,20 @@
"Referencing method 'Buggy.m': return type 'long' is not safe to access in JSNI code");
}
- public void testUnsafeAnnotation() throws UnableToCompleteException {
+ public void testRefInString() {
+ {
+ StringBuffer code = new StringBuffer();
+ code.append("import com.google.gwt.core.client.UnsafeNativeLong;");
+ code.append("class Buggy {\n");
+ code.append(" void print(long x) { }\n");
+ code.append(" native void jsniMeth() /*-{ 'this.@Buggy::print(J)(0)'; }-*/;\n");
+ code.append("}\n");
+
+ shouldGenerateNoError(code);
+ }
+ }
+
+ public void testUnsafeAnnotation() {
{
StringBuffer code = new StringBuffer();
code.append("import com.google.gwt.core.client.UnsafeNativeLong;");
@@ -209,20 +218,7 @@
}
}
- public void testRefInString() throws UnableToCompleteException {
- {
- StringBuffer code = new StringBuffer();
- code.append("import com.google.gwt.core.client.UnsafeNativeLong;");
- code.append("class Buggy {\n");
- code.append(" void print(long x) { }\n");
- code.append(" native void jsniMeth() /*-{ 'this.@Buggy::print(J)(0)'; }-*/;\n");
- code.append("}\n");
-
- shouldGenerateNoError(code);
- }
- }
-
- public void testViolator() throws UnableToCompleteException {
+ public void testViolator() {
{
StringBuffer okay = new StringBuffer();
okay.append("class Buggy {\n");
@@ -274,8 +270,7 @@
}
private TypeOracle buildOracle(CharSequence buggyCode,
- CharSequence extraCode, UnitTestTreeLogger logger)
- throws UnableToCompleteException {
+ CharSequence extraCode, UnitTestTreeLogger logger) {
Set<CompilationUnit> units = new HashSet<CompilationUnit>();
addLongCheckingCups(units);
units.add(new MockCompilationUnit("Buggy", buggyCode.toString()));
@@ -287,8 +282,7 @@
}
private void shouldGenerateError(CharSequence buggyCode,
- CharSequence extraCode, int line, String message)
- throws UnableToCompleteException {
+ CharSequence extraCode, int line, String message) {
UnitTestTreeLogger.Builder b = new UnitTestTreeLogger.Builder();
b.setLowestLogLevel(TreeLogger.ERROR);
if (message != null) {
@@ -306,17 +300,15 @@
}
private void shouldGenerateError(CharSequence buggyCode, int line,
- String message) throws UnableToCompleteException {
+ String message) {
shouldGenerateError(buggyCode, null, line, message);
}
- private void shouldGenerateNoError(CharSequence code)
- throws UnableToCompleteException {
+ private void shouldGenerateNoError(CharSequence code) {
shouldGenerateNoError(code, null);
}
- private void shouldGenerateNoError(CharSequence code, CharSequence extraCode)
- throws UnableToCompleteException {
+ private void shouldGenerateNoError(CharSequence code, CharSequence extraCode) {
shouldGenerateError(code, extraCode, -1, null);
}
}
diff --git a/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java b/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java
index 2516e15..fee4d53 100644
--- a/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/TypeOracleMediatorTest.java
@@ -16,7 +16,6 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JArrayType;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
@@ -59,10 +58,10 @@
private static void assertEqualArraysUnordered(Object[] expected,
Object[] actual) {
assertEquals(expected.length, actual.length);
- for (int i = 0; i < expected.length; i++) {
+ for (Object element : expected) {
boolean matched = false;
- for (int j = 0; j < actual.length; j++) {
- if (expected[i].equals(actual[j])) {
+ for (Object element2 : actual) {
+ if (element.equals(element2)) {
matched = true;
break;
}
@@ -79,8 +78,10 @@
}
private static void assertIsNotAssignable(JClassType from, JClassType to) {
- assertFalse(from.isAssignableTo(to));
- assertFalse(to.isAssignableFrom(from));
+ assertFalse(from + " should not be assignable to " + to,
+ from.isAssignableTo(to));
+ assertFalse(to + " should not be assignable to " + from,
+ to.isAssignableFrom(from));
}
private static void recordAssignability(
@@ -101,11 +102,13 @@
protected CheckedMockCompilationUnit CU_AfterAssimilate = new CheckedMockCompilationUnit(
"test.assim", "AfterAssimilate") {
+ @Override
public void check(JClassType type) {
assertEquals("test.assim.BeforeAssimilate",
type.getSuperclass().getQualifiedSourceName());
}
+ @Override
public String getSource() {
StringBuffer sb = new StringBuffer();
sb.append("package test.assim;\n");
@@ -117,13 +120,16 @@
protected CheckedMockCompilationUnit CU_Assignable = new CheckedMockCompilationUnit(
"test.sub", "Derived", "BaseInterface", "DerivedInterface",
"Derived.Nested") {
+ @Override
public void check(JClassType type) {
- if ("Derived".equals(type.getSimpleSourceName()))
+ if ("Derived".equals(type.getSimpleSourceName())) {
checkDerived(type);
- else if ("Nested".equals(type.getSimpleSourceName()))
+ } else if ("Nested".equals(type.getSimpleSourceName())) {
checkNested(type);
+ }
}
+ @Override
public String getSource() {
StringBuffer sb = new StringBuffer();
sb.append("package test.sub;\n");
@@ -148,10 +154,12 @@
protected CheckedMockCompilationUnit CU_BeforeAssimilate = new CheckedMockCompilationUnit(
"test.assim", "BeforeAssimilate") {
+ @Override
public void check(JClassType type) {
assertEquals("test.assim.BeforeAssimilate", type.getQualifiedSourceName());
}
+ @Override
public String getSource() {
StringBuffer sb = new StringBuffer();
sb.append("package test.assim;\n");
@@ -164,13 +172,15 @@
"test", "BindToTypeScope", "BindToTypeScope.Object",
"BindToTypeScope.DerivedObject") {
+ @Override
public void check(JClassType type) throws NotFoundException {
- if ("BindToTypeScope".equals(type.getSimpleSourceName()))
+ if ("BindToTypeScope".equals(type.getSimpleSourceName())) {
checkBindToTypeScope(type);
- else if ("Object".equals(type.getSimpleSourceName()))
+ } else if ("Object".equals(type.getSimpleSourceName())) {
checkObject(type);
- else
+ } else {
checkDerivedObject(type);
+ }
}
public void checkBindToTypeScope(JClassType type) throws NotFoundException {
@@ -187,6 +197,7 @@
assertEquals("test.BindToTypeScope.Object", type.getQualifiedSourceName());
}
+ @Override
public String getSource() {
StringBuffer sb = new StringBuffer();
sb.append("package test;\n");
@@ -218,6 +229,7 @@
assertNotNull(type.isGenericType());
}
+ @Override
public String getSource() {
StringBuilder sb = new StringBuilder();
sb.append("package parameterized.type.build.dependency;\n");
@@ -230,6 +242,7 @@
protected CheckedMockCompilationUnit CU_DefaultClass = new CheckedMockCompilationUnit(
"test", "DefaultClass") {
+ @Override
public void check(JClassType type) {
assertEquals("DefaultClass", type.getSimpleSourceName());
assertEquals("test.DefaultClass", type.getQualifiedSourceName());
@@ -241,6 +254,7 @@
assertEquals(0, type.getFields().length);
}
+ @Override
public String getSource() {
StringBuffer sb = new StringBuffer();
sb.append("package test;\n");
@@ -257,6 +271,7 @@
assertNotNull(type.getSuperclass().isParameterized());
}
+ @Override
public String getSource() {
StringBuilder sb = new StringBuilder();
sb.append("package test.refresh;\n");
@@ -272,6 +287,7 @@
assertNotNull(type.getSuperclass().isParameterized());
}
+ @Override
public String getSource() {
StringBuilder sb = new StringBuilder();
sb.append("package parameterized.type.build.dependency;\n");
@@ -282,6 +298,7 @@
protected CheckedMockCompilationUnit CU_FieldsAndTypes = new CheckedMockCompilationUnit(
"test", "Fields", "SomeType") {
+ @Override
public void check(JClassType type) throws NotFoundException {
if ("Fields".equals(type.getSimpleSourceName())) {
assertEquals("test.Fields", type.getQualifiedSourceName());
@@ -445,10 +462,11 @@
public void check(JClassType type) {
final String name = type.getSimpleSourceName();
- if ("Enclosing".equals(name))
+ if ("Enclosing".equals(name)) {
checkEnclosing(type);
- else
+ } else {
checkLocal(type);
+ }
}
public void checkEnclosing(JClassType type) {
@@ -603,8 +621,9 @@
methods = type.getOverloads("overloaded");
assertEquals(2, methods.length);
- for (int i = 0; i < methods.length; i++)
- assertEquals("overloaded", methods[i].getName());
+ for (JMethod element : methods) {
+ assertEquals("overloaded", element.getName());
+ }
method = type.getMethod("overloaded", new JType[] {
JPrimitiveType.INT, javaLangObject});
@@ -655,10 +674,11 @@
public void check(JClassType type) {
final String name = type.getSimpleSourceName();
- if ("Outer".equals(name))
+ if ("Outer".equals(name)) {
checkOuter(type);
- else
+ } else {
checkInner(type);
+ }
}
public void checkInner(JClassType type) {
@@ -759,8 +779,7 @@
private final Set<CompilationUnit> units = new HashSet<CompilationUnit>();
public void checkTypes(JClassType[] types) throws NotFoundException {
- for (int i = 0; i < types.length; i++) {
- JClassType type = types[i];
+ for (JClassType type : types) {
check(type);
JClassType[] nestedTypes = type.getNestedTypes();
@@ -768,8 +787,7 @@
}
}
- public void testAssignable() throws UnableToCompleteException,
- TypeOracleException {
+ public void testAssignable() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_Assignable);
units.add(CU_OuterInner);
@@ -806,8 +824,7 @@
}
}
- public void testAssimilation() throws UnableToCompleteException,
- TypeOracleException {
+ public void testAssimilation() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_BeforeAssimilate);
compileAndRefresh();
@@ -824,8 +841,7 @@
assertSame(before, after.getSuperclass());
}
- public void testBindToTypeScope() throws TypeOracleException,
- UnableToCompleteException {
+ public void testBindToTypeScope() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_BindToTypeScope);
compileAndRefresh();
@@ -833,8 +849,7 @@
assertEquals(4, types.length);
}
- public void testDefaultClass() throws TypeOracleException,
- UnableToCompleteException {
+ public void testDefaultClass() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_DefaultClass);
compileAndRefresh();
@@ -842,8 +857,7 @@
assertEquals(2, types.length);
}
- public void testFieldsAndTypes() throws TypeOracleException,
- UnableToCompleteException {
+ public void testFieldsAndTypes() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_FieldsAndTypes);
compileAndRefresh();
@@ -851,7 +865,7 @@
assertEquals(3, types.length);
}
- public void testLocal() throws TypeOracleException, UnableToCompleteException {
+ public void testLocal() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_LocalClass);
compileAndRefresh();
@@ -859,8 +873,7 @@
assertEquals(3, types.length);
}
- public void testMetaData() throws TypeOracleException,
- UnableToCompleteException {
+ public void testMetaData() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_MetaData);
compileAndRefresh();
@@ -868,8 +881,7 @@
assertEquals(2, types.length);
}
- public void testMethodsAndParams() throws TypeOracleException,
- UnableToCompleteException {
+ public void testMethodsAndParams() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_Throwable);
units.add(CU_MethodsAndParams);
@@ -878,8 +890,7 @@
assertEquals(3, types.length);
}
- public void testOuterInner() throws TypeOracleException,
- UnableToCompleteException {
+ public void testOuterInner() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_OuterInner);
compileAndRefresh();
@@ -896,7 +907,7 @@
* CU_DeclaresInnerGenericType.
*/
public void testParameterizedTypeBuildDependencies()
- throws UnableToCompleteException, TypeOracleException {
+ throws TypeOracleException {
units.add(CU_ReferencesParameterizedTypeBeforeItsGenericFormHasBeenProcessed);
units.add(CU_ExtendsParameterizedType);
units.add(CU_DeclaresInnerGenericType);
@@ -914,8 +925,7 @@
* @throws NotFoundException
* @throws IOException
*/
- public void testRefresh() throws UnableToCompleteException,
- TypeOracleException {
+ public void testRefresh() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_ExtendsGenericList);
units.add(CU_GenericList);
@@ -965,8 +975,7 @@
* @throws UnableToCompleteException
* @throws IOException
*/
- public void testRefreshWithErrors() throws UnableToCompleteException,
- TypeOracleException {
+ public void testRefreshWithErrors() throws TypeOracleException {
// Add Object
StringBuffer sb = new StringBuffer();
sb.append("package java.lang;");
@@ -1042,8 +1051,7 @@
assertNull(typeOracle.findType("test.refresh.with.errors.GoodClass"));
}
- public void testSyntaxErrors() throws TypeOracleException,
- UnableToCompleteException {
+ public void testSyntaxErrors() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_HasSyntaxErrors);
compileAndRefresh();
@@ -1054,8 +1062,7 @@
assertEquals("java.lang.Object", types[0].getQualifiedSourceName());
}
- public void testUnresolvedSymbls() throws TypeOracleException,
- UnableToCompleteException {
+ public void testUnresolvedSymbls() throws TypeOracleException {
units.add(CU_Object);
units.add(CU_HasUnresolvedSymbols);
units.add(CU_RefsInfectedCompilationUnit);
@@ -1084,8 +1091,7 @@
}
}
- private void compileAndRefresh() throws UnableToCompleteException,
- TypeOracleException {
+ private void compileAndRefresh() throws TypeOracleException {
TreeLogger logger = createTreeLogger();
CompilationUnitInvalidator.invalidateUnitsWithInvalidRefs(logger, units);
JdtCompiler.compile(units);
diff --git a/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java b/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java
index d657d36..48c34b3 100644
--- a/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java
+++ b/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java
@@ -16,7 +16,6 @@
package com.google.gwt.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.impl.SourceFileCompilationUnit;
@@ -31,14 +30,14 @@
public class TypeOracleTestingUtils {
public static TypeOracle buildStandardTypeOracleWith(TreeLogger logger,
- CompilationUnit... extraUnits) throws UnableToCompleteException {
+ CompilationUnit... extraUnits) {
Set<CompilationUnit> extraUnitSet = new HashSet<CompilationUnit>();
Collections.addAll(extraUnitSet, extraUnits);
return buildStandardTypeOracleWith(logger, extraUnitSet);
}
public static TypeOracle buildStandardTypeOracleWith(TreeLogger logger,
- Set<CompilationUnit> extraUnits) throws UnableToCompleteException {
+ Set<CompilationUnit> extraUnits) {
Set<CompilationUnit> unitSet = new HashSet<CompilationUnit>();
addStandardCups(unitSet);
for (CompilationUnit extraUnit : extraUnits) {
@@ -48,7 +47,7 @@
}
public static TypeOracle buildTypeOracle(TreeLogger logger,
- Set<CompilationUnit> units) throws UnableToCompleteException {
+ Set<CompilationUnit> units) {
JdtCompiler.compile(units);
Set<String> validBinaryTypeNames = new HashSet<String>();
for (CompilationUnit unit : units) {
diff --git a/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java b/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java
index ea2625c..ede0be2 100644
--- a/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java
+++ b/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java
@@ -56,7 +56,7 @@
public static class MockCompilationState extends CompilationState {
public MockCompilationState() {
- super(new JavaSourceOracle() {
+ super(TreeLogger.NULL, new JavaSourceOracle() {
public Set<String> getClassNames() {
return Collections.emptySet();
}
diff --git a/distro-source/core/src/release_notes.html b/distro-source/core/src/release_notes.html
index 37c804b..445a6d4 100644
--- a/distro-source/core/src/release_notes.html
+++ b/distro-source/core/src/release_notes.html
@@ -29,6 +29,7 @@
<h1>Google Web Toolkit Release Notes</h1>
<ul>
<li><a href="#Release_Notes_Current">@GWT_VERSION@</a></li>
+ <li><a href="#Release_Notes_1_5_3">1.5.3</a></li>
<li><a href="#Release_Notes_1_5_2">1.5.2</a></li>
<li><a href="#Release_Notes_1_5_1">1.5.1 (RC2)</a></li>
<li><a href="#Release_Notes_1_5_0">1.5.0 (RC)</a></li>
@@ -49,6 +50,18 @@
<h2>Release Notes for @GWT_VERSION@</h2>
<h3>Fixed Issues</h3>
<ul>
+ <li><code>ConstantMap</code> is really immutable now (it always should
+ have been); it also no longer generates serialization warnings when
+ attempting to serialize <code>Map<String,String></code></li>
+ <li><code>TreeMap</code> and <code>TreeSet</code> are now
+ serializable</li>
+ </ul>
+ <hr/>
+
+ <a name="Release_Notes_1_5_3"></a>
+ <h2>Release Notes for 1.5.3</h2>
+ <h3>Fixed Issues</h3>
+ <ul>
<li>RPC requests no longer fail on the embedded Android web browser</li>
<li>Leaf <code>TreeItems</code> now line up with their non-leaf siblings</li>
<li>Removing the last child node from a <code>TreeItem</code> no longer creates extra margins on the left</li>
diff --git a/eclipse/samples/DynaTable2/build.xml b/eclipse/samples/DynaTable2/build.xml
index c003fe4..b49d710 100644
--- a/eclipse/samples/DynaTable2/build.xml
+++ b/eclipse/samples/DynaTable2/build.xml
@@ -20,7 +20,7 @@
</javac>
</target>
- <target name="deploy" description="Copy output to the war folder">
+ <target name="deploy" depends="gwtc" description="Copy output to the war folder">
<mkdir dir="${outdir}/WEB-INF/lib" />
<copy todir="${outdir}/WEB-INF/lib" file="${gwt.install}/gwt-servlet.jar" />
</target>
@@ -55,14 +55,16 @@
</target>
<target name="shell" depends="javac" description="Run the deployed app in GWT hosted mode">
- <java classname="com.google.gwt.dev.GWTShell" fork="yes" failonerror="true">
+ <java classname="com.google.gwt.dev.GWTHosted" fork="yes" failonerror="true">
<jvmarg value="-Xmx256M"/>
<jvmarg value="-Dgwt.devjar=C:\gwt\releases\1.6\build\staging\gwt-windows-0.0.0\gwt-dev-windows.jar"/>
<arg value="-out" />
<arg file="${outdir}" />
<arg value="-extra" />
<arg file="${extradir}" />
- <arg value="http://localhost:8888/DynaTable2.html" />
+ <arg value="-startupUrl" />
+ <arg value="DynaTable2.html" />
+ <arg value="com.google.gwt.sample.dynatable.DynaTable2" />
<classpath>
<pathelement location="../../../samples/dynatable/src" />
<pathelement location="${outdir}/WEB-INF/classes" />
diff --git a/tools/api-checker/config/gwt15_16userApi.conf b/tools/api-checker/config/gwt15_16userApi.conf
new file mode 100644
index 0000000..3ccdb27
--- /dev/null
+++ b/tools/api-checker/config/gwt15_16userApi.conf
@@ -0,0 +1,29 @@
+#existing API
+
+name_old gwt15userApi
+#sourceFiles and excludedFiles are specified as colon-separated list of files
+sourceFiles_old @OLDROOT@/dev/core/super:@OLDROOT@/user/super:@OLDROOT@/user/src
+excludedFiles_old @OLDROOT@/user/src/com/google/gwt/benchmarks:@OLDROOT@/user/src/com/google/gwt/junit:@OLDROOT@/user/src/com/google/gwt/i18n/rebind:@OLDROOT@/user/src/com/google/gwt/i18n/tools:@OLDROOT@/user/src/com/google/gwt/json:@OLDROOT@/user/src/com/google/gwt/user/rebind:@OLDROOT@/user/src/com/google/gwt/user/server:@OLDROOT@/user/src/com/google/gwt/user/tools:@OLDROOT@/user/super/com/google/gwt/benchmarks:@OLDROOT@/user/super/com/google/gwt/junit
+
+##############################################
+#new Api
+
+name_new gwt16userApi
+#sourceFiles and excludedFiles are specified as colon-separated list of files
+sourceFiles_new ./dev/core/super:./user/super:./user/src
+#:dev/core/src
+excludedFiles_new ./user/src/com/google/gwt/benchmarks:./user/src/com/google/gwt/junit:./user/src/com/google/gwt/i18n/rebind:./user/src/com/google/gwt/i18n/tools:./user/src/com/google/gwt/json:./user/src/com/google/gwt/user/rebind:./user/src/com/google/gwt/user/server:./user/src/com/google/gwt/user/tools:./user/super/com/google/gwt/benchmarks:./user/super/com/google/gwt/junit
+
+##############################################
+#excluded packages
+excludedPackages com.google.gwt.core.client.impl:com.google.gwt.i18n.client.impl:com.google.gwt.user.client.impl:com.google.gwt.user.client.rpc.impl:com.google.gwt.user.client.ui.impl:com.google.gwt.xml.client.impl
+
+##############################################
+#Api whitelist
+# when adding to the white-list, include comments as to why the addition is
+# being made. This needs to be done for this initial white-list below
+
+# the api-checker is currently regarding overloadeded methods that can be
+# overriden. TODO(amitmanjhi): Solving this issue correctly in all cases seems
+# to be hard. Come back and fix this issue, if more such cases come up.
+java.lang.StringBuilder::append(Ljava/lang/StringBuffer;) OVERRIDABLE_METHOD_ARGUMENT_TYPE_CHANGE
diff --git a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiCompatibilityChecker.java b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiCompatibilityChecker.java
index 516b3ce..71bd2e2 100644
--- a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiCompatibilityChecker.java
+++ b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiCompatibilityChecker.java
@@ -106,7 +106,7 @@
public static final boolean DEBUG_DUPLICATE_REMOVAL = false;
// Tweak for log output.
- public static final TreeLogger.Type type = TreeLogger.ERROR;
+ public static final TreeLogger.Type type = TreeLogger.WARN;
// remove duplicates by default
public static Collection<ApiChange> getApiDiff(ApiContainer newApi,
@@ -208,12 +208,14 @@
if (removeDuplicates) {
collection = apiDiff.removeDuplicates(collection);
}
+ Set<String> matchedWhiteList = new HashSet<String>();
Collection<ApiChange> prunedCollection = new ArrayList<ApiChange>();
for (ApiChange apiChange : collection) {
String apiChangeAsString = apiChange.getStringRepresentationWithoutMessage();
apiChangeAsString = apiChangeAsString.trim();
- if (whiteList.remove(apiChangeAsString)) {
+ if (whiteList.contains(apiChangeAsString)) {
+ matchedWhiteList.add(apiChangeAsString);
continue;
}
// check for Status.Compatible and Status.Compatible_with
@@ -227,6 +229,7 @@
}
prunedCollection.add(apiChange);
}
+ whiteList.removeAll(matchedWhiteList);
if (whiteList.size() > 0) {
List<String> al = new ArrayList<String>(whiteList);
Collections.sort(al);
diff --git a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java
index 7cffb0c..84a5235 100644
--- a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java
+++ b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java
@@ -201,6 +201,10 @@
return logger;
}
+ String getName() {
+ return name;
+ }
+
boolean isApiClass(JClassType classType) {
Boolean ret = apiClassCache.get(classType);
if (ret != null) {
@@ -264,8 +268,13 @@
String pkgName = null;
if (file.getName().endsWith("java")) {
pkgName = extractPackageNameFromFile(file);
- logger.log(TreeLogger.DEBUG, "adding pkgName = " + pkgName
- + ", file = " + file.toString(), null);
+ if (pkgName == null) {
+ logger.log(TreeLogger.WARN, "Not adding file = "
+ + file.toString() + ", because packageName = null", null);
+ } else {
+ logger.log(TreeLogger.DEBUG, "adding pkgName = " + pkgName
+ + ", file = " + file.toString(), null);
+ }
}
if (isValidPackage(pkgName, sourcePathEntry.toURL().toString())) {
// Add if it's a source file and the package and fileNames are okay
diff --git a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiPackage.java b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiPackage.java
index 58ea221..b67dbc5 100644
--- a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiPackage.java
+++ b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiPackage.java
@@ -124,7 +124,7 @@
}
}
if (notAddedClassNames.size() > 0) {
- logger.log(TreeLogger.SPAM, "API " + name + ", package: " + name
+ logger.log(TreeLogger.SPAM, "API " + apiContainer.getName() + ", package: " + name
+ ", not adding " + notAddedClassNames.size() + " nonApi classes: "
+ notAddedClassNames, null);
}
diff --git a/user/build.xml b/user/build.xml
index 0539253..6bc6113 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -78,7 +78,7 @@
<target name="remoteweb-test" description="Run a remoteweb test at the given host and path" if="gwt.remote.browsers">
<echo message="Performing remote browser testing at ${gwt.remote.browsers}" />
- <gwt.junit test.args="${test.args} -out www -remoteweb ${gwt.remote.browsers}" test.out="${junit.out}/remoteweb" test.cases="default.web.tests" >
+ <gwt.junit test.args="${test.args} -out www -workDir ${junit.out}/remoteweb/workdir -remoteweb ${gwt.remote.browsers}" test.out="${junit.out}/remoteweb" test.cases="default.web.tests" >
<extraclasspaths>
<pathelement location="${gwt.build}/out/dev/core/bin-test" />
</extraclasspaths>
@@ -87,7 +87,7 @@
<target name="selenium-test" description="Run a remote test using Selenium RC test at the given host and path" if="gwt.selenium.hosts">
<echo message="Performing remote browser testing using Selenium RC at ${gwt.selenium.hosts}" />
- <gwt.junit test.args="${test.args} -out www -selenium ${gwt.selenium.hosts}" test.out="${junit.out}/selenium" test.cases="default.web.tests" >
+ <gwt.junit test.args="${test.args} -out www -workDir ${junit.out}/selenium/workdir -selenium ${gwt.selenium.hosts}" test.out="${junit.out}/selenium" test.cases="default.web.tests" >
<extraclasspaths>
<pathelement location="${gwt.build}/out/dev/core/bin-test" />
</extraclasspaths>
@@ -95,7 +95,7 @@
</target>
<target name="test.hosted" depends="compile, compile.tests" description="Run only hosted-mode tests for this project.">
- <gwt.junit test.args="${test.args}" test.out="${junit.out}/${build.host.platform}-hosted-mode" test.cases="default.hosted.tests" >
+ <gwt.junit test.args="${test.args} -workDir ${junit.out}/${build.host.platform}-hosted-mode/workdir" test.out="${junit.out}/${build.host.platform}-hosted-mode" test.cases="default.hosted.tests" >
<extraclasspaths>
<pathelement location="${gwt.build}/out/dev/core/bin-test" />
</extraclasspaths>
@@ -103,7 +103,7 @@
</target>
<target name="test.web" depends="compile, compile.tests" description="Run only web-mode tests for this project.">
- <gwt.junit test.args="${test.args} -out www -web" test.out="${junit.out}/${build.host.platform}-web-mode" test.cases="default.web.tests" >
+ <gwt.junit test.args="${test.args} -out www -workDir ${junit.out}/${build.host.platform}-web-mode/workdir -web" test.out="${junit.out}/${build.host.platform}-web-mode" test.cases="default.web.tests" >
<extraclasspaths>
<pathelement location="${gwt.build}/out/dev/core/bin-test" />
</extraclasspaths>
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index b2ed7605..cd21132 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -20,7 +20,6 @@
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.dev.BootStrapPlatform;
import com.google.gwt.dev.GWTShell;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ConfigurationProperty;
@@ -174,7 +173,8 @@
if (foundType != null) {
return null;
}
- Map<String, CompilationUnit> unitMap = currentModule.getCompilationState().getCompilationUnitMap();
+ Map<String, CompilationUnit> unitMap = currentModule.getCompilationState(
+ logger).getCompilationUnitMap();
CompilationUnit unit = unitMap.get(typeName);
String errMsg;
if (unit == null) {
@@ -201,8 +201,6 @@
*/
private static JUnitShell getUnitTestShell() {
if (unitTestShell == null) {
- BootStrapPlatform.init();
- BootStrapPlatform.applyPlatformHacks();
unitTestShell = new JUnitShell();
unitTestShell.lastLaunchFailed = true;
String[] args = unitTestShell.synthesizeArgs();
diff --git a/user/src/com/google/gwt/user/tools/.classpathsrc b/user/src/com/google/gwt/user/tools/.classpathsrc
index 336a085..19b3e77 100644
--- a/user/src/com/google/gwt/user/tools/.classpathsrc
+++ b/user/src/com/google/gwt/user/tools/.classpathsrc
@@ -5,6 +5,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="@gwtUserPath"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
- <classpathentry kind="output" path="bin"/>
+ <classpathentry kind="output" path="war/WEB-INF/classes"/>
@eclipseClassPathEntries
</classpath>
diff --git a/user/src/com/google/gwt/user/tools/App.launchsrc b/user/src/com/google/gwt/user/tools/App.launchsrc
index b35bd08..1f9e95c 100644
--- a/user/src/com/google/gwt/user/tools/App.launchsrc
+++ b/user/src/com/google/gwt/user/tools/App.launchsrc
@@ -10,7 +10,8 @@
@eclipseExtraLaunchPaths
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="@vmargs -Xmx256M"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out www @startupUrl"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-out
+ war -startupUrl @startupUrl @moduleName"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="@projectName"/>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
</launchConfiguration>
diff --git a/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc b/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
index eae6bd1..f2cd244 100644
--- a/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
+++ b/user/src/com/google/gwt/user/tools/AppClassTemplate.javasrc
@@ -1,6 +1,10 @@
package @clientPackage;
import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.DialogBox;
@@ -37,7 +41,6 @@
// Create the dialog box
final DialogBox dialogBox = new DialogBox();
- dialogBox.setText("Welcome to GWT!");
dialogBox.setAnimationEnabled(true);
Button closeButton = new Button("close");
VerticalPanel dialogVPanel = new VerticalPanel();
@@ -50,14 +53,36 @@
dialogBox.hide();
}
});
-
+
// Set the contents of the Widget
dialogBox.setWidget(dialogVPanel);
+
+ final EchoServiceAsync echoService = GWT.create(EchoService.class);
+ ServiceDefTarget target = (ServiceDefTarget) echoService;
+
+ // Use a module-relative URLs to ensure that this client code can find
+ // its way home, even when the URL changes (as might happen when you
+ // deploy this as a webapp under an external servlet container).
+ String moduleRelativeURL = GWT.getModuleBaseURL() + "echo";
+ target.setServiceEntryPoint(moduleRelativeURL);
+
+ final String textToServer = "Hello GWT World!";
button.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
+ final String dialogBoxText = "Sending to the server: " + textToServer;
+ dialogBox.setText(dialogBoxText);
dialogBox.center();
dialogBox.show();
+ echoService.echo(textToServer, new AsyncCallback<String>() {
+ public void onFailure(Throwable caught) {
+ Window.alert("Rpc failure");
+ }
+
+ public void onSuccess(String result) {
+ dialogBox.setText(dialogBoxText + "\n " + result);
+ }
+ });
}
});
}
diff --git a/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc b/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
index 5a23afa..9f9c72f 100644
--- a/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
+++ b/user/src/com/google/gwt/user/tools/AppHtml.htmlsrc
@@ -9,6 +9,10 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <!-- -->
+ <!-- Consider inlining CSS to reduce the number of requested files -->
+ <!-- -->
+ <link type="text/css" rel="stylesheet" href="@className.css">
<!-- -->
<!-- Any title is fine -->
<!-- -->
@@ -19,7 +23,7 @@
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
- <script type="text/javascript" language="javascript" src="@moduleName.nocache.js"></script>
+ <script type="text/javascript" language="javascript" src="@deployDir/@newModuleName.nocache.js"></script>
</head>
<!-- -->
diff --git a/user/src/com/google/gwt/user/tools/ApplicationCreator.java b/user/src/com/google/gwt/user/tools/ApplicationCreator.java
index 99948f9..9126cd5 100644
--- a/user/src/com/google/gwt/user/tools/ApplicationCreator.java
+++ b/user/src/com/google/gwt/user/tools/ApplicationCreator.java
@@ -21,6 +21,7 @@
import com.google.gwt.user.tools.util.ArgHandlerIgnore;
import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
import com.google.gwt.user.tools.util.CreatorUtilities;
+import com.google.gwt.util.tools.ArgHandlerDir;
import com.google.gwt.util.tools.ArgHandlerExtra;
import com.google.gwt.util.tools.ArgHandlerOutDir;
import com.google.gwt.util.tools.ArgHandlerString;
@@ -28,6 +29,7 @@
import com.google.gwt.util.tools.Utility;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -144,6 +146,18 @@
}
}
+ static class FileCreator {
+ private final File dir;
+ private final String sourceName;
+ private final String className;
+
+ FileCreator(File dir, String sourceName, String className) {
+ this.dir = dir;
+ this.sourceName = sourceName;
+ this.className = className;
+ }
+ }
+
private static final String PACKAGE_PATH;
static {
@@ -172,11 +186,11 @@
* @throws IOException
*/
static void createApplication(String fullClassName, File outDir,
- String eclipse, boolean overwrite, boolean ignore)
- throws IOException {
- createApplication(fullClassName, outDir, eclipse, overwrite, ignore, null, null);
+ String eclipse, boolean overwrite, boolean ignore) throws IOException {
+ createApplication(fullClassName, outDir, eclipse, overwrite, ignore, null,
+ null);
}
-
+
/**
* @param fullClassName Name of the fully-qualified Java class to create as an
* Application.
@@ -193,11 +207,35 @@
String eclipse, boolean overwrite, boolean ignore,
List<String> extraClassPaths, List<String> extraModules)
throws IOException {
+ createApplication(fullClassName, outDir, eclipse, overwrite, ignore,
+ extraClassPaths, extraModules, null, null);
+ }
+
+ /**
+ * @param fullClassName Name of the fully-qualified Java class to create as an
+ * Application.
+ * @param outDir Where to put the output files
+ * @param eclipse The name of a project to attach a .launch config to
+ * @param overwrite Overwrite an existing files if they exist.
+ * @param ignore Ignore existing files if they exist.
+ * @param extraClassPaths A list of paths to append to the class path for
+ * launch configs.
+ * @param extraModules A list of GWT modules to add 'inherits' tags for.
+ * @param newModuleName The new module name
+ * @param deployDir The deploy directory
+ * @throws IOException
+ */
+ static void createApplication(String fullClassName, File outDir,
+ String eclipse, boolean overwrite, boolean ignore,
+ List<String> extraClassPaths, List<String> extraModules,
+ String newModuleName, File deployDir) throws IOException {
// Figure out the installation directory
+
String installPath = Utility.getInstallPath();
String gwtUserPath = installPath + '/' + "gwt-user.jar";
String gwtDevPath = installPath + '/' + Utility.getDevJarName();
+ String gwtServletPath = installPath + '/' + "gwt-servlet.jar";
// Validate the arguments for extra class path entries and modules.
if (!CreatorUtilities.validatePathsAndModules(gwtUserPath, extraClassPaths,
@@ -236,19 +274,26 @@
pos = clientPackageName.lastIndexOf('.');
File basePackageDir;
String moduleName;
+ String serverPackageName = null;
File javaDir = Utility.getDirectory(outDir, "src", true);
+ Utility.getDirectory(outDir, "test", true);
+ File warDir = Utility.getDirectory(outDir, "war", true);
+ File webInfDir = Utility.getDirectory(warDir, "WEB-INF", true);
if (pos >= 0) {
String basePackage = clientPackageName.substring(0, pos);
moduleName = basePackage + "." + className;
+ serverPackageName = basePackage + ".server";
basePackage = basePackage.replace('.', '/');
basePackageDir = Utility.getDirectory(javaDir, basePackage, true);
} else {
moduleName = className;
basePackageDir = javaDir;
+ serverPackageName = "server";
}
File clientDir = Utility.getDirectory(basePackageDir, "client", true);
File publicDir = Utility.getDirectory(basePackageDir, "public", true);
- String startupUrl = moduleName + "/" + className + ".html";
+ File serverDir = Utility.getDirectory(basePackageDir, "server", true);
+ String startupUrl = className + ".html";
// Create a map of replacements
//
@@ -256,103 +301,125 @@
replacements.put("@className", className);
replacements.put("@moduleName", moduleName);
replacements.put("@clientPackage", clientPackageName);
+ replacements.put("@serverPackage", serverPackageName);
replacements.put("@gwtUserPath", basePathEnv + gwtUserPath);
replacements.put("@gwtDevPath", basePathEnv + gwtDevPath);
- replacements.put("@shellClass", "com.google.gwt.dev.GWTShell");
+ replacements.put("@shellClass", "com.google.gwt.dev.GWTHosted");
replacements.put("@compileClass", "com.google.gwt.dev.GWTCompiler");
replacements.put("@startupUrl", startupUrl);
- replacements.put("@vmargs", isMacOsX ? "-XstartOnFirstThread" : "");
+ replacements.put("@vmargs", isMacOsX
+ ? "<jvmarg value=\"-XstartOnFirstThread\"/>" : "");
replacements.put("@eclipseExtraLaunchPaths",
CreatorUtilities.createEclipseExtraLaunchPaths(extraClassPaths));
replacements.put("@extraModuleInherits",
createExtraModuleInherits(extraModules));
replacements.put("@extraClassPathsColon", CreatorUtilities.appendPaths(":",
extraClassPaths));
- replacements.put("@extraClassPathsSemicolon", CreatorUtilities.appendPaths(";", extraClassPaths));
+ replacements.put("@extraClassPathsSemicolon", CreatorUtilities.appendPaths(
+ ";", extraClassPaths));
+ replacements.put("@newModuleName", (newModuleName != null) ? newModuleName
+ : moduleName);
+ replacements.put("@deployDir", deployDir.getName());
{
- // Create the module
- File moduleXML = Utility.createNormalFile(basePackageDir, className
- + ModuleDefLoader.GWT_MODULE_XML_SUFFIX, overwrite, ignore);
- if (moduleXML != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + "Module.gwt.xmlsrc");
- Utility.writeTemplateFile(moduleXML, out, replacements);
+ // create the module xml file, skeleton html file, skeleton css file,
+ // web.xml file
+ FileCreator fileCreators[] = new FileCreator[] {
+ new FileCreator(basePackageDir, "Module.gwt.xml", className
+ + ModuleDefLoader.GWT_MODULE_XML_SUFFIX),
+ new FileCreator(warDir, "AppHtml.html", className + ".html"),
+ new FileCreator(warDir, "AppCss.css", className + ".css"),
+ new FileCreator(webInfDir, "web.xml", "web.xml"),};
+ for (FileCreator fileCreator : fileCreators) {
+ File file = Utility.createNormalFile(fileCreator.dir,
+ fileCreator.className, overwrite, ignore);
+ if (file != null) {
+ String out = Utility.getFileFromClassPath(PACKAGE_PATH
+ + fileCreator.sourceName + "src");
+ Utility.writeTemplateFile(file, out, replacements);
+ }
}
}
{
- // Create a skeleton html file
- File publicHTML = Utility.createNormalFile(publicDir,
- className + ".html", overwrite, ignore);
- if (publicHTML != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + "AppHtml.htmlsrc");
- Utility.writeTemplateFile(publicHTML, out, replacements);
- }
- }
-
- {
- // Create a skeleton css file
- File publicCSS = Utility.createNormalFile(publicDir, className + ".css",
- overwrite, ignore);
- if (publicCSS != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + "AppCss.csssrc");
- Utility.writeTemplateFile(publicCSS, out, replacements);
- }
- }
-
- {
- // Create a skeleton Application class
- File javaClass = Utility.createNormalFile(clientDir, className + ".java",
- overwrite, ignore);
- if (javaClass != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + "AppClassTemplate.javasrc");
- Utility.writeTemplateFile(javaClass, out, replacements);
+ /*
+ * Create a skeleton Application: main client class, rpc stub for the
+ * client, async counterpart of the rpc stub, rpc implementation on the
+ * server.
+ */
+ FileCreator fileCreators[] = new FileCreator[] {
+ new FileCreator(clientDir, "AppClass", className),
+ new FileCreator(clientDir, "RpcClient", "EchoService"),
+ new FileCreator(clientDir, "RpcAsyncClient", "EchoServiceAsync"),
+ new FileCreator(serverDir, "RpcServer", "EchoServiceImpl"),};
+ for (FileCreator fileCreator : fileCreators) {
+ File javaClass = Utility.createNormalFile(fileCreator.dir,
+ fileCreator.className + ".java", overwrite, ignore);
+ if (javaClass != null) {
+ String out = Utility.getFileFromClassPath(PACKAGE_PATH
+ + fileCreator.sourceName + "Template.javasrc");
+ Utility.writeTemplateFile(javaClass, out, replacements);
+ }
}
}
if (eclipse != null) {
- // Create an eclipse launch config
replacements.put("@projectName", eclipse);
- File launchConfig = Utility.createNormalFile(outDir, className
- + ".launch", overwrite, ignore);
- if (launchConfig != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + "App.launchsrc");
- Utility.writeTemplateFile(launchConfig, out, replacements);
+ // Build the list of extra paths
+ replacements.put("@gwtServletPath", basePathEnv + gwtServletPath);
+ StringBuilder buf = new StringBuilder();
+ if (extraClassPaths != null) {
+ for (String path : extraClassPaths) {
+ buf.append(" <pathelement path=\"" + path + "\"/>");
+ }
}
- }
+ replacements.put("@extraAntPathElements", buf.toString());
- // create startup files
- String extension;
- if (isWindows) {
- extension = ".cmd";
- } else {
- extension = "";
- }
+ StringBuilder classpathEntries = new StringBuilder();
+ if (extraClassPaths != null) {
+ for (String path : extraClassPaths) {
+ File f = new File(path);
- File gwtshell = Utility.createNormalFile(outDir, className + "-shell"
- + extension, overwrite, ignore);
- if (gwtshell != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH + "gwtshell"
- + extension + "src");
- Utility.writeTemplateFile(gwtshell, out, replacements);
- if (extension.length() == 0) {
- chmodExecutable(gwtshell);
+ if (!f.exists()) {
+ throw new FileNotFoundException("extraClassPath: " + path
+ + " must be present before .launch file can be created.");
+ }
+ // Handle both .jar files and paths
+ String kindString;
+ if (f.isDirectory()) {
+ kindString = "output";
+ } else if (path.endsWith(".jar")) {
+ kindString = "lib";
+ } else {
+ throw new RuntimeException("Don't know how to handle path: " + path
+ + ". It doesn't appear to be a directory or a .jar file");
+ }
+ classpathEntries.append(" <classpathentry kind=\"");
+ classpathEntries.append(kindString);
+ classpathEntries.append("\" path=\"");
+ classpathEntries.append(path);
+ classpathEntries.append("\"/>\n");
+ }
}
- }
+ replacements.put("@eclipseClassPathEntries", classpathEntries.toString());
- File gwtcompile = Utility.createNormalFile(outDir, className + "-compile"
- + extension, overwrite, ignore);
- if (gwtcompile != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH + "gwtcompile"
- + extension + "src");
- Utility.writeTemplateFile(gwtcompile, out, replacements);
- if (extension.length() == 0) {
- chmodExecutable(gwtcompile);
+ /*
+ * create an ant file, an eclipse .project, an eclipse .classpath, and an
+ * eclipse launch-config
+ */
+ FileCreator fileCreators[] = new FileCreator[] {
+ new FileCreator(outDir, "project.ant.xml", "build.xml"),
+ new FileCreator(outDir, ".project", ".project"),
+ new FileCreator(outDir, ".classpath", ".classpath"),
+ new FileCreator(outDir, "App.launch", className + ".launch"),};
+ for (FileCreator fileCreator : fileCreators) {
+ File file = Utility.createNormalFile(fileCreator.dir,
+ fileCreator.className, overwrite, ignore);
+ if (file != null) {
+ String out = Utility.getFileFromClassPath(PACKAGE_PATH
+ + fileCreator.sourceName + "src");
+ Utility.writeTemplateFile(file, out, replacements);
+ }
}
}
}
@@ -393,13 +460,15 @@
private ArgHandlerAddModule moduleHandler = new ArgHandlerAddModule();
private File outDir;
private boolean overwrite = false;
+ private String newModuleName = null;
+ private File deployDir;
protected ApplicationCreator() {
registerHandler(new ArgHandlerEclipse() {
@Override
public String getPurpose() {
- return "Creates a debug launch config for the named eclipse project";
+ return "Creates an ant file, an eclipse project, and a launch config";
}
@Override
@@ -440,6 +509,64 @@
}
});
+ // handler to process newModuleName argument
+ registerHandler(new ArgHandlerString() {
+ @Override
+ public String[] getDefaultArgs() {
+ return null; // later reset to moduleName
+ }
+
+ @Override
+ public String getPurpose() {
+ return "Specifies the new name of the module";
+ }
+
+ @Override
+ public String getTag() {
+ return "-moduleName";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[] {"moduleName"};
+ }
+
+ @Override
+ public boolean setString(String str) {
+ newModuleName = str;
+ return true;
+ }
+
+ });
+
+ // handler to create the deployDir
+ registerHandler(new ArgHandlerDir() {
+
+ @Override
+ public String[] getDefaultArgs() {
+ return new String[] {"-deployDir", "deployDir"};
+ }
+
+ @Override
+ public String getPurpose() {
+ return "Specifies the deploy directory (defaults to deployDir)";
+ }
+
+ @Override
+ public String getTag() {
+ return "-deployDir";
+ }
+
+ @Override
+ public void setDir(File dir) {
+ if (dir.getName().length() == 0) {
+ throw new IllegalArgumentException("deployDir may not be empty");
+ }
+ deployDir = dir;
+ }
+
+ });
+
registerHandler(new ArgHandlerAppClass());
registerHandler(classPathHandler);
registerHandler(moduleHandler);
@@ -449,7 +576,7 @@
try {
createApplication(fullClassName, outDir, eclipse, overwrite, ignore,
classPathHandler.getExtraClassPathList(),
- moduleHandler.getExtraModuleList());
+ moduleHandler.getExtraModuleList(), newModuleName, deployDir);
return true;
} catch (IOException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
diff --git a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
index 4228170..79536b4 100644
--- a/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/Module.gwt.xmlsrc
@@ -1,4 +1,4 @@
-<module>
+<module rename-to='@newModuleName' deploy-to='/@deployDir'>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
@@ -15,8 +15,5 @@
<!-- Specify the app entry point class. -->
<entry-point class='@clientPackage.@className'/>
-
- <!-- Specify the application specific style sheet. -->
- <stylesheet src='@className.css' />
-
+
</module>
diff --git a/user/src/com/google/gwt/user/tools/ProjectCreator.java b/user/src/com/google/gwt/user/tools/ProjectCreator.java
deleted file mode 100644
index 0ea5d2b..0000000
--- a/user/src/com/google/gwt/user/tools/ProjectCreator.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright 2007 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.user.tools;
-
-import com.google.gwt.user.tools.util.ArgHandlerAddToClassPath;
-import com.google.gwt.user.tools.util.ArgHandlerEclipse;
-import com.google.gwt.user.tools.util.ArgHandlerIgnore;
-import com.google.gwt.user.tools.util.ArgHandlerOverwrite;
-import com.google.gwt.user.tools.util.CreatorUtilities;
-import com.google.gwt.util.tools.ArgHandlerOutDir;
-import com.google.gwt.util.tools.ArgHandlerString;
-import com.google.gwt.util.tools.ToolBase;
-import com.google.gwt.util.tools.Utility;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Creates a new GWT project.
- */
-public final class ProjectCreator extends ToolBase {
-
- private static final String PACKAGE_PATH;
-
- static {
- String path = ProjectCreator.class.getName();
- path = path.substring(0, path.lastIndexOf('.') + 1);
- PACKAGE_PATH = path.replace('.', '/');
- }
-
- public static void main(String[] args) {
- ProjectCreator creator = new ProjectCreator();
- if (creator.processArgs(args)) {
- if (creator.run()) {
- return;
- }
- }
-
- System.exit(1);
- }
-
- /**
- * Create a set of project files.
- *
- * @param eclipse The name of project to create.
- * @param ant The name of an ant file to create.
- * @param outDir The directory to write into.
- * @param overwrite Overwrite an existing files if they exist.
- * @param ignore Ignore existing files if they exist.
- * @throws IOException
- */
- static void createProject(String eclipse, String ant, File outDir,
- boolean overwrite, boolean ignore) throws IOException {
- createProject(eclipse, ant, outDir, overwrite, ignore, null);
- }
-
- /**
- * Create a set of project files.
- *
- * @param eclipse The name of project to create.
- * @param ant The name of an ant file to create.
- * @param outDir The directory to write into.
- * @param overwrite Overwrite an existing files if they exist.
- * @param ignore Ignore existing files if they exist.
- * @param extraClassPaths class path entries passed on the command line
- * @throws IOException
- */
- static void createProject(String eclipse, String ant, File outDir,
- boolean overwrite, boolean ignore, List<String> extraClassPaths)
- throws IOException {
-
- // Figure out the installation directory
- String installPath = Utility.getInstallPath();
-
- // Create a map of replacements.
- Map<String, String> replacements = new HashMap<String, String>();
- String userJarPath = installPath + '/' + "gwt-user.jar";
- replacements.put("@gwtUserPath", userJarPath);
-
- // Check to see that the passed extra path/module arguments are valid.
- if (!CreatorUtilities.validatePathsAndModules(userJarPath, extraClassPaths,
- null)) {
- return;
- }
-
- Utility.getDirectory(outDir, "src", true);
- Utility.getDirectory(outDir, "test", true);
-
- if (ant != null) {
- // Create an ant build file
- replacements.put("@projectName", ant);
-
- // Build the list of extra paths
- StringBuilder buf = new StringBuilder();
- if (extraClassPaths != null) {
- for (String path : extraClassPaths) {
- buf.append(" <pathelement path=\"" + path + "\"/>");
- }
- }
- replacements.put("@extraAntPathElements", buf.toString());
-
- File antXML = Utility.createNormalFile(outDir, ant + ".ant.xml",
- overwrite, ignore);
- if (antXML != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + "project.ant.xmlsrc");
- Utility.writeTemplateFile(antXML, out, replacements);
- }
- }
-
- if (eclipse != null) {
- // Create an eclipse project file
- replacements.put("@projectName", eclipse);
- File dotProject = Utility.createNormalFile(outDir, ".project", overwrite,
- ignore);
- if (dotProject != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH + ".projectsrc");
- Utility.writeTemplateFile(dotProject, out, replacements);
- }
-
- StringBuilder classpathEntries = new StringBuilder();
- if (extraClassPaths != null) {
- for (String path : extraClassPaths) {
- File f = new File(path);
-
- if (!f.exists()) {
- throw new FileNotFoundException("extraClassPath: " + path
- + " must be present before .launch file can be created.");
- }
- // Handle both .jar files and paths
- String kindString;
- if (f.isDirectory()) {
- kindString = "output";
- } else if (path.endsWith(".jar")) {
- kindString = "lib";
- } else {
- throw new RuntimeException("Don't know how to handle path: " + path
- + ". It doesn't appear to be a directory or a .jar file");
- }
- classpathEntries.append(" <classpathentry kind=\"");
- classpathEntries.append(kindString);
- classpathEntries.append("\" path=\"");
- classpathEntries.append(path);
- classpathEntries.append("\"/>\n");
- }
- }
-
- replacements.put("@eclipseClassPathEntries", classpathEntries.toString());
-
- // Create an eclipse classpath file
- File dotClasspath = Utility.createNormalFile(outDir, ".classpath",
- overwrite, ignore);
- if (dotClasspath != null) {
- String out = Utility.getFileFromClassPath(PACKAGE_PATH
- + ".classpathsrc");
- Utility.writeTemplateFile(dotClasspath, out, replacements);
- }
- }
- }
-
- private String ant = null;
- private String eclipse = null;
- private boolean ignore = false;
- private File outDir = null;
- private boolean overwrite = false;
- private ArgHandlerAddToClassPath classPathHandler = new ArgHandlerAddToClassPath();
-
- protected ProjectCreator() {
-
- registerHandler(new ArgHandlerString() {
-
- @Override
- public String getPurpose() {
- return "Generate an Ant buildfile to compile source (.ant.xml will be appended)";
- }
-
- @Override
- public String getTag() {
- return "-ant";
- }
-
- @Override
- public String[] getTagArgs() {
- return new String[] {"projectName"};
- }
-
- @Override
- public boolean setString(String str) {
- ant = str;
- return true;
- }
-
- });
-
- registerHandler(new ArgHandlerEclipse() {
- @Override
- public String getPurpose() {
- return "Generate an eclipse project";
- }
-
- @Override
- public boolean setString(String str) {
- eclipse = str;
- return true;
- }
- });
-
- registerHandler(new ArgHandlerOutDir() {
- @Override
- public void setDir(File dir) {
- outDir = dir;
- }
- });
-
- registerHandler(new ArgHandlerOverwrite() {
- @Override
- public boolean setFlag() {
- if (ignore) {
- System.err.println("-overwrite cannot be used with -ignore.");
- return false;
- }
- overwrite = true;
- return true;
- }
- });
-
- registerHandler(new ArgHandlerIgnore() {
- @Override
- public boolean setFlag() {
- if (overwrite) {
- System.err.println("-ignore cannot be used with -overwrite.");
- return false;
- }
- ignore = true;
- return true;
- }
- });
-
- registerHandler(classPathHandler);
- }
-
- protected boolean run() {
- try {
- if (ant == null && eclipse == null) {
- System.err.println("Please specify either -ant or -eclipse.");
- printHelp();
- return false;
- }
- createProject(eclipse, ant, outDir, overwrite, ignore,
- classPathHandler.getExtraClassPathList());
- return true;
- } catch (IOException e) {
- System.err.println(e.getClass().getName() + ": " + e.getMessage());
- return false;
- }
- }
-}
diff --git a/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc b/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc
new file mode 100644
index 0000000..52eef3e
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/RpcAsyncClientTemplate.javasrc
@@ -0,0 +1,10 @@
+package @clientPackage;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+/**
+ * The async counterpart of <code>EchoService</code>.
+ */
+public interface EchoServiceAsync {
+ void echo (String input, AsyncCallback<String> callback);
+}
diff --git a/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc b/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc
new file mode 100644
index 0000000..419660c
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/RpcClientTemplate.javasrc
@@ -0,0 +1,10 @@
+package @clientPackage;
+
+import com.google.gwt.user.client.rpc.RemoteService;
+
+/**
+ * The client side stub for the Rpc service.
+ */
+public interface EchoService extends RemoteService {
+ String echo (String input);
+}
diff --git a/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc b/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc
new file mode 100644
index 0000000..3f4ae7e
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/RpcServerTemplate.javasrc
@@ -0,0 +1,16 @@
+package @serverPackage;
+
+import @clientPackage.EchoService;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+/**
+ * The server side implementation of the Rpc service.
+ */
+public class EchoServiceImpl extends RemoteServiceServlet implements
+ EchoService {
+
+ public String echo(String input) {
+ return "Server says: " + input;
+ }
+
+}
diff --git a/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc b/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc
deleted file mode 100644
index 80f6e97..0000000
--- a/user/src/com/google/gwt/user/tools/gwtcompile.cmdsrc
+++ /dev/null
@@ -1 +0,0 @@
-@java -Xmx256M -cp "%~dp0\src;%~dp0\bin;@gwtUserPath;@gwtDevPath@extraClassPathsSemicolon" @compileClass -out "%~dp0\www" %* @moduleName
\ No newline at end of file
diff --git a/user/src/com/google/gwt/user/tools/gwtcompilesrc b/user/src/com/google/gwt/user/tools/gwtcompilesrc
deleted file mode 100644
index 75064a8..0000000
--- a/user/src/com/google/gwt/user/tools/gwtcompilesrc
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-APPDIR=`dirname $0`;
-java @vmargs -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:@gwtUserPath:@gwtDevPath@extraClassPathsColon" @compileClass -out "$APPDIR/www" "$@" @moduleName;
diff --git a/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc b/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc
deleted file mode 100644
index dd14324..0000000
--- a/user/src/com/google/gwt/user/tools/gwtshell.cmdsrc
+++ /dev/null
@@ -1 +0,0 @@
-@java -Xmx256M -cp "%~dp0\src;%~dp0\bin;@gwtUserPath;@gwtDevPath@extraClassPathsSemicolon" @shellClass -out "%~dp0\www" %* @startupUrl
\ No newline at end of file
diff --git a/user/src/com/google/gwt/user/tools/gwtshellsrc b/user/src/com/google/gwt/user/tools/gwtshellsrc
deleted file mode 100644
index 195b443..0000000
--- a/user/src/com/google/gwt/user/tools/gwtshellsrc
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-APPDIR=`dirname $0`;
-java @vmargs -Xmx256M -cp "$APPDIR/src:$APPDIR/bin:@gwtUserPath:@gwtDevPath@extraClassPathsColon" @shellClass -out "$APPDIR/www" "$@" @startupUrl;
diff --git a/user/src/com/google/gwt/user/tools/project.ant.xmlsrc b/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
index 942140d..de75dc9 100644
--- a/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
+++ b/user/src/com/google/gwt/user/tools/project.ant.xmlsrc
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
-<project name="@projectName" default="compile" basedir=".">
+<project name="@projectName" default="build" basedir=".">
<description>
@projectName build file. This is used to package up your project as a jar,
if you want to distribute it. This isn't needed for normal operation.
</description>
+ <property name="outdir" location="war" />
+ <property name="extradir" location="extra" />
<!-- set classpath -->
<path id="project.class.path">
@@ -13,36 +15,78 @@
<!-- Additional dependencies (such as junit) go here -->
</path>
- <target name="compile" description="Compile src to bin">
- <mkdir dir="bin"/>
- <javac srcdir="src:test" destdir="bin" includes="**" debug="on" debuglevel="lines,vars,source" source="1.4">
+ <!-- TODO:
+ 1. revisit this once GWT supports shared dir as a first-clas citizen
+ 2. For a 1.4 server, split this so that the server side code is compiled
+ with a target=1.4 build rule -->
+ <target name="javac" description="Compile project to WEB-INF/classes">
+ <mkdir dir="${outdir}/WEB-INF/classes"/>
+ <javac srcdir="src:test"
+ destdir="${outdir}/WEB-INF/classes"
+ includes="**"
+ debug="true"
+ debuglevel="lines,vars,source"
+ source="1.5"
+ target="1.5"
+ nowarn="true"
+ encoding="utf-8">
<classpath refid="project.class.path"/>
</javac>
</target>
- <target name="package" depends="compile" description="Package up the project as a jar">
- <jar destfile="@projectName.jar">
- <fileset dir="bin">
- <include name="**/*.class"/>
- </fileset>
- <!-- Get everything; source, modules, html files -->
- <fileset dir="src">
- <include name="**"/>
- </fileset>
- <fileset dir="test">
- <include name="**"/>
- </fileset>
- </jar>
+ <target name="deploy" depends="gwtc" description="Copy output to the war folder">
+ <mkdir dir="${outdir}/WEB-INF/lib" />
+ <copy todir="${outdir}/WEB-INF/lib" file="@gwtServletPath" />
</target>
- <target name="clean">
- <!-- Delete the bin directory tree -->
- <delete file="@projectName.jar"/>
- <delete>
- <fileset dir="bin" includes="**/*.class"/>
- </delete>
+ <!-- can add additional arguments like -logLevel INFO or -style PRETTY -->
+ <target name="gwtc" depends="javac" description="Compile to JavaScript">
+ <java failonerror="true" fork="true"
+ classname="@compileClass">
+ <classpath>
+ <pathelement location="src"/>
+ <pathelement location="@gwtDevPath"/>
+ <pathelement location="${outdir}/WEB-INF/classes"/>
+ <pathelement path="${java.class.path}/"/>
+ <pathelement path="@gwtUserPath"/>
+ </classpath>
+ @vmargs
+ <arg value="-out"/>
+ <arg file="${outdir}"/>
+ <arg value="-extra"/>
+ <arg file="${extradir}"/>
+ <arg value="@moduleName"/>
+ </java>
</target>
- <target name="all" depends="package"/>
+ <!-- can add additional arguments like -logLevel INFO -->
+ <target name="shell" depends="javac" description="Run the deployed app in GWT hosted mode">
+ <java failonerror="true" fork="true"
+ classname="@shellClass">
+ <jvmarg value="-Xmx256M"/>
+ <classpath>
+ <pathelement location="src"/>
+ <pathelement location="@gwtDevPath"/>
+ <pathelement path="${java.class.path}/"/>
+ <pathelement path="@gwtUserPath"/>
+ </classpath>
+ @vmargs
+ <arg value="-out"/>
+ <arg file="${outdir}"/>
+ <arg value="-startupUrl"/>
+ <arg value="@startupUrl"/>
+ <arg value="@moduleName"/>
+ </java>
+ </target>
+
+ <target name="build" depends="javac, gwtc, deploy" description="Build this project" />
+
+ <target name="clean" description="Cleans this project's intermediate and
+ output files">
+ <!-- uncomment if the WEB-INF/classes dir only contains GWT output -->
+ <!-- <delete dir="${outdir}/WEB-INF/classes" failonerror="false" /> -->
+ <delete dir="${outdir}/@deployDir" failonerror="false" />
+ <delete dir="${extradir}" failonerror="false" />
+ </target>
</project>
diff --git a/user/src/com/google/gwt/user/tools/web.xmlsrc b/user/src/com/google/gwt/user/tools/web.xmlsrc
new file mode 100644
index 0000000..1d33d1e
--- /dev/null
+++ b/user/src/com/google/gwt/user/tools/web.xmlsrc
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app>
+
+ <servlet>
+ <servlet-name>echoServlet</servlet-name>
+ <servlet-class>@serverPackage.EchoServiceImpl</servlet-class>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>echoServlet</servlet-name>
+ <url-pattern>/@deployDir/echo</url-pattern>
+ </servlet-mapping>
+
+</web-app>