Ensures EntryMethods are traversed first.
Previously GWT happened to process GWT.create() calls in EntryMethods,
before GWT.create() calls in other places. This was never promised
behavior but some apps now depend on it.
This change ensures that this behavior is honored even within the new
incremental compile path.
Change-Id: Id36e91fa455fd95394a6a02ab0356de7053890a6
Review-Link: https://gwt-review.googlesource.com/#/c/10410/
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 6b9497a..40dfd46 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -852,7 +852,7 @@
private Map<JsName, JsLiteral> runObfuscateNamer(PermProps props) throws IllegalNameException {
Map<JsName, JsLiteral> internedLiteralByVariableName =
JsLiteralInterner.exec(jprogram, jsProgram, (byte) (JsLiteralInterner.INTERN_ALL
- & (byte) (jprogram.typeOracle.isInteropEnabled()
+ & (byte) (jprogram.typeOracle.isJsInteropEnabled()
? ~JsLiteralInterner.INTERN_STRINGS : ~0)));
FreshNameGenerator freshNameGenerator = JsObfuscateNamer.exec(jsProgram,
props.getConfigProps());
@@ -1153,7 +1153,7 @@
allRootTypes.add(typeOracle.getSingleJsoImpl(singleJsoIntf).getQualifiedSourceName());
}
- if (jprogram.typeOracle.isInteropEnabled()) {
+ if (jprogram.typeOracle.isJsInteropEnabled()) {
// find any types with @JsExport could be entry points as well
nextType:
for (com.google.gwt.dev.javac.typemodel.JClassType type :
diff --git a/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java
index 3a5295e..acf70ab 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java
@@ -162,7 +162,7 @@
// Only perform the interning optimization when optimizations are enabled.
internedTextByVariableName =
JsLiteralInterner.exec(jprogram, jsProgram, (byte) (JsLiteralInterner.INTERN_ALL
- & (byte) (jprogram.typeOracle.isInteropEnabled()
+ & (byte) (jprogram.typeOracle.isJsInteropEnabled()
? ~JsLiteralInterner.INTERN_STRINGS : ~0)));
}
JsVerboseNamer.exec(jsProgram, config);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index f38950a..35a20a2 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -58,7 +58,7 @@
* Returns whether a class is a synthetic Prototype class generated by APT or user.
*/
public boolean isJsTypePrototype(JDeclaredType classType) {
- return typeOracle.isInteropEnabled() && classType instanceof JClassType
+ return typeOracle.isJsInteropEnabled() && classType instanceof JClassType
&& ((JClassType) classType).isJsPrototypeStub();
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
index a1f049c..1629395 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
@@ -165,7 +165,7 @@
* 3) the method returns or accepts JsAware/JsConvert types.
*/
public boolean needsJsInteropBridgeMethod(JMethod x) {
- if (!isInteropEnabled()) {
+ if (!isJsInteropEnabled()) {
return false;
}
@@ -255,14 +255,14 @@
}
public boolean isExportedField(JField field) {
- return isInteropEnabled() && field.getExportName() != null;
+ return isJsInteropEnabled() && field.getExportName() != null;
}
public boolean isExportedMethod(JMethod method) {
- return isInteropEnabled() && method.getExportName() != null && !method.isNoExport();
+ return isJsInteropEnabled() && method.getExportName() != null && !method.isNoExport();
}
- public boolean isInteropEnabled() {
+ public boolean isJsInteropEnabled() {
return jsInteropMode != OptionJsInteropMode.Mode.NONE;
}
@@ -852,7 +852,7 @@
* Get the nearest JS type.
*/
public JDeclaredType getNearestJsType(JType type, boolean mustHavePrototype) {
- if (!isInteropEnabled()) {
+ if (!isJsInteropEnabled()) {
return null;
}
@@ -1094,7 +1094,7 @@
}
public boolean isJsTypeMethod(JMethod x) {
- if (!isInteropEnabled()) {
+ if (!isJsInteropEnabled()) {
return false;
}
@@ -1121,7 +1121,7 @@
* Whether the type is a JS interface (does not check supertypes).
*/
public boolean isJsType(JType type) {
- return isInteropEnabled()
+ return isJsInteropEnabled()
&& (type instanceof JDeclaredType && ((JDeclaredType) type).isJsType());
}
@@ -1130,7 +1130,7 @@
* one of the types has a js prototype.
*/
public boolean isOrExtendsJsType(JType type, boolean mustHavePrototype) {
- if (isInteropEnabled()) {
+ if (isJsInteropEnabled()) {
JDeclaredType dtype = getNearestJsType(type, mustHavePrototype);
return dtype != null;
} else {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 016e301..1dd41e8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -937,7 +937,7 @@
globalStmts.add(vars);
}
- if (typeOracle.isInteropEnabled() &&
+ if (typeOracle.isJsInteropEnabled() &&
typeOracle.isInstantiatedType(x) && !typeOracle.isJavaScriptObject(x) &&
x != program.getTypeJavaLangString()) {
// done after class setup because exports may rely on static vars
@@ -1190,7 +1190,7 @@
globalStmts.add(vars);
}
- if (typeOracle.isInteropEnabled()) {
+ if (typeOracle.isJsInteropEnabled()) {
generateExports(x, exportStmts);
}
}
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 9aef5c6..f68ca3e 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
@@ -708,11 +708,14 @@
private MinimalRebuildCache minimalRebuildCache;
private boolean incrementalCompile;
private boolean isLibraryCompile;
+ private boolean jsInteropEnabled;
+ private final List<String> rootTypeSourceNames = new ArrayList<String>();
public UnifyAst(TreeLogger logger, CompilerContext compilerContext, JProgram program,
JsProgram jsProgram, RebindPermutationOracle rpo) {
this.incrementalCompile = compilerContext.getOptions().isIncrementalCompileEnabled();
this.isLibraryCompile = !compilerContext.shouldCompileMonolithic();
+ this.jsInteropEnabled = program.typeOracle.isJsInteropEnabled();
this.logger = logger;
this.compilerContext = compilerContext;
@@ -731,28 +734,9 @@
}
}
- public void addRootTypes(Collection<String> sourceTypeNames) throws UnableToCompleteException {
- List<String> binaryTypeNames = new ArrayList<String>();
- for (String sourceTypeName : sourceTypeNames) {
- JDeclaredType type =
- internalFindType(sourceTypeName, sourceNameBasedTypeLocator, true);
- binaryTypeNames.add(type.getName());
- if (type != null && program.typeOracle.isInteropEnabled() &&
- (isJsType(type) || hasAnyExports(type))) {
- instantiate(type);
- for (JField field : type.getFields()) {
- flowInto(field);
- }
- for (JMethod method : type.getMethods()) {
- flowInto(method);
- }
- }
- }
- minimalRebuildCache.setRootTypeNames(binaryTypeNames);
- if (errorsFound) {
- // Already logged.
- throw new UnableToCompleteException();
- }
+ public void addRootTypes(Collection<String> rootTypeSourceNames) {
+ assert this.rootTypeSourceNames.isEmpty();
+ this.rootTypeSourceNames.addAll(rootTypeSourceNames);
}
/**
@@ -766,13 +750,7 @@
}
for (JDeclaredType type : program.getDeclaredTypes()) {
- instantiate(type);
- for (JField field : type.getFields()) {
- flowInto(field);
- }
- for (JMethod method : type.getMethods()) {
- flowInto(method);
- }
+ fullFlowIntoType(type);
}
mainLoop();
@@ -798,6 +776,22 @@
flowInto(entryMethod);
}
+ // Ensure that root types are loaded and possibly (depending on mode) traversed.
+ List<String> rootTypeBinaryNames = new ArrayList<String>();
+ for (String rootTypeSourceName : rootTypeSourceNames) {
+ JDeclaredType rootType =
+ internalFindType(rootTypeSourceName, sourceNameBasedTypeLocator, true);
+ if (rootType == null) {
+ continue;
+ }
+
+ rootTypeBinaryNames.add(rootType.getName());
+ if (jsInteropEnabled && (isJsType(rootType) || hasAnyExports(rootType))) {
+ fullFlowIntoType(rootType);
+ }
+ }
+ minimalRebuildCache.setRootTypeNames(rootTypeBinaryNames);
+
// Some fields and methods in codegen types might only become referenced as the result of
// visitor execution after unification. Since we don't want those fields are methods to be
// prematurely pruned here we defensively trace them now.
@@ -826,13 +820,7 @@
continue;
}
- instantiate(type);
- for (JField field : type.getFields()) {
- flowInto(field);
- }
- for (JMethod method : type.getMethods()) {
- flowInto(method);
- }
+ fullFlowIntoType(type);
}
}
@@ -1041,7 +1029,7 @@
}
private boolean hasAnyExports(JDeclaredType t) {
- if (!program.typeOracle.isInteropEnabled()) {
+ if (!jsInteropEnabled) {
return false;
}
@@ -1182,11 +1170,11 @@
// The traversal of this type will accumulate rebinder type to rebound type associations, but
// the accumulation should start from scratch, so clear any existing associations that might
// have been collected in previous compiles.
- minimalRebuildCache.clearRebinderTypeAssociations(type.getName());
- fullFlowTypes.add(type.getName());
+ minimalRebuildCache.clearRebinderTypeAssociations(typeName);
+ fullFlowTypes.add(typeName);
// Remove the type from the remaining stale types set so that the fullFlowIntoStaleTypes()
// attempt is shorter.
- processedStaleTypeNames.add(type.getName());
+ processedStaleTypeNames.add(typeName);
instantiate(type);
for (JField field : type.getFields()) {
flowInto(field);
@@ -1484,7 +1472,7 @@
}
private boolean isJsType(JDeclaredType intf) {
- if (!program.typeOracle.isInteropEnabled()) {
+ if (!jsInteropEnabled) {
return false;
}