8026936: Initialize LamdbaToMethod lazily and as required
Reviewed-by: jjg, rfield
Contributed-by: jan.lahoda@oracle.com
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Oct 23 07:50:04 2013 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Oct 23 15:45:18 2013 -0700
@@ -271,10 +271,6 @@
*/
protected TransTypes transTypes;
- /** The lambda translator.
- */
- protected LambdaToMethod lambdaToMethod;
-
/** The syntactic sugar desweetener.
*/
protected Lower lower;
@@ -388,8 +384,6 @@
options = Options.instance(context);
- lambdaToMethod = LambdaToMethod.instance(context);
-
verbose = options.isSet(VERBOSE);
sourceOutput = options.isSet(PRINTSOURCE); // used to be -s
stubOutput = options.isSet("-stubs");
@@ -1393,6 +1387,7 @@
*/
class ScanNested extends TreeScanner {
Set<Env<AttrContext>> dependencies = new LinkedHashSet<Env<AttrContext>>();
+ protected boolean hasLambdas;
@Override
public void visitClassDef(JCClassDecl node) {
Type st = types.supertype(node.sym.type);
@@ -1402,7 +1397,18 @@
Env<AttrContext> stEnv = enter.getEnv(c);
if (stEnv != null && env != stEnv) {
if (dependencies.add(stEnv)) {
- scan(stEnv.tree);
+ boolean prevHasLambdas = hasLambdas;
+ try {
+ scan(stEnv.tree);
+ } finally {
+ /*
+ * ignore any updates to hasLambdas made during
+ * the nested scan, this ensures an initalized
+ * LambdaToMethod is available only to those
+ * classes that contain lambdas
+ */
+ hasLambdas = prevHasLambdas;
+ }
}
envForSuperTypeFound = true;
}
@@ -1410,6 +1416,16 @@
}
super.visitClassDef(node);
}
+ @Override
+ public void visitLambda(JCLambda tree) {
+ hasLambdas = true;
+ super.visitLambda(tree);
+ }
+ @Override
+ public void visitReference(JCMemberReference tree) {
+ hasLambdas = true;
+ super.visitReference(tree);
+ }
}
ScanNested scanner = new ScanNested();
scanner.scan(env.tree);
@@ -1468,11 +1484,11 @@
env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
compileStates.put(env, CompileState.TRANSTYPES);
- if (source.allowLambda()) {
+ if (source.allowLambda() && scanner.hasLambdas) {
if (shouldStop(CompileState.UNLAMBDA))
return;
- env.tree = lambdaToMethod.translateTopLevelClass(env, env.tree, localMake);
+ env.tree = LambdaToMethod.instance(context).translateTopLevelClass(env, env.tree, localMake);
compileStates.put(env, CompileState.UNLAMBDA);
}