Roberto Lublinerman has uploaded a new change for review.
https://gwt-review.googlesource.com/2650
Change subject: Adds Java 7 new language features.
......................................................................
Adds Java 7 new language features.
Adds the Java 7 new language features: namely, the diamond operator, new
numerical literal formats,
multiexception catch, switch/case on string literals and try-with-resources.
Adds a new flag -source to select source level compatibility (java 6 or
java 7); -source defaults to java 6.
Change-Id: I91c1f39ff20a2e7ac131d647bf4c96e34ce47a70
---
M dev/build.xml
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/JavaSourceParser.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/GwtAstBuilder.java
M dev/core/src/com/google/gwt/dev/jjs/impl/ToStringGenerationVisitor.java
M dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.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
D
dev/core/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
M dev/core/test/com/google/gwt/dev/CompilerTest.java
M
dev/core/test/com/google/gwt/dev/javac/BinaryTypeReferenceRestrictionsCheckerTest.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 eclipse/dev/.classpath
M eclipse/dev/compiler/.classpath
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/Enum.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
50 files changed, 1,794 insertions(+), 1,751 deletions(-)
diff --git a/dev/build.xml b/dev/build.xml
index 6b10f1c..93cf591 100755
--- a/dev/build.xml
+++ b/dev/build.xml
@@ -56,7 +56,8 @@
<fileset dir="${gwt.tools.lib}">
<include name="apache/tapestry-util-text-4.0.2.jar" />
<include name="apache/ant-1.6.5.jar" />
- <include name="eclipse/jdt-3.4.2_r894.jar" />
+ <include
name="eclipse/org.eclipse.jdt.core_3.8.3.v20130121-145325.jar" />
+ <include
name="eclipse/jdtCompilerAdapter-3.8.3.v20130121-145325.jar" />
<include name="guava/guava-10.0.1/guava-10.0.1-rebased.jar" />
<include name="jscomp/r1649/compiler-rebased.jar" />
<include name="jetty/jetty-6.1.11.jar" />
@@ -105,7 +106,8 @@
<gwt.jar destfile="${alldeps.jar}">
<zipfileset
src="${gwt.tools.lib}/apache/tapestry-util-text-4.0.2.jar" />
<zipfileset src="${gwt.tools.lib}/apache/ant-1.6.5.jar" />
- <zipfileset src="${gwt.tools.lib}/eclipse/jdt-3.4.2_r894.jar" />
+ <zipfileset
src="${gwt.tools.lib}/eclipse/org.eclipse.jdt.core_3.8.3.v20130121-145325.jar"
/>
+ <zipfileset
src="${gwt.tools.lib}/eclipse/jdtCompilerAdapter-3.8.3.v20130121-145325.jar"
/>
<zipfileset
src="${gwt.tools.lib}/guava/guava-10.0.1/guava-10.0.1-rebased.jar" />
<zipfileset
src="${gwt.tools.lib}/jscomp/r1649/compiler-rebased.jar" />
<zipfileset src="${gwt.tools.lib}/jetty/jetty-6.1.11.jar" />
@@ -180,7 +182,8 @@
<include name="org/eclipse/jdt/**"/>
<classpath>
<pathelement location="${gwt.tools.lib}/apache/ant-1.6.5.jar" />
- <pathelement
location="${gwt.tools.lib}/eclipse/jdt-3.4.2_r894.jar" />
+ <pathelement
location="${gwt.tools.lib}/eclipse/org.eclipse.jdt.core_3.8.3.v20130121-145325.jar"
/>
+ <pathelement
location="${gwt.tools.lib}/eclipse/jdtCompilerAdapter-3.8.3.v20130121-145325.jar"
/>
<pathelement
location="${gwt.tools.lib}/apache/commons/commons-collections-3.2.1.jar" />
<pathelement
location="${gwt.tools.lib}/guava/guava-10.0.1/guava-10.0.1-rebased.jar" />
<pathelement
location="${gwt.tools.lib}/jscomp/r1649/compiler-rebased.jar" />
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..009ab8e 100644
---
a/dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
+++
b/dev/codeserver/java/com/google/gwt/dev/codeserver/CompilerOptionsImpl.java
@@ -19,8 +19,11 @@
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;
+import com.google.gwt.dev.util.arg.OptionSource.SourceLevel;
import java.io.File;
+import java.lang.Override;
import java.util.Arrays;
import java.util.List;
@@ -31,10 +34,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
@@ -101,6 +106,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..f3dbe99 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;
@@ -25,6 +28,7 @@
import com.google.gwt.util.tools.ArgHandlerString;
import java.io.File;
+import java.lang.Override;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
@@ -46,6 +50,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.defaultSourceLevel;
/**
* Sets each option to the appropriate value, based on command-line
arguments.
@@ -105,6 +111,13 @@
}
/**
+ * Java source level compatibility,
+ */
+ SourceLevel getSourceLevel() {
+ return sourceLevel;
+ }
+
+ /**
* If true, just compile the modules, then exit.
*/
boolean isCompileTest() {
@@ -147,6 +160,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..033a6e9 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);
+ 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..2f5d852 100644
---
a/dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
+++
b/dev/codeserver/java/com/google/gwt/dev/codeserver/UnmodifiableCompilerOptions.java
@@ -19,6 +19,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.CompilerOptions;
import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.util.arg.OptionSource;
import java.io.File;
import java.util.List;
@@ -173,6 +174,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..1a4a9eb 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.SourceLevel._6;
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 level) {
+ sourceLevel = level;
+ }
}
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..d2ede9b 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..872a82c 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.defaultSourceLevel);
}
- 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..173b407 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.defaultSourceLevel);
}
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/JavaSourceParser.java
b/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java
index 85bea16..32cbfcc 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JavaSourceParser.java
@@ -178,10 +178,11 @@
* @return a CompilationUnitDeclaration or null if parsing failed
*/
private static CompilationUnitDeclaration parseJava(String javaSource) {
- CodeSnippetParsingUtil parsingUtil = new CodeSnippetParsingUtil();
+ CodeSnippetParsingUtil parsingUtil = new CodeSnippetParsingUtil(true);
CompilerOptions options = new CompilerOptions();
- options.complianceLevel = ClassFileConstants.JDK1_5;
- options.sourceLevel = ClassFileConstants.JDK1_5;
+ options.complianceLevel = ClassFileConstants.JDK1_6;
+ options.originalSourceLevel = ClassFileConstants.JDK1_6;
+ options.sourceLevel = ClassFileConstants.JDK1_6;
CompilationUnitDeclaration unit = parsingUtil.parseCompilationUnit(
javaSource.toString().toCharArray(), options.getMap(), true);
if (unit.compilationResult().hasProblems()) {
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 c0d6ebb..dc30308 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;
@@ -225,6 +227,11 @@
}
@Override
+ public boolean ignoreOptionalProblems() {
+ return false;
+ }
+
+ @Override
public String toString() {
return builder.toString();
}
@@ -374,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;
}
@@ -571,11 +578,17 @@
public static List<CompilationUnit> compile(TreeLogger logger,
Collection<CompilationUnitBuilder> builders)
throws UnableToCompleteException {
+ return compile(logger, builders, OptionSource.defaultSourceLevel);
+ }
+
+ 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 {
@@ -583,9 +596,20 @@
}
}
- public static CompilerOptions getCompilerOptions() {
- CompilerOptions options = new CompilerOptions();
- options.complianceLevel = options.sourceLevel = options.targetJDK =
ClassFileConstants.JDK1_6;
+
+ public static CompilerOptions getStandardCompilerOptions() {
+ CompilerOptions options = new CompilerOptions() {
+ {
+ warningThreshold.clearAll();
+ }
+ };
+
+ long jdtSourceLevel =
sourceLevelMap.get(OptionSource.defaultSourceLevel);
+
+ options.originalSourceLevel = jdtSourceLevel;
+ options.complianceLevel = jdtSourceLevel;
+ options.sourceLevel = jdtSourceLevel;
+ options.targetJDK = jdtSourceLevel;
// Generate debug info for debugging the output.
options.produceDebugAttributes =
@@ -599,8 +623,18 @@
// Turn off all warnings, saves some memory / speed.
options.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference
= false;
options.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable
= false;
- options.warningThreshold = 0;
options.inlineJsrBytecode = true;
+ return options;
+ }
+
+ public CompilerOptions getCompilerOptions() {
+ CompilerOptions options = getStandardCompilerOptions();
+ long jdtSourceLevel = sourceLevelMap.get(sourceLevel);
+
+ options.originalSourceLevel = jdtSourceLevel;
+ options.complianceLevel = jdtSourceLevel;
+ options.sourceLevel = jdtSourceLevel;
+ options.targetJDK = jdtSourceLevel;
return options;
}
@@ -696,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> sourceLevelMap =
+ new HashMap<SourceLevel, Long>();
+
+ static {
+ sourceLevelMap.put(OptionSource.SourceLevel._6,
ClassFileConstants.JDK1_6);
+ sourceLevelMap.put(OptionSource.SourceLevel._7,
ClassFileConstants.JDK1_7);
+ }
+
+ public JdtCompiler(UnitProcessor processor, SourceLevel sourceLevel) {
this.processor = processor;
+ this.sourceLevel = sourceLevel;
}
public void addCompiledUnit(CompilationUnit unit) {
@@ -909,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..caa74c3 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.defaultSourceLevel);
}
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..eac422d 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.defaultSourceLevel;
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..ae02fb3 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
@@ -24,19 +24,43 @@
*/
public class JTryStatement extends JStatement {
+ private final List<List<JType>> catchTypes;
private final List<JLocalRef> catchArgs;
private final List<JBlock> catchBlocks;
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 catchTypes each element of this list contains the catch types
the corresponding catch
+ * block has. (Each catch block might have multiple
Exception types associated
+ * in Java 7).
+ * @param catchArgs each element of this list correspond to the
exception variable declared in
+ * corresponding catch statement.
+ * @param catchBlocks each element of this list contains the statement
block for the corresponding
+ * catch block.
+ * @param finallyBlock the statement block corresponding to the finally
construct.
+ */
+ public JTryStatement(SourceInfo info, JBlock tryBlock, List<List<JType>>
catchTypes,
+ List<JLocalRef> catchArgs, List<JBlock> catchBlocks, JBlock
finallyBlock) {
super(info);
assert (catchArgs.size() == catchBlocks.size());
+ assert (catchArgs.size() == catchTypes.size());
this.tryBlock = tryBlock;
this.catchArgs = catchArgs;
+ this.catchTypes = catchTypes;
this.catchBlocks = catchBlocks;
this.finallyBlock = finallyBlock;
+ }
+
+ public List<List<JType>> getCatchTypes() {
+ return catchTypes;
}
public List<JLocalRef> getCatchArgs() {
@@ -55,6 +79,15 @@
return tryBlock;
}
+
+ /**
+ * Resolve an external reference during AST stitching.
+ */
+ public void resolve(int i, int j, JReferenceType newType) {
+ assert newType.replaces(catchTypes.get(i).get(j));
+ catchTypes.get(i).set(j, newType);
+ }
+
public void traverse(JVisitor visitor, Context ctx) {
if (visitor.visit(this, ctx)) {
visitor.accept(tryBlock);
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..b5a8591 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;
@@ -77,7 +81,8 @@
/*
* 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!
*/
@@ -86,10 +91,23 @@
for (int i = x.getCatchBlocks().size() - 1; i >= 0; --i) {
JBlock block = x.getCatchBlocks().get(i);
JLocalRef arg = x.getCatchArgs().get(i);
+ List<JType> exceptionsTypes = x.getCatchTypes().get(i);
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);
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..9518bc0 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
@@ -581,13 +581,27 @@
// 1) Remove catch blocks whose exception type is not instantiable.
List<JLocalRef> catchArgs = x.getCatchArgs();
List<JBlock> catchBlocks = x.getCatchBlocks();
+ List<List<JType>> catchTypes = x.getCatchTypes();
+ Iterator<List<JType>> itClauses = catchTypes.iterator();
Iterator<JLocalRef> itA = catchArgs.iterator();
Iterator<JBlock> itB = catchBlocks.iterator();
- while (itA.hasNext()) {
- JLocalRef localRef = itA.next();
+ while (itClauses.hasNext()) {
+ List<JType> types = itClauses.next();
+ itA.next();
itB.next();
- JReferenceType type = (JReferenceType) localRef.getType();
- if (!program.typeOracle.isInstantiatedType(type) || type ==
program.getTypeNull()) {
+ // Go over the types in the multiexception and remove the ones
that are not instantiable.
+ Iterator<JType> itTypes = types.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 (types.isEmpty()) {
+ itClauses.remove();
itA.remove();
itB.remove();
madeChanges();
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 9423eeb..a271359 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;
@@ -544,9 +547,6 @@
SourceInfo info = makeSourceInfo(x);
JType type = typeMap.get(x.resolvedType);
JExpression expression = pop(x.expression);
- if (x.type instanceof NameReference) {
- pop(x.type);
- }
push(new JCastOperation(info, type, expression));
} catch (Throwable e) {
throw translateException(x, e);
@@ -1426,17 +1426,272 @@
List<JBlock> catchBlocks = pop(x.catchBlocks);
JBlock tryBlock = pop(x.tryBlock);
+ if (x.resources.length > 0 ) {
+ // Apply the source transformation described bellow to support
try-with-resources.
+ tryBlock = normalizeTryWithResources(info, x, tryBlock, scope);
+ }
List<JLocalRef> catchArgs = new ArrayList<JLocalRef>();
+ List<List<JType>> catchTypeLists = new ArrayList<List<JType>>();
if (x.catchBlocks != null) {
for (Argument argument : x.catchArguments) {
JLocal local = (JLocal) curMethod.locals.get(argument.binding);
catchArgs.add(new JLocalRef(info, local));
+
+ List<JType> catchTypes = new ArrayList<JType>();
+ catchTypeLists.add(catchTypes);
+
+ 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());
+ }
}
}
- push(new JTryStatement(info, tryBlock, catchArgs, catchBlocks,
finallyBlock));
+ push(new JTryStatement(info, tryBlock, catchTypeLists, catchArgs,
catchBlocks,
+ 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<List<JType>> catchTypes = new ArrayList<List<JType>>();
+ catchTypes.add(new ArrayList<JType>());
+ catchTypes.get(0).add(javaLangThrowable);
+
+ // add catch exception variable.
+ JLocal catchVar =
+ createTempLocal(info, "$caught_ex", javaLangThrowable, false,
curMethod.body);
+
+ List<JLocalRef> catchArgs = new ArrayList<JLocalRef>();
+ catchArgs.add(new JLocalRef(info, catchVar));
+
+ JBlock catchBlock = new JBlock(info);
+ catchBlock.addStmt(createAssignment(info, javaLangThrowable,
exceptionVar, catchVar));
+ catchBlock.addStmt(new JThrowStatement(info, new JLocalRef(info,
exceptionVar)));
+
+ List<JBlock> catchBlocks = new ArrayList<JBlock>();
+ catchBlocks.add(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, catchTypes,
catchArgs, catchBlocks,
+ 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<List<JType>> catchTypes = new ArrayList<List<JType>>();
+ catchTypes.add(new ArrayList<JType>());
+ catchTypes.get(0).add(javaLangThrowable);
+
+ // add catch exception variable.
+ JLocal catchVar =
+ createTempLocal(info, "$caught_ex", javaLangThrowable, false,
curMethod.body);
+
+ List<JLocalRef> catchArgs = new ArrayList<JLocalRef>();
+ catchArgs.add(new JLocalRef(info, catchVar));
+
+ 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);
+ List<JBlock> catchBlocks = new ArrayList<JBlock>();
+ catchBlocks.add(catchBlock);
+ JBlock innerTryBlock = new JBlock(info);
+ innerTryBlock.addStmt(resourceClose);
+ // make try block
+ JTryStatement tryBlock = new JTryStatement(info, innerTryBlock ,
catchTypes, catchArgs,
+ catchBlocks, 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
@@ -2787,6 +3042,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();
@@ -2899,6 +3156,8 @@
JClassType javaLangString = null;
+ JClassType javaLangThrowable = null;
+
Map<MethodDeclaration, JsniMethod> jsniMethods;
Map<String, Binding> jsniRefs;
@@ -2942,6 +3201,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.
@@ -2967,7 +3227,7 @@
javaLangObject = null;
javaLangString = null;
javaLangClass = null;
-
+ javaLangThrowable = null;
return result;
}
@@ -3073,14 +3333,7 @@
if (x.fields != null) {
for (FieldDeclaration field : x.fields) {
- if (x.binding.isLocalType() && field.isStatic()) {
- /*
- * Source compatibility with genJavaAst; static fields in local
- * types don't get visited.
- */
- } else {
- createField(field);
- }
+ createField(field);
}
}
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..10e59b3 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();
@@ -890,8 +891,17 @@
for (int i = 0, c = x.getCatchArgs().size(); i < c; ++i) {
print(CHARS_CATCH);
lparen();
+
+ Iterator<JType> it = x.getCatchTypes().get(i).iterator();
+ printTypeName(it.next());
+ while (it.hasNext()) {
+ print(CHARS_PIPE);
+ printTypeName(it.next());
+ }
+ space();
+
JLocalRef localRef = x.getCatchArgs().get(i);
- accept(localRef.getTarget());
+ printName(localRef.getTarget());
rparen();
space();
JBlock block = x.getCatchBlocks().get(i);
@@ -1150,11 +1160,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/UnifyAst.java
b/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
index 5aa134c..fa339a9 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,17 @@
}
@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 (int i = 0; i < x.getCatchTypes().size(); i++) {
+ for (int j = 0; j < x.getCatchTypes().get(i).size(); j++) {
+ x.resolve(i, j, translate( (JReferenceType)
x.getCatchTypes().get(i).get(j)));
+ }
+ }
+ }
+
+ @Override
public void endVisit(JVariable x, Context ctx) {
x.setType(translate(x.getType()));
}
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..79192f8
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
@@ -0,0 +1,75 @@
+/*
+ * 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> levelMap =
+ new HashMap<String, SourceLevel>();
+
+ private final OptionSource options;
+
+ public ArgHandlerSource(OptionSource options) {
+ this.options = options;
+ for (SourceLevel sourceLevel : SourceLevel.values()) {
+ levelMap.put(sourceLevel.getStringValue(), sourceLevel);
+ levelMap.put(sourceLevel.getAltStringValue(), sourceLevel);
+ }
+ }
+
+ @Override
+ public String[] getDefaultArgs() {
+ return new
String[]{getTag(),OptionSource.defaultSourceLevel.getStringValue() };
+ }
+
+ @Override
+ public String getPurpose() {
+ return "Specifies source level (defaults to " +
OptionSource.defaultSourceLevel + ")";
+ }
+
+ @Override
+ public String getTag() {
+ return "-source";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[]{"[" + Joiner.on(",").join(SourceLevel.values())
+ "]"};
+ }
+
+ @Override
+ public boolean setString(String value) {
+ SourceLevel level = levelMap.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..b3aaec9
--- /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.
+ */
+ public 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;
+ }
+ }
+
+ public static final SourceLevel defaultSourceLevel = SourceLevel._6;
+
+ SourceLevel getSourceLevel();
+
+ void setSourceLevel(SourceLevel level);
+}
diff --git
a/dev/core/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
b/dev/core/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
deleted file mode 100644
index 999d008..0000000
---
a/dev/core/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ /dev/null
@@ -1,1671 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- *
http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
-
*******************************************************************************/
-package org.eclipse.jdt.internal.compiler.lookup;
-
-import com.google.gwt.dev.util.collect.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.util.Util;
-import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
-
-public class SourceTypeBinding extends ReferenceBinding {
- public ReferenceBinding superclass;
- public ReferenceBinding[] superInterfaces;
- private FieldBinding[] fields;
- private MethodBinding[] methods;
- public ReferenceBinding[] memberTypes;
- public TypeVariableBinding[] typeVariables;
-
- public ClassScope scope;
-
- // Synthetics are separated into 5 categories: methods, super methods,
fields, class literals, changed declaring type bindings and bridge methods
- // if a new category is added, also increment MAX_SYNTHETICS
- private final static int METHOD_EMUL = 0;
- private final static int FIELD_EMUL = 1;
- private final static int CLASS_LITERAL_EMUL = 2;
- private final static int RECEIVER_TYPE_EMUL = 3;
-
- private final static int MAX_SYNTHETICS = 4;
-
- HashMap[] synthetics;
- char[] genericReferenceTypeSignature;
-
- private SimpleLookupTable storedAnnotations = null; // keys are this
ReferenceBinding & its fields and methods, value is an AnnotationHolder
-
-public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage,
ClassScope scope) {
- this.compoundName = compoundName;
- this.fPackage = fPackage;
- this.fileName = scope.referenceCompilationUnit().getFileName();
- this.modifiers = scope.referenceContext.modifiers;
- this.sourceName =
scope.referenceContext.name;
- this.scope = scope;
-
- // expect the fields & methods to be initialized correctly later
- this.fields = Binding.UNINITIALIZED_FIELDS;
- this.methods = Binding.UNINITIALIZED_METHODS;
-
- computeId();
-}
-
-private void addDefaultAbstractMethods() {
- if ((this.tagBits & TagBits.KnowsDefaultAbstractMethods) != 0) return;
-
- this.tagBits |= TagBits.KnowsDefaultAbstractMethods;
- if (isClass() && isAbstract()) {
- if (this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2)
- return; // no longer added for post 1.2 targets
-
- ReferenceBinding[] itsInterfaces = superInterfaces();
- if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
- MethodBinding[] defaultAbstracts = null;
- int defaultAbstractsCount = 0;
- ReferenceBinding[] interfacesToVisit = itsInterfaces;
- int nextPosition = interfacesToVisit.length;
- for (int i = 0; i < nextPosition; i++) {
- ReferenceBinding superType = interfacesToVisit[i];
- if (superType.isValidBinding()) {
- MethodBinding[] superMethods = superType.methods();
- nextAbstractMethod: for (int m = superMethods.length; --m >= 0;) {
- MethodBinding method = superMethods[m];
- // explicitly implemented ?
- if (implementsMethod(method))
- continue nextAbstractMethod;
- if (defaultAbstractsCount == 0) {
- defaultAbstracts = new MethodBinding[5];
- } else {
- // already added as default abstract ?
- for (int k = 0; k < defaultAbstractsCount; k++) {
- MethodBinding alreadyAdded = defaultAbstracts[k];
- if (CharOperation.equals(alreadyAdded.selector, method.selector)
&& alreadyAdded.areParametersEqual(method))
- continue nextAbstractMethod;
- }
- }
- MethodBinding defaultAbstract = new MethodBinding(
- method.modifiers | ExtraCompilerModifiers.AccDefaultAbstract |
ClassFileConstants.AccSynthetic,
- method.selector,
- method.returnType,
- method.parameters,
- method.thrownExceptions,
- this);
- if (defaultAbstractsCount == defaultAbstracts.length)
- System.arraycopy(defaultAbstracts, 0, defaultAbstracts = new
MethodBinding[2 * defaultAbstractsCount], 0, defaultAbstractsCount);
- defaultAbstracts[defaultAbstractsCount++] = defaultAbstract;
- }
-
- if ((itsInterfaces = superType.superInterfaces()) !=
Binding.NO_SUPERINTERFACES) {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new
ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
- }
- }
- }
- if (defaultAbstractsCount > 0) {
- int length = this.methods.length;
- System.arraycopy(this.methods, 0, this.methods = new
MethodBinding[length + defaultAbstractsCount], 0, length);
- System.arraycopy(defaultAbstracts, 0, this.methods, length,
defaultAbstractsCount);
- // re-sort methods
- length = length + defaultAbstractsCount;
- if (length > 1)
- ReferenceBinding.sortMethods(this.methods, 0, length);
- // this.tagBits |= TagBits.AreMethodsSorted; -- already set in
#methods()
- }
- }
- }
-}
-/* Add a new synthetic field for <actualOuterLocalVariable>.
-* Answer the new field or the existing field if one already existed.
-*/
-public FieldBinding addSyntheticFieldForInnerclass(LocalVariableBinding
actualOuterLocalVariable) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
- this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();
-
- FieldBinding synthField = (FieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable);
- if (synthField == null) {
- synthField = new SyntheticFieldBinding(
- CharOperation.concat(TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX,
actualOuterLocalVariable.name),
- actualOuterLocalVariable.type,
- ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal |
ClassFileConstants.AccSynthetic,
- this,
- Constant.NotAConstant,
- this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
-
this.synthetics[SourceTypeBinding.FIELD_EMUL].put(actualOuterLocalVariable,
synthField);
- }
-
- // ensure there is not already such a field defined by the user
- boolean needRecheck;
- int index = 1;
- do {
- needRecheck = false;
- FieldBinding existingField;
- if ((existingField = this.getField(synthField.name, true
/*resolve*/)) != null) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
- FieldDeclaration fieldDecl = typeDecl.fields[i];
- if (fieldDecl.binding == existingField) {
- synthField.name = CharOperation.concat(
- TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX,
- actualOuterLocalVariable.name,
- ("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
- needRecheck = true;
- break;
- }
- }
- }
- } while (needRecheck);
- return synthField;
-}
-/* Add a new synthetic field for <enclosingType>.
-* Answer the new field or the existing field if one already existed.
-*/
-public FieldBinding addSyntheticFieldForInnerclass(ReferenceBinding
enclosingType) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
- this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();
-
- FieldBinding synthField = (FieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get(enclosingType);
- if (synthField == null) {
- synthField = new SyntheticFieldBinding(
- CharOperation.concat(
- TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
- String.valueOf(enclosingType.depth()).toCharArray()),
- enclosingType,
- ClassFileConstants.AccDefault | ClassFileConstants.AccFinal |
ClassFileConstants.AccSynthetic,
- this,
- Constant.NotAConstant,
- this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
- this.synthetics[SourceTypeBinding.FIELD_EMUL].put(enclosingType,
synthField);
- }
- // ensure there is not already such a field defined by the user
- boolean needRecheck;
- do {
- needRecheck = false;
- FieldBinding existingField;
- if ((existingField = this.getField(synthField.name, true
/*resolve*/)) != null) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
- FieldDeclaration fieldDecl = typeDecl.fields[i];
- if (fieldDecl.binding == existingField) {
- if (this.scope.compilerOptions().complianceLevel >=
ClassFileConstants.JDK1_5) {
- synthField.name = CharOperation.concat(
- synthField.name,
- "$".toCharArray()); //$NON-NLS-1$
- needRecheck = true;
- } else {
- this.scope.problemReporter().duplicateFieldInType(this, fieldDecl);
- }
- break;
- }
- }
- }
- } while (needRecheck);
- return synthField;
-}
-/* Add a new synthetic field for a class literal access.
-* Answer the new field or the existing field if one already existed.
-*/
-public FieldBinding addSyntheticFieldForClassLiteral(TypeBinding
targetType, BlockScope blockScope) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null)
- this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] = new HashMap();
-
- // use a different table than FIELDS, given there might be a collision
between emulation of X.this$0 and X.class.
- FieldBinding synthField = (FieldBinding)
this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].get(targetType);
- if (synthField == null) {
- synthField = new SyntheticFieldBinding(
- CharOperation.concat(
- TypeConstants.SYNTHETIC_CLASS,
-
String.valueOf(this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size()).toCharArray()),
- blockScope.getJavaLangClass(),
- ClassFileConstants.AccDefault | ClassFileConstants.AccStatic |
ClassFileConstants.AccSynthetic,
- this,
- Constant.NotAConstant,
- this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size());
- this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].put(targetType,
synthField);
- }
- // ensure there is not already such a field defined by the user
- FieldBinding existingField;
- if ((existingField = this.getField(synthField.name, true /*resolve*/)) !=
null) {
- TypeDeclaration typeDecl = blockScope.referenceType();
- for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
- FieldDeclaration fieldDecl = typeDecl.fields[i];
- if (fieldDecl.binding == existingField) {
- blockScope.problemReporter().duplicateFieldInType(this, fieldDecl);
- break;
- }
- }
- }
- return synthField;
-}
-/* Add a new synthetic field for the emulation of the assert statement.
-* Answer the new field or the existing field if one already existed.
-*/
-public FieldBinding addSyntheticFieldForAssert(BlockScope blockScope) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
- this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();
-
- FieldBinding synthField = (FieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get("assertionEmulation");
//$NON-NLS-1$
- if (synthField == null) {
- synthField = new SyntheticFieldBinding(
- TypeConstants.SYNTHETIC_ASSERT_DISABLED,
- TypeBinding.BOOLEAN,
- ClassFileConstants.AccDefault | ClassFileConstants.AccStatic |
ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal,
- this,
- Constant.NotAConstant,
- this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
- this.synthetics[SourceTypeBinding.FIELD_EMUL].put("assertionEmulation",
synthField); //$NON-NLS-1$
- }
- // ensure there is not already such a field defined by the user
- // ensure there is not already such a field defined by the user
- boolean needRecheck;
- int index = 0;
- do {
- needRecheck = false;
- FieldBinding existingField;
- if ((existingField = this.getField(synthField.name, true
/*resolve*/)) != null) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
- FieldDeclaration fieldDecl = typeDecl.fields[i];
- if (fieldDecl.binding == existingField) {
- synthField.name = CharOperation.concat(
- TypeConstants.SYNTHETIC_ASSERT_DISABLED,
- ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
- needRecheck = true;
- break;
- }
- }
- }
- } while (needRecheck);
- return synthField;
-}
-/* Add a new synthetic field for recording all enum constant values
-* Answer the new field or the existing field if one already existed.
-*/
-public FieldBinding addSyntheticFieldForEnumValues() {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
- this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();
-
- FieldBinding synthField = (FieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get("enumConstantValues");
//$NON-NLS-1$
- if (synthField == null) {
- synthField = new SyntheticFieldBinding(
- TypeConstants.SYNTHETIC_ENUM_VALUES,
- this.scope.createArrayType(this,1),
- ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic |
ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal,
- this,
- Constant.NotAConstant,
- this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
- this.synthetics[SourceTypeBinding.FIELD_EMUL].put("enumConstantValues",
synthField); //$NON-NLS-1$
- }
- // ensure there is not already such a field defined by the user
- // ensure there is not already such a field defined by the user
- boolean needRecheck;
- int index = 0;
- do {
- needRecheck = false;
- FieldBinding existingField;
- if ((existingField = this.getField(synthField.name, true
/*resolve*/)) != null) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
- FieldDeclaration fieldDecl = typeDecl.fields[i];
- if (fieldDecl.binding == existingField) {
- synthField.name = CharOperation.concat(
- TypeConstants.SYNTHETIC_ENUM_VALUES,
- ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
- needRecheck = true;
- break;
- }
- }
- }
- } while (needRecheck);
- return synthField;
-}
-/* Add a new synthetic access method for read/write access to
<targetField>.
- Answer the new method or the existing method if one already existed.
-*/
-public SyntheticMethodBinding addSyntheticMethod(FieldBinding targetField,
boolean isReadAccess) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
- this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();
-
- SyntheticMethodBinding accessMethod = null;
- SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetField);
- if (accessors == null) {
- accessMethod = new SyntheticMethodBinding(targetField, isReadAccess,
this);
- this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetField,
accessors = new SyntheticMethodBinding[2]);
- accessors[isReadAccess ? 0 : 1] = accessMethod;
- } else {
- if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) {
- accessMethod = new SyntheticMethodBinding(targetField, isReadAccess,
this);
- accessors[isReadAccess ? 0 : 1] = accessMethod;
- }
- }
- return accessMethod;
-}
-/* Add a new synthetic method the enum type. Selector can either
be 'values' or 'valueOf'.
- * char[] constants from TypeConstants must be used:
TypeConstants.VALUES/VALUEOF
-*/
-public SyntheticMethodBinding addSyntheticEnumMethod(char[] selector) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
- this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();
-
- SyntheticMethodBinding accessMethod = null;
- SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(selector);
- if (accessors == null) {
- accessMethod = new SyntheticMethodBinding(this, selector);
- this.synthetics[SourceTypeBinding.METHOD_EMUL].put(selector, accessors =
new SyntheticMethodBinding[2]);
- accessors[0] = accessMethod;
- } else {
- if ((accessMethod = accessors[0]) == null) {
- accessMethod = new SyntheticMethodBinding(this, selector);
- accessors[0] = accessMethod;
- }
- }
- return accessMethod;
-}
-/*
- * Add a synthetic field to handle the cache of the switch translation
table for the corresponding enum type
- */
-public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[]
fieldName, String key) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
- this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap();
-
- SyntheticFieldBinding synthField = (SyntheticFieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get(key);
- if (synthField == null) {
- synthField = new SyntheticFieldBinding(
- fieldName,
- this.scope.createArrayType(TypeBinding.INT,1),
- ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic |
ClassFileConstants.AccSynthetic,
- this,
- Constant.NotAConstant,
- this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
- this.synthetics[SourceTypeBinding.FIELD_EMUL].put(key, synthField);
- }
- // ensure there is not already such a field defined by the user
- boolean needRecheck;
- int index = 0;
- do {
- needRecheck = false;
- FieldBinding existingField;
- if ((existingField = this.getField(synthField.name, true
/*resolve*/)) != null) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
- FieldDeclaration fieldDecl = typeDecl.fields[i];
- if (fieldDecl.binding == existingField) {
- synthField.name = CharOperation.concat(
- fieldName,
- ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
- needRecheck = true;
- break;
- }
- }
- }
- } while (needRecheck);
- return synthField;
-}
-/* Add a new synthetic method the enum type. Selector can either
be 'values' or 'valueOf'.
- * char[] constants from TypeConstants must be used:
TypeConstants.VALUES/VALUEOF
-*/
-public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(TypeBinding
enumBinding) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
- this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();
-
- SyntheticMethodBinding accessMethod = null;
- char[] selector =
CharOperation.concat(TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE,
enumBinding.constantPoolName());
- CharOperation.replace(selector, '/', '$');
- final String key = new String(selector);
- SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(key);
- // first add the corresponding synthetic field
- if (accessors == null) {
- // then create the synthetic method
- final SyntheticFieldBinding fieldBinding =
this.addSyntheticFieldForSwitchEnum(selector, key);
- accessMethod = new SyntheticMethodBinding(fieldBinding, this,
enumBinding, selector);
- this.synthetics[SourceTypeBinding.METHOD_EMUL].put(key, accessors = new
SyntheticMethodBinding[2]);
- accessors[0] = accessMethod;
- } else {
- if ((accessMethod = accessors[0]) == null) {
- final SyntheticFieldBinding fieldBinding =
this.addSyntheticFieldForSwitchEnum(selector, key);
- accessMethod = new SyntheticMethodBinding(fieldBinding, this,
enumBinding, selector);
- accessors[0] = accessMethod;
- }
- }
- return accessMethod;
-}
-/* Add a new synthetic access method for access to <targetMethod>.
- * Must distinguish access method used for super access from others (need
to use invokespecial bytecode)
- Answer the new method or the existing method if one already existed.
-*/
-public SyntheticMethodBinding addSyntheticMethod(MethodBinding
targetMethod, boolean isSuperAccess) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
- this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();
-
- SyntheticMethodBinding accessMethod = null;
- SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetMethod);
- if (accessors == null) {
- accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess,
this);
- this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetMethod,
accessors = new SyntheticMethodBinding[2]);
- accessors[isSuperAccess ? 0 : 1] = accessMethod;
- } else {
- if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) {
- accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess,
this);
- accessors[isSuperAccess ? 0 : 1] = accessMethod;
- }
- }
- return accessMethod;
-}
-/*
- * Record the fact that bridge methods need to be generated to override
certain inherited methods
- */
-public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding
inheritedMethodToBridge, MethodBinding targetMethod) {
- if (isInterface()) return null; // only classes & enums get bridge methods
- // targetMethod may be inherited
- if (inheritedMethodToBridge.returnType.erasure() ==
targetMethod.returnType.erasure()
- && inheritedMethodToBridge.areParameterErasuresEqual(targetMethod)) {
- return null; // do not need bridge method
- }
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) {
- this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap();
- } else {
- // check to see if there is another equivalent inheritedMethod already
added
- Iterator synthMethods =
this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator();
- while (synthMethods.hasNext()) {
- Object synthetic = synthMethods.next();
- if (synthetic instanceof MethodBinding) {
- MethodBinding method = (MethodBinding) synthetic;
- if (CharOperation.equals(inheritedMethodToBridge.selector,
method.selector)
- && inheritedMethodToBridge.returnType.erasure() ==
method.returnType.erasure()
- && inheritedMethodToBridge.areParameterErasuresEqual(method)) {
- return null;
- }
- }
- }
- }
-
- SyntheticMethodBinding accessMethod = null;
- SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
- if (accessors == null) {
- accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge,
targetMethod, this);
-
this.synthetics[SourceTypeBinding.METHOD_EMUL].put(inheritedMethodToBridge,
accessors = new SyntheticMethodBinding[2]);
- accessors[1] = accessMethod;
- } else {
- if ((accessMethod = accessors[1]) == null) {
- accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge,
targetMethod, this);
- accessors[1] = accessMethod;
- }
- }
- return accessMethod;
-}
-boolean areFieldsInitialized() {
- return this.fields != Binding.UNINITIALIZED_FIELDS;
-}
-boolean areMethodsInitialized() {
- return this.methods != Binding.UNINITIALIZED_METHODS;
-}
-public int kind() {
- if (this.typeVariables != Binding.NO_TYPE_VARIABLES) return
Binding.GENERIC_TYPE;
- return Binding.TYPE;
-}
-
-public char[] computeUniqueKey(boolean isLeaf) {
- char[] uniqueKey = super.computeUniqueKey(isLeaf);
- if (uniqueKey.length == 2) return uniqueKey; // problem type's unique key
is "L;"
- if (Util.isClassFileName(this.fileName)) return uniqueKey; // no need to
insert compilation unit name for a .class file
-
- // insert compilation unit name if the type name is not the main type name
- int end = CharOperation.lastIndexOf('.', this.fileName);
- if (end != -1) {
- int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
- char[] mainTypeName = CharOperation.subarray(this.fileName, start, end);
- start = CharOperation.lastIndexOf('/', uniqueKey) + 1;
- if (start == 0)
- start = 1; // start after L
- end = CharOperation.indexOf('$', uniqueKey, start);
- if (end == -1)
- end = CharOperation.indexOf('<', uniqueKey, start);
- if (end == -1)
- end = CharOperation.indexOf(';', uniqueKey, start);
- char[] topLevelType = CharOperation.subarray(uniqueKey, start, end);
- if (!CharOperation.equals(topLevelType, mainTypeName)) {
- StringBuffer buffer = new StringBuffer();
- buffer.append(uniqueKey, 0, start);
- buffer.append(mainTypeName);
- buffer.append('~');
- buffer.append(topLevelType);
- buffer.append(uniqueKey, end, uniqueKey.length - end);
- int length = buffer.length();
- uniqueKey = new char[length];
- buffer.getChars(0, length, uniqueKey, 0);
- return uniqueKey;
- }
- }
- return uniqueKey;
-}
-
-void faultInTypesForFieldsAndMethods() {
- // check @Deprecated annotation
- getAnnotationTagBits(); // marks as deprecated by side effect
- ReferenceBinding enclosingType = this.enclosingType();
- if (enclosingType != null && enclosingType.isViewedAsDeprecated()
&& !this.isDeprecated())
- this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
- fields();
- methods();
-
- for (int i = 0, length = this.memberTypes.length; i < length; i++)
- ((SourceTypeBinding)
this.memberTypes[i]).faultInTypesForFieldsAndMethods();
-}
-// NOTE: the type of each field of a source type is resolved when needed
-public FieldBinding[] fields() {
- if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
- return this.fields;
-
- int failed = 0;
- FieldBinding[] resolvedFields = this.fields;
- try {
- // lazily sort fields
- if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
- int length = this.fields.length;
- if (length > 1)
- ReferenceBinding.sortFields(this.fields, 0, length);
- this.tagBits |= TagBits.AreFieldsSorted;
- }
- for (int i = 0, length = this.fields.length; i < length; i++) {
- if (resolveTypeFor(this.fields[i]) == null) {
- // do not alter original field array until resolution is over, due to
reentrance (143259)
- if (resolvedFields == this.fields) {
- System.arraycopy(this.fields, 0, resolvedFields = new
FieldBinding[length], 0, length);
- }
- resolvedFields[i] = null;
- failed++;
- }
- }
- } finally {
- if (failed > 0) {
- // ensure fields are consistent reqardless of the error
- int newSize = resolvedFields.length - failed;
- if (newSize == 0)
- return this.fields = Binding.NO_FIELDS;
-
- FieldBinding[] newFields = new FieldBinding[newSize];
- for (int i = 0, j = 0, length = resolvedFields.length; i < length; i++)
{
- if (resolvedFields[i] != null)
- newFields[j++] = resolvedFields[i];
- }
- this.fields = newFields;
- }
- }
- this.tagBits |= TagBits.AreFieldsComplete;
- return this.fields;
-}
-/**
- * @see
org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
- */
-public char[] genericTypeSignature() {
- if (this.genericReferenceTypeSignature == null)
- this.genericReferenceTypeSignature =
computeGenericTypeSignature(this.typeVariables);
- return this.genericReferenceTypeSignature;
-}
-/**
- * <param1 ... paramN>superclass superinterface1 ... superinterfaceN
- *
<T:LY<TT;>;U:Ljava/lang/Object;V::Ljava/lang/Runnable;:Ljava/lang/Cloneable;:Ljava/util/Map;>Ljava/lang/Exception;Ljava/lang/Runnable;
- */
-public char[] genericSignature() {
- StringBuffer sig = null;
- if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
- sig = new StringBuffer(10);
- sig.append('<');
- for (int i = 0, length = this.typeVariables.length; i < length; i++)
- sig.append(this.typeVariables[i].genericSignature());
- sig.append('>');
- } else {
- // could still need a signature if any of supertypes is parameterized
- noSignature: if (this.superclass == null |
| !this.superclass.isParameterizedType()) {
- for (int i = 0, length = this.superInterfaces.length; i < length;
i++)
- if (this.superInterfaces[i].isParameterizedType())
- break noSignature;
- return null;
- }
- sig = new StringBuffer(10);
- }
- if (this.superclass != null)
- sig.append(this.superclass.genericTypeSignature());
- else // interface scenario only (as Object cannot be generic) - 65953
- sig.append(this.scope.getJavaLangObject().genericTypeSignature());
- for (int i = 0, length = this.superInterfaces.length; i < length; i++)
- sig.append(this.superInterfaces[i].genericTypeSignature());
- return sig.toString().toCharArray();
-}
-
-/**
- * Compute the tagbits for standard annotations. For source types, these
could require
- * lazily resolving corresponding annotation nodes, in case of forward
references.
- * @see
org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
- */
-public long getAnnotationTagBits() {
- if ((this.tagBits & TagBits.AnnotationResolved) == 0 && this.scope !=
null) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
- try {
- typeDecl.staticInitializerScope.insideTypeAnnotation = true;
- ASTNode.resolveAnnotations(typeDecl.staticInitializerScope,
typeDecl.annotations, this);
- } finally {
- typeDecl.staticInitializerScope.insideTypeAnnotation = old;
- }
- if ((this.tagBits & TagBits.AnnotationDeprecated) != 0)
- this.modifiers |= ClassFileConstants.AccDeprecated;
- }
- return this.tagBits;
-}
-public MethodBinding[] getDefaultAbstractMethods() {
- int count = 0;
- for (int i = this.methods.length; --i >= 0;)
- if (this.methods[i].isDefaultAbstract())
- count++;
- if (count == 0) return Binding.NO_METHODS;
-
- MethodBinding[] result = new MethodBinding[count];
- count = 0;
- for (int i = this.methods.length; --i >= 0;)
- if (this.methods[i].isDefaultAbstract())
- result[count++] = this.methods[i];
- return result;
-}
-// NOTE: the return type, arg & exception types of each method of a source
type are resolved when needed
-public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
- int argCount = argumentTypes.length;
- if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved
all arg types & return type of the methods
- long range;
- if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT,
this.methods)) >= 0) {
- nextMethod: for (int imethod = (int)range, end = (int)(range >> 32);
imethod <= end; imethod++) {
- MethodBinding method = this.methods[imethod];
- if (method.parameters.length == argCount) {
- TypeBinding[] toMatch = method.parameters;
- for (int iarg = 0; iarg < argCount; iarg++)
- if (toMatch[iarg] != argumentTypes[iarg])
- continue nextMethod;
- return method;
- }
- }
- }
- } else {
- // lazily sort methods
- if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
- int length = this.methods.length;
- if (length > 1)
- ReferenceBinding.sortMethods(this.methods, 0, length);
- this.tagBits |= TagBits.AreMethodsSorted;
- }
- long range;
- if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT,
this.methods)) >= 0) {
- nextMethod: for (int imethod = (int)range, end = (int)(range >> 32);
imethod <= end; imethod++) {
- MethodBinding method = this.methods[imethod];
- if (resolveTypesFor(method) == null || method.returnType == null) {
- methods();
- return getExactConstructor(argumentTypes); // try again since the
problem methods have been removed
- }
- if (method.parameters.length == argCount) {
- TypeBinding[] toMatch = method.parameters;
- for (int iarg = 0; iarg < argCount; iarg++)
- if (toMatch[iarg] != argumentTypes[iarg])
- continue nextMethod;
- return method;
- }
- }
- }
- }
- return null;
-}
-
-//NOTE: the return type, arg & exception types of each method of a source
type are resolved when needed
-//searches up the hierarchy as long as no potential (but not exact) match
was found.
-public MethodBinding getExactMethod(char[] selector, TypeBinding[]
argumentTypes, CompilationUnitScope refScope) {
- // sender from refScope calls recordTypeReference(this)
- int argCount = argumentTypes.length;
- boolean foundNothing = true;
-
- if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved
all arg types & return type of the methods
- long range;
- if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >=
0) {
- nextMethod: for (int imethod = (int)range, end = (int)(range >> 32);
imethod <= end; imethod++) {
- MethodBinding method = this.methods[imethod];
- foundNothing = false; // inner type lookups must know that a method
with this name exists
- if (method.parameters.length == argCount) {
- TypeBinding[] toMatch = method.parameters;
- for (int iarg = 0; iarg < argCount; iarg++)
- if (toMatch[iarg] != argumentTypes[iarg])
- continue nextMethod;
- return method;
- }
- }
- }
- } else {
- // lazily sort methods
- if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
- int length = this.methods.length;
- if (length > 1)
- ReferenceBinding.sortMethods(this.methods, 0, length);
- this.tagBits |= TagBits.AreMethodsSorted;
- }
-
- long range;
- if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >=
0) {
- // check unresolved method
- int start = (int) range, end = (int) (range >> 32);
- for (int imethod = start; imethod <= end; imethod++) {
- MethodBinding method = this.methods[imethod];
- if (resolveTypesFor(method) == null || method.returnType == null) {
- methods();
- return getExactMethod(selector, argumentTypes, refScope); // try
again since the problem methods have been removed
- }
- }
- // check dup collisions
- boolean isSource15 = this.scope.compilerOptions().sourceLevel >=
ClassFileConstants.JDK1_5;
- for (int i = start; i <= end; i++) {
- MethodBinding method1 = this.methods[i];
- for (int j = end; j > i; j--) {
- MethodBinding method2 = this.methods[j];
- boolean paramsMatch = isSource15
- ? method1.areParameterErasuresEqual(method2)
- : method1.areParametersEqual(method2);
- if (paramsMatch) {
- methods();
- return getExactMethod(selector, argumentTypes, refScope); // try
again since the problem methods have been removed
- }
- }
- }
- nextMethod: for (int imethod = start; imethod <= end; imethod++) {
- MethodBinding method = this.methods[imethod];
- TypeBinding[] toMatch = method.parameters;
- if (toMatch.length == argCount) {
- for (int iarg = 0; iarg < argCount; iarg++)
- if (toMatch[iarg] != argumentTypes[iarg])
- continue nextMethod;
- return method;
- }
- }
- }
- }
-
- if (foundNothing) {
- if (isInterface()) {
- if (this.superInterfaces.length == 1) {
- if (refScope != null)
- refScope.recordTypeReference(this.superInterfaces[0]);
- return this.superInterfaces[0].getExactMethod(selector, argumentTypes,
refScope);
- }
- } else if (this.superclass != null) {
- if (refScope != null)
- refScope.recordTypeReference(this.superclass);
- return this.superclass.getExactMethod(selector, argumentTypes,
refScope);
- }
- }
- return null;
-}
-
-//NOTE: the type of a field of a source type is resolved when needed
-public FieldBinding getField(char[] fieldName, boolean needResolve) {
-
- if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
- return ReferenceBinding.binarySearch(fieldName, this.fields);
-
- // lazily sort fields
- if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
- int length = this.fields.length;
- if (length > 1)
- ReferenceBinding.sortFields(this.fields, 0, length);
- this.tagBits |= TagBits.AreFieldsSorted;
- }
- // always resolve anyway on source types
- FieldBinding field = ReferenceBinding.binarySearch(fieldName,
this.fields);
- if (field != null) {
- FieldBinding result = null;
- try {
- result = resolveTypeFor(field);
- return result;
- } finally {
- if (result == null) {
- // ensure fields are consistent reqardless of the error
- int newSize = this.fields.length - 1;
- if (newSize == 0) {
- this.fields = Binding.NO_FIELDS;
- } else {
- FieldBinding[] newFields = new FieldBinding[newSize];
- int index = 0;
- for (int i = 0, length = this.fields.length; i < length; i++) {
- FieldBinding f = this.fields[i];
- if (f == field) continue;
- newFields[index++] = f;
- }
- this.fields = newFields;
- }
- }
- }
- }
- return null;
-}
-
-// NOTE: the return type, arg & exception types of each method of a source
type are resolved when needed
-public MethodBinding[] getMethods(char[] selector) {
- if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
- long range;
- if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >=
0) {
- int start = (int) range, end = (int) (range >> 32);
- int length = end - start + 1;
- MethodBinding[] result;
- System.arraycopy(this.methods, start, result = new
MethodBinding[length], 0, length);
- return result;
- } else {
- return Binding.NO_METHODS;
- }
- }
- // lazily sort methods
- if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
- int length = this.methods.length;
- if (length > 1)
- ReferenceBinding.sortMethods(this.methods, 0, length);
- this.tagBits |= TagBits.AreMethodsSorted;
- }
- MethodBinding[] result;
- long range;
- if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0)
{
- int start = (int) range, end = (int) (range >> 32);
- for (int i = start; i <= end; i++) {
- MethodBinding method = this.methods[i];
- if (resolveTypesFor(method) == null || method.returnType == null) {
- methods();
- return getMethods(selector); // try again since the problem methods
have been removed
- }
- }
- int length = end - start + 1;
- System.arraycopy(this.methods, start, result = new
MethodBinding[length], 0, length);
- } else {
- return Binding.NO_METHODS;
- }
- boolean isSource15 = this.scope.compilerOptions().sourceLevel >=
ClassFileConstants.JDK1_5;
- for (int i = 0, length = result.length - 1; i < length; i++) {
- MethodBinding method = result[i];
- for (int j = length; j > i; j--) {
- boolean paramsMatch = isSource15
- ? method.areParameterErasuresEqual(result[j])
- : method.areParametersEqual(result[j]);
- if (paramsMatch) {
- methods();
- return getMethods(selector); // try again since the duplicate methods
have been removed
- }
- }
- }
- return result;
-}
-/* Answer the synthetic field for <actualOuterLocalVariable>
-* or null if one does not exist.
-*/
-public FieldBinding getSyntheticField(LocalVariableBinding
actualOuterLocalVariable) {
- if (this.synthetics == null ||
this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null;
- return (FieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable);
-}
-/* Answer the synthetic field for <targetEnclosingType>
-* or null if one does not exist.
-*/
-public FieldBinding getSyntheticField(ReferenceBinding
targetEnclosingType, boolean onlyExactMatch) {
-
- if (this.synthetics == null ||
this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null;
- FieldBinding field = (FieldBinding)
this.synthetics[SourceTypeBinding.FIELD_EMUL].get(targetEnclosingType);
- if (field != null) return field;
-
- // type compatibility : to handle cases such as
- // class T { class M{}}
- // class S extends T { class N extends M {}} --> need to use S as a
default enclosing instance for the super constructor call in N().
- if (!onlyExactMatch){
- Iterator accessFields =
this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator();
- while (accessFields.hasNext()) {
- field = (FieldBinding) accessFields.next();
- if
(CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
field.name)
- && field.type.findSuperTypeOriginatingFrom(targetEnclosingType) !=
null)
- return field;
- }
- }
- return null;
-}
-/*
- * Answer the bridge method associated for an inherited methods or null
if one does not exist
- */
-public SyntheticMethodBinding getSyntheticBridgeMethod(MethodBinding
inheritedMethodToBridge) {
- if (this.synthetics == null) return null;
- if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) return null;
- SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
- if (accessors == null) return null;
- return accessors[1];
-}
-
-/**
- * @see
org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
- */
-public void initializeDeprecatedAnnotationTagBits() {
- if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
- TypeDeclaration typeDecl = this.scope.referenceContext;
- boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
- try {
- typeDecl.staticInitializerScope.insideTypeAnnotation = true;
- ASTNode.resolveDeprecatedAnnotations(typeDecl.staticInitializerScope,
typeDecl.annotations, this);
- this.tagBits |= TagBits.DeprecatedAnnotationResolved;
- } finally {
- typeDecl.staticInitializerScope.insideTypeAnnotation = old;
- }
- if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) {
- this.modifiers |= ClassFileConstants.AccDeprecated;
- }
- }
-}
-
-// ensure the receiver knows its hierarchy & fields/methods so static
imports can be resolved correctly
-// see bug 230026
-void initializeForStaticImports() {
- if (this.scope == null) return; // already initialized
-
- if (this.superInterfaces == null)
- this.scope.connectTypeHierarchy();
- this.scope.buildFields();
- this.scope.buildMethods();
-}
-
-/**
- * Returns true if a type is identical to another one,
- * or for generic types, true if compared to its raw type.
- */
-public boolean isEquivalentTo(TypeBinding otherType) {
-
- if (this == otherType) return true;
- if (otherType == null) return false;
- switch(otherType.kind()) {
-
- case Binding.WILDCARD_TYPE :
- case Binding.INTERSECTION_TYPE:
- return ((WildcardBinding) otherType).boundCheck(this);
-
- case Binding.PARAMETERIZED_TYPE :
- if ((otherType.tagBits & TagBits.HasDirectWildcard) == 0 &&
(!this.isMemberType() || !otherType.isMemberType()))
- return false; // should have been identical
- ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding)
otherType;
- if (this != otherParamType.genericType())
- return false;
- if (!isStatic()) { // static member types do not compare their enclosing
- ReferenceBinding enclosing = enclosingType();
- if (enclosing != null) {
- ReferenceBinding otherEnclosing =
otherParamType.enclosingType();
- if (otherEnclosing == null) return false;
- if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) ==
0) {
- if (enclosing != otherEnclosing) return false;
- } else {
- if
(!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
- }
- }
- }
- int length = this.typeVariables == null ? 0 : this.typeVariables.length;
- TypeBinding[] otherArguments = otherParamType.arguments;
- int otherLength = otherArguments == null ? 0 : otherArguments.length;
- if (otherLength != length)
- return false;
- for (int i = 0; i < length; i++)
- if
(!this.typeVariables[i].isTypeArgumentContainedBy(otherArguments[i]))
- return false;
- return true;
-
- case Binding.RAW_TYPE :
- return otherType.erasure() == this;
- }
- return false;
-}
-public boolean isGenericType() {
- return this.typeVariables != Binding.NO_TYPE_VARIABLES;
-}
-public ReferenceBinding[] memberTypes() {
- return this.memberTypes;
-}
-public FieldBinding getUpdatedFieldBinding(FieldBinding targetField,
ReferenceBinding newDeclaringClass) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null)
- this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap();
-
- Hashtable fieldMap = (Hashtable)
this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].get(targetField);
- if (fieldMap == null) {
- fieldMap = new Hashtable(5);
- this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(targetField,
fieldMap);
- }
- FieldBinding updatedField = (FieldBinding)
fieldMap.get(newDeclaringClass);
- if (updatedField == null){
- updatedField = new FieldBinding(targetField, newDeclaringClass);
- fieldMap.put(newDeclaringClass, updatedField);
- }
- return updatedField;
-}
-public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod,
ReferenceBinding newDeclaringClass) {
- if (this.synthetics == null)
- this.synthetics = new HashMap[MAX_SYNTHETICS];
- if (this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] == null)
- this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL] = new HashMap();
-
- Hashtable methodMap = (Hashtable)
this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].get(targetMethod);
- if (methodMap == null) {
- methodMap = new Hashtable(5);
- this.synthetics[SourceTypeBinding.RECEIVER_TYPE_EMUL].put(targetMethod,
methodMap);
- }
- MethodBinding updatedMethod = (MethodBinding)
methodMap.get(newDeclaringClass);
- if (updatedMethod == null){
- updatedMethod = new MethodBinding(targetMethod, newDeclaringClass);
- methodMap.put(newDeclaringClass, updatedMethod);
- }
- return updatedMethod;
-}
-public boolean hasMemberTypes() {
- return this.memberTypes.length > 0;
-}
-// NOTE: the return type, arg & exception types of each method of a source
type are resolved when needed
-public MethodBinding[] methods() {
- if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
- return this.methods;
-
- // lazily sort methods
- if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
- int length = this.methods.length;
- if (length > 1)
- ReferenceBinding.sortMethods(this.methods, 0, length);
- this.tagBits |= TagBits.AreMethodsSorted;
- }
-
- int failed = 0;
- MethodBinding[] resolvedMethods = this.methods;
- try {
- for (int i = 0, length = this.methods.length; i < length; i++) {
- if (resolveTypesFor(this.methods[i]) == null) {
- // do not alter original method array until resolution is over, due to
reentrance (143259)
- if (resolvedMethods == this.methods) {
- System.arraycopy(this.methods, 0, resolvedMethods = new
MethodBinding[length], 0, length);
- }
- resolvedMethods[i] = null; // unable to resolve parameters
- failed++;
- }
- }
-
- // find & report collision cases
- boolean complyTo15 = this.scope.compilerOptions().sourceLevel >=
ClassFileConstants.JDK1_5;
- for (int i = 0, length = this.methods.length; i < length; i++) {
- MethodBinding method = resolvedMethods[i];
- if (method == null)
- continue;
- char[] selector = method.selector;
- AbstractMethodDeclaration methodDecl = null;
- nextSibling: for (int j = i + 1; j < length; j++) {
- MethodBinding method2 = resolvedMethods[j];
- if (method2 == null)
- continue nextSibling;
- if (!CharOperation.equals(selector, method2.selector))
- break nextSibling; // methods with same selector are contiguous
-
- if (complyTo15 && method.returnType != null && method2.returnType !=
null) {
- // 8.4.2, for collision to be detected between m1 and m2:
- // signature(m1) == signature(m2) i.e. same arity, same type
parameter count, can be substituted
- // signature(m1) == erasure(signature(m2)) or erasure(signature(m1))
== signature(m2)
- TypeBinding[] params1 = method.parameters;
- TypeBinding[] params2 = method2.parameters;
- int pLength = params1.length;
- if (pLength != params2.length)
- continue nextSibling;
-
- TypeVariableBinding[] vars = method.typeVariables;
- TypeVariableBinding[] vars2 = method2.typeVariables;
- boolean equalTypeVars = vars == vars2;
- MethodBinding subMethod = method2;
- if (!equalTypeVars) {
- MethodBinding temp = method.computeSubstitutedMethod(method2,
this.scope.environment());
- if (temp != null) {
- equalTypeVars = true;
- subMethod = temp;
- }
- }
- boolean equalParams = method.areParametersEqual(subMethod);
- if (equalParams && equalTypeVars) {
- // duplicates regardless of return types
- } else if (method.returnType.erasure() ==
subMethod.returnType.erasure() && (equalParams ||
method.areParameterErasuresEqual(method2))) {
- // name clash for sure if not duplicates, report as duplicates
- } else if (!equalTypeVars && vars != Binding.NO_TYPE_VARIABLES &&
vars2 != Binding.NO_TYPE_VARIABLES) {
- // type variables are different so we can distinguish between methods
- continue nextSibling;
- } else if (pLength > 0) {
- // check to see if the erasure of either method is equal to the other
- int index = pLength;
- for (; --index >= 0;) {
- if (params1[index] != params2[index].erasure())
- break;
- if (params1[index] == params2[index]) {
- TypeBinding type = params1[index].leafComponentType();
- if (type instanceof SourceTypeBinding && type.typeVariables() !=
Binding.NO_TYPE_VARIABLES) {
- index = pLength; // handle comparing identical source types like
X<T>... its erasure is itself BUT we need to answer false
- break;
- }
- }
- }
- if (index >= 0 && index < pLength) {
- for (index = pLength; --index >= 0;)
- if (params1[index].erasure() != params2[index])
- break;
- }
- if (index >= 0)
- continue nextSibling;
- }
- } else if (!method.areParametersEqual(method2)) { // prior to 1.5,
parameter identity meant a collision case
- continue nextSibling;
- }
- boolean isEnumSpecialMethod = isEnum() &&
(CharOperation.equals(selector,TypeConstants.VALUEOF) ||
CharOperation.equals(selector,TypeConstants.VALUES));
- // report duplicate
- if (methodDecl == null) {
- methodDecl = method.sourceMethod(); // cannot be retrieved after
binding is lost & may still be null if method is special
- if (methodDecl != null && methodDecl.binding != null) { // ensure its
a valid user defined method
- if (isEnumSpecialMethod) {
- this.scope.problemReporter().duplicateEnumSpecialMethod(this,
methodDecl);
- } else {
- this.scope.problemReporter().duplicateMethodInType(this,
methodDecl, method.areParametersEqual(method2));
- }
- methodDecl.binding = null;
- // do not alter original method array until resolution is over, due
to reentrance (143259)
- if (resolvedMethods == this.methods) {
- System.arraycopy(this.methods, 0, resolvedMethods = new
MethodBinding[length], 0, length);
- }
- resolvedMethods[i] = null;
- failed++;
- }
- }
- AbstractMethodDeclaration method2Decl = method2.sourceMethod();
- if (method2Decl != null && method2Decl.binding != null) { // ensure
its a valid user defined method
- if (isEnumSpecialMethod) {
- this.scope.problemReporter().duplicateEnumSpecialMethod(this,
method2Decl);
- } else {
- this.scope.problemReporter().duplicateMethodInType(this,
method2Decl, method.areParametersEqual(method2));
- }
- method2Decl.binding = null;
- // do not alter original method array until resolution is over, due
to reentrance (143259)
- if (resolvedMethods == this.methods) {
- System.arraycopy(this.methods, 0, resolvedMethods = new
MethodBinding[length], 0, length);
- }
- resolvedMethods[j] = null;
- failed++;
- }
- }
- if (method.returnType == null && methodDecl == null) { // forget method
with invalid return type... was kept to detect possible collisions
- methodDecl = method.sourceMethod();
- if (methodDecl != null) {
- methodDecl.binding = null;
- }
- // do not alter original method array until resolution is over, due to
reentrance (143259)
- if (resolvedMethods == this.methods) {
- System.arraycopy(this.methods, 0, resolvedMethods = new
MethodBinding[length], 0, length);
- }
- resolvedMethods[i] = null;
- failed++;
- }
- }
- } finally {
- if (failed > 0) {
- int newSize = resolvedMethods.length - failed;
- if (newSize == 0) {
- this.methods = Binding.NO_METHODS;
- } else {
- MethodBinding[] newMethods = new MethodBinding[newSize];
- for (int i = 0, j = 0, length = resolvedMethods.length; i < length;
i++)
- if (resolvedMethods[i] != null)
- newMethods[j++] = resolvedMethods[i];
- this.methods = newMethods;
- }
- }
-
- // handle forward references to potential default abstract methods
- addDefaultAbstractMethods();
- this.tagBits |= TagBits.AreMethodsComplete;
- }
- return this.methods;
-}
-public FieldBinding resolveTypeFor(FieldBinding field) {
- if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
- return field;
-
- if (this.scope.compilerOptions().sourceLevel >=
ClassFileConstants.JDK1_5) {
- if ((field.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
- field.modifiers |= ClassFileConstants.AccDeprecated;
- }
- if (isViewedAsDeprecated() && !field.isDeprecated())
- field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
- if (hasRestrictedAccess())
- field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
- FieldDeclaration[] fieldDecls = this.scope.referenceContext.fields;
- for (int f = 0, length = fieldDecls.length; f < length; f++) {
- if (fieldDecls[f].binding != field)
- continue;
-
- MethodScope initializationScope = field.isStatic()
- ? this.scope.referenceContext.staticInitializerScope
- : this.scope.referenceContext.initializerScope;
- FieldBinding previousField = initializationScope.initializedField;
- try {
- initializationScope.initializedField = field;
- FieldDeclaration fieldDecl = fieldDecls[f];
- TypeBinding fieldType =
- fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT
- ? initializationScope.environment().convertToRawType(this, false
/*do not force conversion of enclosing types*/) // enum constant is
implicitly of declaring enum type
- : fieldDecl.type.resolveType(initializationScope, true /* check
bounds*/);
- field.type = fieldType;
- field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
- if (fieldType == null) {
- fieldDecl.binding = null;
- return null;
- }
- if (fieldType == TypeBinding.VOID) {
- this.scope.problemReporter().variableTypeCannotBeVoid(fieldDecl);
- fieldDecl.binding = null;
- return null;
- }
- if (fieldType.isArrayType() && ((ArrayBinding)
fieldType).leafComponentType == TypeBinding.VOID) {
- this.scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecl);
- fieldDecl.binding = null;
- return null;
- }
- if ((fieldType.tagBits & TagBits.HasMissingType) != 0) {
- field.tagBits |= TagBits.HasMissingType;
- }
- TypeBinding leafType = fieldType.leafComponentType();
- if (leafType instanceof ReferenceBinding &&
(((ReferenceBinding)leafType).modifiers &
ExtraCompilerModifiers.AccGenericSignature) != 0) {
- field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
- }
- } finally {
- initializationScope.initializedField = previousField;
- }
- return field;
- }
- return null; // should never reach this point
-}
-public MethodBinding resolveTypesFor(MethodBinding method) {
- if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
- return method;
-
- if (this.scope.compilerOptions().sourceLevel >=
ClassFileConstants.JDK1_5) {
- if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
- method.modifiers |= ClassFileConstants.AccDeprecated;
- }
- if (isViewedAsDeprecated() && !method.isDeprecated())
- method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
- if (hasRestrictedAccess())
- method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
-
- AbstractMethodDeclaration methodDecl = method.sourceMethod();
- if (methodDecl == null) return null; // method could not be resolved in
previous iteration
-
- TypeParameter[] typeParameters = methodDecl.typeParameters();
- if (typeParameters != null) {
- methodDecl.scope.connectTypeVariables(typeParameters, true);
- // Perform deferred bound checks for type variables (only done after
type variable hierarchy is connected)
- for (int i = 0, paramLength = typeParameters.length; i < paramLength;
i++)
- typeParameters[i].checkBounds(methodDecl.scope);
- }
- TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
- if (exceptionTypes != null) {
- int size = exceptionTypes.length;
- method.thrownExceptions = new ReferenceBinding[size];
- int count = 0;
- ReferenceBinding resolvedExceptionType;
- for (int i = 0; i < size; i++) {
- resolvedExceptionType = (ReferenceBinding)
exceptionTypes[i].resolveType(methodDecl.scope, true /* check bounds*/);
- if (resolvedExceptionType == null)
- continue;
- if (resolvedExceptionType.isBoundParameterizedType()) {
-
methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType,
exceptionTypes[i]);
- continue;
- }
- if
(resolvedExceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable,
true) == null) {
- if (resolvedExceptionType.isValidBinding()) {
- methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i],
resolvedExceptionType);
- continue;
- }
- }
- if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) {
- method.tagBits |= TagBits.HasMissingType;
- }
- method.modifiers |= (resolvedExceptionType.modifiers &
ExtraCompilerModifiers.AccGenericSignature);
- method.thrownExceptions[count++] = resolvedExceptionType;
- }
- if (count < size)
- System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions =
new ReferenceBinding[count], 0, count);
- }
-
- boolean foundArgProblem = false;
- Argument[] arguments = methodDecl.arguments;
- if (arguments != null) {
- int size = arguments.length;
- method.parameters = Binding.NO_PARAMETERS;
- TypeBinding[] newParameters = new TypeBinding[size];
- for (int i = 0; i < size; i++) {
- Argument arg = arguments[i];
- if (arg.annotations != null) {
- method.tagBits |= TagBits.HasParameterAnnotations;
- }
- TypeBinding parameterType = arg.type.resolveType(methodDecl.scope, true
/* check bounds*/);
- if (parameterType == null) {
- foundArgProblem = true;
- } else if (parameterType == TypeBinding.VOID) {
- methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(this,
methodDecl, arg);
- foundArgProblem = true;
- } else {
- if ((parameterType.tagBits & TagBits.HasMissingType) != 0) {
- method.tagBits |= TagBits.HasMissingType;
- }
- TypeBinding leafType = parameterType.leafComponentType();
- if (leafType instanceof ReferenceBinding && (((ReferenceBinding)
leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
- method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
- newParameters[i] = parameterType;
- arg.binding = new LocalVariableBinding(arg, parameterType,
arg.modifiers, true);
- }
- }
- // only assign parameters if no problems are found
- if (!foundArgProblem) {
- method.parameters = newParameters;
- }
- }
-
- boolean foundReturnTypeProblem = false;
- if (!method.isConstructor()) {
- TypeReference returnType = methodDecl instanceof MethodDeclaration
- ? ((MethodDeclaration) methodDecl).returnType
- : null;
- if (returnType == null) {
- methodDecl.scope.problemReporter().missingReturnType(methodDecl);
- method.returnType = null;
- foundReturnTypeProblem = true;
- } else {
- TypeBinding methodType = returnType.resolveType(methodDecl.scope, true
/* check bounds*/);
- if (methodType == null) {
- foundReturnTypeProblem = true;
- } else if (methodType.isArrayType() && ((ArrayBinding)
methodType).leafComponentType == TypeBinding.VOID) {
-
methodDecl.scope.problemReporter().returnTypeCannotBeVoidArray((MethodDeclaration)
methodDecl);
- foundReturnTypeProblem = true;
- } else {
- if ((methodType.tagBits & TagBits.HasMissingType) != 0) {
- method.tagBits |= TagBits.HasMissingType;
- }
- method.returnType = methodType;
- TypeBinding leafType = methodType.leafComponentType();
- if (leafType instanceof ReferenceBinding && (((ReferenceBinding)
leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
- method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
- }
- }
- }
- if (foundArgProblem) {
- methodDecl.binding = null;
- method.parameters = Binding.NO_PARAMETERS; // see 107004
- // nullify type parameter bindings as well as they have a backpointer to
the method binding
- // (see
https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134)
- if (typeParameters != null)
- for (int i = 0, length = typeParameters.length; i < length; i++)
- typeParameters[i].binding = null;
- return null;
- }
- if (foundReturnTypeProblem)
- return method; // but its still unresolved with a null return type & is
still connected to its method declaration
-
- method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
- return method;
-}
-public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean
forceInitialization) {
- if (forceInitialization)
- binding.getAnnotationTagBits(); // ensure annotations are up to date
- return super.retrieveAnnotationHolder(binding, false);
-}
-public void setFields(FieldBinding[] fields) {
- this.fields = fields;
-}
-public void setMethods(MethodBinding[] methods) {
- this.methods = methods;
-}
-public final int sourceEnd() {
- return this.scope.referenceContext.sourceEnd;
-}
-public final int sourceStart() {
- return this.scope.referenceContext.sourceStart;
-}
-SimpleLookupTable storedAnnotations(boolean forceInitialize) {
- if (forceInitialize && this.storedAnnotations == null && this.scope !=
null) { // scope null when no annotation cached, and type got processed
fully (159631)
- this.scope.referenceCompilationUnit().compilationResult.hasAnnotations =
true;
- if (!this.scope.environment().globalOptions.storeAnnotations)
- return null; // not supported during this compile
- this.storedAnnotations = new SimpleLookupTable(3);
- }
- return this.storedAnnotations;
-}
-public ReferenceBinding superclass() {
- return this.superclass;
-}
-public ReferenceBinding[] superInterfaces() {
- return this.superInterfaces;
-}
-// TODO (philippe) could be a performance issue since some senders are
building the list just to count them
-public SyntheticMethodBinding[] syntheticMethods() {
-
- if (this.synthetics == null ||
this.synthetics[SourceTypeBinding.METHOD_EMUL] == null ||
this.synthetics[SourceTypeBinding.METHOD_EMUL].size() == 0) return null;
-
- // difficult to compute size up front because of the embedded arrays so
assume there is only 1
- int index = 0;
- SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1];
- Iterator fieldsOrMethods =
this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator();
- while (fieldsOrMethods.hasNext()) {
-
- Object fieldOrMethod = fieldsOrMethods.next();
-
- if (fieldOrMethod instanceof MethodBinding) {
-
- SyntheticMethodBinding[] methodAccessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(fieldOrMethod);
- int numberOfAccessors = 0;
- if (methodAccessors[0] != null) numberOfAccessors++;
- if (methodAccessors[1] != null) numberOfAccessors++;
- if (index + numberOfAccessors > bindings.length)
- System.arraycopy(bindings, 0, (bindings = new
SyntheticMethodBinding[index + numberOfAccessors]), 0, index);
- if (methodAccessors[0] != null)
- bindings[index++] = methodAccessors[0]; // super access
- if (methodAccessors[1] != null)
- bindings[index++] = methodAccessors[1]; // normal access or bridge
-
- } else {
-
- SyntheticMethodBinding[] fieldAccessors = (SyntheticMethodBinding[])
this.synthetics[SourceTypeBinding.METHOD_EMUL].get(fieldOrMethod);
- int numberOfAccessors = 0;
- if (fieldAccessors[0] != null) numberOfAccessors++;
- if (fieldAccessors[1] != null) numberOfAccessors++;
- if (index + numberOfAccessors > bindings.length)
- System.arraycopy(bindings, 0, (bindings = new
SyntheticMethodBinding[index + numberOfAccessors]), 0, index);
- if (fieldAccessors[0] != null)
- bindings[index++] = fieldAccessors[0]; // read access
- if (fieldAccessors[1] != null)
- bindings[index++] = fieldAccessors[1]; // write access
- }
- }
-
- // sort them in according to their own indexes
- int length;
- SyntheticMethodBinding[] sortedBindings = new
SyntheticMethodBinding[length = bindings.length];
- for (int i = 0; i < length; i++){
- SyntheticMethodBinding binding = bindings[i];
- sortedBindings[binding.index] = binding;
- }
- return sortedBindings;
-}
-/**
- * Answer the collection of synthetic fields to append into the classfile
- */
-public FieldBinding[] syntheticFields() {
-
- if (this.synthetics == null) return null;
-
- int fieldSize = this.synthetics[SourceTypeBinding.FIELD_EMUL] == null ?
0 : this.synthetics[SourceTypeBinding.FIELD_EMUL].size();
- int literalSize = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL]
== null ? 0 :this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size();
- int totalSize = fieldSize + literalSize;
- if (totalSize == 0) return null;
- FieldBinding[] bindings = new FieldBinding[totalSize];
-
- // add innerclass synthetics
- if (this.synthetics[SourceTypeBinding.FIELD_EMUL] != null){
- Iterator elements =
this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator();
- for (int i = 0; i < fieldSize; i++) {
- SyntheticFieldBinding synthBinding = (SyntheticFieldBinding)
elements.next();
- bindings[synthBinding.index] = synthBinding;
- }
- }
- // add class literal synthetics
- if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] != null){
- Iterator elements =
this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].values().iterator();
- for (int i = 0; i < literalSize; i++) {
- SyntheticFieldBinding synthBinding = (SyntheticFieldBinding)
elements.next();
- bindings[fieldSize+synthBinding.index] = synthBinding;
- }
- }
- return bindings;
-}
-public String toString() {
- StringBuffer buffer = new StringBuffer(30);
- buffer.append("(id="); //$NON-NLS-1$
- if (
this.id == TypeIds.NoId)
- buffer.append("NoId"); //$NON-NLS-1$
- else
- buffer.append(
this.id);
- buffer.append(")\n"); //$NON-NLS-1$
- if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
- if (isPublic()) buffer.append("public "); //$NON-NLS-1$
- if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
- if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
- if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
- if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
- if (isFinal()) buffer.append("final "); //$NON-NLS-1$
-
- if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
- else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
- else if (isClass()) buffer.append("class "); //$NON-NLS-1$
- else buffer.append("interface "); //$NON-NLS-1$
- buffer.append((this.compoundName != null) ?
CharOperation.toString(this.compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
-
- if (this.typeVariables == null) {
- buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
- } else if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
- buffer.append("<"); //$NON-NLS-1$
- for (int i = 0, length = this.typeVariables.length; i < length; i++) {
- if (i > 0) buffer.append(", "); //$NON-NLS-1$
- if (this.typeVariables[i] == null) {
- buffer.append("NULL TYPE VARIABLE"); //$NON-NLS-1$
- continue;
- }
- char[] varChars = this.typeVariables[i].toString().toCharArray();
- buffer.append(varChars, 1, varChars.length - 2);
- }
- buffer.append(">"); //$NON-NLS-1$
- }
- buffer.append("\n\textends "); //$NON-NLS-1$
- buffer.append((this.superclass != null) ?
this.superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
-
- if (this.superInterfaces != null) {
- if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
- buffer.append("\n\timplements : "); //$NON-NLS-1$
- for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
- if (i > 0)
- buffer.append(", "); //$NON-NLS-1$
- buffer.append((this.superInterfaces[i] != null) ?
this.superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
- }
- }
- } else {
- buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
- }
-
- if (enclosingType() != null) {
- buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
- buffer.append(enclosingType().debugName());
- }
-
- if (this.fields != null) {
- if (this.fields != Binding.NO_FIELDS) {
- buffer.append("\n/* fields */"); //$NON-NLS-1$
- for (int i = 0, length = this.fields.length; i < length; i++)
- buffer.append('\n').append((this.fields[i] != null) ?
this.fields[i].toString() : "NULL FIELD"); //$NON-NLS-1$
- }
- } else {
- buffer.append("NULL FIELDS"); //$NON-NLS-1$
- }
-
- if (this.methods != null) {
- if (this.methods != Binding.NO_METHODS) {
- buffer.append("\n/* methods */"); //$NON-NLS-1$
- for (int i = 0, length = this.methods.length; i < length; i++)
- buffer.append('\n').append((this.methods[i] != null) ?
this.methods[i].toString() : "NULL METHOD"); //$NON-NLS-1$
- }
- } else {
- buffer.append("NULL METHODS"); //$NON-NLS-1$
- }
-
- if (this.memberTypes != null) {
- if (this.memberTypes != Binding.NO_MEMBER_TYPES) {
- buffer.append("\n/* members */"); //$NON-NLS-1$
- for (int i = 0, length = this.memberTypes.length; i < length; i++)
- buffer.append('\n').append((this.memberTypes[i] != null) ?
this.memberTypes[i].toString() : "NULL TYPE"); //$NON-NLS-1$
- }
- } else {
- buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
- }
-
- buffer.append("\n\n"); //$NON-NLS-1$
- return buffer.toString();
-}
-public TypeVariableBinding[] typeVariables() {
- return this.typeVariables;
-}
-void verifyMethods(MethodVerifier verifier) {
- verifier.verify(this);
-
- for (int i = this.memberTypes.length; --i >= 0;)
- ((SourceTypeBinding) this.memberTypes[i]).verifyMethods(verifier);
-}
-}
diff --git a/dev/core/test/com/google/gwt/dev/CompilerTest.java
b/dev/core/test/com/google/gwt/dev/CompilerTest.java
index 2c47e86..cbb341e 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", "-source", "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, "-source", "ssss");
+ assertProcessFailure(argProcessor, "-source", "1.5");
}
}
diff --git
a/dev/core/test/com/google/gwt/dev/javac/BinaryTypeReferenceRestrictionsCheckerTest.java
b/dev/core/test/com/google/gwt/dev/javac/BinaryTypeReferenceRestrictionsCheckerTest.java
index a9d037d..3c4319a 100644
---
a/dev/core/test/com/google/gwt/dev/javac/BinaryTypeReferenceRestrictionsCheckerTest.java
+++
b/dev/core/test/com/google/gwt/dev/javac/BinaryTypeReferenceRestrictionsCheckerTest.java
@@ -64,6 +64,10 @@
return null;
}
+ public char[] getEnclosingMethod() {
+ return null;
+ }
+
public char[] getEnclosingTypeName() {
return null;
}
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..4f45c7f 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.defaultSourceLevel);
} 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 59841f5..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()));
}
}
@@ -167,6 +167,10 @@
return
Shared.getShortName(Shared.getTypeName(sourceFile)).toCharArray();
}
+ public boolean ignoreOptionalProblems() {
+ return false;
+ }
+
public char[][] getPackageName() {
return CharOperation.splitOn('.', Shared.getPackageName(
Shared.getTypeName(sourceFile)).toCharArray());
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..c21f2f2
--- /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..a7d33cb 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 compativility option.
+ */
+ protected SourceLevel sourceLevel = OptionSource.defaultSourceLevel;
}
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..85321f8
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/Java7AstTest.java
@@ -0,0 +1,329 @@
+/*
+ * 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.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.CompilationUnit;
+import com.google.gwt.dev.javac.CompilationUnitBuilder;
+import com.google.gwt.dev.javac.JdtCompiler;
+import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
+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.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;
+
+/**
+ * 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();
+ }
+
+}
\ No newline at end of file
diff --git a/eclipse/dev/.classpath b/eclipse/dev/.classpath
index 4b1f5b4..5af023d 100644
--- a/eclipse/dev/.classpath
+++ b/eclipse/dev/.classpath
@@ -6,7 +6,8 @@
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/apache/ant-1.6.5.jar"
sourcepath="/GWT_TOOLS/lib/apache/ant-1.6.5-src.zip"/>
<classpathentry kind="var"
path="GWT_TOOLS/lib/apache/tapestry-util-text-4.0.2.jar"
sourcepath="/GWT_TOOLS/lib/apache/tapestry-util-text-4.0.2-src.zip"/>
- <classpathentry kind="var"
path="GWT_TOOLS/lib/eclipse/jdt-3.4.2_r894.jar"
sourcepath="/GWT_TOOLS/lib/eclipse/jdt-3.4.2_r894-src.zip"/>
+ <classpathentry kind="var"
path="GWT_TOOLS/lib/eclipse/org.eclipse.jdt.core_3.8.3.v20130121-145325.jar"
sourcepath="/GWT_TOOLS/lib/eclipse/org.eclipse.jdt.core.source_3.8.3.v20130121-145325.jar"/>
+ <classpathentry kind="var"
path="GWT_TOOLS/lib/eclipse/jdtCompilerAdapter-3.8.3.v20130121-145325.jar"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/jetty/jetty-6.1.11.jar"
sourcepath="/GWT_TOOLS/lib/jetty/jetty-6.1.11-src.zip"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/junit/junit-4.8.2.jar"
sourcepath="/GWT_TOOLS/lib/junit/junit-4.8.2-src.zip"/>
<classpathentry kind="var"
path="GWT_TOOLS/lib/tomcat/ant-launcher-1.6.5.jar"/>
diff --git a/eclipse/dev/compiler/.classpath
b/eclipse/dev/compiler/.classpath
index c4d43a0..a951438 100644
--- a/eclipse/dev/compiler/.classpath
+++ b/eclipse/dev/compiler/.classpath
@@ -4,7 +4,8 @@
<classpathentry excluding="com/google/gwt/dev/jjs/intrinsic/" kind="src"
path="core/super"/>
<classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/apache/ant-1.6.5.jar"
sourcepath="/GWT_TOOLS/lib/apache/ant-1.6.5-src.zip"/>
- <classpathentry kind="var"
path="GWT_TOOLS/lib/eclipse/jdt-3.4.2_r894.jar"
sourcepath="/GWT_TOOLS/lib/eclipse/jdt-3.4.2_r894-src.zip"/>
+ <classpathentry kind="var"
path="GWT_TOOLS/lib/eclipse/org.eclipse.jdt.core_3.8.3.v20130121-145325.jar"
sourcepath="/GWT_TOOLS/lib/eclipse/org.eclipse.jdt.core.source_3.8.3.v20130121-145325.jar"/>
+ <classpathentry kind="var"
path="GWT_TOOLS/lib/eclipse/jdtCompilerAdapter-3.8.3.v20130121-145325.jar"/>
<classpathentry kind="var" path="GWT_TOOLS/lib/junit/junit-4.8.2.jar"
sourcepath="/GWT_TOOLS/lib/junit/junit-4.8.2-src.zip"/>
<classpathentry kind="var"
path="GWT_TOOLS/lib/tomcat/commons-collections-3.1.jar"
sourcepath="/GWT_TOOLS/lib/tomcat/commons-collections-3.1-src.zip"/>
<classpathentry kind="var"
path="GWT_TOOLS/lib/guava/guava-10.0.1/guava-10.0.1-rebased.jar"/>
diff --git a/user/src/com/google/gwt/core/shared/SerializableThrowable.java
b/user/src/com/google/gwt/core/shared/SerializableThrowable.java
index a44fb04..2aa0be0 100644
--- a/user/src/com/google/gwt/core/shared/SerializableThrowable.java
+++ b/user/src/com/google/gwt/core/shared/SerializableThrowable.java
@@ -21,6 +21,9 @@
* 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.
+ *
+ * NOTE: Does not serialize suppressed exceptions to remain compatible
with Java 6.
+ *
* <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
@@ -121,6 +124,11 @@
SerializableThrowable throwable = new SerializableThrowable(null,
t.getMessage());
throwable.setStackTrace(t.getStackTrace());
throwable.initCause(t.getCause());
+ // TODO(rluble): Once we require Java 7 uncomment the following 3
lines.
+ // for (Throwable suppressedException : t.getSuppressed()) {
+ // throwable.addSuppressed(fromThrowable(suppressedException));
+ // }
+
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..77ec8cb
--- /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>cose()</code> and can be used
in the try-with-resources
+ * statetment.
+ */
+public interface AutoCloseable {
+
+ /**
+ * Closes this resource.
+ * @throws Exception
+ */
+ void close() throws Exception;
+}
diff --git a/user/super/com/google/gwt/emul/java/lang/Enum.java
b/user/super/com/google/gwt/emul/java/lang/Enum.java
index 89bf69d..2f7df89 100644
--- a/user/super/com/google/gwt/emul/java/lang/Enum.java
+++ b/user/super/com/google/gwt/emul/java/lang/Enum.java
@@ -85,7 +85,7 @@
// if (this.getDeclaringClass() != other.getDeclaringClass()) {
// throw new ClassCastException();
// }
- return this.ordinal - other.ordinal;
+ return this.ordinal - ((Enum) other).ordinal;
}
@Override
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..deed644 100644
--- a/user/super/com/google/gwt/emul/java/lang/Throwable.java
+++ b/user/super/com/google/gwt/emul/java/lang/Throwable.java
@@ -19,6 +19,8 @@
import java.io.PrintStream;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
/**
* See <a
@@ -40,6 +42,7 @@
*/
private transient Throwable cause;
private String detailMessage;
+ private transient List<Throwable> suppressed;
private transient StackTraceElement[] stackTrace;
{
@@ -61,6 +64,13 @@
public Throwable(Throwable cause) {
this.detailMessage = (cause == null) ? null : cause.toString();
this.cause = cause;
+ }
+
+ public final void addSuppressed(Throwable exception) {
+ if (suppressed == null) {
+ suppressed = new ArrayList<Throwable>(1);
+ }
+ suppressed.add(exception);
}
/**
@@ -97,6 +107,13 @@
return stackTrace;
}
+ public final Throwable[] getSuppressed() {
+ if (suppressed == null) {
+ suppressed = new ArrayList<Throwable>(1);
+ }
+ return suppressed.toArray(new Throwable[suppressed.size()]);
+ }
+
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..5c542a5
--- /dev/null
+++
b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java7Test.java
@@ -0,0 +1,282 @@
+/*
+ * 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
+ int million = 1_000_000;
+
+ int five = 0b101;
+
+
+ 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);
+ }
+
+ 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..80d10bd
--- /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() {
+ }
+}
--
To view, visit
https://gwt-review.googlesource.com/2650
To unsubscribe, visit
https://gwt-review.googlesource.com/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I91c1f39ff20a2e7ac131d647bf4c96e34ce47a70
Gerrit-PatchSet: 1
Gerrit-Project: gwt
Gerrit-Branch: master
Gerrit-Owner: Roberto Lublinerman <
rlu...@google.com>