Change in gwt[master]: Adds the remaining (and more complex) Java 7 new language fe...

55 views
Skip to first unread message

Roberto Lublinerman

unread,
May 8, 2013, 1:54:56 PM5/8/13
to Matthew Dempsky, Rodrigo Chandia, Goktug Gokdogan, Roberto Lublinerman
Roberto Lublinerman has uploaded a new change for review.

https://gwt-review.googlesource.com/2680


Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: Ic46ae3c9ee49518cfddc6f6f329b721e6645802d
---
M dev/codeserver/java/com/google/gwt/dev/codeserver/CodeServer.java
M dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
M dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
M dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
M
dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
M dev/core/src/com/google/gwt/dev/CompileModule.java
M dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
M dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
M dev/core/src/com/google/gwt/dev/Compiler.java
M dev/core/src/com/google/gwt/dev/DevMode.java
M dev/core/src/com/google/gwt/dev/DevModeBase.java
M dev/core/src/com/google/gwt/dev/Precompile.java
M dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
M dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
M dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
M dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
M dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
M dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
M dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
A dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
A dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/CompilerTest.java
M dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
M dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java
M dev/core/test/com/google/gwt/dev/javac/JdtBehaviorTest.java
A dev/core/test/com/google/gwt/dev/javac/JdtJava7Test.java
M dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitter2Test.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
A dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
M user/src/com/google/gwt/junit/JUnitShell.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Exception.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
A
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/CompilerSuite.java
A user/test/com/google/gwt/dev/jjs/Java7Test.gwt.xml
A user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
49 files changed, 1,860 insertions(+), 121 deletions(-)



diff --git
a/dev/codeserver/java/com/google/gwt/dev/codeserver/CodeServer.java
b/dev/codeserver/java/com/google/gwt/dev/codeserver/CodeServer.java
index 01f3a65..2641b5d 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/CodeServer.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/CodeServer.java
@@ -116,9 +116,9 @@
for (String moduleName : options.getModuleNames()) {
AppSpace appSpace = AppSpace.create(new File(workDir, moduleName));

- Recompiler recompiler = new Recompiler(appSpace, moduleName,
- options.getSourcePath(), options.getPreferredHost() + ":" +
options.getPort(),
- options.getRecompileListener(), options.isCompileTest(), logger);
+ Recompiler recompiler = new Recompiler(appSpace, moduleName,
options.getSourcePath(),
+ options.getPreferredHost() + ":" + options.getPort(),
options.getRecompileListener(),
+ options.isCompileTest(), options.getSourceLevel(), logger);
modules.addModuleState(new ModuleState(recompiler, logger,
options.getNoPrecompile()));
}
return modules;
diff --git
a/dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
b/dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
index e8f65e7..5d2f5c1 100644
---
a/dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
+++
b/dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
@@ -19,6 +19,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.jjs.JsOutputOption;
import com.google.gwt.dev.util.arg.OptionOptimize;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;

import java.io.File;
import java.util.Arrays;
@@ -31,10 +32,12 @@
class CompilerOptionsImpl extends UnmodifiableCompilerOptions {
private final CompileDir compileDir;
private final String moduleName;
+ private final SourceLevel sourceLevel;

- CompilerOptionsImpl(CompileDir compileDir, String moduleName) {
+ CompilerOptionsImpl(CompileDir compileDir, String moduleName,
SourceLevel sourceLevel) {
this.compileDir = compileDir;
this.moduleName = moduleName;
+ this.sourceLevel = sourceLevel;
}

@Override
@@ -51,7 +54,7 @@
public int getFragmentCount() {
return -1;
}
-
+
@Override
public int getFragmentsMerge() {
return -1;
@@ -101,6 +104,11 @@
}

@Override
+ public SourceLevel getSourceLevel() {
+ return sourceLevel;
+ }
+
+ @Override
public File getWarDir() {
return compileDir.getWarDir();
}
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
b/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
index 08380bd..99b0575 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
@@ -17,6 +17,9 @@
package com.google.gwt.dev.codeserver;

import com.google.gwt.dev.ArgProcessorBase;
+import com.google.gwt.dev.util.arg.ArgHandlerSource;
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import com.google.gwt.util.tools.ArgHandler;
import com.google.gwt.util.tools.ArgHandlerDir;
import com.google.gwt.util.tools.ArgHandlerExtra;
@@ -46,6 +49,8 @@
private String preferredHost = "localhost";
private int port = 9876;
private RecompileListener recompileListener = RecompileListener.NONE;
+ // Use the same default as the GWT compiler.
+ private SourceLevel sourceLevel = OptionSource.DEFAULT_SOURCE_LEVEL;

/**
* Sets each option to the appropriate value, based on command-line
arguments.
@@ -105,6 +110,13 @@
}

/**
+ * Java source level compatibility,
+ */
+ SourceLevel getSourceLevel() {
+ return sourceLevel;
+ }
+
+ /**
* If true, just compile the modules, then exit.
*/
boolean isCompileTest() {
@@ -147,6 +159,17 @@
registerHandler(new AllowMissingSourceDirFlag());
registerHandler(new SourceFlag());
registerHandler(new ModuleNameArgument());
+ registerHandler(new ArgHandlerSource(new OptionSource() {
+ @Override
+ public SourceLevel getSourceLevel() {
+ return sourceLevel;
+ }
+
+ @Override
+ public void setSourceLevel(SourceLevel sourceLevel) {
+ Options.this.sourceLevel = sourceLevel;
+ }
+ }));
}

@Override
diff --git
a/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
b/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
index 025c2b9..b246f34 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
@@ -33,6 +33,7 @@
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.resource.impl.ResourceOracleImpl;
import com.google.gwt.dev.resource.impl.ZipFileClassPathEntry;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import com.google.gwt.dev.util.log.CompositeTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

@@ -55,6 +56,7 @@
private final TreeLogger logger;
private String serverPrefix;
private int compilesDone = 0;
+ private SourceLevel sourceLevel;

// after renaming
private AtomicReference<String> moduleName = new
AtomicReference<String>(null);
@@ -65,7 +67,7 @@

Recompiler(AppSpace appSpace, String moduleName, List<File> sourcePath,
String serverPrefix, RecompileListener listener, boolean
failIfListenerFails,
- TreeLogger logger) {
+ SourceLevel sourceLevel, TreeLogger logger) {
this.appSpace = appSpace;
this.originalModuleName = moduleName;
this.sourcePath = sourcePath;
@@ -73,6 +75,7 @@
this.failIfListenerFails = failIfListenerFails;
this.logger = logger;
this.serverPrefix = serverPrefix;
+ this.sourceLevel = sourceLevel;
}

synchronized CompileDir compile(Map<String, String> bindingProperties)
@@ -101,13 +104,12 @@

boolean success = false;
try {
-
ModuleDef module = loadModule(compileLogger, bindingProperties);
String newModuleName = module.getName(); // includes any rename
moduleName.set(newModuleName);


- CompilerOptions options = new CompilerOptionsImpl(compileDir,
newModuleName);
+ CompilerOptions options = new CompilerOptionsImpl(compileDir,
newModuleName, sourceLevel);

success = new Compiler(options).run(compileLogger, module);
lastBuild.set(compileDir); // makes compile log available over HTTP
diff --git
a/dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
b/dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
index b6b63e7..404d9b0 100644
---
a/dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
+++
b/dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
@@ -173,6 +173,11 @@
}

@Override
+ public final void setSourceLevel(SourceLevel sourceLevel) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public final void setSoycEnabled(boolean enabled) {
throw new UnsupportedOperationException();
}
diff --git a/dev/core/src/com/google/gwt/dev/CompileModule.java
b/dev/core/src/com/google/gwt/dev/CompileModule.java
index 8ba6fb5..eb30158 100644
--- a/dev/core/src/com/google/gwt/dev/CompileModule.java
+++ b/dev/core/src/com/google/gwt/dev/CompileModule.java
@@ -275,7 +275,8 @@

CompilationState compilationState;
try {
- compilationState =
module.getCompilationState(logger, !options.isStrict());
+ compilationState =
module.getCompilationState(logger, !options.isStrict(),
+ options.getSourceLevel());
} catch (Throwable e) {
CompilationProblemReporter.logAndTranslateException(logger, e);
return false;
diff --git a/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
b/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
index 82965c9..3e3ffe3 100644
--- a/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
+++ b/dev/core/src/com/google/gwt/dev/CompileTaskOptions.java
@@ -18,11 +18,12 @@
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.OptionSource;
import com.google.gwt.dev.util.arg.OptionWorkDir;

/**
* A common set of options for all compile tasks.
*/
public interface CompileTaskOptions extends OptionGuiLogger,
OptionModuleName,
- OptionLogLevel, OptionWorkDir {
+ OptionLogLevel, OptionWorkDir, OptionSource {
}
diff --git a/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
b/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
index cabbc4f..3caa68a 100644
--- a/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
+++ b/dev/core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java
@@ -16,6 +16,8 @@
package com.google.gwt.dev;

import com.google.gwt.core.ext.TreeLogger.Type;
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;

import java.io.File;
import java.util.ArrayList;
@@ -30,6 +32,7 @@
private final List<String> moduleNames = new ArrayList<String>();
private boolean useGuiLogger;
private File workDir;
+ private SourceLevel sourceLevel = OptionSource.DEFAULT_SOURCE_LEVEL;

public CompileTaskOptionsImpl() {
}
@@ -85,4 +88,14 @@
public void setWorkDir(File workDir) {
this.workDir = workDir;
}
+
+ @Override
+ public SourceLevel getSourceLevel() {
+ return sourceLevel;
+ }
+
+ @Override
+ public void setSourceLevel(SourceLevel sourceLevel) {
+ this.sourceLevel = sourceLevel;
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/Compiler.java
b/dev/core/src/com/google/gwt/dev/Compiler.java
index ca97510..994bfec 100644
--- a/dev/core/src/com/google/gwt/dev/Compiler.java
+++ b/dev/core/src/com/google/gwt/dev/Compiler.java
@@ -33,6 +33,7 @@
import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
import com.google.gwt.dev.util.arg.ArgHandlerLocalWorkers;
+import com.google.gwt.dev.util.arg.ArgHandlerSource;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
@@ -62,6 +63,7 @@
registerHandler(new ArgHandlerWarDir(options));
registerHandler(new ArgHandlerDeployDir(options));
registerHandler(new ArgHandlerExtraDir(options));
+ registerHandler(new ArgHandlerSource(options));
}

@Override
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java
b/dev/core/src/com/google/gwt/dev/DevMode.java
index 47845a4..658eecd 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -36,6 +36,7 @@
import com.google.gwt.dev.util.arg.ArgHandlerDisableUpdateCheck;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
+import com.google.gwt.dev.util.arg.ArgHandlerSource;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
@@ -182,6 +183,7 @@
registerHandler(new ArgHandlerExtraDir(options));
registerHandler(new ArgHandlerWorkDirOptional(options));
registerHandler(new ArgHandlerDisableUpdateCheck(options));
+ registerHandler(new ArgHandlerSource(options));
registerHandler(new ArgHandlerModuleName(options) {
@Override
public String getPurpose() {
diff --git a/dev/core/src/com/google/gwt/dev/DevModeBase.java
b/dev/core/src/com/google/gwt/dev/DevModeBase.java
index d4374c8..a5253cb 100644
--- a/dev/core/src/com/google/gwt/dev/DevModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/DevModeBase.java
@@ -106,7 +106,7 @@
ArchivePreloader.preloadArchives(logger, moduleDef);

CompilationState compilationState =
- moduleDef.getCompilationState(logger, !options.isStrict());
+ moduleDef.getCompilationState(logger, !options.isStrict(),
options.getSourceLevel());
ShellModuleSpaceHost host =
doCreateShellModuleSpaceHost(logger, compilationState,
moduleDef);
return host;
diff --git a/dev/core/src/com/google/gwt/dev/Precompile.java
b/dev/core/src/com/google/gwt/dev/Precompile.java
index 323fc67..a224c93 100644
--- a/dev/core/src/com/google/gwt/dev/Precompile.java
+++ b/dev/core/src/com/google/gwt/dev/Precompile.java
@@ -155,7 +155,7 @@
Event validateEvent =
SpeedTracerLogger.start(CompilerEventType.VALIDATE);
try {
CompilationState compilationState =
- module.getCompilationState(logger, !jjsOptions.isStrict());
+ module.getCompilationState(logger, !jjsOptions.isStrict(),
jjsOptions.getSourceLevel());
if (jjsOptions.isStrict() && compilationState.hasErrors()) {
abortDueToStrictMode(logger);
}
@@ -244,7 +244,7 @@

try {
CompilationState compilationState =
- module.getCompilationState(logger, !jjsOptions.isStrict());
+ module.getCompilationState(logger, !jjsOptions.isStrict(),
jjsOptions.getSourceLevel());
if (jjsOptions.isStrict() && compilationState.hasErrors()) {
abortDueToStrictMode(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 378ab1a..a8e1265 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
@@ -33,6 +33,8 @@
import com.google.gwt.dev.resource.impl.ResourceOracleImpl;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
@@ -364,15 +366,16 @@
}

public CompilationState getCompilationState(TreeLogger logger) throws
UnableToCompleteException {
- return getCompilationState(logger, false);
+ return getCompilationState(logger, false,
OptionSource.DEFAULT_SOURCE_LEVEL);
}

- public synchronized CompilationState getCompilationState(TreeLogger
logger, boolean suppressErrors)
+ public synchronized CompilationState getCompilationState(TreeLogger
logger,
+ boolean suppressErrors, SourceLevel sourceLevel)
throws UnableToCompleteException {
doRefresh();
CompilationState compilationState =
CompilationStateBuilder.buildFrom(logger,
lazySourceOracle.getResources(), null,
- suppressErrors);
+ suppressErrors, sourceLevel);
checkForSeedTypes(logger, compilationState);
return compilationState;
}
diff --git
a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
index 99c3770..b899e92 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
@@ -25,6 +25,8 @@
import com.google.gwt.dev.js.ast.JsRootScope;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.StringInterner;
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
@@ -154,7 +156,7 @@
/**
* The JDT compiler.
*/
- private final JdtCompiler compiler = new JdtCompiler(new
UnitProcessorImpl());
+ private final JdtCompiler compiler;

/**
* Continuation state for JSNI checking.
@@ -164,7 +166,9 @@

private final boolean suppressErrors;

- public CompileMoreLater(AdditionalTypeProviderDelegate delegate,
boolean suppressErrors) {
+ public CompileMoreLater(AdditionalTypeProviderDelegate delegate,
boolean suppressErrors,
+ SourceLevel sourceLevel) {
+ this.compiler = new JdtCompiler(new UnitProcessorImpl(),
sourceLevel);
compiler.setAdditionalTypeProviderDelegate(delegate);
this.suppressErrors = suppressErrors;
}
@@ -402,12 +406,13 @@

public static CompilationState buildFrom(TreeLogger logger,
Set<Resource> resources)
throws UnableToCompleteException {
- return buildFrom(logger, resources, null, false);
+ return buildFrom(logger, resources, null, false,
OptionSource.DEFAULT_SOURCE_LEVEL);
}

public static CompilationState buildFrom(TreeLogger logger,
Set<Resource> resources,
- AdditionalTypeProviderDelegate delegate) throws
UnableToCompleteException {
- return buildFrom(logger, resources, delegate, false);
+ AdditionalTypeProviderDelegate delegate, SourceLevel sourceLevel)
+ throws UnableToCompleteException {
+ return buildFrom(logger, resources, delegate, false, sourceLevel);
}

/**
@@ -416,11 +421,12 @@
* @throws UnableToCompleteException if the compiler aborts (not a
normal compile error).
*/
public static CompilationState buildFrom(TreeLogger logger,
Set<Resource> resources,
- AdditionalTypeProviderDelegate delegate, boolean suppressErrors)
+ AdditionalTypeProviderDelegate delegate, boolean suppressErrors,
+ SourceLevel sourceLevel)
throws UnableToCompleteException {
Event event =
SpeedTracerLogger.start(DevModeEventType.CSB_BUILD_FROM_ORACLE);
try {
- return instance.doBuildFrom(logger, resources, delegate,
suppressErrors);
+ return instance.doBuildFrom(logger, resources, delegate,
suppressErrors, sourceLevel);
} finally {
event.end();
}
@@ -451,7 +457,8 @@
* TODO: maybe use a finer brush than to synchronize the whole thing.
*/
public synchronized CompilationState doBuildFrom(TreeLogger logger,
Set<Resource> resources,
- AdditionalTypeProviderDelegate compilerDelegate, boolean
suppressErrors)
+ AdditionalTypeProviderDelegate compilerDelegate, boolean
suppressErrors,
+ SourceLevel sourceLevel)
throws UnableToCompleteException {

// Units we definitely want to build.
@@ -461,7 +468,8 @@
Map<CompilationUnitBuilder, CompilationUnit> cachedUnits =
new IdentityHashMap<CompilationUnitBuilder, CompilationUnit>();

- CompileMoreLater compileMoreLater = new
CompileMoreLater(compilerDelegate, suppressErrors);
+ CompileMoreLater compileMoreLater = new
CompileMoreLater(compilerDelegate, suppressErrors,
+ sourceLevel);

// For each incoming Java source file...
for (Resource resource : resources) {
@@ -503,8 +511,9 @@
}

public CompilationState doBuildFrom(TreeLogger logger, Set<Resource>
resources,
- boolean suppressErrors) throws UnableToCompleteException {
- return doBuildFrom(logger, resources, null, suppressErrors);
+ boolean suppressErrors, SourceLevel sourceLevel)
+ throws UnableToCompleteException {
+ return doBuildFrom(logger, resources, null, suppressErrors,
sourceLevel);
}

/**
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 716e2c6..252fed4 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
@@ -21,6 +21,8 @@
import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.util.Name.BinaryName;
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
@@ -379,9 +381,9 @@
private TreeLogger logger;
private int abortCount = 0;

- public CompilerImpl(TreeLogger logger) {
+ public CompilerImpl(TreeLogger logger, CompilerOptions
compilerOptions) {
super(new INameEnvironmentImpl(),
DefaultErrorHandlingPolicies.proceedWithAllProblems(),
- getCompilerOptions(), new ICompilerRequestorImpl(), new
DefaultProblemFactory(
+ compilerOptions, new ICompilerRequestorImpl(), new
DefaultProblemFactory(
Locale.getDefault()));
this.logger = logger;
}
@@ -576,11 +578,17 @@
public static List<CompilationUnit> compile(TreeLogger logger,
Collection<CompilationUnitBuilder> builders)
throws UnableToCompleteException {
+ return compile(logger, builders, OptionSource.DEFAULT_SOURCE_LEVEL);
+ }
+
+ public static List<CompilationUnit> compile(TreeLogger logger,
+ Collection<CompilationUnitBuilder> builders, SourceLevel sourceLevel)
+ throws UnableToCompleteException {
Event jdtCompilerEvent =
SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER);

try {
DefaultUnitProcessor processor = new DefaultUnitProcessor();
- JdtCompiler compiler = new JdtCompiler(processor);
+ JdtCompiler compiler = new JdtCompiler(processor, sourceLevel);
compiler.doCompile(logger, builders);
return processor.getResults();
} finally {
@@ -588,14 +596,20 @@
}
}

- public static CompilerOptions getCompilerOptions() {
+
+ public static CompilerOptions getStandardCompilerOptions() {
CompilerOptions options = new CompilerOptions() {
{
warningThreshold.clearAll();
}
};
- options.originalSourceLevel = options.complianceLevel =
options.sourceLevel =
- options.targetJDK = ClassFileConstants.JDK1_6;
+
+ long jdtSourceLevel =
jdtLevelByGwtLevel.get(OptionSource.DEFAULT_SOURCE_LEVEL);
+
+ options.originalSourceLevel = jdtSourceLevel;
+ options.complianceLevel = jdtSourceLevel;
+ options.sourceLevel = jdtSourceLevel;
+ options.targetJDK = jdtSourceLevel;

// Generate debug info for debugging the output.
options.produceDebugAttributes =
@@ -610,6 +624,17 @@
options.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference
= false;
options.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable
= false;
options.inlineJsrBytecode = true;
+ return options;
+ }
+
+ public CompilerOptions getCompilerOptions() {
+ CompilerOptions options = getStandardCompilerOptions();
+ long jdtSourceLevel = jdtLevelByGwtLevel.get(sourceLevel);
+
+ options.originalSourceLevel = jdtSourceLevel;
+ options.complianceLevel = jdtSourceLevel;
+ options.sourceLevel = jdtSourceLevel;
+ options.targetJDK = jdtSourceLevel;
return options;
}

@@ -705,8 +730,26 @@

private final UnitProcessor processor;

- public JdtCompiler(UnitProcessor processor) {
+ /**
+ * Java source level compatibility.
+ */
+ private final OptionSource.SourceLevel sourceLevel;
+
+ /**
+ * Maps from SourceLevel, the gwt compiler java source compatibility
levels, to JDT
+ * java source compatibility levels.
+ */
+ private static final Map<SourceLevel, Long> jdtLevelByGwtLevel =
+ new HashMap<SourceLevel, Long>();
+
+ static {
+ jdtLevelByGwtLevel.put(OptionSource.SourceLevel._6,
ClassFileConstants.JDK1_6);
+ jdtLevelByGwtLevel.put(OptionSource.SourceLevel._7,
ClassFileConstants.JDK1_7);
+ }
+
+ public JdtCompiler(UnitProcessor processor, SourceLevel sourceLevel) {
this.processor = processor;
+ this.sourceLevel = sourceLevel;
}

public void addCompiledUnit(CompilationUnit unit) {
@@ -918,7 +961,7 @@
icus.add(new Adapter(builder));
}

- compilerImpl = new CompilerImpl(logger);
+ compilerImpl = new CompilerImpl(logger, getCompilerOptions());
try {
compilerImpl.compile(icus.toArray(new
ICompilationUnit[icus.size()]));
} catch (AbortCompilation e) {
diff --git
a/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
b/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
index 2aa2dc6..d13d733 100644
---
a/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
+++
b/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
@@ -24,6 +24,7 @@
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockResource;
import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.util.arg.OptionSource;
import com.google.gwt.dev.util.collect.HashSet;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

@@ -104,7 +105,8 @@

private CompilationState buildCompilationState() throws
UnableToCompleteException {
TreeLogger logger = treeLogger != null ? treeLogger : createLogger();
- return new CompilationStateBuilder().doBuildFrom(logger, resources,
null, false);
+ return new CompilationStateBuilder().doBuildFrom(logger, resources,
null, false,
+ OptionSource.DEFAULT_SOURCE_LEVEL);
}

private TreeLogger createLogger() {
diff --git
a/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
b/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
index ea413fb..062b1b3 100644
---
a/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
+++
b/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
@@ -398,6 +398,7 @@
code.append("public class Throwable {\n");
code.append(" public String getMessage() { return \"\"; }\n");
code.append(" public Throwable getCause() { return null; }\n");
+ code.append(" void addSuppressed(Throwable ex) { } \n");
code.append("}\n");
return code;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
index 9c1c6dd..b5cb2a0 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
@@ -31,6 +31,7 @@
import com.google.gwt.dev.util.arg.OptionRemoveDuplicateFunctions;
import com.google.gwt.dev.util.arg.OptionRunAsyncEnabled;
import com.google.gwt.dev.util.arg.OptionScriptStyle;
+import com.google.gwt.dev.util.arg.OptionSource;
import com.google.gwt.dev.util.arg.OptionSoycDetailed;
import com.google.gwt.dev.util.arg.OptionSoycEnabled;
import com.google.gwt.dev.util.arg.OptionSoycHtmlDisabled;
@@ -44,6 +45,6 @@
OptionEnableAssertions, OptionInlineLiteralParameters,
OptionOptimizeDataflow,
OptionRunAsyncEnabled, OptionScriptStyle, OptionSoycEnabled,
OptionSoycDetailed,
OptionOptimizePrecompile, OptionOrdinalizeEnums,
OptionRemoveDuplicateFunctions, OptionStrict,
- OptionSoycHtmlDisabled, OptionEnableClosureCompiler,
OptionFragmentsMerge, OptionFragmentCount {
-
+ OptionSoycHtmlDisabled, OptionEnableClosureCompiler,
OptionFragmentsMerge, OptionFragmentCount,
+ OptionSource {
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
b/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
index 7a5bbf9..13e6edd 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptionsImpl.java
@@ -16,6 +16,7 @@
package com.google.gwt.dev.jjs;

import com.google.gwt.dev.util.arg.OptionOptimize;
+import com.google.gwt.dev.util.arg.OptionSource;

import java.io.Serializable;

@@ -45,6 +46,7 @@
private boolean soycExtra = false;
private boolean soycHtmlDisabled = false;
private boolean strict = false;
+ private SourceLevel sourceLevel = OptionSource.DEFAULT_SOURCE_LEVEL;

public JJSOptionsImpl() {
}
@@ -74,6 +76,7 @@
setSoycExtra(other.isSoycExtra());
setSoycHtmlDisabled(other.isSoycHtmlDisabled());
setStrict(other.isStrict());
+ setSourceLevel(other.getSourceLevel());
}

@Override
@@ -97,6 +100,10 @@
}

@Override
+ public SourceLevel getSourceLevel() {
+ return sourceLevel;
+ }
+
@Deprecated
public boolean isAggressivelyOptimize() {
return aggressivelyOptimize;
@@ -248,6 +255,11 @@
}

@Override
+ public void setSourceLevel(SourceLevel sourceLevel) {
+ this.sourceLevel = sourceLevel;
+ }
+
+ @Override
public void setSoycEnabled(boolean enabled) {
soycEnabled = enabled;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
b/dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
index 1f2d0ca..1c2a707 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
@@ -17,6 +17,7 @@

import com.google.gwt.dev.jjs.SourceInfo;

+import java.io.Serializable;
import java.util.List;

/**
@@ -24,27 +25,58 @@
*/
public class JTryStatement extends JStatement {

- private final List<JLocalRef> catchArgs;
- private final List<JBlock> catchBlocks;
+ /**
+ * Represents the catch clause parts of the try statement.
+ */
+ public static class CatchClause implements Serializable {
+ private final List<JType> catchTypes;
+ private final JLocalRef arg;
+ private final JBlock block;
+
+ public CatchClause(List<JType> catchTypes, JLocalRef arg, JBlock
block) {
+ this.catchTypes = catchTypes;
+ this.arg = arg;
+ this.block = block;
+ }
+
+ public List<JType> getTypes() {
+ return catchTypes;
+ }
+
+ public JLocalRef getArg() {
+ return arg;
+ }
+
+ public JBlock getBlock() {
+ return block;
+ }
+ }
+
+ private final List<CatchClause> catchClauses;
private final JBlock finallyBlock;
private final JBlock tryBlock;

- public JTryStatement(SourceInfo info, JBlock tryBlock, List<JLocalRef>
catchArgs,
- List<JBlock> catchBlocks, JBlock finallyBlock) {
+ /**
+ * Construct a Java try statement.
+ *
+ * Parameters catchTypes, catchArgs and catchBlocks must agree on size.
Each element of each
+ * of these lists corresponds to a catch statement.
+ *
+ * @param info the source information.
+ * @param tryBlock the statement block inside the try construct.
+ * @param catchClauses each element of this list contains a catch
clause.
+ * @param finallyBlock the statement block corresponding to the finally
construct.
+ */
+ public JTryStatement(SourceInfo info, JBlock tryBlock, List<CatchClause>
catchClauses,
+ JBlock finallyBlock) {
super(info);
- assert (catchArgs.size() == catchBlocks.size());
this.tryBlock = tryBlock;
- this.catchArgs = catchArgs;
- this.catchBlocks = catchBlocks;
+ this.catchClauses = catchClauses;
this.finallyBlock = finallyBlock;
}

- public List<JLocalRef> getCatchArgs() {
- return catchArgs;
- }
-
- public List<JBlock> getCatchBlocks() {
- return catchBlocks;
+ public List<CatchClause> getCatchClauses() {
+ return catchClauses;
}

public JBlock getFinallyBlock() {
@@ -58,8 +90,11 @@
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
visitor.accept(tryBlock);
- visitor.accept(catchArgs);
- visitor.accept(catchBlocks);
+
+ for (CatchClause clause : catchClauses) {
+ visitor.accept(clause.getArg());
+ visitor.accept(clause.getBlock());
+ }
// TODO: normalize this so it's never null?
if (finallyBlock != null) {
visitor.accept(finallyBlock);
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
index c055674..f903e8b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
@@ -17,6 +17,8 @@

import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.Context;
+import com.google.gwt.dev.jjs.ast.JBinaryOperation;
+import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JBlock;
import com.google.gwt.dev.jjs.ast.JDeclarationStatement;
import com.google.gwt.dev.jjs.ast.JExpression;
@@ -28,11 +30,13 @@
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
+import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JThrowStatement;
import com.google.gwt.dev.jjs.ast.JTryStatement;
+import com.google.gwt.dev.jjs.ast.JType;

import java.util.ArrayList;
import java.util.List;
@@ -58,11 +62,11 @@
// @Override
@Override
public void endVisit(JTryStatement x, Context ctx) {
- if (x.getCatchBlocks().isEmpty()) {
+ if (x.getCatchClauses().isEmpty()) {
return;
}

- SourceInfo catchInfo = x.getCatchBlocks().get(0).getSourceInfo();
+ SourceInfo catchInfo =
x.getCatchClauses().get(0).getBlock().getSourceInfo();
JLocal exVar = popTempLocal();
JBlock newCatchBlock = new JBlock(catchInfo);

@@ -77,19 +81,34 @@

/*
* Build up a series of if, else if statements to test the type of
the
- * exception object against the type of the user's catch block.
+ * exception object against the types of the user's catch block.
Each catch block might have
+ * multiple types in Java 7.
*
* Go backwards so we can nest the else statements in the correct
order!
*/
- // rethrow the current exception if no one caught it
+ // rethrow the current exception if no one caught it.
JStatement cur = new JThrowStatement(catchInfo, new
JLocalRef(catchInfo, exVar));
- for (int i = x.getCatchBlocks().size() - 1; i >= 0; --i) {
- JBlock block = x.getCatchBlocks().get(i);
- JLocalRef arg = x.getCatchArgs().get(i);
+ for (int i = x.getCatchClauses().size() - 1; i >= 0; i--) {
+ JTryStatement.CatchClause clause = x.getCatchClauses().get(i);
+ JBlock block = clause.getBlock();
+ JLocalRef arg = clause.getArg();
+ List<JType> exceptionsTypes = clause.getTypes();
catchInfo = block.getSourceInfo();
- JReferenceType argType = (JReferenceType) arg.getType();
- // if ($e instanceof ArgType) { var userVar = $e; <user code> }
- JExpression ifTest = new JInstanceOf(catchInfo, argType, new
JLocalRef(catchInfo, exVar));
+
+ // if ($e instanceof ArgType1 or $e instanceof ArgType2 ...) {
+ // var userVar = $e; <user code>
+ // }
+
+ // Handle the first Exception type.
+ JExpression ifTest = new JInstanceOf(catchInfo, (JReferenceType)
exceptionsTypes.get(0),
+ new JLocalRef(catchInfo, exVar));
+ // Handle the rest of the Exception types if any.
+ for (int j = 1; j < exceptionsTypes.size(); j++) {
+ JExpression orExp = new JInstanceOf(catchInfo, (JReferenceType)
exceptionsTypes.get(j),
+ new JLocalRef(catchInfo, exVar));
+ ifTest = new JBinaryOperation(catchInfo, JPrimitiveType.BOOLEAN,
JBinaryOperator.OR,
+ ifTest, orExp);
+ }
JDeclarationStatement declaration =
new JDeclarationStatement(catchInfo, arg, new
JLocalRef(catchInfo, exVar));
block.addStmt(0, declaration);
@@ -98,10 +117,13 @@
}

newCatchBlock.addStmt(cur);
- x.getCatchArgs().clear();
- x.getCatchArgs().add(new JLocalRef(newCatchBlock.getSourceInfo(),
exVar));
- x.getCatchBlocks().clear();
- x.getCatchBlocks().add(newCatchBlock);
+
+ // Replace with a single catch block.
+ x.getCatchClauses().clear();
+ List<JType> newCatchTypes = new ArrayList<JType>(1);
+ newCatchTypes.add(exVar.getType());
+ x.getCatchClauses().add(new JTryStatement.CatchClause(newCatchTypes,
+ new JLocalRef(newCatchBlock.getSourceInfo(), exVar),
newCatchBlock));
}

// @Override
@@ -115,7 +137,7 @@
// @Override
@Override
public boolean visit(JTryStatement x, Context ctx) {
- if (!x.getCatchBlocks().isEmpty()) {
+ if (!x.getCatchClauses().isEmpty()) {
pushTempLocal(x.getSourceInfo());
}
return true;
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
index 0907c57..2c778cf 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
@@ -579,24 +579,31 @@
@Override
public void endVisit(JTryStatement x, Context ctx) {
// 1) Remove catch blocks whose exception type is not instantiable.
- List<JLocalRef> catchArgs = x.getCatchArgs();
- List<JBlock> catchBlocks = x.getCatchBlocks();
- Iterator<JLocalRef> itA = catchArgs.iterator();
- Iterator<JBlock> itB = catchBlocks.iterator();
- while (itA.hasNext()) {
- JLocalRef localRef = itA.next();
- itB.next();
- JReferenceType type = (JReferenceType) localRef.getType();
- if (!program.typeOracle.isInstantiatedType(type) || type ==
program.getTypeNull()) {
- itA.remove();
- itB.remove();
+ List<JTryStatement.CatchClause> catchClauses = x.getCatchClauses();
+
+ Iterator<JTryStatement.CatchClause> itClauses =
catchClauses.iterator();
+ while (itClauses.hasNext()) {
+ JTryStatement.CatchClause clause = itClauses.next();
+ // Go over the types in the multiexception and remove the ones
that are not instantiable.
+ Iterator<JType> itTypes = clause.getTypes().iterator();
+ while (itTypes.hasNext()) {
+ JReferenceType type = (JReferenceType) itTypes.next();
+ if (!program.typeOracle.isInstantiatedType(type) || type ==
program.getTypeNull()) {
+ itTypes.remove();
+ madeChanges();
+ }
+ }
+
+ // if all exception types are gone then remove whole clause.
+ if (clause.getTypes().isEmpty()) {
+ itClauses.remove();
madeChanges();
}
}

// Compute properties regarding the state of this try statement
boolean noTry = Simplifier.isEmpty(x.getTryBlock());
- boolean noCatch = catchArgs.size() == 0;
+ boolean noCatch = catchClauses.size() == 0;
boolean noFinally = Simplifier.isEmpty(x.getFinallyBlock());

if (noTry) {
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 81e13ee..c0e1423 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -432,12 +432,9 @@
@Override
public boolean visit(JTryStatement x, Context ctx) {
accept(x.getTryBlock());
-
- List<JLocalRef> catchArgs = x.getCatchArgs();
- List<JBlock> catchBlocks = x.getCatchBlocks();
- for (int i = 0, c = catchArgs.size(); i < c; ++i) {
- JLocalRef arg = catchArgs.get(i);
- JBlock catchBlock = catchBlocks.get(i);
+ for (JTryStatement.CatchClause clause : x.getCatchClauses()) {
+ JLocalRef arg = clause.getArg();
+ JBlock catchBlock = clause.getBlock();
JsCatch jsCatch = new JsCatch(x.getSourceInfo(), peek(),
arg.getTarget().getName());
JsParameter jsParam = jsCatch.getParameter();
names.put(arg.getTarget(), jsParam.getName());
@@ -1466,12 +1463,12 @@
}
}

- int size = x.getCatchArgs().size();
- assert (size < 2 && size == x.getCatchBlocks().size());
+ int size = x.getCatchClauses().size();
+ assert (size < 2);
if (size == 1) {
JsBlock catchBlock = (JsBlock) pop(); // catchBlocks
pop(); // catchArgs
- JsCatch jsCatch = catchMap.get(x.getCatchBlocks().get(0));
+ JsCatch jsCatch =
catchMap.get(x.getCatchClauses().get(0).getBlock());
jsCatch.setBody(catchBlock);
jsTry.getCatches().add(jsCatch);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index c6c75e5..cf58284 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -177,7 +177,9 @@
import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
@@ -186,6 +188,7 @@
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
@@ -286,7 +289,8 @@
}
}

- private void processClassLiteral(JsNameRef nameRef, SourceInfo info,
JType type, JsContext ctx) {
+ private void processClassLiteral(JsNameRef nameRef, SourceInfo info,
JType type,
+ JsContext ctx) {
assert !ctx.isLvalue();
JsniClassLiteral classLiteral = new JsniClassLiteral(info,
nameRef.getIdent(), type);
nativeMethodBody.addClassRef(classLiteral);
@@ -1423,17 +1427,266 @@
List<JBlock> catchBlocks = pop(x.catchBlocks);
JBlock tryBlock = pop(x.tryBlock);

- List<JLocalRef> catchArgs = new ArrayList<JLocalRef>();
+ if (x.resources.length > 0) {
+ tryBlock = normalizeTryWithResources(info, x, tryBlock, scope);
+ }
+ List<JTryStatement.CatchClause> catchClauses =
+ new ArrayList<JTryStatement.CatchClause>();
if (x.catchBlocks != null) {
- for (Argument argument : x.catchArguments) {
+ for (int i = 0; i < x.catchArguments.length; i++) {
+ Argument argument = x.catchArguments[i];
JLocal local = (JLocal) curMethod.locals.get(argument.binding);
- catchArgs.add(new JLocalRef(info, local));
+
+ List<JType> catchTypes = new ArrayList<JType>();
+ if (argument.type instanceof UnionTypeReference) {
+ // This is a multiexception
+ for (TypeReference type : ((UnionTypeReference)
argument.type).typeReferences) {
+ catchTypes.add(typeMap.get(type.resolvedType));
+ }
+ } else {
+ // Regular exception
+ catchTypes.add(local.getType());
+ }
+ catchClauses.add(new JTryStatement.CatchClause(catchTypes, new
JLocalRef(info, local),
+ catchBlocks.get(i)));
}
}
- push(new JTryStatement(info, tryBlock, catchArgs, catchBlocks,
finallyBlock));
+ push(new JTryStatement(info, tryBlock, catchClauses,
finallyBlock));
} catch (Throwable e) {
throw translateException(x, e);
}
+ }
+
+ private JBlock normalizeTryWithResources(SourceInfo info, TryStatement
x, JBlock tryBlock,
+ BlockScope scope) {
+ /**
+ * Apply the following source transformation:
+ *
+ * try (A1 a1 = new A1(); ... ; An an = new An()) {
+ * ... tryBlock...
+ * } ...catch/finally blocks
+ *
+ * to
+ *
+ * try {
+ * A1 a1 = new A1();... ; An an = new An();
+ * Throwable $exception = null;
+ * try {
+ * ... tryBlock...
+ * } catch (Throwable t) {
+ * $exception = t;
+ * throw t;
+ * } finally {
+ * if (an != null) {
+ * try {
+ * an.close();
+ * } catch (Throwable t) {
+ * if ($exception == null) {
+ * $exception = t;
+ * } else {
+ * $exception.addSuppressed(t);
+ * }
+ * }
+ * }
+ * ...
+ * if (a1 != null) {
+ * try {
+ * a1.close();
+ * } catch (Throwable t) {
+ * if ($exception == null) {
+ * $exception = t;
+ * } else {
+ * $exception.addSuppressed(t);
+ * }
+ * }
+ * }
+ * if ($exception != null) {
+ * throw $exception;
+ * }
+ * } ...catch/finally blocks
+ *
+ */
+
+ JBlock innerBlock = new JBlock(info);
+ // add resource variables
+ List<JLocal> resourceVariables = new ArrayList<JLocal>();
+ for (int i = x.resources.length - 1; i >= 0; i--) {
+ // Needs to iterate back to front to be inline with the contents
of the stack.
+
+ JDeclarationStatement resourceDecl = pop(x.resources[i]);
+
+ JLocal resourceVar = (JLocal)
curMethod.locals.get(x.resources[i].binding);
+ resourceVariables.add(0, resourceVar);
+ innerBlock.addStmt(0, resourceDecl);
+ }
+
+ // add exception variable
+ JLocal exceptionVar =
+ createTempLocal(info, "$primary_ex", javaLangThrowable, false,
curMethod.body);
+
+ innerBlock.addStmt(makeDeclaration(info, exceptionVar,
JNullLiteral.INSTANCE));
+
+ // create catch block
+ List<JTryStatement.CatchClause> catchClauses = new
ArrayList<JTryStatement.CatchClause>(1);
+
+ List<JType> clauseTypes = new ArrayList<JType>(1);
+ clauseTypes.add(javaLangThrowable);
+
+ // add catch exception variable.
+ JLocal catchVar =
+ createTempLocal(info, "$caught_ex", javaLangThrowable, false,
curMethod.body);
+
+ JBlock catchBlock = new JBlock(info);
+ catchBlock.addStmt(createAssignment(info, javaLangThrowable,
exceptionVar, catchVar));
+ catchBlock.addStmt(new JThrowStatement(info, new JLocalRef(info,
exceptionVar)));
+
+ catchClauses.add(new JTryStatement.CatchClause(clauseTypes, new
JLocalRef(info, catchVar),
+ catchBlock));
+
+ // create finally block
+ JBlock finallyBlock = new JBlock(info);
+ for (int i = x.resources.length - 1; i >= 0; i--) {
+ finallyBlock.addStmt(createCloseBlockFor(info, x.resources[i],
+ resourceVariables.get(i), exceptionVar, scope));
+ }
+
+ // if (exception != null) throw exception
+ JExpression exceptionNotNull = new JBinaryOperation(info,
JPrimitiveType.BOOLEAN,
+ JBinaryOperator.NEQ, new JLocalRef(info, exceptionVar),
JNullLiteral.INSTANCE);
+ finallyBlock.addStmt(new JIfStatement(info, exceptionNotNull,
+ new JThrowStatement(info, new JLocalRef(info, exceptionVar)),
null));
+
+
+ // Stitch all together into a inner try block
+ innerBlock.addStmt(new JTryStatement(info, tryBlock, catchClauses,
+ finallyBlock));
+ return innerBlock;
+ }
+
+ private JLocal createTempLocal(SourceInfo info, String prefix, JType
type, boolean isFinal,
+ JMethodBody enclosingMethodBody) {
+ int index = curMethod.body.getLocals().size() + 1;
+ return JProgram.createLocal(info, prefix + "_" + index,
+ javaLangThrowable, false, curMethod.body);
+ }
+
+ private JStatement createCloseBlockFor(final SourceInfo info, final
LocalDeclaration resource,
+ JLocal resourceVar, JLocal exceptionVar, BlockScope scope) {
+ /**
+ * Create the following code:
+ *
+ * if (resource != null) {
+ * try {
+ * resource.close();
+ * } catch (Throwable t) {
+ * if ($ex == null) {
+ * $ex = t;
+ * } else {
+ * $ex.addSuppressed(t);
+ * }
+ * }
+ */
+
+ // create catch block
+ List<JTryStatement.CatchClause> catchClauses = new
ArrayList<JTryStatement.CatchClause>(1);
+
+ List<JType> clauseTypes = new ArrayList<JType>(1);
+ clauseTypes.add(javaLangThrowable);
+
+ // add catch exception variable.
+ JLocal catchVar =
+ createTempLocal(info, "$caught_ex", javaLangThrowable, false,
curMethod.body);
+
+ MethodBinding closeMethod = scope.getMethod(resource.binding.type,
CLOSE, new TypeBinding[0],
+ createInvokationSite(resource));
+
+ JStatement resourceClose = new JMethodCall(info, new
JLocalRef(info, resourceVar),
+ typeMap.get(closeMethod)).makeStatement();
+
+
+ // Crate catch block
+ JBlock catchBlock = new JBlock(info);
+
+ JStatement assignException = createAssignment(info,
javaLangThrowable, exceptionVar, catchVar);
+
+ MethodBinding addSuppressedMethod =
scope.getJavaLangThrowable().getExactMethod(ADDSUPRESSED,
+ new TypeBinding[] {scope.getJavaLangThrowable()},
scope.compilationUnitScope());
+ JMethodCall addSuppressedCall = new JMethodCall(info, new
JLocalRef(info, exceptionVar),
+ typeMap.get(addSuppressedMethod));
+ addSuppressedCall.addArg(new JLocalRef(info, catchVar));
+ // Surround with if exception == null
+ JExpression exceptionIsNull = new JBinaryOperation(info,
JPrimitiveType.BOOLEAN,
+ JBinaryOperator.EQ, new JLocalRef(info, exceptionVar),
JNullLiteral.INSTANCE);
+ JIfStatement exceptionIf = new JIfStatement(info, exceptionIsNull,
assignException,
+ addSuppressedCall.makeStatement());
+ catchBlock.addStmt(exceptionIf);
+ JBlock innerTryBlock = new JBlock(info);
+ innerTryBlock.addStmt(resourceClose);
+ // make try block
+ catchClauses.add(new JTryStatement.CatchClause(clauseTypes, new
JLocalRef(info, catchVar),
+ catchBlock));
+ JTryStatement tryBlock = new JTryStatement(info, innerTryBlock,
catchClauses, null);
+ // Surround with if resource != null
+ JExpression resourceNotNull = new JBinaryOperation(info,
JPrimitiveType.BOOLEAN,
+ JBinaryOperator.NEQ, new JLocalRef(info, resourceVar),
JNullLiteral.INSTANCE);
+ JIfStatement closeClause = new JIfStatement(info, resourceNotNull,
tryBlock, null);
+
+ return closeClause;
+ }
+
+ private JStatement createAssignment(SourceInfo info, JType type,
JLocal lhs, JLocal rhs) {
+ return new JBinaryOperation(info, type, JBinaryOperator.ASG, new
JLocalRef(info, lhs),
+ new JLocalRef(info, rhs)).makeStatement();
+ }
+
+ /**
+ * Create an empty invokation site (like in
org.eclipse.jdt.internal.compiler.ast.TryStatement:
+ * analyzeCode).
+ */
+ private InvocationSite createInvokationSite(final LocalDeclaration
resource) {
+ return new InvocationSite() {
+ @Override
+ public TypeBinding[] genericTypeArguments() {
+ return new TypeBinding[0];
+ }
+
+ @Override
+ public boolean isSuperAccess() {
+ return false;
+ }
+
+ @Override
+ public boolean isTypeAccess() {
+ return false;
+ }
+
+ @Override
+ public void setActualReceiverType(ReferenceBinding receiverType) {
+ }
+
+ @Override
+ public void setDepth(int depth) {
+ }
+
+ @Override
+ public void setFieldIndex(int depth) {
+ }
+
+ @Override
+ public int sourceEnd() {
+ return resource.sourceStart();
+ }
+
+ @Override
+ public int sourceStart() {
+ return resource.sourceEnd();
+ }
+
+ @Override
+ public TypeBinding expectedType() {
+ return null;
+ }
+ };
}

@Override
@@ -2784,6 +3037,8 @@
private static final char[] VALUE = "Value".toCharArray();
private static final char[] VALUE_OF = "valueOf".toCharArray();
private static final char[] VALUES = "values".toCharArray();
+ private static final char[] CLOSE = "close".toCharArray();
+ private static final char[] ADDSUPRESSED = "addSuppressed".toCharArray();

static {
InternalCompilerException.preload();
@@ -2896,6 +3151,8 @@

JClassType javaLangString = null;

+ JClassType javaLangThrowable = null;
+
Map<MethodDeclaration, JsniMethod> jsniMethods;

Map<String, Binding> jsniRefs;
@@ -2939,6 +3196,7 @@
javaLangObject = (JClassType)
typeMap.get(cud.scope.getJavaLangObject());
javaLangString = (JClassType)
typeMap.get(cud.scope.getJavaLangString());
javaLangClass = (JClassType) typeMap.get(cud.scope.getJavaLangClass());
+ javaLangThrowable = (JClassType)
typeMap.get(cud.scope.getJavaLangThrowable());

for (TypeDeclaration typeDecl : cud.types) {
// Resolve super type / interface relationships.
@@ -2964,7 +3222,7 @@
javaLangObject = null;
javaLangString = null;
javaLangClass = null;
-
+ javaLangThrowable = null;
return result;
}

diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
index 691752a..d2c69de 100644
---
a/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
+++
b/dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
@@ -132,6 +132,7 @@
protected static final char[] CHARS_NATIVE = "native ".toCharArray();
protected static final char[] CHARS_NEW = "new ".toCharArray();
protected static final char[] CHARS_NULL = "null".toCharArray();
+ protected static final char[] CHARS_PIPE = " | ".toCharArray();
protected static final char[] CHARS_PRIVATE = "private ".toCharArray();
protected static final char[] CHARS_PROTECTED
= "protected ".toCharArray();
protected static final char[] CHARS_PUBLIC = "public ".toCharArray();
@@ -887,15 +888,22 @@
public boolean visit(JTryStatement x, Context ctx) {
print(CHARS_TRY);
accept(x.getTryBlock());
- for (int i = 0, c = x.getCatchArgs().size(); i < c; ++i) {
+ for (JTryStatement.CatchClause clause : x.getCatchClauses()) {
print(CHARS_CATCH);
lparen();
- JLocalRef localRef = x.getCatchArgs().get(i);
- accept(localRef.getTarget());
+
+ Iterator<JType> it = clause.getTypes().iterator();
+ printTypeName(it.next());
+ while (it.hasNext()) {
+ print(CHARS_PIPE);
+ printTypeName(it.next());
+ }
+ space();
+
+ printName(clause.getArg().getTarget());
rparen();
space();
- JBlock block = x.getCatchBlocks().get(i);
- accept(block);
+ accept(clause.getBlock());
}
if (x.getFinallyBlock() != null) {
print(CHARS_FINALLY);
@@ -1150,11 +1158,15 @@
}

protected void visitCollectionWithCommas(Iterator<? extends JNode> iter)
{
+ visitCollectionWith(CHARS_COMMA, iter);
+ }
+
+ protected void visitCollectionWith(char[] ch, Iterator<? extends JNode>
iter) {
if (iter.hasNext()) {
accept(iter.next());
}
while (iter.hasNext()) {
- print(CHARS_COMMA);
+ print(ch);
accept(iter.next());
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
index ae6205c..5ac6ea7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
@@ -34,7 +34,6 @@
import com.google.gwt.dev.jjs.ast.JInstanceOf;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JLocal;
-import com.google.gwt.dev.jjs.ast.JLocalRef;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
@@ -291,8 +290,8 @@
public void endVisit(JTryStatement x, Context ctx) {
// Never tighten args to catch blocks
// Fake an assignment-to-self to prevent tightening
- for (JLocalRef arg : x.getCatchArgs()) {
- addAssignment(arg.getTarget(), arg);
+ for (JTryStatement.CatchClause clause : x.getCatchClauses()) {
+ addAssignment(clause.getArg().getTarget(), clause.getArg());
}
}

diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
index 5aa134c..346eff1 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
@@ -61,6 +61,7 @@
import com.google.gwt.dev.jjs.ast.JReturnStatement;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
import com.google.gwt.dev.jjs.ast.JThisRef;
+import com.google.gwt.dev.jjs.ast.JTryStatement;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVariable;
import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
@@ -318,6 +319,20 @@
}

@Override
+ public void endVisit(JTryStatement x, Context ctx) {
+ // Needs to resolve the Exceptions Types explicitly they are
multiple in Java 7 and
+ // potentially different from the one in the exception variable.
+ for (JTryStatement.CatchClause clause : x.getCatchClauses()) {
+ List<JType> types = clause.getTypes();
+ for (int i = 0; i < types.size(); i++) {
+ JReferenceType resolvedType = translate((JReferenceType)
types.get(i));
+ assert resolvedType.replaces(types.get(i));
+ types.set(i, resolvedType);
+ }
+ }
+ }
+
+ @Override
public void endVisit(JVariable x, Context ctx) {
x.setType(translate(x.getType()));
}
diff --git
a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
index f643eb7..9b7f6d3 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
@@ -763,7 +763,8 @@
List<Integer> catchBlockPos = new ArrayList<Integer>();
List<List<Exit>> catchExits = new ArrayList<List<Exit>>();

- for (JBlock b : x.getCatchBlocks()) {
+ for (JTryStatement.CatchClause clause : x.getCatchClauses()) {
+ JBlock b = clause.getBlock();
catchBlockPos.add(nodes.size());
accept(b);
catchExits.add(removeCurrentExits());
@@ -790,12 +791,16 @@
if (e.isThrow()) {
// If execution of the try block completes abruptly because of
a
// throw of a value V, then there is a choice:
- nextCatchBlock : for (int i = 0; i < x.getCatchArgs().size();
++i) {
+ nextCatchBlock : for (int i = 0; i <
x.getCatchClauses().size(); ++i) {
// If the run-time type of V is assignable (�5.2) to the
// Parameter of any catch clause of the try statement, then
// the first (leftmost) such catch clause is selected.
- JClassType catchType =
- (JClassType) x.getCatchArgs().get(i).getType();
+
+ // TODO(rluble): we are safely overapproximating the
exception
+ // caught in this block by the type of the exception
variable.
+ // We could do better in multiexceptions.
+ JClassType catchType =
+ (JClassType) x.getCatchClauses().get(i).getArg().getType();
JType exceptionType = e.getExceptionType();

boolean canCatch = false;
@@ -806,7 +811,12 @@
// Catch clause fully covers exception type. We'll land
// here for sure.
canCatch = true;
- fullCatch = true;
+ // Safe approximation. If it is a multi exception with
only one
+ // exception declared in the clause then the variable is
of the
+ // the same type as the exception declared and the
approximation
+ // is exact hence and this is a full catch.
+ fullCatch = x.getCatchClauses().get(i).getTypes().size()
== 1 &&
+ x.getCatchClauses().get(i).getTypes().get(0) ==
catchType;
} else if (typeOracle.canTriviallyCast(catchType,
exceptionType)) {
// We can land here if we throw some subclass of
// exceptionType
@@ -864,12 +874,16 @@
// If execution of the try block completes abruptly because of
a
// throw of a value V, then there is a choice:

- nextCatchBlock : for (int i = 0; i < x.getCatchArgs().size();
++i) {
+ nextCatchBlock : for (int i = 0; i <
x.getCatchClauses().size(); ++i) {
// If the run-time type of V is assignable to the parameter
of any
// catch clause of the try statement, then the first
// (leftmost) such catch clause is selected.
- JClassType catchType =
- (JClassType) x.getCatchArgs().get(i).getType();
+
+ // TODO(rluble): we are safely overapproximating the
exception
+ // caught in this block by the type of the exception
variable.
+ // We could do better in multiexceptions.
+ JClassType catchType =
+ (JClassType) x.getCatchClauses().get(i).getArg().getType();
JType exceptionType = e.getExceptionType();

boolean canCatch = false;
@@ -880,7 +894,12 @@
// Catch clause fully covers exception type. We'll land
// here for sure.
canCatch = true;
- fullCatch = true;
+ // Safe approximation. If it is a multi exception with
only one
+ // exception declared in the clause then the variable is
of the
+ // the same type as the exception declared and the
approximation
+ // is exact hence and this is a full catch.
+ fullCatch = x.getCatchClauses().get(i).getTypes().size()
== 1 &&
+ x.getCatchClauses().get(i).getTypes().get(0) ==
catchType;
} else if (typeOracle.canTriviallyCast(catchType,
exceptionType)) {
// We can land here if we throw some subclass of
// exceptionType
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
new file mode 100644
index 0000000..64ae052
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013 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.dev.util.arg.OptionSource.SourceLevel;
+import com.google.gwt.thirdparty.guava.common.base.Joiner;
+import com.google.gwt.util.tools.ArgHandlerString;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Set the java source level compatibility.
+ */
+public class ArgHandlerSource extends ArgHandlerString {
+ private final Map<String, SourceLevel> sourceLevelsByString =
+ new HashMap<String, SourceLevel>();
+
+ private final OptionSource options;
+
+ public ArgHandlerSource(OptionSource options) {
+ this.options = options;
+ for (SourceLevel sourceLevel : SourceLevel.values()) {
+ sourceLevelsByString.put(sourceLevel.getStringValue(), sourceLevel);
+ sourceLevelsByString.put(sourceLevel.getAltStringValue(),
sourceLevel);
+ }
+ }
+
+ @Override
+ public String[] getDefaultArgs() {
+ return new String[]{getTag(),
OptionSource.DEFAULT_SOURCE_LEVEL.getStringValue()};
+ }
+
+ @Override
+ public String getPurpose() {
+ return "Specifies source level (defaults to " +
OptionSource.DEFAULT_SOURCE_LEVEL + ")";
+ }
+
+ @Override
+ public String getTag() {
+ return "-sourceLevel";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[]{"[" + Joiner.on(",").join(SourceLevel.values())
+ "]"};
+ }
+
+ @Override
+ public boolean setString(String value) {
+ SourceLevel level = sourceLevelsByString.get(value);
+ if (value == null) {
+ System.err.println("Source level must be one of [" +
+ Joiner.on(",").join(SourceLevel.values()) + "].");
+ return false;
+ }
+ options.setSourceLevel(level);
+ return true;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java
b/dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java
new file mode 100644
index 0000000..15c11a2
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 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;
+
+/**
+ * An option that can indicates the java source level compatibility.
+ */
+public interface OptionSource {
+
+ /**
+ * Java source level compatibility constants.
+ */
+ enum SourceLevel {
+ _6("1.6", "6"),
+ _7("1.7", "7");
+
+ private final String stringValue;
+ private final String altStringValue;
+
+ private SourceLevel(String stringValue, String altStringValue) {
+ this.stringValue = stringValue;
+ this.altStringValue = altStringValue;
+ }
+
+ /**
+ * Returns a string value representation for the source level.
+ */
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ /**
+ * Returns an alternate string value representation for the source
level.
+ */
+ public String getAltStringValue() {
+ return altStringValue;
+ }
+
+ @Override
+ public String toString() {
+ return stringValue;
+ }
+ }
+
+ static final SourceLevel DEFAULT_SOURCE_LEVEL = SourceLevel._6;
+
+ SourceLevel getSourceLevel();
+
+ void setSourceLevel(SourceLevel level);
+}
diff --git
a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
index c437453..3bfc877 100644
---
a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
+++
b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
@@ -65,5 +65,30 @@
static boolean throwAssertionError_Object(Object message) {
throw new AssertionError(message);
}
+
+
+ /**
+ * Use by the try-with-resources construct. Look at
+ * {@link com.google.gwt.dev.jjs.impl.GwtAstBuilder.createCloseBlockFor}.
+ *
+ * @param resource a resource implementing the AutoCloseable interface.
+ * @param mainException an exception being propagated.
+ * @return an exception to propagate or {@code null} if none.
+ */
+ static Throwable safeClose(AutoCloseable resource, Throwable
mainException) {
+ if (resource == null) {
+ return mainException;
+ }
+
+ try {
+ resource.close();
+ } catch (Throwable e) {
+ if (mainException == null) {
+ return e;
+ }
+ mainException.addSuppressed(e);
+ }
+ return mainException;
+ }
// CHECKSTYLE_ON
}
diff --git a/dev/core/test/com/google/gwt/dev/CompilerTest.java
b/dev/core/test/com/google/gwt/dev/CompilerTest.java
index 2c47e86..6bd12da 100644
--- a/dev/core/test/com/google/gwt/dev/CompilerTest.java
+++ b/dev/core/test/com/google/gwt/dev/CompilerTest.java
@@ -18,6 +18,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.Compiler.CompilerOptionsImpl;
import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.util.arg.OptionSource;

import java.io.File;

@@ -37,7 +38,7 @@
assertProcessSuccess(argProcessor, "-logLevel", "DEBUG", "-style",
"PRETTY", "-ea", "-XdisableAggressiveOptimization", "-gen", "myGen",
"-war", "myWar", "-workDir", "myWork", "-extra", "myExtra",
- "-localWorkers", "2", "c.g.g.h.H", "my.Module");
+ "-localWorkers", "2", "-sourceLevel", "1.7", "c.g.g.h.H", "my.Module");

assertEquals(new File("myGen").getAbsoluteFile(),
options.getGenDir().getAbsoluteFile());
@@ -55,6 +56,8 @@
assertFalse(options.shouldOptimizeDataflow());
assertFalse(options.shouldOrdinalizeEnums());
assertFalse(options.shouldRemoveDuplicateFunctions());
+
+ assertEquals(OptionSource.SourceLevel._7, options.getSourceLevel());

assertEquals(2, options.getModuleNames().size());
assertEquals("c.g.g.h.H", options.getModuleNames().get(0));
@@ -87,5 +90,7 @@

public void testForbiddenArgs() {
assertProcessFailure(argProcessor, "-out", "www");
+ assertProcessFailure(argProcessor, "-sourceLevel", "ssss");
+ assertProcessFailure(argProcessor, "-sourceLevel", "1.5");
}
}
diff --git
a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
index 8d74ce9..d909f1c 100644
--- a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
@@ -22,6 +22,7 @@
import com.google.gwt.dev.javac.testing.impl.MockResourceOracle;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.arg.OptionSource;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

@@ -123,7 +124,8 @@

protected void rebuildCompilationState() {
try {
- state = isolatedBuilder.doBuildFrom(createTreeLogger(),
oracle.getResources(), false);
+ state = isolatedBuilder.doBuildFrom(createTreeLogger(),
oracle.getResources(), false,
+ OptionSource.DEFAULT_SOURCE_LEVEL);
} catch (UnableToCompleteException e) {
throw new RuntimeException(e);
}
diff --git
a/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java
b/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java
index 4073095..ff00bf7 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JavaCompilationSuite.java
@@ -50,6 +50,7 @@
suite.addTestSuite(JavaSourceParserTest.class);
suite.addTestSuite(JdtBehaviorTest.class);
suite.addTestSuite(JdtCompilerTest.class);
+ suite.addTestSuite(JdtJava7Test.class);
suite.addTestSuite(JsniCheckerTest.class);
suite.addTestSuite(JsniCollectorTest.class);
suite.addTestSuite(JSORestrictionsTest.class);
diff --git a/dev/core/test/com/google/gwt/dev/javac/JdtBehaviorTest.java
b/dev/core/test/com/google/gwt/dev/javac/JdtBehaviorTest.java
index bfbec85..0be5bac 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JdtBehaviorTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JdtBehaviorTest.java
@@ -60,7 +60,7 @@
public CompilerImpl(INameEnvironment environment,
ICompilerRequestor requestor) {
super(environment,
DefaultErrorHandlingPolicies.proceedWithAllProblems(),
- JdtCompiler.getCompilerOptions(), requestor,
+ JdtCompiler.getStandardCompilerOptions(), requestor,
new DefaultProblemFactory(Locale.getDefault()));
}
}
diff --git a/dev/core/test/com/google/gwt/dev/javac/JdtJava7Test.java
b/dev/core/test/com/google/gwt/dev/javac/JdtJava7Test.java
new file mode 100644
index 0000000..64581c9
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/javac/JdtJava7Test.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2013 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.javac;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
+import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
+import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.util.Strings;
+import com.google.gwt.dev.util.arg.OptionSource;
+
+import junit.framework.TestCase;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Test class for language features introduced in Java 7.
+ *
+ * Only tests that the JDT accepts and compiles the new syntax..
+ */
+public class JdtJava7Test extends TestCase {
+
+ static void assertUnitHasErrors(CompilationUnit unit, int numErrors) {
+ assertTrue(unit.isError());
+ assertEquals(numErrors, unit.getProblems().length);
+ }
+
+ static void assertUnitsCompiled(Collection<CompilationUnit> units) {
+ for (CompilationUnit unit : units) {
+ if (unit.isError()) {
+ String[] messages = new String[unit.getProblems().length];
+ int i = 0;
+ for (CategorizedProblem pb : unit.getProblems()) {
+ messages[i] = pb.getMessage();
+ }
+ fail(Strings.join(messages, "\n"));
+ }
+ assertTrue(unit.getCompiledClasses().size() > 0);
+ }
+ }
+
+ public void testCompileNewStyleLiterals() throws Exception {
+ List<CompilationUnitBuilder> builders = new
ArrayList<CompilationUnitBuilder>();
+ addAll(builders, JavaResourceBase.getStandardResources());
+ addAll(builders, LIST_T, ARRAYLIST_T, INTEGERLITERALS);
+ Collection<CompilationUnit> units = compile(TreeLogger.NULL, builders);
+ assertUnitsCompiled(units);
+ }
+
+ public void testCompileSwitchWithStrings() throws Exception {
+ List<CompilationUnitBuilder> builders = new
ArrayList<CompilationUnitBuilder>();
+ addAll(builders, JavaResourceBase.getStandardResources());
+ addAll(builders, LIST_T, ARRAYLIST_T, STRINGSWITCHTEST);
+ Collection<CompilationUnit> units = compile(TreeLogger.NULL, builders);
+ assertUnitsCompiled(units);
+ }
+
+ public void testCompileDiamondOperator() throws Exception {
+ List<CompilationUnitBuilder> builders = new
ArrayList<CompilationUnitBuilder>();
+ addAll(builders, JavaResourceBase.getStandardResources());
+ addAll(builders, LIST_T, ARRAYLIST_T, DIAMOND_OPERATOR);
+ Collection<CompilationUnit> units = compile(TreeLogger.NULL, builders);
+ assertUnitsCompiled(units);
+ }
+
+ public void testCompileTryWithResources() throws Exception {
+ List<CompilationUnitBuilder> builders = new
ArrayList<CompilationUnitBuilder>();
+ addAll(builders, JavaResourceBase.getStandardResources());
+ addAll(builders, JAVA_LANG_AUTOCLOSEABLE,
+ TEST_RESOURCE, TRY_WITH_RESOURCES);
+ Collection<CompilationUnit> units = compile(TreeLogger.NULL, builders);
+ assertUnitsCompiled(units);
+ }
+
+ public void testCompileMultiExceptions() throws Exception {
+ List<CompilationUnitBuilder> builders = new
ArrayList<CompilationUnitBuilder>();
+ addAll(builders, JavaResourceBase.getStandardResources());
+ addAll(builders, EXCEPTION1, EXCEPTION2, MULTI_EXCEPTIONS);
+ Collection<CompilationUnit> units = compile(TreeLogger.NULL, builders);
+ assertUnitsCompiled(units);
+ }
+
+
+ public static final MockJavaResource INTEGERLITERALS = new
MockJavaResource(
+ "com.google.gwt.IntegerLiterals") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class IntegerLiterals {\n");
+ code.append(" int million = 1_000_000;\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource STRINGSWITCHTEST =
+ new MockJavaResource("com.google.gwt.StringSwitchTest") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class StringSwitchTest {\n");
+ code.append(" int test() { \n");
+ code.append(" int result = 0;");
+ code.append(" String f = \"AA\";");
+ code.append(" switch(f) {");
+ code.append(" case \"CC\": result = - 1; break;");
+ code.append(" case \"BB\": result = 1;");
+ code.append(" case \"AA\": result = result + 1;
break;");
+ code.append(" default: result = -2; break;");
+ code.append(" } \n");
+ code.append(" return result; \n");
+ code.append(" } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource DIAMOND_OPERATOR = new
MockJavaResource(
+ "com.google.gwt.DiamondTest") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import com.google.gwt.List;\n");
+ code.append("import com.google.gwt.ArrayList;\n");
+ code.append("public class DiamondTest {\n");
+ code.append(" void test() {\n");
+ code.append(" List<String> list = new ArrayList<>();\n");
+ code.append(" } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource TRY_WITH_RESOURCES =
+ new MockJavaResource("com.google.gwt.TryWithResourcesTest") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import com.google.gwt.TestResource;\n");
+ code.append("public class TryWithResourcesTest {\n");
+ code.append(" void test() { \n");
+ code.append(" try( TestResource tr1 = new TestResource();
\n");
+ code.append(" TestResource tr2 = new TestResource())
{\n");
+ code.append(" } \n");
+ code.append(" } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource MULTI_EXCEPTIONS =
+ new MockJavaResource("com.google.gwt.MultiExceptionTest") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import com.google.gwt.Exception1;\n");
+ code.append("import com.google.gwt.Exception2;\n");
+ code.append("public class MultiExceptionTest {\n");
+ code.append(" void test() { \n");
+ code.append(" int i = 1;\n");
+ code.append(" try {\n");
+ code.append(" if (i > 0) {\n");
+ code.append(" throw new Exception1();\n");
+ code.append(" } else {\n");
+ code.append(" throw new Exception2();\n");
+ code.append(" }");
+ code.append(" } catch (Exception1 | Exception2 e) { \n");
+ code.append(" }\n");
+ code.append(" } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource LIST_T = new MockJavaResource(
+ "com.google.gwt.List") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public interface List<T> {\n");
+ code.append(" T method1(); \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource ARRAYLIST_T = new MockJavaResource(
+ "com.google.gwt.ArrayList") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import com.google.gwt.List;\n");
+ code.append("public class ArrayList<T> implements List<T> {\n");
+ code.append(" public T method1() { return null; } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+
+ public static final MockJavaResource JAVA_LANG_AUTOCLOSEABLE = new
MockJavaResource(
+ "java.lang.AutoCloseable") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package java.lang;\n");
+ code.append("import java.lang.Exception;\n");
+ code.append("public interface AutoCloseable {\n");
+ code.append(" void close() throws Exception; \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+
+ public static final MockJavaResource TEST_RESOURCE = new
MockJavaResource(
+ "com.google.gwt.TestResource") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class TestResource implements AutoCloseable
{\n");
+ code.append(" public void close() { } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource EXCEPTION1 = new MockJavaResource(
+ "com.google.gwt.Exception1") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import java.lang.Exception;\n");
+ code.append("public class Exception1 extends Exception {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource EXCEPTION2 = new MockJavaResource(
+ "com.google.gwt.Exception2") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import java.lang.Exception;\n");
+ code.append("public class Exception2 extends Exception {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ private void addAll(Collection<CompilationUnitBuilder> units,
+ Resource... sourceFiles) {
+ for (Resource sourceFile : sourceFiles) {
+ units.add(CompilationUnitBuilder.create(sourceFile));
+ }
+ }
+
+ private List<CompilationUnit> compile(TreeLogger logger,
+ Collection<CompilationUnitBuilder> builders) throws
UnableToCompleteException {
+ return JdtCompiler.compile(logger, builders,
OptionSource.SourceLevel._7);
+ }
+
+}
diff --git
a/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitter2Test.java
b/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitter2Test.java
index 105b169..9d64fa5 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitter2Test.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/CodeSplitter2Test.java
@@ -261,7 +261,7 @@
addBuiltinClasses(sourceOracle);
CompilationState state =
CompilationStateBuilder.buildFrom(logger,
sourceOracle.getResources(),
- getAdditionalTypeProviderDelegate());
+ getAdditionalTypeProviderDelegate(), sourceLevel);
jProgram =
JavaAstConstructor.construct(logger, state, "test.EntryPoint",
"com.google.gwt.lang.Exceptions");
@@ -292,7 +292,7 @@
addBuiltinClasses(sourceOracle);
CompilationState state =
CompilationStateBuilder.buildFrom(logger,
sourceOracle.getResources(),
- getAdditionalTypeProviderDelegate());
+ getAdditionalTypeProviderDelegate(), sourceLevel);
jProgram =
JavaAstConstructor.construct(logger, state, "test.EntryPoint",
"com.google.gwt.lang.Exceptions");
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
b/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
index 28b104b..8ee385d 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
@@ -31,6 +31,8 @@
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.util.Strings;
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;

@@ -237,7 +239,7 @@
addBuiltinClasses(sourceOracle);
CompilationState state =
CompilationStateBuilder.buildFrom(logger,
sourceOracle.getResources(),
- getAdditionalTypeProviderDelegate());
+ getAdditionalTypeProviderDelegate(), sourceLevel);
JProgram program =
JavaAstConstructor.construct(logger, state, "test.EntryPoint",
"com.google.gwt.lang.Exceptions");
@@ -282,4 +284,9 @@
protected AdditionalTypeProviderDelegate
getAdditionalTypeProviderDelegate() {
return null;
}
+
+ /**
+ * Java source level compatibility option.
+ */
+ protected SourceLevel sourceLevel = OptionSource.DEFAULT_SOURCE_LEVEL;
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
new file mode 100644
index 0000000..09edd8f
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2013 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.jjs.impl;
+
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
+import com.google.gwt.dev.jjs.ast.JBlock;
+import com.google.gwt.dev.jjs.ast.JExpression;
+import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JMethodBody;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.ast.JReturnStatement;
+import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.dev.util.arg.OptionSource;
+
+/**
+ * Tests that {@link GwtAstBuilder} correctly builds the AST for features
introduced in Java 7.
+ */
+public class Java7AstTest extends JJSTestBase {
+
+ @Override
+ public void setUp() {
+ sourceLevel = OptionSource.SourceLevel._7;
+ addAll(LIST_T, ARRAYLIST_T, JAVA_LANG_AUTOCLOSEABLE, TEST_RESOURCE,
EXCEPTION1, EXCEPTION2);
+ }
+
+ public void testCompileNewStyleLiterals() throws Exception {
+ assertEqualExpression("int", "10000000", "1_000_0000");
+ assertEqualExpression("int", "5", "0b101");
+ assertEqualExpression("int", "6", "0B110");
+ }
+
+ public void testCompileStringSwitch() throws Exception {
+ assertEqualBlock(
+ "String input = \"\";" +
+ "switch (input) {" +
+ " case \"AA\": break;" +
+ " case \"BB\": break;" +
+ "}",
+ "String input = \"\";" +
+ "switch (input) {" +
+ " case \"AA\": break;" +
+ " case \"BB\": break;" +
+ "}");
+ }
+
+
+ public void testCompileDiamondOperator() throws Exception {
+ addSnippetImport("com.google.gwt.List");
+ addSnippetImport("com.google.gwt.ArrayList");
+ assertEqualBlock(
+ "List l = new ArrayList();",
+ "List<String> l = new ArrayList<>();");
+ }
+
+
+ public void testCompileTryWithResources() throws Exception {
+ addSnippetImport("java.lang.AutoCloseable");
+ addSnippetImport("com.google.gwt.TestResource");
+ // TODO(rluble): Temp variable numbering when building
try-with-resource statements in
+ // GwtAstBuilder might make this test brittle.
+ assertEqualBlock(""
+ + "try { "
+ + " final TestResource r1 = new TestResource(); "
+ + " Throwable $primary_ex_2 = null; "
+ + " try { "
+ + " } catch (Throwable $caught_ex_3) { "
+ + " $primary_ex_2 = $caught_ex_3;"
+ + " throw $primary_ex_2;"
+ + " } finally {"
+ + " if (r1 != null)"
+ + " try {"
+ + " r1.close();"
+ + " } catch (Throwable $caught_ex_4) {"
+ + " if ($primary_ex_2 == null) "
+ + " $primary_ex_2 = $caught_ex_4;"
+ + " else"
+ + " $primary_ex_2.addSuppressed($caught_ex_4);"
+ + " }"
+ + " if ($primary_ex_2 != null)"
+ + " throw $primary_ex_2;"
+ + " }"
+ + "}",
+ "try (TestResource r1 = new TestResource(); ) { }");
+ assertEqualBlock(""
+ + "try { "
+ + " final TestResource r1 = new TestResource(); "
+ + " final TestResource r2 = new TestResource(); "
+ + " Throwable $primary_ex_3 = null; "
+ + " try { "
+ + " } catch (Throwable $caught_ex_4) { "
+ + " $primary_ex_3 = $caught_ex_4;"
+ + " throw $primary_ex_3;"
+ + " } finally {"
+ + " if (r2 != null)"
+ + " try {"
+ + " r2.close();"
+ + " } catch (Throwable $caught_ex_5) {"
+ + " if ($primary_ex_3 == null)"
+ + " $primary_ex_3 = $caught_ex_5;"
+ + " else"
+ + " $primary_ex_3.addSuppressed($caught_ex_5);"
+ + " }"
+ + " if (r1 != null) "
+ + " try {"
+ + " r1.close();"
+ + " } catch (Throwable $caught_ex_6) {"
+ + " if ($primary_ex_3 == null)"
+ + " $primary_ex_3 = $caught_ex_6;"
+ + " else"
+ + " $primary_ex_3.addSuppressed($caught_ex_6);"
+ + " }"
+ + " if ($primary_ex_3 != null)"
+ + " throw $primary_ex_3;"
+ + " }"
+ + "}",
+ "try (TestResource r1 = new TestResource(); TestResource r2 = new
TestResource();) { }");
+ }
+
+
+ public void testCompileMultiExceptions() throws Exception {
+ addSnippetImport("com.google.gwt.Exception1");
+ addSnippetImport("com.google.gwt.Exception2");
+ assertEqualBlock(""
+ + "int i = 0;"
+ + "try {"
+ + " if (i == 0) {"
+ + " throw new Exception1(); "
+ + " } else {"
+ + " throw new Exception2();"
+ + " }"
+ + "} catch(Exception1 | Exception2 e) {"
+ + "}", ""
+ + "int i = 0;"
+ + "try {"
+ + " if (i == 0) {"
+ + " throw new Exception1(); "
+ + " } else {"
+ + " throw new Exception2();"
+ + " }"
+ + "} catch(Exception1 | Exception2 e) {"
+ + "}");
+ }
+
+ public static final MockJavaResource INTEGERLITERALS = new
MockJavaResource(
+ "com.google.gwt.IntegerLiterals") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class IntegerLiterals {\n");
+ code.append(" int million = 1_000_000;\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource STRINGSWITCHTEST =
+ new MockJavaResource("com.google.gwt.StringSwitchTest") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class StringSwitchTest {\n");
+ code.append(" int test() { \n");
+ code.append(" int result = 0;");
+ code.append(" String f = \"AA\";");
+ code.append(" switch(f) {");
+ code.append(" case \"CC\": result = - 1; break;");
+ code.append(" case \"BB\": result = 1;");
+ code.append(" case \"AA\": result = result + 1;
break;");
+ code.append(" default: result = -2; break;");
+ code.append(" } \n");
+ code.append(" return result; \n");
+ code.append(" } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource LIST_T = new MockJavaResource(
+ "com.google.gwt.List") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public interface List<T> {\n");
+ code.append(" T method1(); \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource ARRAYLIST_T = new MockJavaResource(
+ "com.google.gwt.ArrayList") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("import com.google.gwt.List;\n");
+ code.append("public class ArrayList<T> implements List<T> {\n");
+ code.append(" public T method1() { return null; } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+
+ public static final MockJavaResource JAVA_LANG_AUTOCLOSEABLE = new
MockJavaResource(
+ "java.lang.AutoCloseable") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package java.lang;\n");
+ code.append("import java.lang.Exception;\n");
+ code.append("public interface AutoCloseable {\n");
+ code.append(" void close() throws Exception; \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+
+ public static final MockJavaResource TEST_RESOURCE = new
MockJavaResource(
+ "com.google.gwt.TestResource") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class TestResource implements AutoCloseable
{\n");
+ code.append(" public void close() { } \n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource EXCEPTION1 = new MockJavaResource(
+ "com.google.gwt.Exception1") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class Exception1 extends Exception {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ public static final MockJavaResource EXCEPTION2 = new MockJavaResource(
+ "com.google.gwt.Exception2") {
+ @Override
+ public CharSequence getContent() {
+ StringBuilder code = new StringBuilder();
+ code.append("package com.google.gwt;\n");
+ code.append("public class Exception2 extends Exception {\n");
+ code.append("}\n");
+ return code;
+ }
+ };
+
+ private void addAll(Resource... sourceFiles) {
+ for (Resource sourceFile : sourceFiles) {
+ sourceOracle.addOrReplace(sourceFile);
+ }
+ }
+
+ private void assertEqualExpression(String type, String expected , String
expression)
+ throws UnableToCompleteException {
+ JExpression testExpresssion = getExpression(type, expression);
+ assertEquals(expected, testExpresssion.toSource());
+ }
+
+ private JExpression getExpression(String type, String expression)
+ throws UnableToCompleteException {
+ JProgram program = compileSnippet(type, "return " + expression + ";");
+ JMethod mainMethod = findMainMethod(program);
+ JMethodBody body = (JMethodBody) mainMethod.getBody();
+ JReturnStatement returnStmt = (JReturnStatement)
body.getStatements().get(0);
+ return returnStmt.getExpr();
+ }
+ private void assertEqualBlock(String expected , String input)
+ throws UnableToCompleteException {
+ JBlock testExpression = getStatement(input);
+ assertEquals(
+ ("{ " + expected + "}").replaceAll("\\s+", " ")
+ .replaceAll("\\s([\\p{Punct}&&[^$]])", "$1")
+ .replaceAll("([\\p{Punct}&&[^$]])\\s", "$1"),
+ testExpression.toSource().replaceAll("\\s+", " ")
+ .replaceAll("\\s([\\p{Punct}&&[^$]])", "$1")
+ .replaceAll("([\\p{Punct}&&[^$]])\\s", "$1"));
+ }
+
+ private JBlock getStatement(String statement)
+ throws UnableToCompleteException {
+ JProgram program = compileSnippet("void", statement);
+ JMethod mainMethod = findMainMethod(program);
+ JMethodBody body = (JMethodBody) mainMethod.getBody();
+ return body.getBlock();
+ }
+
+}
diff --git a/user/src/com/google/gwt/core/shared/SerializableThrowable.java
b/user/src/com/google/gwt/core/shared/SerializableThrowable.java
index a44fb04..d626f45 100644
--- a/user/src/com/google/gwt/core/shared/SerializableThrowable.java
+++ b/user/src/com/google/gwt/core/shared/SerializableThrowable.java
@@ -21,6 +21,7 @@
* A serializable copy of a {@link Throwable}, including its causes and
stack trace. It overrides
* {@code #toString} to mimic original {@link Throwable#toString()} so
that {@link #printStackTrace}
* will work as if it is coming from the original exception.
+ *
* <p>
* This class is especially useful for logging and testing as the emulated
Throwable class does not
* serialize recursively and does not serialize the stack trace. This
class, as an alternative, can
@@ -29,6 +30,8 @@
* <p>
* Please note that, to get more useful stack traces from client side,
this class needs to be used
* in conjunction with {@link
com.google.gwt.core.server.StackTraceDeobfuscator}.
+ * <p>
+ * NOTE: Does not serialize suppressed exceptions to remain compatible
with Java 6 and below.
*/
public final class SerializableThrowable extends Throwable {

@@ -121,6 +124,7 @@
SerializableThrowable throwable = new SerializableThrowable(null,
t.getMessage());
throwable.setStackTrace(t.getStackTrace());
throwable.initCause(t.getCause());
+
if (isClassMetadataAvailable()) {
throwable.setDesignatedType(t.getClass().getName(), true);
} else {
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java
b/user/src/com/google/gwt/junit/JUnitShell.java
index 4838338..c1c04e7 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -25,6 +25,7 @@
import com.google.gwt.core.shared.SerializableThrowable;
import com.google.gwt.dev.ArgProcessorBase;
import com.google.gwt.dev.Compiler;
+import com.google.gwt.dev.CompilerOptions;
import com.google.gwt.dev.DevMode;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ModuleDef;
@@ -55,6 +56,7 @@
import com.google.gwt.dev.util.arg.ArgHandlerMaxPermsPerPrecompile;
import com.google.gwt.dev.util.arg.ArgHandlerOptimize;
import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
+import com.google.gwt.dev.util.arg.ArgHandlerSource;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
import com.google.gwt.junit.JUnitMessageQueue.ClientStatus;
@@ -181,6 +183,8 @@
registerHandler(new ArgHandlerDeployDir(options));
registerHandler(new ArgHandlerExtraDir(options));
registerHandler(new ArgHandlerWorkDirOptional(options));
+ registerHandler(new ArgHandlerSource(options));
+
// DISABLE: ArgHandlerModuleName

/*
@@ -625,6 +629,18 @@
return null;
}
return unitTestShell.remoteUserAgents;
+ }
+
+ /**
+ * Get the compiler options
+ *
+ * @return the the compiler options that have been set.
+ */
+ public static CompilerOptions getCompilerOptions() {
+ if (unitTestShell == null) {
+ return null;
+ }
+ return unitTestShell.options;
}

/**
@@ -1294,7 +1310,8 @@
if (!sameTest) {
currentModule = compileStrategy.maybeCompileModule(moduleName,
syntheticModuleName, strategy, batchingStrategy, getTopLogger());
- currentCompilationState =
currentModule.getCompilationState(getTopLogger(), true);
+ currentCompilationState =
currentModule.getCompilationState(getTopLogger(), true,
+ options.getSourceLevel());
}
assert (currentModule != null);

diff --git a/user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
b/user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
new file mode 100644
index 0000000..9ef122c
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2013 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 java.lang;
+
+/**
+ * Indicates that a class implements <code>close()</code> and can be used
in a try-with-resources
+ * statement.
+ */
+public interface AutoCloseable {
+
+ /**
+ * Closes this resource.
+ * @throws Exception
+ */
+ void close() throws Exception;
+}
diff --git a/user/super/com/google/gwt/emul/java/lang/Exception.java
b/user/super/com/google/gwt/emul/java/lang/Exception.java
index 20158b1..4ea8673 100644
--- a/user/super/com/google/gwt/emul/java/lang/Exception.java
+++ b/user/super/com/google/gwt/emul/java/lang/Exception.java
@@ -36,5 +36,4 @@
public Exception(Throwable cause) {
super(cause);
}
-
}
diff --git a/user/super/com/google/gwt/emul/java/lang/Throwable.java
b/user/super/com/google/gwt/emul/java/lang/Throwable.java
index dd9ecb9..adff358 100644
--- a/user/super/com/google/gwt/emul/java/lang/Throwable.java
+++ b/user/super/com/google/gwt/emul/java/lang/Throwable.java
@@ -16,6 +16,7 @@
package java.lang;

import com.google.gwt.core.client.impl.StackTraceCreator;
+import com.google.gwt.lang.Array;

import java.io.PrintStream;
import java.io.Serializable;
@@ -40,6 +41,7 @@
*/
private transient Throwable cause;
private String detailMessage;
+ private transient Throwable[] suppressed = new Throwable[0];
private transient StackTraceElement[] stackTrace;

{
@@ -61,6 +63,21 @@
public Throwable(Throwable cause) {
this.detailMessage = (cause == null) ? null : cause.toString();
this.cause = cause;
+ }
+
+ /**
+ * Call to add an exception that was suppressed. Used by
try-with-resources.
+ */
+ public final void addSuppressed(Throwable exception) {
+ assert exception != null;
+ assert exception != this;
+
+ Throwable[] newSuppressed = new Throwable[suppressed.length + 1];
+ for (int i = 0; i < suppressed.length; i++) {
+ newSuppressed[i] = suppressed[i];
+ }
+ newSuppressed[newSuppressed.length - 1] = exception;
+ suppressed = newSuppressed;
}

/**
@@ -97,6 +114,15 @@
return stackTrace;
}

+ /**
+ * Retruns the array of Exception that this one suppressed.
+ */
+ public final Throwable[] getSuppressed() {
+ assert suppressed != null;
+
+ return suppressed;
+ }
+
public Throwable initCause(Throwable cause) {
if (this.cause != null) {
throw new IllegalStateException("Can't overwrite cause");
diff --git
a/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
new file mode 100644
index 0000000..fac4b3f
--- /dev/null
+++
b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2013 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.jjs.test;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Tests Java 7 features. It is super sourced so that gwt can be compiles
under Java 6.
+ *
+ * IMPORTANT: For each test here there must exists the corresponding
method in the non super sourced
+ * version.
+ *
+ * Eventually this test will graduate and not be super sourced.
+ */
+public class Java7Test extends GWTTestCase {
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.dev.jjs.Java7Test";
+ }
+
+ // new style class literals
+// CHECKSTYLE:OFF
+ int million = 1_000_000;
+
+ int five = 0b101;
+// CHECKSTYLE:ON
+
+ public void testNewStyleLiterals() {
+ assertEquals(1000000, million);
+ assertEquals(5, five);
+ }
+
+ public void testSwitchOnString() {
+
+ String s = "AA";
+ int result = -1;
+ switch (s) {
+ case "BB":
+ result = 0;
+ break;
+ case "CC":
+ case "AA":
+ result = 1;
+ break;
+ }
+ assertEquals(1, result);
+ }
+
+ final List<String> log = new ArrayList<String>();
+
+ public class Resource implements AutoCloseable {
+
+ String name;
+ public Resource(String name) {
+ this.name = name;
+ log.add("Open " + name);
+ }y
+
+ public void doSomething() {
+ log.add("doSomething " + name);
+ }
+
+ public void throwException(String text) throws E1 {
+ throw new E1(text + " in " + name);
+ }
+
+ public void close() throws Exception {
+ log.add("Close " + name);
+ }
+ }
+
+ public class ResourceWithExceptionOnClose extends Resource {
+
+
+ public ResourceWithExceptionOnClose(String name) {
+ super(name);
+ }
+
+ public void close() throws Exception {
+ throw new E1("Exception in close " + name);
+ }
+ }
+
+ public void testResource() throws Exception{
+ log.clear();
+ try(Resource c = new Resource("A")) {
+
+ c.doSomething();
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "doSomething A",
+ "Close A");
+ }
+
+ public void test3Resources() throws Exception{
+ log.clear();
+ try(Resource rA = new Resource("A");
+ Resource rB = new Resource("B");
+ Resource rC = new Resource("C")) {
+
+ rA.doSomething();
+ rB.doSomething();
+ rC.doSomething();
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "doSomething B",
+ "doSomething C",
+ "Close C",
+ "Close B",
+ "Close A"
+ );
+ }
+
+ public void testResourcesWithExceptions() throws Exception{
+ log.clear();
+ try(Resource rA = new Resource("A");
+ Resource rB = new ResourceWithExceptionOnClose("B");
+ Resource rC = new Resource("C")) {
+
+ rA.doSomething();
+ rB.doSomething();
+ rC.doSomething();
+ } catch (Exception e) {
+ log.add(e.getMessage());
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "doSomething B",
+ "doSomething C",
+ "Close C",
+ "Close A",
+ "Exception in close B"
+ );
+ }
+
+ public void testResourcesWithSuppressedExceptions() throws Exception{
+ log.clear();
+ try(Resource rA = new ResourceWithExceptionOnClose("A");
+ Resource rB = new Resource("B");
+ Resource rC = new ResourceWithExceptionOnClose("C")) {
+
+ rA.doSomething();
+ rB.doSomething();
+ rC.doSomething();
+ } catch (Exception e) {
+ log.add(e.getMessage());
+ for (Throwable t : e.getSuppressed()) {
+ log.add("Suppressed: " + t.getMessage());
+ }
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "doSomething B",
+ "doSomething C",
+ "Close B",
+ "Exception in close C",
+ "Suppressed: Exception in close A"
+ );
+
+ log.clear();
+ try(Resource rA = new Resource("A");
+ Resource rB = new ResourceWithExceptionOnClose("B");
+ Resource rC = new Resource("C")) {
+
+ rA.doSomething();
+ rB.throwException("E1 here");
+ rC.doSomething();
+ } catch (Exception e) {
+ log.add(e.getMessage());
+ for (Throwable t : e.getSuppressed()) {
+ log.add("Suppressed: " + t.getMessage());
+ }
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "Close C",
+ "Close A",
+ "E1 here in B",
+ "Suppressed: Exception in close B"
+ );
+
+ }
+
+ private void assertContentsInOrder(Iterable<String> contents, String...
elements ) {
+ int sz = elements.length;
+ Iterator<String> it = contents.iterator();
+ for(int i = 0; i < sz; i++) {
+ assertTrue(it.hasNext());
+ String expected = it.next();
+ assertEquals(elements[i], expected);
+ }
+ assertFalse(it.hasNext());
+ }
+
+ public static class E1 extends Exception {
+ String name;
+ public E1(String name) {
+ this.name = name;
+ }
+
+ public int methodE1() {
+ return 0;
+ }
+
+ @Override
+ public String getMessage() {
+ return name;
+ }
+ }
+
+ public static class E2 extends E1 {
+ public E2(String name) {
+ super(name);
+ }
+
+ public int methodE2() {
+ return 1;
+ }
+ }
+
+ public static class E3 extends E1 {
+ public E3(String name) {
+ super(name);
+ }
+
+ public int methodE3() {
+ return 2;
+ }
+ }
+
+ public void testMultiExceptions() {
+
+ int choose = 0;
+
+ try {
+ if (choose == 0) {
+ throw new E1("e1");
+ } else if (choose ==1) {
+ throw new E2("e2");
+ }
+
+ fail("Exception was not trown");
+ } catch (E2 | E3 x) {
+ // The compiler will assign x a common supertype/superinterface of
E2 and E3.
+ // Here we make sure that this clause is not entered when the
supertype is thrown.
+ fail("Caught E1 instead of E2|E3");
+ } catch (E1 x) {
+ }
+ }
+}
diff --git a/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
b/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
index 98d00fb..40a30df 100644
--- a/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
+++ b/user/test/com/google/gwt/dev/jjs/CompilerSuite.java
@@ -34,6 +34,7 @@
import com.google.gwt.dev.jjs.test.InnerClassTest;
import com.google.gwt.dev.jjs.test.InnerOuterSuperTest;
import com.google.gwt.dev.jjs.test.JStaticEvalTest;
+import com.google.gwt.dev.jjs.test.Java7Test;
import com.google.gwt.dev.jjs.test.JavaAccessFromJavaScriptTest;
import com.google.gwt.dev.jjs.test.JsStaticEvalTest;
import com.google.gwt.dev.jjs.test.JsniConstructorTest;
@@ -81,6 +82,7 @@
suite.addTestSuite(InitialLoadSequenceTest.class);
suite.addTestSuite(InnerClassTest.class);
suite.addTestSuite(InnerOuterSuperTest.class);
+ suite.addTestSuite(Java7Test.class);
suite.addTestSuite(JavaAccessFromJavaScriptTest.class);
suite.addTestSuite(JsniConstructorTest.class);
suite.addTestSuite(JsoTest.class);
diff --git a/user/test/com/google/gwt/dev/jjs/Java7Test.gwt.xml
b/user/test/com/google/gwt/dev/jjs/Java7Test.gwt.xml
new file mode 100644
index 0000000..f6c0c9e
--- /dev/null
+++ b/user/test/com/google/gwt/dev/jjs/Java7Test.gwt.xml
@@ -0,0 +1,19 @@
+<!--
-->
+<!-- Copyright 2013 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 -->
+<!-- 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. License for the specific language governing permissions
and -->
+<!-- limitations under the
License. -->
+
+<!-- Contains tests for breaking out of the client source path -->
+<module>
+ <inherits name="com.google.gwt.core.Core" />
+ <super-source path='super' />
+</module>
\ No newline at end of file
diff --git a/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
b/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
new file mode 100644
index 0000000..81edd67
--- /dev/null
+++ b/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2013 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.jjs.test;
+
+import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.junit.JUnitShell;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * Dummy test case. Java7Test is super sourced so that gwt can be compiled
by java 6.
+ *
+ * NOTE: Make sure this class has the same test methods of its
supersourced variant.
+ */
+public class Java7Test extends GWTTestCase {
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.dev.jjs.Java7Test";
+ }
+
+ @Override
+ public void runTest() throws Throwable {
+ // Only run these tests if -source 7 (or greated) is enabled.
+ if (JUnitShell.getCompilerOptions().getSourceLevel()
+ .compareTo(OptionSource.SourceLevel._7) >= 0) {
+ super.runTest();
+ }
+ }
+
+ public void testNewStyleLiterals() {
+ // Make sure we are using the right Java7Test if the source
compatibility level is set to Java 7
+ // or above.
+ assertFalse((JUnitShell.getCompilerOptions().getSourceLevel()
+ .compareTo(OptionSource.SourceLevel._7) >= 0));
+ }
+
+ public void testSwitchOnString() {
+ }
+
+ public void testResource() throws Exception {
+ }
+
+ public void test3Resources() throws Exception {
+ }
+
+ public void testResourcesWithExceptions() throws Exception {
+ }
+
+ public void testResourcesWithSuppressedExceptions() throws Exception {
+ }
+
+ public void testMultiExceptions() {
+ }
+}
diff --git a/user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
b/user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
index b835950..000e1dc 100644
--- a/user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
@@ -94,6 +94,21 @@
assertEquals("TestClass.testCaller(fakefile2:97)",
trace[1].toString());
}

+ public void testAddSuppressed() {
+ Throwable throwable = new Throwable("primary");
+ assertNotNull(throwable.getSuppressed());
+ assertEquals(0, throwable.getSuppressed().length);
+ Throwable suppressed1 = new Throwable("suppressed1");
+ throwable.addSuppressed(suppressed1);
+ assertEquals(1, throwable.getSuppressed().length);
+ assertEquals(suppressed1, throwable.getSuppressed()[0]);
+ Throwable suppressed2 = new Throwable("suppressed1");
+ throwable.addSuppressed(suppressed2);
+ assertEquals(2, throwable.getSuppressed().length);
+ assertEquals(suppressed1, throwable.getSuppressed()[0]);
+ assertEquals(suppressed2, throwable.getSuppressed()[1]);
+ }
+
// Returns true if stack trace is obfuscated.
private boolean isObfuscated(StackTraceElement[] trace) {
if (trace == null || trace.length == 0) {

--
To view, visit https://gwt-review.googlesource.com/2680
To unsubscribe, visit https://gwt-review.googlesource.com/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic46ae3c9ee49518cfddc6f6f329b721e6645802d
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Roberto Lublinerman

unread,
May 8, 2013, 2:14:38 PM5/8/13
to Matthew Dempsky, Rodrigo Chandia, Goktug Gokdogan, Roberto Lublinerman
Roberto Lublinerman has uploaded a new change for review.

https://gwt-review.googlesource.com/2681


Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Exception.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
18 files changed, 915 insertions(+), 78 deletions(-)
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
index 7766e62..e47d8ec 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
@@ -34,7 +34,7 @@
@Override
public void setUp() {
sourceLevel = OptionSource.SourceLevel._7;
- addAll(LIST_T, ARRAYLIST_T);
+ addAll(LIST_T, ARRAYLIST_T, JAVA_LANG_AUTOCLOSEABLE, TEST_RESOURCE,
EXCEPTION1, EXCEPTION2);
}

public void testCompileNewStyleLiterals() throws Exception {
@@ -64,6 +64,94 @@
assertEqualBlock(
"List l = new ArrayList();",
public static final MockJavaResource INTEGERLITERALS = new
MockJavaResource(
@@ -129,6 +217,58 @@
}
};
private void addAll(Resource... sourceFiles) {
for (Resource sourceFile : sourceFiles) {
sourceOracle.addOrReplace(sourceFile);
@@ -168,5 +308,4 @@
JMethodBody body = (JMethodBody) mainMethod.getBody();
return body.getBlock();
}
-
index 8e19d9d..fac4b3f 100644
---
a/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
+++
b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -63,4 +63,225 @@
}
assertEquals(1, result);
diff --git a/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
b/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
index 242ee21..81edd67 100644
--- a/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
+++ b/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -49,4 +49,19 @@

public void testSwitchOnString() {
}
+
+ public void testResource() throws Exception {
+ }
+
+ public void test3Resources() throws Exception {
+ }
+
+ public void testResourcesWithExceptions() throws Exception {
+ }
+
+ public void testResourcesWithSuppressedExceptions() throws Exception {
+ }
+
+ public void testMultiExceptions() {
+ }
}
To view, visit https://gwt-review.googlesource.com/2681
To unsubscribe, visit https://gwt-review.googlesource.com/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c

Roberto Lublinerman

unread,
May 8, 2013, 2:16:18 PM5/8/13
to Roberto Lublinerman
Roberto Lublinerman has abandoned this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Abandoned

Redid as dependent patch.
Gerrit-MessageType: abandon

Matthew Dempsky

unread,
May 8, 2013, 3:06:46 PM5/8/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, John Stalcup
Matthew Dempsky has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 1: Verified-1

Oops, this change failed the build and/or style presubmit. :( More details
at http://gwt-ci.dempsky.org:8080/job/gwt.presubmit/46
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>
Gerrit-HasComments: No

Matthew Dempsky

unread,
May 8, 2013, 3:08:38 PM5/8/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Matthew Dempsky, John Stalcup
Matthew Dempsky has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 1:

(1 comment)

....................................................
File user/super/com/google/gwt/emul/java/lang/Throwable.java
Line 19: import com.google.gwt.lang.Array;
Unused import.
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>
Gerrit-HasComments: Yes

Goktug Gokdogan

unread,
May 8, 2013, 3:45:35 PM5/8/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup
Goktug Gokdogan has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 1:

(9 comments)

....................................................
File user/src/com/google/gwt/core/shared/SerializableThrowable.java
Line 34: * NOTE: Does not serialize suppressed exceptions to remain
compatible with Java 6 and below.
Don't forget to create a thread on this issue =)


....................................................
File user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
Line 3: *
nit: spaces here


Line 19: * Indicates that a class implements <code>close()</code> and can
be used in a try-with-resources
Can you just refer to jdk documentation like the other classes in this
package?


Line 26: * @throws Exception
remove empty @throws


....................................................
File user/super/com/google/gwt/emul/java/lang/Exception.java
Line 38: }
I guess this class is not intended to be here :)


....................................................
File user/super/com/google/gwt/emul/java/lang/Throwable.java
Line 40: * SerializabilityUtil.fieldQualifiesForSerialization(Field)
method.
can you put a todo item for missing stuff related to suppressed exceptions?
Also can you create an issue to follow up on this?


Line 44: private transient Throwable[] suppressed = new Throwable[0];
it is better to instantiate this lazily.


Line 74:
asserts are just like javadocs, nothing more. In this kind of scenarios we
want guaranteed checks. (see go/java-practices/assertions).


Line 78: }
you don't need the whole array copy. This will only run in script mode.
just set the array. The whole method can look something like:

public final void addSuppressed(Throwable exception) {
if (exception == null) {
throw new NPE();
}

if (exception == this) {
throw new IllegalArgumentException("Self-suppress not permitted");
}

if (suppressed == null ) {
suppressed = new Throwable[] { exception };
} else {
suppressed[suppressed.length] = exception;
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>

Roberto Lublinerman

unread,
May 8, 2013, 5:09:49 PM5/8/13
to Roberto Lublinerman, Matthew Dempsky, Matthew Dempsky, Ray Cromwell, Thomas Broyer, John Stalcup, Brian Slesinsky, Goktug Gokdogan
Hello Matthew Dempsky,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#2).
18 files changed, 922 insertions(+), 78 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 2
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Matthew Dempsky

unread,
May 8, 2013, 5:17:38 PM5/8/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, John Stalcup
Matthew Dempsky has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 2: Verified+1

Hoorays, this change passed the build and style presubmit. :D More details
at http://build.gwtproject.org/job/gwt.presubmit/47
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 2
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>
Gerrit-HasComments: No

Roberto Lublinerman

unread,
May 9, 2013, 10:35:48 PM5/9/13
to Roberto Lublinerman, Matthew Dempsky, Leeroy Jenkins, Matthew Dempsky, Ray Cromwell, Thomas Broyer, John Stalcup, Brian Slesinsky, Goktug Gokdogan
Hello Matthew Dempsky, Leeroy Jenkins,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#4).

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Exception.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
23 files changed, 893 insertions(+), 94 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 4
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Leeroy Jenkins <jen...@gwtproject.org>

Roberto Lublinerman

unread,
May 9, 2013, 11:33:06 PM5/9/13
to Roberto Lublinerman, Matthew Dempsky, Leeroy Jenkins, Matthew Dempsky, Ray Cromwell, Thomas Broyer, John Stalcup, Brian Slesinsky, Goktug Gokdogan
Hello Matthew Dempsky, Leeroy Jenkins,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#5).

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
22 files changed, 869 insertions(+), 93 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 5
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Roberto Lublinerman

unread,
May 10, 2013, 3:29:55 PM5/10/13
to Roberto Lublinerman, Matthew Dempsky, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan, Ray Cromwell, Thomas Broyer, John Stalcup, Brian Slesinsky
Hello Matthew Dempsky, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#6).

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
21 files changed, 763 insertions(+), 92 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 6
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Leeroy Jenkins <jen...@gwtproject.org>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>

Roberto Lublinerman

unread,
May 17, 2013, 1:31:57 PM5/17/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup, Leeroy Jenkins
Roberto Lublinerman has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 6:

Ping.
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 6
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Leeroy Jenkins <jen...@gwtproject.org>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>
Gerrit-HasComments: No

Roberto Lublinerman

unread,
May 17, 2013, 8:16:38 PM5/17/13
to Roberto Lublinerman, Matthew Dempsky, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan, Ray Cromwell, Thomas Broyer, John Stalcup, Brian Slesinsky
Hello Matthew Dempsky, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#7).

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
21 files changed, 760 insertions(+), 89 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 7
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Roberto Lublinerman

unread,
May 17, 2013, 8:21:40 PM5/17/13
to Roberto Lublinerman, Matthew Dempsky, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan, Ray Cromwell, Thomas Broyer, John Stalcup, Brian Slesinsky
Hello Matthew Dempsky, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#8).

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/emultest/java/lang/ThrowableTest.java
21 files changed, 760 insertions(+), 89 deletions(-)


Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 8
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Ray Cromwell

unread,
May 20, 2013, 8:14:59 PM5/20/13
to Roberto Lublinerman, Matthew Dempsky, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup, Leeroy Jenkins
Ray Cromwell has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 8: Code-Review+2

(1 comment)

....................................................
File dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
Line 895: Iterator<JType> it = clause.getTypes().iterator();
visitCollectionWithCommas(CHARS_PIPE, it) ?
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 8
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Leeroy Jenkins <jen...@gwtproject.org>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>
Gerrit-HasComments: Yes

Roberto Lublinerman

unread,
May 20, 2013, 8:57:47 PM5/20/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup, Leeroy Jenkins
Roberto Lublinerman has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 8:

(1 comment)

Thanks for this as well.

....................................................
File dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
Line 895: Iterator<JType> it = clause.getTypes().iterator();
Originaly that is what I planned but it the accept for JClassType prints
the whole class declaration and here we only need to print the type name. I
crave for lambdas....
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 8
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Roberto Lublinerman

unread,
May 20, 2013, 9:47:55 PM5/20/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Matthew Dempsky, Leeroy Jenkins, Goktug Gokdogan, Thomas Broyer, John Stalcup, Brian Slesinsky
Hello Matthew Dempsky, Ray Cromwell, Matthew Dempsky, Leeroy Jenkins,
Goktug Gokdogan,

I'd like you to reexamine a change. Please visit

https://gwt-review.googlesource.com/2681

to look at the new patch set (#9).

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................

Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
20 files changed, 761 insertions(+), 89 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 9
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Roberto Lublinerman

unread,
May 20, 2013, 10:00:50 PM5/20/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup, Leeroy Jenkins
Roberto Lublinerman has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 9:

Previous patch was approved and changes since then are trivial.
Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 9
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Brian Slesinsky <skyb...@google.com>
Gerrit-Reviewer: Goktug Gokdogan <gok...@google.com>
Gerrit-Reviewer: John Stalcup <sta...@google.com>
Gerrit-Reviewer: Leeroy Jenkins <jen...@gwtproject.org>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@gwtproject.org>
Gerrit-Reviewer: Ray Cromwell <cromw...@google.com>
Gerrit-Reviewer: Roberto Lublinerman <rlu...@google.com>
Gerrit-Reviewer: Thomas Broyer <t.br...@gmail.com>
Gerrit-HasComments: No

Roberto Lublinerman

unread,
May 20, 2013, 10:01:09 PM5/20/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup, Leeroy Jenkins
Roberto Lublinerman has posted comments on this change.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Patch Set 9: Code-Review+2

Previous patch was approved and changes since then are trivial.

Gerrit-MessageType: comment
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 9
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>

Roberto Lublinerman

unread,
May 20, 2013, 10:01:13 PM5/20/13
to Roberto Lublinerman, Matthew Dempsky, Ray Cromwell, Brian Slesinsky, Thomas Broyer, Goktug Gokdogan, Matthew Dempsky, John Stalcup, Leeroy Jenkins
Roberto Lublinerman has submitted this change and it was merged.

Change subject: Adds the remaining (and more complex) Java 7 new language
features.
......................................................................


Adds the remaining (and more complex) Java 7 new language features.

Adds the remaining Java 7 new language features: namely, multiexception
catch
and try-with-resources.

Fixes issue 7999, issue 6960.

Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
---
M dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
M dev/core/src/com/google/gwt/dev/jjs/ast/JTryStatement.java
M dev/core/src/com/google/gwt/dev/jjs/impl/CatchBlockNormalizer.java
M dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
M dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
M dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
M
dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
M dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
M dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
M user/src/com/google/gwt/core/shared/SerializableThrowable.java
A user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
M user/super/com/google/gwt/emul/java/lang/Throwable.java
M
user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
M user/test/com/google/gwt/dev/jjs/test/Java7Test.java
20 files changed, 761 insertions(+), 89 deletions(-)

Approvals:
Roberto Lublinerman: Looks good to me, approved
Leeroy Jenkins: Verified



diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
index 6c12533..d149f4f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JClassType.java
@@ -50,7 +50,7 @@
/**
* Construct a bare-bones deserialized external class.
*/
- private JClassType(String name) {
+ JClassType(String name) {
super(SourceOrigin.UNKNOWN, name);
isAbstract = false;
setExternal(true);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
index dede802..f11627e 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
@@ -47,7 +47,7 @@
}

private Object readResolve() {
- return new JMethod(signature, enclosingType);
+ return new JMethod(signature, enclosingType, false);
}
}

@@ -141,15 +141,30 @@
}

/**
+ * Creates an externalized representation for a method that needs to be
resolved.
+ * Useful to refer to methods of magic classes during GwtAstBuilder
execution.
+ *
+ * @param fullClassName the class where the method is defined.
+ * @param signature the signature of the method (including its name).
+ *
+ */
+ public static JMethod getExternalizedMethod(String fullClassName, String
signature,
+ boolean isStatic) {
+
+ JClassType cls = new JClassType(fullClassName);
+ return new JMethod(signature, cls, isStatic);
+ }
+
+ /**
* Construct a bare-bones deserialized external method.
*/
- private JMethod(String signature, JDeclaredType enclosingType) {
+ private JMethod(String signature, JDeclaredType enclosingType, boolean
isStatic) {
super(SourceOrigin.UNKNOWN);
this.name = signature.substring(0, signature.indexOf('('));
this.enclosingType = enclosingType;
this.signature = signature;
this.isAbstract = false;
- this.isStatic = false;
+ this.isStatic = isStatic;
this.access = AccessModifier.PUBLIC.ordinal();
}

diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
index 9afa7be..ee89165 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethodCall.java
@@ -100,7 +100,8 @@
* allows us to preserve type information during the latter phases of
* compilation.
*/
- public JMethodCall(SourceInfo info, JExpression instance, JMethod
method, JType overrideReturnType) {
+ public JMethodCall(SourceInfo info, JExpression instance, JMethod method,
+ JType overrideReturnType) {
super(info);
assert (method != null);
assert (instance != null || method.isStatic());
index c6c75e5..efa5c90 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -177,7 +177,9 @@
import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
@@ -286,7 +288,8 @@
}
}

- private void processClassLiteral(JsNameRef nameRef, SourceInfo info,
JType type, JsContext ctx) {
+ private void processClassLiteral(JsNameRef nameRef, SourceInfo info,
JType type,
+ JsContext ctx) {
assert !ctx.isLvalue();
JsniClassLiteral classLiteral = new JsniClassLiteral(info,
nameRef.getIdent(), type);
nativeMethodBody.addClassRef(classLiteral);
@@ -1423,17 +1426,160 @@
+ * $exception = Exceptions.safeClose(an, $exception);
+ * ...
+ * $exception = Exceptions.safeClose(a1, $exception);
+ * $ex = Exceptions.safeClose(resource, $ex);
+ *
+ * which is equivalent to
+ *
+ * if (resource != null) {
+ * try {
+ * resource.close();
+ * } catch (Throwable t) {
+ * if ($ex == null) {
+ * $ex = t;
+ * } else {
+ * $ex.addSuppressed(t);
+ * }
+ * }
+ */
+
+ JMethodCall safeCloseCall = new JMethodCall(info, null,
SAFE_CLOSE_METHOD);
+ safeCloseCall.addArg(0, new JLocalRef(info, resourceVar));
+ safeCloseCall.addArg(1, new JLocalRef(info, exceptionVar));
+
+ return new JBinaryOperation(info, javaLangThrowable,
JBinaryOperator.ASG, new JLocalRef(info,
+ exceptionVar), safeCloseCall).makeStatement();
+ }
+
+ private JStatement createAssignment(SourceInfo info, JType type,
JLocal lhs, JLocal rhs) {
+ return new JBinaryOperation(info, type, JBinaryOperator.ASG, new
JLocalRef(info, lhs),
+ new JLocalRef(info, rhs)).makeStatement();
}

@Override
@@ -2784,6 +2930,8 @@
private static final char[] VALUE = "Value".toCharArray();
private static final char[] VALUE_OF = "valueOf".toCharArray();
private static final char[] VALUES = "values".toCharArray();
+ private static final char[] CLOSE = "close".toCharArray();
+ private static final char[] ADDSUPRESSED = "addSuppressed".toCharArray();

static {
InternalCompilerException.preload();
@@ -2896,6 +3044,8 @@

JClassType javaLangString = null;

+ JClassType javaLangThrowable = null;
+
Map<MethodDeclaration, JsniMethod> jsniMethods;

Map<String, Binding> jsniRefs;
@@ -2907,6 +3057,16 @@
private List<JDeclaredType> newTypes;

private String sourceMapPath;
+
+ /**
+ * Externalized class and method form for Exceptions.safeClose() to
provide support
+ * for try-with-resources.
+ *
+ * The externalized form will be resolved during AST stitching.
+ */
+ static JMethod SAFE_CLOSE_METHOD =
JMethod.getExternalizedMethod("com.google.gwt.lang.Exceptions",
+ "safeClose(Ljava/lang/AutoCloseable;Ljava/lang/Throwable;)Ljava/lang/Throwable;",
true);
+

/**
* Builds all the GWT AST nodes that correspond to one Java source file.
@@ -2939,6 +3099,7 @@
javaLangObject = (JClassType)
typeMap.get(cud.scope.getJavaLangObject());
javaLangString = (JClassType)
typeMap.get(cud.scope.getJavaLangString());
javaLangClass = (JClassType) typeMap.get(cud.scope.getJavaLangClass());
+ javaLangThrowable = (JClassType)
typeMap.get(cud.scope.getJavaLangThrowable());

for (TypeDeclaration typeDecl : cud.types) {
// Resolve super type / interface relationships.
@@ -2964,7 +3125,7 @@
index c437453..09e4bab 100644
---
a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
+++
b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Exceptions.java
@@ -65,5 +65,29 @@
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
b/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
index 747ff4a..a17a51e 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java
@@ -255,12 +255,29 @@
}
});

+ sourceOracle.addOrReplace(new
MockJavaResource("java.lang.AutoCloseable") {
+ @Override
+ public CharSequence getContent() {
+ return ""
+ + "package java.lang;"
+ + "public interface AutoCloseable { "
+ + " void close() throws Exception;"
+ + "}";
+ }
+ });
+
sourceOracle.addOrReplace(new
MockJavaResource("com.google.gwt.lang.Exceptions") {
@Override
public CharSequence getContent() {
- return "package com.google.gwt.lang;" +
- "public class Exceptions { static boolean throwAssertionError()
{ throw new RuntimeException(); } }";
- }
+ return ""
+ + "package com.google.gwt.lang;"
+ + "public class Exceptions { "
+ + " static boolean throwAssertionError() { throw new
RuntimeException(); }"
+ + " static Throwable safeClose(AutoCloseable resource,
Throwable mainException) {"
+ + " return mainException;"
+ + " } "
+ + "}";
+ }
});

sourceOracle.addOrReplace(new MockJavaResource("java.lang.String") {
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
index 5e261ea..3ed0dbf 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
@@ -32,10 +32,14 @@
*/
public class Java7AstTest extends JJSTestBase {

+ // TODO(rluble): add similar tests to ensure that the AST construction
is correct for all types
+ // of nodes.
@Override
public void setUp() {
sourceLevel = SourceLevel.JAVA7;
- addAll(Java7MockResources.LIST_T, Java7MockResources.ARRAYLIST_T);
+ addAll(Java7MockResources.LIST_T, Java7MockResources.ARRAYLIST_T,
+ JavaResourceBase.AUTOCLOSEABLE, Java7MockResources.TEST_RESOURCE,
+ Java7MockResources.EXCEPTION1, Java7MockResources.EXCEPTION2);
}

public void testCompileNewStyleLiterals() throws Exception {
@@ -115,5 +119,4 @@
JMethodBody body = (JMethodBody) mainMethod.getBody();
return body.getBlock();
}
-
}
diff --git a/user/src/com/google/gwt/core/shared/SerializableThrowable.java
b/user/src/com/google/gwt/core/shared/SerializableThrowable.java
index 82ccaae..cbbd612 100644
--- a/user/src/com/google/gwt/core/shared/SerializableThrowable.java
+++ b/user/src/com/google/gwt/core/shared/SerializableThrowable.java
@@ -22,6 +22,7 @@
* A serializable copy of a {@link Throwable}, including its causes and
stack trace. It overrides
* {@code #toString} to mimic original {@link Throwable#toString()} so
that {@link #printStackTrace}
* will work as if it is coming from the original exception.
+ *
* <p>
* This class is especially useful for logging and testing as the emulated
Throwable class does not
* serialize recursively and does not serialize the stack trace. This
class, as an alternative, can
@@ -30,6 +31,8 @@
* <p>
* Please note that, to get more useful stack traces from client side,
this class needs to be used
* in conjunction with {@link
com.google.gwt.core.server.StackTraceDeobfuscator}.
+ * <p>
+ * NOTE: Does not serialize suppressed exceptions to remain compatible
with Java 6 and below.
*/
public final class SerializableThrowable extends Throwable {

diff --git a/user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
b/user/super/com/google/gwt/emul/java/lang/AutoCloseable.java
new file mode 100644
index 0000000..7bf4144
+ * See <a
+ *
href="http://docs.oracle.com/javase/7/docs/api/java/lang/AutoCloseable.html">the
+ * official Java API doc</a> for details.
+ */
+public interface AutoCloseable {
+
+ /**
+ * Closes this resource.
+ */
+ void close() throws Exception;
+}
diff --git a/user/super/com/google/gwt/emul/java/lang/Throwable.java
b/user/super/com/google/gwt/emul/java/lang/Throwable.java
index dd9ecb9..e929e59 100644
--- a/user/super/com/google/gwt/emul/java/lang/Throwable.java
+++ b/user/super/com/google/gwt/emul/java/lang/Throwable.java
@@ -37,30 +37,73 @@
* to ensure that only the detailMessage field is serialized. Changing
the
* field modifiers below may necessitate a change to the server's
* SerializabilityUtil.fieldQualifiesForSerialization(Field) method.
+ *
+ * TODO(rluble): Add remaining functionality for suppressed Exceptions
(e.g.
+ * printing). Also review the class for missing Java 7 compatibility.
*/
private transient Throwable cause;
private String detailMessage;
+ private transient Throwable[] suppressedExceptions;
private transient StackTraceElement[] stackTrace;
-
- {
- fillInStackTrace();
- }
+ private transient boolean disableSuppression;

public Throwable() {
+ fillInStackTrace();
}

public Throwable(String message) {
this.detailMessage = message;
+ fillInStackTrace();
}

public Throwable(String message, Throwable cause) {
this.cause = cause;
this.detailMessage = message;
+ fillInStackTrace();
}

public Throwable(Throwable cause) {
this.detailMessage = (cause == null) ? null : cause.toString();
this.cause = cause;
+ fillInStackTrace();
+ }
+
+ /**
+ * Constructor that allows subclasses disabling exception suppression
and stack traces.
+ * Those features should only be disabled in very specific cases.
+ */
+ protected Throwable(String message, Throwable cause, boolean
enableSuppression,
+ boolean writetableStackTrace) {
+ if (writetableStackTrace) {
+ fillInStackTrace();
+ }
+ this.cause = cause;
+ this.detailMessage = message;
+ this.disableSuppression = !enableSuppression;
+ }
+
+ /**
+ * Call to add an exception that was suppressed. Used by
try-with-resources.
+ */
+ public final void addSuppressed(Throwable exception) {
+ if (exception == null) {
+ throw new NullPointerException("Cannot suppress a null exception.");
+ }
+ if (exception == this) {
+ throw new IllegalArgumentException("Exception can not suppress
itself.");
+ }
+
+ if (disableSuppression) {
+ return;
+ }
+
+ if (suppressedExceptions == null) {
+ suppressedExceptions = new Throwable[] { exception };
+ } else {
+ // TRICK: This is not correct Java (would give an OOBE, but it works
in JS and
+ // this code will only be executed in JS.
+ suppressedExceptions[suppressedExceptions.length] = exception;
+ }
}

/**
@@ -97,6 +140,17 @@
return stackTrace;
}

+ /**
+ * Returns the array of Exception that this one suppressedExceptions.
+ */
+ public final Throwable[] getSuppressed() {
+ if (suppressedExceptions == null) {
+ suppressedExceptions = new Throwable[0];
+ }
+
+ return suppressedExceptions;
+ }
+
public Throwable initCause(Throwable cause) {
if (this.cause != null) {
throw new IllegalStateException("Can't overwrite cause");
diff --git
a/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
index f849634..26a32ac 100644
---
a/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
+++
b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -63,4 +63,245 @@
}
assertEquals(1, result);
}
+
+ final List<String> log = new ArrayList<String>();
+
+ public class Resource implements AutoCloseable {
+
+ String name;
+ public Resource(String name) {
+ this.name = name;
+ log.add("Open " + name);
+ }
+ try (Resource c = new Resource("A")) {
+
+ c.doSomething();
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "doSomething A",
+ "Close A");
+ }
+
+ public void test3Resources() throws Exception{
+ log.clear();
+ try (Resource rA = new Resource("A");
+ Resource rB = new Resource("B");
+ Resource rC = new Resource("C")) {
+
+ rA.doSomething();
+ rB.doSomething();
+ rC.doSomething();
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "doSomething B",
+ "doSomething C",
+ "Close C",
+ "Close B",
+ "Close A"
+ );
+ }
+
+ public void testResourcesWithExceptions() throws Exception{
+ log.clear();
+ try (Resource rA = new Resource("A");
+ Resource rB = new ResourceWithExceptionOnClose("B");
+ Resource rC = new Resource("C")) {
+
+ rA.doSomething();
+ rB.doSomething();
+ rC.doSomething();
+ } catch (Exception e) {
+ log.add(e.getMessage());
+ } finally {
+ log.add("finally");
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "doSomething B",
+ "doSomething C",
+ "Close C",
+ "Close A",
+ "Exception in close B",
+ "finally"
+ );
+ }
+
+ public void testResourcesWithSuppressedExceptions() throws Exception{
+ log.clear();
+ try (Resource rA = new ResourceWithExceptionOnClose("A");
+ try (Resource rA = new Resource("A");
+ Resource rB = new ResourceWithExceptionOnClose("B");
+ Resource rC = new Resource("C")) {
+
+ rA.doSomething();
+ rB.throwException("E1 here");
+ rC.doSomething();
+ } catch (Exception e) {
+ log.add(e.getMessage());
+ for (Throwable t : e.getSuppressed()) {
+ log.add("Suppressed: " + t.getMessage());
+ }
+ } finally {
+ log.add("finally");
+ }
+
+ assertContentsInOrder(log,
+ "Open A",
+ "Open B",
+ "Open C",
+ "doSomething A",
+ "Close C",
+ "Close A",
+ "E1 here in B",
+ "Suppressed: Exception in close B",
+ "finally"
+ );
+ }
+
+ public void testAddSuppressedExceptions() {
+ Throwable throwable = new Throwable("primary");
+ assertNotNull(throwable.getSuppressed());
+ assertEquals(0, throwable.getSuppressed().length);
+ Throwable suppressed1 = new Throwable("suppressed1");
+ throwable.addSuppressed(suppressed1);
+ assertEquals(1, throwable.getSuppressed().length);
+ assertEquals(suppressed1, throwable.getSuppressed()[0]);
+ Throwable suppressed2 = new Throwable("suppressed2");
+ throwable.addSuppressed(suppressed2);
+ assertEquals(2, throwable.getSuppressed().length);
+ assertEquals(suppressed1, throwable.getSuppressed()[0]);
+ assertEquals(suppressed2, throwable.getSuppressed()[1]);
+ }
+
+ private void assertContentsInOrder(Iterable<String> contents, String...
elements ) {
+ int sz = elements.length;
+ Iterator<String> it = contents.iterator();
+ for (int i = 0; i < sz; i++) {
index 2ef1c47..e463279 100644
--- a/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
+++ b/user/test/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -49,4 +49,22 @@

public void testSwitchOnString() {
}
+
+ public void testResource() throws Exception {
+ }
+
+ public void test3Resources() throws Exception {
+ }
+
+ public void testResourcesWithExceptions() throws Exception {
+ }
+
+ public void testResourcesWithSuppressedExceptions() throws Exception {
+ }
+
+ public void testMultiExceptions() {
+ }
+
+ public void testAddSuppressedExceptions() {
+ }
Gerrit-MessageType: merged
Gerrit-Change-Id: If973b8c847d1202aca794221f32ae4b33b616f9c
Gerrit-PatchSet: 9
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <rlu...@google.com>
Reply all
Reply to author
Forward
0 new messages