Merge

Wed, 08 May 2013 10:27:52 +0100

author
chegar
date
Wed, 08 May 2013 10:27:52 +0100
changeset 1830
8074ccd57d89
parent 1828
27cda5134748
parent 1718
ec434cfd2752
child 1831
9d7d36e6927c

Merge

     1.1 --- a/.hgtags	Sun Apr 28 08:16:41 2013 +0100
     1.2 +++ b/.hgtags	Wed May 08 10:27:52 2013 +0100
     1.3 @@ -209,3 +209,4 @@
     1.4  4a48f31735349782ad13980267358c97076adc66 jdk8-b85
     1.5  6ab578e141dfd17c4dc03869bb204aafa490c9f4 jdk8-b86
     1.6  1329f9c38d93c8caf339d7687df8371d06fe9e56 jdk8-b87
     1.7 +a1e10f3adc47c8602a72e43a41403a642e73e0b1 jdk8-b88
     2.1 --- a/make/build.xml	Sun Apr 28 08:16:41 2013 +0100
     2.2 +++ b/make/build.xml	Wed May 08 10:27:52 2013 +0100
     2.3 @@ -717,6 +717,29 @@
     2.4      <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
     2.5  
     2.6      <!--
     2.7 +    **** crules targets.
     2.8 +    -->
     2.9 +
    2.10 +    <target name="build-crules" depends="-def-compilecrules,-def-build-jar-with-services">
    2.11 +        <compilecrules/>
    2.12 +        <build-jar-with-services
    2.13 +                    name="crules"
    2.14 +                    includes="crules/* crules/resources/*"
    2.15 +                    classes.dir="${build.toolclasses.dir}"
    2.16 +                    lib.dir="${build.toolclasses.dir}"
    2.17 +                    jarmainclass=""
    2.18 +                    jarclasspath="crules.jar"
    2.19 +                    service.type="com.sun.source.util.Plugin"
    2.20 +                    service.provider="crules.MutableFieldsAnalyzer"/>
    2.21 +        <build-tool name="crules"/>
    2.22 +    </target>
    2.23 +
    2.24 +    <target name="check-coding-rules" depends="build-bootstrap-javac,-create-import-jdk-stubs,build-crules">
    2.25 +        <build-classes includes="${javac.includes}"
    2.26 +            plugin.options="-J-Xbootclasspath/a:${build.toolclasses.dir}/crules.jar -Xplugin:mutable_fields_analyzer" />
    2.27 +    </target>
    2.28 +
    2.29 +    <!--
    2.30      **** Create import JDK stubs.
    2.31      -->
    2.32  
    2.33 @@ -811,6 +834,31 @@
    2.34          </macrodef>
    2.35      </target>
    2.36  
    2.37 +    <target name="-def-build-jar-with-services">
    2.38 +        <macrodef name="build-jar-with-services">
    2.39 +            <attribute name="name"/>
    2.40 +            <attribute name="includes"/>
    2.41 +            <attribute name="classes.dir" default="${build.classes.dir}"/>
    2.42 +            <attribute name="lib.dir" default="${dist.lib.dir}"/>
    2.43 +            <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
    2.44 +            <attribute name="jarclasspath" default=""/>
    2.45 +            <attribute name="service.type" default=""/>
    2.46 +            <attribute name="service.provider" default=""/>
    2.47 +            <sequential>
    2.48 +                <mkdir dir="${build.toolclasses.dir}"/>
    2.49 +                <jar destfile="@{lib.dir}/@{name}.jar"
    2.50 +                     basedir="@{classes.dir}"
    2.51 +                     includes="@{includes}">
    2.52 +                    <service type="@{service.type}" provider="@{service.provider}"/>
    2.53 +                    <manifest>
    2.54 +                        <attribute name="Main-Class" value="@{jarmainclass}"/>
    2.55 +                        <attribute name="Class-Path" value="@{jarclasspath}"/>
    2.56 +                    </manifest>
    2.57 +                </jar>
    2.58 +            </sequential>
    2.59 +        </macrodef>
    2.60 +    </target>
    2.61 +
    2.62      <target name="-def-build-classes" depends="-def-pcompile">
    2.63          <macrodef name="build-classes">
    2.64              <attribute name="includes"/>
    2.65 @@ -826,6 +874,7 @@
    2.66              <attribute name="target" default="${javac.target}"/>
    2.67              <attribute name="release" default="${release}"/>
    2.68              <attribute name="full.version" default="${full.version}"/>
    2.69 +            <attribute name="plugin.options" default=""/>
    2.70              <sequential>
    2.71                  <echo level="verbose" message="build-classes: excludes=@{excludes}"/>
    2.72                  <echo level="verbose" message="build-classes: bootclasspath.opt=@{bootclasspath.opt}"/>
    2.73 @@ -868,6 +917,7 @@
    2.74                      <compilerarg line="${javac.no.jdk.warnings}"/>
    2.75                      <compilerarg line="${javac.version.opt}"/>
    2.76                      <compilerarg line="${javac.lint.opts}"/>
    2.77 +                    <compilerarg line="@{plugin.options}"/>
    2.78                  </javac>
    2.79                  <copy todir="@{classes.dir}" includeemptydirs="false">
    2.80                      <fileset dir="${src.classes.dir}" includes="@{includes}" excludes="@{excludes}">
    2.81 @@ -935,6 +985,32 @@
    2.82                   classpath="${build.toolclasses.dir}/"/>
    2.83      </target>
    2.84  
    2.85 +    <target name="-def-compilecrules">
    2.86 +        <macrodef name="compilecrules">
    2.87 +            <sequential>
    2.88 +                <mkdir dir="${build.toolclasses.dir}"/>
    2.89 +                <javac fork="true"
    2.90 +                       source="${boot.javac.source}"
    2.91 +                       target="${boot.javac.target}"
    2.92 +                       executable="${boot.java.home}/bin/javac"
    2.93 +                       srcdir="${make.tools.dir}"
    2.94 +                       includes="crules/*"
    2.95 +                       destdir="${build.toolclasses.dir}/"
    2.96 +                       classpath="${ant.core.lib}"
    2.97 +                       bootclasspath="${boot.java.home}/jre/lib/rt.jar"
    2.98 +                       includeantruntime="false">
    2.99 +                    <compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
   2.100 +                    <compilerarg line="${javac.lint.opts}"/>
   2.101 +                </javac>
   2.102 +                <copy todir="${build.toolclasses.dir}/" includeemptydirs="false">
   2.103 +                    <fileset dir="${make.tools.dir}">
   2.104 +                        <include name="**/*.properties"/>
   2.105 +                    </fileset>
   2.106 +                </copy>
   2.107 +            </sequential>
   2.108 +        </macrodef>
   2.109 +    </target>
   2.110 +
   2.111      <target name="-def-genstubs" depends="build-bootstrap-javac" if="require.import.jdk.stubs">
   2.112          <mkdir dir="${build.toolclasses.dir}"/>
   2.113          <javac fork="true"
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/make/tools/crules/AbstractCodingRulesAnalyzer.java	Wed May 08 10:27:52 2013 +0100
     3.3 @@ -0,0 +1,117 @@
     3.4 +/*
     3.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +package crules;
    3.28 +
    3.29 +import java.text.MessageFormat;
    3.30 +import java.util.Locale;
    3.31 +import java.util.ResourceBundle;
    3.32 +
    3.33 +import javax.lang.model.element.TypeElement;
    3.34 +import javax.tools.JavaFileObject;
    3.35 +
    3.36 +import com.sun.source.tree.Tree;
    3.37 +import com.sun.source.util.JavacTask;
    3.38 +import com.sun.source.util.Plugin;
    3.39 +import com.sun.source.util.TaskEvent;
    3.40 +import com.sun.source.util.TaskListener;
    3.41 +import com.sun.source.util.Trees;
    3.42 +import com.sun.tools.javac.api.BasicJavacTask;
    3.43 +import com.sun.tools.javac.tree.JCTree;
    3.44 +import com.sun.tools.javac.tree.TreeScanner;
    3.45 +import com.sun.tools.javac.util.Context;
    3.46 +import com.sun.tools.javac.util.Log;
    3.47 +
    3.48 +import static com.sun.source.util.TaskEvent.Kind;
    3.49 +
    3.50 +public abstract class AbstractCodingRulesAnalyzer implements Plugin {
    3.51 +
    3.52 +    protected Log log;
    3.53 +    protected Trees trees;
    3.54 +    protected TreeScanner treeVisitor;
    3.55 +    protected Kind eventKind;
    3.56 +    protected Messages messages;
    3.57 +
    3.58 +    public void init(JavacTask task, String... args) {
    3.59 +        BasicJavacTask impl = (BasicJavacTask)task;
    3.60 +        Context context = impl.getContext();
    3.61 +        log = Log.instance(context);
    3.62 +        trees = Trees.instance(task);
    3.63 +        messages = new Messages();
    3.64 +        task.addTaskListener(new PostAnalyzeTaskListener());
    3.65 +    }
    3.66 +
    3.67 +    public class PostAnalyzeTaskListener implements TaskListener {
    3.68 +
    3.69 +        @Override
    3.70 +        public void started(TaskEvent taskEvent) {}
    3.71 +
    3.72 +        @Override
    3.73 +        public void finished(TaskEvent taskEvent) {
    3.74 +            if (taskEvent.getKind().equals(eventKind)) {
    3.75 +                TypeElement typeElem = taskEvent.getTypeElement();
    3.76 +                Tree tree = trees.getTree(typeElem);
    3.77 +                if (tree != null) {
    3.78 +                    JavaFileObject prevSource = log.currentSourceFile();
    3.79 +                    try {
    3.80 +                        log.useSource(taskEvent.getCompilationUnit().getSourceFile());
    3.81 +                        treeVisitor.scan((JCTree)tree);
    3.82 +                    } finally {
    3.83 +                        log.useSource(prevSource);
    3.84 +                    }
    3.85 +                }
    3.86 +            }
    3.87 +        }
    3.88 +    }
    3.89 +
    3.90 +    class Messages {
    3.91 +        ResourceBundle bundle;
    3.92 +
    3.93 +        Messages() {
    3.94 +            String name = getClass().getPackage().getName() + ".resources.crules";
    3.95 +            bundle = ResourceBundle.getBundle(name, Locale.ENGLISH);
    3.96 +        }
    3.97 +
    3.98 +        public void error(JCTree tree, String code, Object... args) {
    3.99 +            String msg = (code == null) ? (String) args[0] : localize(code, args);
   3.100 +            log.error(tree, "proc.messager", msg.toString());
   3.101 +        }
   3.102 +
   3.103 +        private String localize(String code, Object... args) {
   3.104 +            String msg = bundle.getString(code);
   3.105 +            if (msg == null) {
   3.106 +                StringBuilder sb = new StringBuilder();
   3.107 +                sb.append("message file broken: code=").append(code);
   3.108 +                if (args.length > 0) {
   3.109 +                    sb.append(" arguments={0}");
   3.110 +                    for (int i = 1; i < args.length; i++) {
   3.111 +                        sb.append(", {").append(i).append("}");
   3.112 +                    }
   3.113 +                }
   3.114 +                msg = sb.toString();
   3.115 +            }
   3.116 +            return MessageFormat.format(msg, args);
   3.117 +        }
   3.118 +    }
   3.119 +
   3.120 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/make/tools/crules/MutableFieldsAnalyzer.java	Wed May 08 10:27:52 2013 +0100
     4.3 @@ -0,0 +1,118 @@
     4.4 +/*
     4.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.23 + * or visit www.oracle.com if you need additional information or have any
    4.24 + * questions.
    4.25 + */
    4.26 +
    4.27 +package crules;
    4.28 +
    4.29 +import java.util.Arrays;
    4.30 +import java.util.HashMap;
    4.31 +import java.util.List;
    4.32 +import java.util.Map;
    4.33 +
    4.34 +import com.sun.tools.javac.code.Kinds;
    4.35 +import com.sun.tools.javac.tree.TreeScanner;
    4.36 +
    4.37 +import static com.sun.source.util.TaskEvent.Kind;
    4.38 +import static com.sun.tools.javac.code.Flags.*;
    4.39 +import static com.sun.tools.javac.tree.JCTree.JCVariableDecl;
    4.40 +
    4.41 +public class MutableFieldsAnalyzer extends AbstractCodingRulesAnalyzer {
    4.42 +
    4.43 +    public MutableFieldsAnalyzer() {
    4.44 +        treeVisitor = new MutableFieldsVisitor();
    4.45 +        eventKind = Kind.ANALYZE;
    4.46 +    }
    4.47 +
    4.48 +    public String getName() {
    4.49 +        return "mutable_fields_analyzer";
    4.50 +    }
    4.51 +
    4.52 +    private boolean ignoreField(String className, String field) {
    4.53 +        List<String> currentFieldsToIgnore =
    4.54 +                classFieldsToIgnoreMap.get(className);
    4.55 +        if (currentFieldsToIgnore != null) {
    4.56 +            for (String fieldToIgnore : currentFieldsToIgnore) {
    4.57 +                if (field.equals(fieldToIgnore)) {
    4.58 +                    return true;
    4.59 +                }
    4.60 +            }
    4.61 +        }
    4.62 +        return false;
    4.63 +    }
    4.64 +
    4.65 +    class MutableFieldsVisitor extends TreeScanner {
    4.66 +
    4.67 +        @Override
    4.68 +        public void visitVarDef(JCVariableDecl tree) {
    4.69 +            boolean isJavacPack = tree.sym.outermostClass().fullname.toString()
    4.70 +                    .contains(packageToCheck);
    4.71 +            if (isJavacPack &&
    4.72 +                (tree.sym.flags() & SYNTHETIC) == 0 &&
    4.73 +                tree.sym.owner.kind == Kinds.TYP) {
    4.74 +                if (!ignoreField(tree.sym.owner.flatName().toString(),
    4.75 +                        tree.getName().toString())) {
    4.76 +                    boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
    4.77 +                    boolean nonFinalStaticEnumField =
    4.78 +                            (tree.sym.flags() & (ENUM | FINAL)) == 0;
    4.79 +                    boolean nonFinalStaticField =
    4.80 +                            (tree.sym.flags() & STATIC) != 0 &&
    4.81 +                            (tree.sym.flags() & FINAL) == 0;
    4.82 +                    if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
    4.83 +                        messages.error(tree, "crules.err.var.must.be.final", tree);
    4.84 +                    }
    4.85 +                }
    4.86 +            }
    4.87 +            super.visitVarDef(tree);
    4.88 +        }
    4.89 +
    4.90 +    }
    4.91 +
    4.92 +    private static final String packageToCheck = "com.sun.tools.javac";
    4.93 +
    4.94 +    private static final Map<String, List<String>> classFieldsToIgnoreMap =
    4.95 +                new HashMap<String, List<String>>();
    4.96 +
    4.97 +    static {
    4.98 +        classFieldsToIgnoreMap.
    4.99 +                put("com.sun.tools.javac.util.JCDiagnostic",
   4.100 +                    Arrays.asList("fragmentFormatter"));
   4.101 +        classFieldsToIgnoreMap.
   4.102 +                put("com.sun.tools.javac.util.JavacMessages",
   4.103 +                    Arrays.asList("defaultBundle", "defaultMessages"));
   4.104 +        classFieldsToIgnoreMap.
   4.105 +                put("com.sun.tools.javac.file.ZipFileIndexCache",
   4.106 +                    Arrays.asList("sharedInstance"));
   4.107 +        classFieldsToIgnoreMap.
   4.108 +                put("com.sun.tools.javac.main.JavaCompiler",
   4.109 +                    Arrays.asList("versionRB"));
   4.110 +        classFieldsToIgnoreMap.
   4.111 +                put("com.sun.tools.javac.code.Type",
   4.112 +                    Arrays.asList("moreInfo"));
   4.113 +        classFieldsToIgnoreMap.
   4.114 +                put("com.sun.tools.javac.util.SharedNameTable",
   4.115 +                    Arrays.asList("freelist"));
   4.116 +        classFieldsToIgnoreMap.
   4.117 +                put("com.sun.tools.javac.util.Log",
   4.118 +                    Arrays.asList("useRawMessages"));
   4.119 +    }
   4.120 +
   4.121 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/make/tools/crules/resources/crules.properties	Wed May 08 10:27:52 2013 +0100
     5.3 @@ -0,0 +1,28 @@
     5.4 +#
     5.5 +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     5.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 +#
     5.8 +# This code is free software; you can redistribute it and/or modify it
     5.9 +# under the terms of the GNU General Public License version 2 only, as
    5.10 +# published by the Free Software Foundation.  Oracle designates this
    5.11 +# particular file as subject to the "Classpath" exception as provided
    5.12 +# by Oracle in the LICENSE file that accompanied this code.
    5.13 +#
    5.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
    5.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.17 +# version 2 for more details (a copy is included in the LICENSE file that
    5.18 +# accompanied this code).
    5.19 +#
    5.20 +# You should have received a copy of the GNU General Public License version
    5.21 +# 2 along with this work; if not, write to the Free Software Foundation,
    5.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.23 +#
    5.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.25 +# or visit www.oracle.com if you need additional information or have any
    5.26 +# questions.
    5.27 +#
    5.28 +
    5.29 +# 0: symbol
    5.30 +crules.err.var.must.be.final=\
    5.31 +    Static variable {0} must be final
     6.1 --- a/src/share/classes/com/sun/tools/classfile/Dependencies.java	Sun Apr 28 08:16:41 2013 +0100
     6.2 +++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java	Wed May 08 10:27:52 2013 +0100
     6.3 @@ -315,7 +315,7 @@
     6.4      static class SimpleLocation implements Location {
     6.5          public SimpleLocation(String name) {
     6.6              this.name = name;
     6.7 -            this.className = name.replace('/', '.').replace('$', '.');
     6.8 +            this.className = name.replace('/', '.');
     6.9          }
    6.10  
    6.11          public String getName() {
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/share/classes/com/sun/tools/classfile/ReferenceFinder.java	Wed May 08 10:27:52 2013 +0100
     7.3 @@ -0,0 +1,240 @@
     7.4 +/*
     7.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.  Oracle designates this
    7.11 + * particular file as subject to the "Classpath" exception as provided
    7.12 + * by Oracle in the LICENSE file that accompanied this code.
    7.13 + *
    7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 + * version 2 for more details (a copy is included in the LICENSE file that
    7.18 + * accompanied this code).
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License version
    7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 + *
    7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 + * or visit www.oracle.com if you need additional information or have any
    7.26 + * questions.
    7.27 + */
    7.28 +
    7.29 +package com.sun.tools.classfile;
    7.30 +
    7.31 +import java.util.ArrayList;
    7.32 +import java.util.HashSet;
    7.33 +import java.util.List;
    7.34 +import java.util.Objects;
    7.35 +import java.util.Set;
    7.36 +import com.sun.tools.classfile.Instruction.TypeKind;
    7.37 +import static com.sun.tools.classfile.ConstantPool.*;
    7.38 +
    7.39 +/**
    7.40 + * A utility class to find where in a ClassFile references
    7.41 + * a {@link CONSTANT_Methodref_info method},
    7.42 + * a {@link CONSTANT_InterfaceMethodref_info interface method,
    7.43 + * or a {@link CONSTANT_Fieldref_info field}.
    7.44 + */
    7.45 +public final class ReferenceFinder {
    7.46 +    /**
    7.47 +     * Filter for ReferenceFinder of what constant pool entries for reference lookup.
    7.48 +     */
    7.49 +    public interface Filter {
    7.50 +        /**
    7.51 +         * Decides if the given CPRefInfo entry should be accepted or filtered.
    7.52 +         *
    7.53 +         * @param cpool  ConstantPool of the ClassFile being parsed
    7.54 +         * @param cpref  constant pool entry representing a reference to
    7.55 +         *               a fields method, and interface method.
    7.56 +         * @return {@code true} if accepted; otherwise {@code false}
    7.57 +         */
    7.58 +        boolean accept(ConstantPool cpool, CPRefInfo cpref);
    7.59 +    }
    7.60 +
    7.61 +    /**
    7.62 +     * Visitor of individual method of a ClassFile that references the
    7.63 +     * accepted field, method, or interface method references.
    7.64 +     */
    7.65 +    public interface Visitor {
    7.66 +        /**
    7.67 +         * Invoked for a method containing one or more accepted CPRefInfo entries
    7.68 +         *
    7.69 +         * @param cf      ClassFile
    7.70 +         * @param method  Method that does the references the accepted references
    7.71 +         * @param refs    Accepted constant pool method/field reference
    7.72 +         */
    7.73 +        void visit(ClassFile cf, Method method, List<CPRefInfo> refConstantPool);
    7.74 +    }
    7.75 +
    7.76 +    private final Filter filter;
    7.77 +    private final Visitor visitor;
    7.78 +
    7.79 +    /**
    7.80 +     * Constructor.
    7.81 +     */
    7.82 +    public ReferenceFinder(Filter filter, Visitor visitor) {
    7.83 +        this.filter = Objects.requireNonNull(filter);
    7.84 +        this.visitor = Objects.requireNonNull(visitor);
    7.85 +    }
    7.86 +
    7.87 +    /**
    7.88 +     * Parses a given ClassFile and invoke the visitor if there is any reference
    7.89 +     * to the constant pool entries referencing field, method, or
    7.90 +     * interface method that are accepted. This method will return
    7.91 +     * {@code true} if there is one or more accepted constant pool entries
    7.92 +     * to lookup; otherwise, it will return {@code false}.
    7.93 +     *
    7.94 +     * @param  cf  ClassFile
    7.95 +     * @return {@code true} if the given class file is processed to lookup
    7.96 +     *         references
    7.97 +     * @throws ConstantPoolException if an error of the constant pool
    7.98 +     */
    7.99 +    public boolean parse(ClassFile cf) throws ConstantPoolException {
   7.100 +        List<Integer> cprefs = new ArrayList<Integer>();
   7.101 +        int index = 1;
   7.102 +        for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) {
   7.103 +            if (cpInfo.accept(cpVisitor, cf.constant_pool)) {
   7.104 +                cprefs.add(index);
   7.105 +            }
   7.106 +            index += cpInfo.size();
   7.107 +        }
   7.108 +
   7.109 +        if (cprefs.isEmpty()) {
   7.110 +            return false;
   7.111 +        }
   7.112 +
   7.113 +        for (Method m : cf.methods) {
   7.114 +            Set<Integer> ids = new HashSet<Integer>();
   7.115 +            Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);
   7.116 +            if (c_attr != null) {
   7.117 +                for (Instruction instr : c_attr.getInstructions()) {
   7.118 +                    int idx = instr.accept(codeVisitor, cprefs);
   7.119 +                    if (idx > 0) {
   7.120 +                        ids.add(idx);
   7.121 +                    }
   7.122 +                }
   7.123 +            }
   7.124 +            if (ids.size() > 0) {
   7.125 +                List<CPRefInfo> refInfos = new ArrayList<CPRefInfo>(ids.size());
   7.126 +                for (int id : ids) {
   7.127 +                    refInfos.add(CPRefInfo.class.cast(cf.constant_pool.get(id)));
   7.128 +                }
   7.129 +                visitor.visit(cf, m, refInfos);
   7.130 +            }
   7.131 +        }
   7.132 +        return true;
   7.133 +    }
   7.134 +
   7.135 +    private ConstantPool.Visitor<Boolean,ConstantPool> cpVisitor =
   7.136 +            new ConstantPool.Visitor<Boolean,ConstantPool>()
   7.137 +    {
   7.138 +        public Boolean visitClass(CONSTANT_Class_info info, ConstantPool cpool) {
   7.139 +            return false;
   7.140 +        }
   7.141 +
   7.142 +        public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ConstantPool cpool) {
   7.143 +            return filter.accept(cpool, info);
   7.144 +        }
   7.145 +
   7.146 +        public Boolean visitMethodref(CONSTANT_Methodref_info info, ConstantPool cpool) {
   7.147 +            return filter.accept(cpool, info);
   7.148 +        }
   7.149 +
   7.150 +        public Boolean visitFieldref(CONSTANT_Fieldref_info info, ConstantPool cpool) {
   7.151 +            return filter.accept(cpool, info);
   7.152 +        }
   7.153 +
   7.154 +        public Boolean visitDouble(CONSTANT_Double_info info, ConstantPool cpool) {
   7.155 +            return false;
   7.156 +        }
   7.157 +
   7.158 +        public Boolean visitFloat(CONSTANT_Float_info info, ConstantPool cpool) {
   7.159 +            return false;
   7.160 +        }
   7.161 +
   7.162 +        public Boolean visitInteger(CONSTANT_Integer_info info, ConstantPool cpool) {
   7.163 +            return false;
   7.164 +        }
   7.165 +
   7.166 +        public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ConstantPool cpool) {
   7.167 +            return false;
   7.168 +        }
   7.169 +
   7.170 +        public Boolean visitLong(CONSTANT_Long_info info, ConstantPool cpool) {
   7.171 +            return false;
   7.172 +        }
   7.173 +
   7.174 +        public Boolean visitNameAndType(CONSTANT_NameAndType_info info, ConstantPool cpool) {
   7.175 +            return false;
   7.176 +        }
   7.177 +
   7.178 +        public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, ConstantPool cpool) {
   7.179 +            return false;
   7.180 +        }
   7.181 +
   7.182 +        public Boolean visitMethodType(CONSTANT_MethodType_info info, ConstantPool cpool) {
   7.183 +            return false;
   7.184 +        }
   7.185 +
   7.186 +        public Boolean visitString(CONSTANT_String_info info, ConstantPool cpool) {
   7.187 +            return false;
   7.188 +        }
   7.189 +
   7.190 +        public Boolean visitUtf8(CONSTANT_Utf8_info info, ConstantPool cpool) {
   7.191 +            return false;
   7.192 +        }
   7.193 +    };
   7.194 +
   7.195 +    private Instruction.KindVisitor<Integer, List<Integer>> codeVisitor =
   7.196 +            new Instruction.KindVisitor<Integer, List<Integer>>()
   7.197 +    {
   7.198 +        public Integer visitNoOperands(Instruction instr, List<Integer> p) {
   7.199 +            return 0;
   7.200 +        }
   7.201 +
   7.202 +        public Integer visitArrayType(Instruction instr, TypeKind kind, List<Integer> p) {
   7.203 +            return 0;
   7.204 +        }
   7.205 +
   7.206 +        public Integer visitBranch(Instruction instr, int offset, List<Integer> p) {
   7.207 +            return 0;
   7.208 +        }
   7.209 +
   7.210 +        public Integer visitConstantPoolRef(Instruction instr, int index, List<Integer> p) {
   7.211 +            return p.contains(index) ? index : 0;
   7.212 +        }
   7.213 +
   7.214 +        public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List<Integer> p) {
   7.215 +            return p.contains(index) ? index : 0;
   7.216 +        }
   7.217 +
   7.218 +        public Integer visitLocal(Instruction instr, int index, List<Integer> p) {
   7.219 +            return 0;
   7.220 +        }
   7.221 +
   7.222 +        public Integer visitLocalAndValue(Instruction instr, int index, int value, List<Integer> p) {
   7.223 +            return 0;
   7.224 +        }
   7.225 +
   7.226 +        public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List<Integer> p) {
   7.227 +            return 0;
   7.228 +        }
   7.229 +
   7.230 +        public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List<Integer> p) {
   7.231 +            return 0;
   7.232 +        }
   7.233 +
   7.234 +        public Integer visitValue(Instruction instr, int value, List<Integer> p) {
   7.235 +            return 0;
   7.236 +        }
   7.237 +
   7.238 +        public Integer visitUnknown(Instruction instr, List<Integer> p) {
   7.239 +            return 0;
   7.240 +        }
   7.241 +    };
   7.242 +}
   7.243 +
     8.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Sun Apr 28 08:16:41 2013 +0100
     8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed May 08 10:27:52 2013 +0100
     8.3 @@ -1078,7 +1078,8 @@
     8.4                  mask = MethodFlags;
     8.5              }
     8.6              // Imply STRICTFP if owner has STRICTFP set.
     8.7 -            if (((flags|implicit) & Flags.ABSTRACT) == 0)
     8.8 +            if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
     8.9 +                ((flags) & Flags.DEFAULT) != 0)
    8.10                  implicit |= sym.owner.flags_field & STRICTFP;
    8.11              break;
    8.12          case TYP:
     9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Sun Apr 28 08:16:41 2013 +0100
     9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Wed May 08 10:27:52 2013 +0100
     9.3 @@ -35,7 +35,6 @@
     9.4  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
     9.5  
     9.6  import com.sun.tools.javac.code.Symbol.*;
     9.7 -import com.sun.tools.javac.comp.Resolve;
     9.8  import com.sun.tools.javac.tree.JCTree.*;
     9.9  
    9.10  import static com.sun.tools.javac.code.Flags.*;
    9.11 @@ -277,6 +276,15 @@
    9.12      }
    9.13  
    9.14      /**
    9.15 +     * Utility method to reset several Bits instances.
    9.16 +     */
    9.17 +    private void resetBits(Bits... bits) {
    9.18 +        for (Bits b : bits) {
    9.19 +            b.reset();
    9.20 +        }
    9.21 +    }
    9.22 +
    9.23 +    /**
    9.24       * Base visitor class for all visitors implementing dataflow analysis logic.
    9.25       * This class define the shared logic for handling jumps (break/continue statements).
    9.26       */
    9.27 @@ -1294,11 +1302,11 @@
    9.28  
    9.29          /** The set of definitely assigned variables.
    9.30           */
    9.31 -        Bits inits;
    9.32 +        final Bits inits;
    9.33  
    9.34          /** The set of definitely unassigned variables.
    9.35           */
    9.36 -        Bits uninits;
    9.37 +        final Bits uninits;
    9.38  
    9.39          /** The set of variables that are definitely unassigned everywhere
    9.40           *  in current try block. This variable is maintained lazily; it is
    9.41 @@ -1308,15 +1316,15 @@
    9.42           *  anywhere in current try block, intersect uninitsTry and
    9.43           *  uninits.
    9.44           */
    9.45 -        Bits uninitsTry;
    9.46 +        final Bits uninitsTry;
    9.47  
    9.48          /** When analyzing a condition, inits and uninits are null.
    9.49           *  Instead we have:
    9.50           */
    9.51 -        Bits initsWhenTrue;
    9.52 -        Bits initsWhenFalse;
    9.53 -        Bits uninitsWhenTrue;
    9.54 -        Bits uninitsWhenFalse;
    9.55 +        final Bits initsWhenTrue;
    9.56 +        final Bits initsWhenFalse;
    9.57 +        final Bits uninitsWhenTrue;
    9.58 +        final Bits uninitsWhenFalse;
    9.59  
    9.60          /** A mapping from addresses to variable symbols.
    9.61           */
    9.62 @@ -1348,15 +1356,25 @@
    9.63          /** The starting position of the analysed tree */
    9.64          int startPos;
    9.65  
    9.66 +        AssignAnalyzer() {
    9.67 +            inits = new Bits();
    9.68 +            uninits = new Bits();
    9.69 +            uninitsTry = new Bits();
    9.70 +            initsWhenTrue = new Bits(true);
    9.71 +            initsWhenFalse = new Bits(true);
    9.72 +            uninitsWhenTrue = new Bits(true);
    9.73 +            uninitsWhenFalse = new Bits(true);
    9.74 +        }
    9.75 +
    9.76          class AssignPendingExit extends BaseAnalyzer.PendingExit {
    9.77  
    9.78 -            Bits exit_inits;
    9.79 -            Bits exit_uninits;
    9.80 +            final Bits exit_inits = new Bits(true);
    9.81 +            final Bits exit_uninits = new Bits(true);
    9.82  
    9.83 -            AssignPendingExit(JCTree tree, Bits inits, Bits uninits) {
    9.84 +            AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
    9.85                  super(tree);
    9.86 -                this.exit_inits = inits.dup();
    9.87 -                this.exit_uninits = uninits.dup();
    9.88 +                this.exit_inits.assign(inits);
    9.89 +                this.exit_uninits.assign(uninits);
    9.90              }
    9.91  
    9.92              void resolveJump() {
    9.93 @@ -1476,19 +1494,20 @@
    9.94          /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
    9.95           */
    9.96          void split(boolean setToNull) {
    9.97 -            initsWhenFalse = inits.dup();
    9.98 -            uninitsWhenFalse = uninits.dup();
    9.99 -            initsWhenTrue = inits;
   9.100 -            uninitsWhenTrue = uninits;
   9.101 -            if (setToNull)
   9.102 -                inits = uninits = null;
   9.103 +            initsWhenFalse.assign(inits);
   9.104 +            uninitsWhenFalse.assign(uninits);
   9.105 +            initsWhenTrue.assign(inits);
   9.106 +            uninitsWhenTrue.assign(uninits);
   9.107 +            if (setToNull) {
   9.108 +                resetBits(inits, uninits);
   9.109 +            }
   9.110          }
   9.111  
   9.112          /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
   9.113           */
   9.114          void merge() {
   9.115 -            inits = initsWhenFalse.andSet(initsWhenTrue);
   9.116 -            uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
   9.117 +            inits.assign(initsWhenFalse.andSet(initsWhenTrue));
   9.118 +            uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
   9.119          }
   9.120  
   9.121      /* ************************************************************************
   9.122 @@ -1501,7 +1520,7 @@
   9.123          void scanExpr(JCTree tree) {
   9.124              if (tree != null) {
   9.125                  scan(tree);
   9.126 -                if (inits == null) merge();
   9.127 +                if (inits.isReset()) merge();
   9.128              }
   9.129          }
   9.130  
   9.131 @@ -1518,28 +1537,29 @@
   9.132           */
   9.133          void scanCond(JCTree tree) {
   9.134              if (tree.type.isFalse()) {
   9.135 -                if (inits == null) merge();
   9.136 -                initsWhenTrue = inits.dup();
   9.137 +                if (inits.isReset()) merge();
   9.138 +                initsWhenTrue.assign(inits);
   9.139                  initsWhenTrue.inclRange(firstadr, nextadr);
   9.140 -                uninitsWhenTrue = uninits.dup();
   9.141 +                uninitsWhenTrue.assign(uninits);
   9.142                  uninitsWhenTrue.inclRange(firstadr, nextadr);
   9.143 -                initsWhenFalse = inits;
   9.144 -                uninitsWhenFalse = uninits;
   9.145 +                initsWhenFalse.assign(inits);
   9.146 +                uninitsWhenFalse.assign(uninits);
   9.147              } else if (tree.type.isTrue()) {
   9.148 -                if (inits == null) merge();
   9.149 -                initsWhenFalse = inits.dup();
   9.150 +                if (inits.isReset()) merge();
   9.151 +                initsWhenFalse.assign(inits);
   9.152                  initsWhenFalse.inclRange(firstadr, nextadr);
   9.153 -                uninitsWhenFalse = uninits.dup();
   9.154 +                uninitsWhenFalse.assign(uninits);
   9.155                  uninitsWhenFalse.inclRange(firstadr, nextadr);
   9.156 -                initsWhenTrue = inits;
   9.157 -                uninitsWhenTrue = uninits;
   9.158 +                initsWhenTrue.assign(inits);
   9.159 +                uninitsWhenTrue.assign(uninits);
   9.160              } else {
   9.161                  scan(tree);
   9.162 -                if (inits != null)
   9.163 +                if (!inits.isReset())
   9.164                      split(tree.type != syms.unknownType);
   9.165              }
   9.166 -            if (tree.type != syms.unknownType)
   9.167 -                inits = uninits = null;
   9.168 +            if (tree.type != syms.unknownType) {
   9.169 +                resetBits(inits, uninits);
   9.170 +            }
   9.171          }
   9.172  
   9.173          /* ------------ Visitor methods for various sorts of trees -------------*/
   9.174 @@ -1619,8 +1639,8 @@
   9.175          public void visitMethodDef(JCMethodDecl tree) {
   9.176              if (tree.body == null) return;
   9.177  
   9.178 -            Bits initsPrev = inits.dup();
   9.179 -            Bits uninitsPrev = uninits.dup();
   9.180 +            final Bits initsPrev = new Bits(inits);
   9.181 +            final Bits uninitsPrev = new Bits(uninits);
   9.182              int nextadrPrev = nextadr;
   9.183              int firstadrPrev = firstadr;
   9.184              int returnadrPrev = returnadr;
   9.185 @@ -1658,14 +1678,14 @@
   9.186                      exits = exits.tail;
   9.187                      Assert.check(exit.tree.hasTag(RETURN), exit.tree);
   9.188                      if (isInitialConstructor) {
   9.189 -                        inits = exit.exit_inits;
   9.190 +                        inits.assign(exit.exit_inits);
   9.191                          for (int i = firstadr; i < nextadr; i++)
   9.192                              checkInit(exit.tree.pos(), vars[i]);
   9.193                      }
   9.194                  }
   9.195              } finally {
   9.196 -                inits = initsPrev;
   9.197 -                uninits = uninitsPrev;
   9.198 +                inits.assign(initsPrev);
   9.199 +                uninits.assign(uninitsPrev);
   9.200                  nextadr = nextadrPrev;
   9.201                  firstadr = firstadrPrev;
   9.202                  returnadr = returnadrPrev;
   9.203 @@ -1698,31 +1718,31 @@
   9.204              ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
   9.205              FlowKind prevFlowKind = flowKind;
   9.206              flowKind = FlowKind.NORMAL;
   9.207 -            Bits initsSkip = null;
   9.208 -            Bits uninitsSkip = null;
   9.209 +            final Bits initsSkip = new Bits(true);
   9.210 +            final Bits uninitsSkip = new Bits(true);
   9.211              pendingExits = new ListBuffer<AssignPendingExit>();
   9.212              int prevErrors = log.nerrors;
   9.213              do {
   9.214 -                Bits uninitsEntry = uninits.dup();
   9.215 +                final Bits uninitsEntry = new Bits(uninits);
   9.216                  uninitsEntry.excludeFrom(nextadr);
   9.217                  scan(tree.body);
   9.218                  resolveContinues(tree);
   9.219                  scanCond(tree.cond);
   9.220                  if (!flowKind.isFinal()) {
   9.221 -                    initsSkip = initsWhenFalse;
   9.222 -                    uninitsSkip = uninitsWhenFalse;
   9.223 +                    initsSkip.assign(initsWhenFalse);
   9.224 +                    uninitsSkip.assign(uninitsWhenFalse);
   9.225                  }
   9.226                  if (log.nerrors !=  prevErrors ||
   9.227                      flowKind.isFinal() ||
   9.228 -                    uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
   9.229 +                    new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
   9.230                      break;
   9.231 -                inits = initsWhenTrue;
   9.232 -                uninits = uninitsEntry.andSet(uninitsWhenTrue);
   9.233 +                inits.assign(initsWhenTrue);
   9.234 +                uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
   9.235                  flowKind = FlowKind.SPECULATIVE_LOOP;
   9.236              } while (true);
   9.237              flowKind = prevFlowKind;
   9.238 -            inits = initsSkip;
   9.239 -            uninits = uninitsSkip;
   9.240 +            inits.assign(initsSkip);
   9.241 +            uninits.assign(uninitsSkip);
   9.242              resolveBreaks(tree, prevPendingExits);
   9.243          }
   9.244  
   9.245 @@ -1730,34 +1750,34 @@
   9.246              ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
   9.247              FlowKind prevFlowKind = flowKind;
   9.248              flowKind = FlowKind.NORMAL;
   9.249 -            Bits initsSkip = null;
   9.250 -            Bits uninitsSkip = null;
   9.251 +            final Bits initsSkip = new Bits(true);
   9.252 +            final Bits uninitsSkip = new Bits(true);
   9.253              pendingExits = new ListBuffer<AssignPendingExit>();
   9.254              int prevErrors = log.nerrors;
   9.255 -            Bits uninitsEntry = uninits.dup();
   9.256 +            final Bits uninitsEntry = new Bits(uninits);
   9.257              uninitsEntry.excludeFrom(nextadr);
   9.258              do {
   9.259                  scanCond(tree.cond);
   9.260                  if (!flowKind.isFinal()) {
   9.261 -                    initsSkip = initsWhenFalse;
   9.262 -                    uninitsSkip = uninitsWhenFalse;
   9.263 +                    initsSkip.assign(initsWhenFalse) ;
   9.264 +                    uninitsSkip.assign(uninitsWhenFalse);
   9.265                  }
   9.266 -                inits = initsWhenTrue;
   9.267 -                uninits = uninitsWhenTrue;
   9.268 +                inits.assign(initsWhenTrue);
   9.269 +                uninits.assign(uninitsWhenTrue);
   9.270                  scan(tree.body);
   9.271                  resolveContinues(tree);
   9.272                  if (log.nerrors != prevErrors ||
   9.273                      flowKind.isFinal() ||
   9.274 -                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
   9.275 +                    new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
   9.276                      break;
   9.277 -                uninits = uninitsEntry.andSet(uninits);
   9.278 +                uninits.assign(uninitsEntry.andSet(uninits));
   9.279                  flowKind = FlowKind.SPECULATIVE_LOOP;
   9.280              } while (true);
   9.281              flowKind = prevFlowKind;
   9.282              //a variable is DA/DU after the while statement, if it's DA/DU assuming the
   9.283              //branch is not taken AND if it's DA/DU before any break statement
   9.284 -            inits = initsSkip;
   9.285 -            uninits = uninitsSkip;
   9.286 +            inits.assign(initsSkip);
   9.287 +            uninits.assign(uninitsSkip);
   9.288              resolveBreaks(tree, prevPendingExits);
   9.289          }
   9.290  
   9.291 @@ -1767,25 +1787,25 @@
   9.292              flowKind = FlowKind.NORMAL;
   9.293              int nextadrPrev = nextadr;
   9.294              scan(tree.init);
   9.295 -            Bits initsSkip = null;
   9.296 -            Bits uninitsSkip = null;
   9.297 +            final Bits initsSkip = new Bits(true);
   9.298 +            final Bits uninitsSkip = new Bits(true);
   9.299              pendingExits = new ListBuffer<AssignPendingExit>();
   9.300              int prevErrors = log.nerrors;
   9.301              do {
   9.302 -                Bits uninitsEntry = uninits.dup();
   9.303 +                final Bits uninitsEntry = new Bits(uninits);
   9.304                  uninitsEntry.excludeFrom(nextadr);
   9.305                  if (tree.cond != null) {
   9.306                      scanCond(tree.cond);
   9.307                      if (!flowKind.isFinal()) {
   9.308 -                        initsSkip = initsWhenFalse;
   9.309 -                        uninitsSkip = uninitsWhenFalse;
   9.310 +                        initsSkip.assign(initsWhenFalse);
   9.311 +                        uninitsSkip.assign(uninitsWhenFalse);
   9.312                      }
   9.313 -                    inits = initsWhenTrue;
   9.314 -                    uninits = uninitsWhenTrue;
   9.315 +                    inits.assign(initsWhenTrue);
   9.316 +                    uninits.assign(uninitsWhenTrue);
   9.317                  } else if (!flowKind.isFinal()) {
   9.318 -                    initsSkip = inits.dup();
   9.319 +                    initsSkip.assign(inits);
   9.320                      initsSkip.inclRange(firstadr, nextadr);
   9.321 -                    uninitsSkip = uninits.dup();
   9.322 +                    uninitsSkip.assign(uninits);
   9.323                      uninitsSkip.inclRange(firstadr, nextadr);
   9.324                  }
   9.325                  scan(tree.body);
   9.326 @@ -1793,16 +1813,16 @@
   9.327                  scan(tree.step);
   9.328                  if (log.nerrors != prevErrors ||
   9.329                      flowKind.isFinal() ||
   9.330 -                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
   9.331 +                    new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
   9.332                      break;
   9.333 -                uninits = uninitsEntry.andSet(uninits);
   9.334 +                uninits.assign(uninitsEntry.andSet(uninits));
   9.335                  flowKind = FlowKind.SPECULATIVE_LOOP;
   9.336              } while (true);
   9.337              flowKind = prevFlowKind;
   9.338              //a variable is DA/DU after a for loop, if it's DA/DU assuming the
   9.339              //branch is not taken AND if it's DA/DU before any break statement
   9.340 -            inits = initsSkip;
   9.341 -            uninits = uninitsSkip;
   9.342 +            inits.assign(initsSkip);
   9.343 +            uninits.assign(uninitsSkip);
   9.344              resolveBreaks(tree, prevPendingExits);
   9.345              nextadr = nextadrPrev;
   9.346          }
   9.347 @@ -1815,27 +1835,27 @@
   9.348              flowKind = FlowKind.NORMAL;
   9.349              int nextadrPrev = nextadr;
   9.350              scan(tree.expr);
   9.351 -            Bits initsStart = inits.dup();
   9.352 -            Bits uninitsStart = uninits.dup();
   9.353 +            final Bits initsStart = new Bits(inits);
   9.354 +            final Bits uninitsStart = new Bits(uninits);
   9.355  
   9.356              letInit(tree.pos(), tree.var.sym);
   9.357              pendingExits = new ListBuffer<AssignPendingExit>();
   9.358              int prevErrors = log.nerrors;
   9.359              do {
   9.360 -                Bits uninitsEntry = uninits.dup();
   9.361 +                final Bits uninitsEntry = new Bits(uninits);
   9.362                  uninitsEntry.excludeFrom(nextadr);
   9.363                  scan(tree.body);
   9.364                  resolveContinues(tree);
   9.365                  if (log.nerrors != prevErrors ||
   9.366                      flowKind.isFinal() ||
   9.367 -                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
   9.368 +                    new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
   9.369                      break;
   9.370 -                uninits = uninitsEntry.andSet(uninits);
   9.371 +                uninits.assign(uninitsEntry.andSet(uninits));
   9.372                  flowKind = FlowKind.SPECULATIVE_LOOP;
   9.373              } while (true);
   9.374              flowKind = prevFlowKind;
   9.375 -            inits = initsStart;
   9.376 -            uninits = uninitsStart.andSet(uninits);
   9.377 +            inits.assign(initsStart);
   9.378 +            uninits.assign(uninitsStart.andSet(uninits));
   9.379              resolveBreaks(tree, prevPendingExits);
   9.380              nextadr = nextadrPrev;
   9.381          }
   9.382 @@ -1852,12 +1872,12 @@
   9.383              pendingExits = new ListBuffer<AssignPendingExit>();
   9.384              int nextadrPrev = nextadr;
   9.385              scanExpr(tree.selector);
   9.386 -            Bits initsSwitch = inits;
   9.387 -            Bits uninitsSwitch = uninits.dup();
   9.388 +            final Bits initsSwitch = new Bits(inits);
   9.389 +            final Bits uninitsSwitch = new Bits(uninits);
   9.390              boolean hasDefault = false;
   9.391              for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
   9.392 -                inits = initsSwitch.dup();
   9.393 -                uninits = uninits.andSet(uninitsSwitch);
   9.394 +                inits.assign(initsSwitch);
   9.395 +                uninits.assign(uninits.andSet(uninitsSwitch));
   9.396                  JCCase c = l.head;
   9.397                  if (c.pat == null)
   9.398                      hasDefault = true;
   9.399 @@ -1875,8 +1895,8 @@
   9.400          }
   9.401          // where
   9.402              /** Add any variables defined in stats to inits and uninits. */
   9.403 -            private void addVars(List<JCStatement> stats, Bits inits,
   9.404 -                                        Bits uninits) {
   9.405 +            private void addVars(List<JCStatement> stats, final Bits inits,
   9.406 +                                        final Bits uninits) {
   9.407                  for (;stats.nonEmpty(); stats = stats.tail) {
   9.408                      JCTree stat = stats.head;
   9.409                      if (stat.hasTag(VARDEF)) {
   9.410 @@ -1889,11 +1909,11 @@
   9.411  
   9.412          public void visitTry(JCTry tree) {
   9.413              ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
   9.414 -            Bits uninitsTryPrev = uninitsTry;
   9.415 +            final Bits uninitsTryPrev = new Bits(uninitsTry);
   9.416              ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
   9.417              pendingExits = new ListBuffer<AssignPendingExit>();
   9.418 -            Bits initsTry = inits.dup();
   9.419 -            uninitsTry = uninits.dup();
   9.420 +            final Bits initsTry = new Bits(inits);
   9.421 +            uninitsTry.assign(uninits);
   9.422              for (JCTree resource : tree.resources) {
   9.423                  if (resource instanceof JCVariableDecl) {
   9.424                      JCVariableDecl vdecl = (JCVariableDecl) resource;
   9.425 @@ -1908,8 +1928,8 @@
   9.426              }
   9.427              scan(tree.body);
   9.428              uninitsTry.andSet(uninits);
   9.429 -            Bits initsEnd = inits;
   9.430 -            Bits uninitsEnd = uninits;
   9.431 +            final Bits initsEnd = new Bits(inits);
   9.432 +            final Bits uninitsEnd = new Bits(uninits);
   9.433              int nextadrCatch = nextadr;
   9.434  
   9.435              if (!resourceVarDecls.isEmpty() &&
   9.436 @@ -1925,8 +1945,8 @@
   9.437  
   9.438              for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   9.439                  JCVariableDecl param = l.head.param;
   9.440 -                inits = initsTry.dup();
   9.441 -                uninits = uninitsTry.dup();
   9.442 +                inits.assign(initsTry);
   9.443 +                uninits.assign(uninitsTry);
   9.444                  scan(param);
   9.445                  inits.incl(param.sym.adr);
   9.446                  uninits.excl(param.sym.adr);
   9.447 @@ -1936,8 +1956,8 @@
   9.448                  nextadr = nextadrCatch;
   9.449              }
   9.450              if (tree.finalizer != null) {
   9.451 -                inits = initsTry.dup();
   9.452 -                uninits = uninitsTry.dup();
   9.453 +                inits.assign(initsTry);
   9.454 +                uninits.assign(uninitsTry);
   9.455                  ListBuffer<AssignPendingExit> exits = pendingExits;
   9.456                  pendingExits = prevPendingExits;
   9.457                  scan(tree.finalizer);
   9.458 @@ -1958,8 +1978,8 @@
   9.459                      inits.orSet(initsEnd);
   9.460                  }
   9.461              } else {
   9.462 -                inits = initsEnd;
   9.463 -                uninits = uninitsEnd;
   9.464 +                inits.assign(initsEnd);
   9.465 +                uninits.assign(uninitsEnd);
   9.466                  ListBuffer<AssignPendingExit> exits = pendingExits;
   9.467                  pendingExits = prevPendingExits;
   9.468                  while (exits.nonEmpty()) pendingExits.append(exits.next());
   9.469 @@ -1969,10 +1989,10 @@
   9.470  
   9.471          public void visitConditional(JCConditional tree) {
   9.472              scanCond(tree.cond);
   9.473 -            Bits initsBeforeElse = initsWhenFalse;
   9.474 -            Bits uninitsBeforeElse = uninitsWhenFalse;
   9.475 -            inits = initsWhenTrue;
   9.476 -            uninits = uninitsWhenTrue;
   9.477 +            final Bits initsBeforeElse = new Bits(initsWhenFalse);
   9.478 +            final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
   9.479 +            inits.assign(initsWhenTrue);
   9.480 +            uninits.assign(uninitsWhenTrue);
   9.481              if (tree.truepart.type.hasTag(BOOLEAN) &&
   9.482                  tree.falsepart.type.hasTag(BOOLEAN)) {
   9.483                  // if b and c are boolean valued, then
   9.484 @@ -1980,12 +2000,12 @@
   9.485                  //    v is (un)assigned after b when true and
   9.486                  //    v is (un)assigned after c when true
   9.487                  scanCond(tree.truepart);
   9.488 -                Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
   9.489 -                Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
   9.490 -                Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
   9.491 -                Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
   9.492 -                inits = initsBeforeElse;
   9.493 -                uninits = uninitsBeforeElse;
   9.494 +                final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue);
   9.495 +                final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
   9.496 +                final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
   9.497 +                final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
   9.498 +                inits.assign(initsBeforeElse);
   9.499 +                uninits.assign(uninitsBeforeElse);
   9.500                  scanCond(tree.falsepart);
   9.501                  initsWhenTrue.andSet(initsAfterThenWhenTrue);
   9.502                  initsWhenFalse.andSet(initsAfterThenWhenFalse);
   9.503 @@ -1993,10 +2013,10 @@
   9.504                  uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
   9.505              } else {
   9.506                  scanExpr(tree.truepart);
   9.507 -                Bits initsAfterThen = inits.dup();
   9.508 -                Bits uninitsAfterThen = uninits.dup();
   9.509 -                inits = initsBeforeElse;
   9.510 -                uninits = uninitsBeforeElse;
   9.511 +                final Bits initsAfterThen = new Bits(inits);
   9.512 +                final Bits uninitsAfterThen = new Bits(uninits);
   9.513 +                inits.assign(initsBeforeElse);
   9.514 +                uninits.assign(uninitsBeforeElse);
   9.515                  scanExpr(tree.falsepart);
   9.516                  inits.andSet(initsAfterThen);
   9.517                  uninits.andSet(uninitsAfterThen);
   9.518 @@ -2005,16 +2025,16 @@
   9.519  
   9.520          public void visitIf(JCIf tree) {
   9.521              scanCond(tree.cond);
   9.522 -            Bits initsBeforeElse = initsWhenFalse;
   9.523 -            Bits uninitsBeforeElse = uninitsWhenFalse;
   9.524 -            inits = initsWhenTrue;
   9.525 -            uninits = uninitsWhenTrue;
   9.526 +            final Bits initsBeforeElse = new Bits(initsWhenFalse);
   9.527 +            final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
   9.528 +            inits.assign(initsWhenTrue);
   9.529 +            uninits.assign(uninitsWhenTrue);
   9.530              scan(tree.thenpart);
   9.531              if (tree.elsepart != null) {
   9.532 -                Bits initsAfterThen = inits.dup();
   9.533 -                Bits uninitsAfterThen = uninits.dup();
   9.534 -                inits = initsBeforeElse;
   9.535 -                uninits = uninitsBeforeElse;
   9.536 +                final Bits initsAfterThen = new Bits(inits);
   9.537 +                final Bits uninitsAfterThen = new Bits(uninits);
   9.538 +                inits.assign(initsBeforeElse);
   9.539 +                uninits.assign(uninitsBeforeElse);
   9.540                  scan(tree.elsepart);
   9.541                  inits.andSet(initsAfterThen);
   9.542                  uninits.andSet(uninitsAfterThen);
   9.543 @@ -2055,8 +2075,8 @@
   9.544  
   9.545          @Override
   9.546          public void visitLambda(JCLambda tree) {
   9.547 -            Bits prevUninits = uninits;
   9.548 -            Bits prevInits = inits;
   9.549 +            final Bits prevUninits = new Bits(uninits);
   9.550 +            final Bits prevInits = new Bits(inits);
   9.551              int returnadrPrev = returnadr;
   9.552              ListBuffer<AssignPendingExit> prevPending = pendingExits;
   9.553              try {
   9.554 @@ -2076,8 +2096,8 @@
   9.555              }
   9.556              finally {
   9.557                  returnadr = returnadrPrev;
   9.558 -                uninits = prevUninits;
   9.559 -                inits = prevInits;
   9.560 +                uninits.assign(prevUninits);
   9.561 +                inits.assign(prevInits);
   9.562                  pendingExits = prevPending;
   9.563              }
   9.564          }
   9.565 @@ -2088,17 +2108,17 @@
   9.566          }
   9.567  
   9.568          public void visitAssert(JCAssert tree) {
   9.569 -            Bits initsExit = inits.dup();
   9.570 -            Bits uninitsExit = uninits.dup();
   9.571 +            final Bits initsExit = new Bits(inits);
   9.572 +            final Bits uninitsExit = new Bits(uninits);
   9.573              scanCond(tree.cond);
   9.574              uninitsExit.andSet(uninitsWhenTrue);
   9.575              if (tree.detail != null) {
   9.576 -                inits = initsWhenFalse;
   9.577 -                uninits = uninitsWhenFalse;
   9.578 +                inits.assign(initsWhenFalse);
   9.579 +                uninits.assign(uninitsWhenFalse);
   9.580                  scanExpr(tree.detail);
   9.581              }
   9.582 -            inits = initsExit;
   9.583 -            uninits = uninitsExit;
   9.584 +            inits.assign(initsExit);
   9.585 +            uninits.assign(uninitsExit);
   9.586          }
   9.587  
   9.588          public void visitAssign(JCAssign tree) {
   9.589 @@ -2120,12 +2140,12 @@
   9.590              switch (tree.getTag()) {
   9.591              case NOT:
   9.592                  scanCond(tree.arg);
   9.593 -                Bits t = initsWhenFalse;
   9.594 -                initsWhenFalse = initsWhenTrue;
   9.595 -                initsWhenTrue = t;
   9.596 -                t = uninitsWhenFalse;
   9.597 -                uninitsWhenFalse = uninitsWhenTrue;
   9.598 -                uninitsWhenTrue = t;
   9.599 +                final Bits t = new Bits(initsWhenFalse);
   9.600 +                initsWhenFalse.assign(initsWhenTrue);
   9.601 +                initsWhenTrue.assign(t);
   9.602 +                t.assign(uninitsWhenFalse);
   9.603 +                uninitsWhenFalse.assign(uninitsWhenTrue);
   9.604 +                uninitsWhenTrue.assign(t);
   9.605                  break;
   9.606              case PREINC: case POSTINC:
   9.607              case PREDEC: case POSTDEC:
   9.608 @@ -2141,20 +2161,20 @@
   9.609              switch (tree.getTag()) {
   9.610              case AND:
   9.611                  scanCond(tree.lhs);
   9.612 -                Bits initsWhenFalseLeft = initsWhenFalse;
   9.613 -                Bits uninitsWhenFalseLeft = uninitsWhenFalse;
   9.614 -                inits = initsWhenTrue;
   9.615 -                uninits = uninitsWhenTrue;
   9.616 +                final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
   9.617 +                final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
   9.618 +                inits.assign(initsWhenTrue);
   9.619 +                uninits.assign(uninitsWhenTrue);
   9.620                  scanCond(tree.rhs);
   9.621                  initsWhenFalse.andSet(initsWhenFalseLeft);
   9.622                  uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
   9.623                  break;
   9.624              case OR:
   9.625                  scanCond(tree.lhs);
   9.626 -                Bits initsWhenTrueLeft = initsWhenTrue;
   9.627 -                Bits uninitsWhenTrueLeft = uninitsWhenTrue;
   9.628 -                inits = initsWhenFalse;
   9.629 -                uninits = uninitsWhenFalse;
   9.630 +                final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
   9.631 +                final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
   9.632 +                inits.assign(initsWhenFalse);
   9.633 +                uninits.assign(uninitsWhenFalse);
   9.634                  scanCond(tree.rhs);
   9.635                  initsWhenTrue.andSet(initsWhenTrueLeft);
   9.636                  uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
   9.637 @@ -2200,11 +2220,7 @@
   9.638                  attrEnv = env;
   9.639                  Flow.this.make = make;
   9.640                  startPos = tree.pos().getStartPosition();
   9.641 -                inits = new Bits();
   9.642 -                uninits = new Bits();
   9.643 -                uninitsTry = new Bits();
   9.644 -                initsWhenTrue = initsWhenFalse =
   9.645 -                    uninitsWhenTrue = uninitsWhenFalse = null;
   9.646 +
   9.647                  if (vars == null)
   9.648                      vars = new VarSymbol[32];
   9.649                  else
   9.650 @@ -2219,9 +2235,8 @@
   9.651              } finally {
   9.652                  // note that recursive invocations of this method fail hard
   9.653                  startPos = -1;
   9.654 -                inits = uninits = uninitsTry = null;
   9.655 -                initsWhenTrue = initsWhenFalse =
   9.656 -                    uninitsWhenTrue = uninitsWhenFalse = null;
   9.657 +                resetBits(inits, uninits, uninitsTry, initsWhenTrue,
   9.658 +                        initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse);
   9.659                  if (vars != null) for (int i=0; i<vars.length; i++)
   9.660                      vars[i] = null;
   9.661                  firstadr = 0;
    10.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Sun Apr 28 08:16:41 2013 +0100
    10.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed May 08 10:27:52 2013 +0100
    10.3 @@ -40,10 +40,9 @@
    10.4  import com.sun.tools.javac.code.Symbol.VarSymbol;
    10.5  import com.sun.tools.javac.code.Symtab;
    10.6  import com.sun.tools.javac.code.Type;
    10.7 -import com.sun.tools.javac.code.Type.ClassType;
    10.8  import com.sun.tools.javac.code.Type.MethodType;
    10.9  import com.sun.tools.javac.code.Types;
   10.10 -import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzer.*;
   10.11 +import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
   10.12  import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
   10.13  import com.sun.tools.javac.jvm.*;
   10.14  import com.sun.tools.javac.util.*;
   10.15 @@ -81,7 +80,7 @@
   10.16      private Env<AttrContext> attrEnv;
   10.17  
   10.18      /** the analyzer scanner */
   10.19 -    private LambdaAnalyzer analyzer;
   10.20 +    private LambdaAnalyzerPreprocessor analyzer;
   10.21  
   10.22      /** map from lambda trees to translation contexts */
   10.23      private Map<JCTree, TranslationContext<?>> contextMap;
   10.24 @@ -156,7 +155,7 @@
   10.25          make = TreeMaker.instance(context);
   10.26          types = Types.instance(context);
   10.27          transTypes = TransTypes.instance(context);
   10.28 -        analyzer = new LambdaAnalyzer();
   10.29 +        analyzer = new LambdaAnalyzerPreprocessor();
   10.30      }
   10.31      // </editor-fold>
   10.32  
   10.33 @@ -206,7 +205,7 @@
   10.34      public void visitClassDef(JCClassDecl tree) {
   10.35          if (tree.sym.owner.kind == PCK) {
   10.36              //analyze class
   10.37 -            analyzer.analyzeClass(tree);
   10.38 +            tree = analyzer.analyzeAndPreprocessClass(tree);
   10.39          }
   10.40          KlassInfo prevKlassInfo = kInfo;
   10.41          try {
   10.42 @@ -531,16 +530,25 @@
   10.43      /** Make an attributed class instance creation expression.
   10.44       *  @param ctype    The class type.
   10.45       *  @param args     The constructor arguments.
   10.46 +     *  @param cons     The constructor symbol
   10.47       */
   10.48 -    JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
   10.49 +    JCNewClass makeNewClass(Type ctype, List<JCExpression> args, Symbol cons) {
   10.50          JCNewClass tree = make.NewClass(null,
   10.51              null, make.QualIdent(ctype.tsym), args, null);
   10.52 -        tree.constructor = rs.resolveConstructor(
   10.53 -            null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil());
   10.54 +        tree.constructor = cons;
   10.55          tree.type = ctype;
   10.56          return tree;
   10.57      }
   10.58  
   10.59 +    /** Make an attributed class instance creation expression.
   10.60 +     *  @param ctype    The class type.
   10.61 +     *  @param args     The constructor arguments.
   10.62 +     */
   10.63 +    JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
   10.64 +        return makeNewClass(ctype, args,
   10.65 +                rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil()));
   10.66 +     }
   10.67 +
   10.68      private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym,
   10.69              DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
   10.70          String functionalInterfaceClass = classSig(targetType);
   10.71 @@ -1019,8 +1027,9 @@
   10.72       * This visitor collects information about translation of a lambda expression.
   10.73       * More specifically, it keeps track of the enclosing contexts and captured locals
   10.74       * accessed by the lambda being translated (as well as other useful info).
   10.75 +     * It also translates away problems for LambdaToMethod.
   10.76       */
   10.77 -    class LambdaAnalyzer extends TreeScanner {
   10.78 +    class LambdaAnalyzerPreprocessor extends TreeTranslator {
   10.79  
   10.80          /** the frame stack - used to reconstruct translation info about enclosing scopes */
   10.81          private List<Frame> frameStack;
   10.82 @@ -1047,10 +1056,10 @@
   10.83          private Map<ClassSymbol, Symbol> clinits =
   10.84                  new HashMap<ClassSymbol, Symbol>();
   10.85  
   10.86 -        private void analyzeClass(JCClassDecl tree) {
   10.87 +        private JCClassDecl analyzeAndPreprocessClass(JCClassDecl tree) {
   10.88              frameStack = List.nil();
   10.89              localClassDefs = new HashMap<Symbol, JCClassDecl>();
   10.90 -            scan(tree);
   10.91 +            return translate(tree);
   10.92          }
   10.93  
   10.94          @Override
   10.95 @@ -1154,7 +1163,7 @@
   10.96                      frameStack.head.addLocal(param.sym);
   10.97                  }
   10.98                  contextMap.put(tree, context);
   10.99 -                scan(tree.body);
  10.100 +                super.visitLambda(tree);
  10.101                  context.complete();
  10.102              }
  10.103              finally {
  10.104 @@ -1220,12 +1229,47 @@
  10.105                      };
  10.106                      fvc.scan(localCDef);
  10.107                  }
  10.108 -            }
  10.109 +        }
  10.110  
  10.111 +        /**
  10.112 +         * Method references to local class constructors, may, if the local
  10.113 +         * class references local variables, have implicit constructor
  10.114 +         * parameters added in Lower; As a result, the invokedynamic bootstrap
  10.115 +         * information added in the LambdaToMethod pass will have the wrong
  10.116 +         * signature. Hooks between Lower and LambdaToMethod have been added to
  10.117 +         * handle normal "new" in this case. This visitor converts potentially
  10.118 +         * effected method references into a lambda containing a normal "new" of
  10.119 +         * the class.
  10.120 +         *
  10.121 +         * @param tree
  10.122 +         */
  10.123          @Override
  10.124          public void visitReference(JCMemberReference tree) {
  10.125 -            scan(tree.getQualifierExpression());
  10.126 -            contextMap.put(tree, makeReferenceContext(tree));
  10.127 +            if (tree.getMode() == ReferenceMode.NEW
  10.128 +                    && tree.kind != ReferenceKind.ARRAY_CTOR
  10.129 +                    && tree.sym.owner.isLocal()) {
  10.130 +                MethodSymbol consSym = (MethodSymbol) tree.sym;
  10.131 +                List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
  10.132 +                Type classType = consSym.owner.type;
  10.133 +
  10.134 +                // Make new-class call
  10.135 +                List<JCVariableDecl> params = make.Params(ptypes, owner());
  10.136 +                JCNewClass nc = makeNewClass(classType, make.Idents(params));
  10.137 +                nc.pos = tree.pos;
  10.138 +
  10.139 +                // Make lambda holding the new-class call
  10.140 +                JCLambda slam = make.Lambda(params, nc);
  10.141 +                slam.descriptorType = tree.descriptorType;
  10.142 +                slam.targets = tree.targets;
  10.143 +                slam.type = tree.type;
  10.144 +                slam.pos = tree.pos;
  10.145 +
  10.146 +                // Now it is a lambda, process as such
  10.147 +                visitLambda(slam);
  10.148 +            } else {
  10.149 +                super.visitReference(tree);
  10.150 +                contextMap.put(tree, makeReferenceContext(tree));
  10.151 +            }
  10.152          }
  10.153  
  10.154          @Override
  10.155 @@ -1240,10 +1284,8 @@
  10.156                      }
  10.157                      localContext = localContext.prev;
  10.158                  }
  10.159 -                scan(tree.selected);
  10.160 -            } else {
  10.161 -                super.visitSelect(tree);
  10.162              }
  10.163 +            super.visitSelect(tree);
  10.164          }
  10.165  
  10.166          @Override
    11.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Sun Apr 28 08:16:41 2013 +0100
    11.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Wed May 08 10:27:52 2013 +0100
    11.3 @@ -1647,7 +1647,7 @@
    11.4          State dup() {
    11.5              try {
    11.6                  State state = (State)super.clone();
    11.7 -                state.defined = defined.dup();
    11.8 +                state.defined = new Bits(defined);
    11.9                  state.stack = stack.clone();
   11.10                  if (locks != null) state.locks = locks.clone();
   11.11                  if (debugCode) {
   11.12 @@ -1775,7 +1775,7 @@
   11.13          }
   11.14  
   11.15          State join(State other) {
   11.16 -            defined = defined.andSet(other.defined);
   11.17 +            defined.andSet(other.defined);
   11.18              Assert.check(stacksize == other.stacksize
   11.19                      && nlocks == other.nlocks);
   11.20              for (int i=0; i<stacksize; ) {
   11.21 @@ -1887,7 +1887,7 @@
   11.22      /** Set the current variable defined state. */
   11.23      public void setDefined(Bits newDefined) {
   11.24          if (alive && newDefined != state.defined) {
   11.25 -            Bits diff = state.defined.dup().xorSet(newDefined);
   11.26 +            Bits diff = new Bits(state.defined).xorSet(newDefined);
   11.27              for (int adr = diff.nextBit(0);
   11.28                   adr >= 0;
   11.29                   adr = diff.nextBit(adr+1)) {
    12.1 --- a/src/share/classes/com/sun/tools/javac/util/Bits.java	Sun Apr 28 08:16:41 2013 +0100
    12.2 +++ b/src/share/classes/com/sun/tools/javac/util/Bits.java	Wed May 08 10:27:52 2013 +0100
    12.3 @@ -1,5 +1,5 @@
    12.4  /*
    12.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
    12.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
    12.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.8   *
    12.9   * This code is free software; you can redistribute it and/or modify it
   12.10 @@ -27,6 +27,8 @@
   12.11  
   12.12  import java.util.Arrays;
   12.13  
   12.14 +import static com.sun.tools.javac.util.Bits.BitsOpKind.*;
   12.15 +
   12.16  /** A class for extensible, mutable bit sets.
   12.17   *
   12.18   *  <p><b>This is NOT part of any supported API.
   12.19 @@ -36,31 +38,114 @@
   12.20   */
   12.21  public class Bits {
   12.22  
   12.23 +    public enum BitsOpKind {
   12.24 +        INIT,
   12.25 +        CLEAR,
   12.26 +        INCL_BIT,
   12.27 +        EXCL_BIT,
   12.28 +        ASSIGN,
   12.29 +        AND_SET,
   12.30 +        OR_SET,
   12.31 +        DIFF_SET,
   12.32 +        XOR_SET,
   12.33 +        INCL_RANGE,
   12.34 +        EXCL_RANGE,
   12.35 +    }
   12.36 +
   12.37 +    //       ____________      reset    _________
   12.38 +    //      /  UNKNOWN   \   <-------- / UNINIT  \
   12.39 +    //      \____________/       |     \_________/
   12.40 +    //            |              |          |
   12.41 +    //            |assign        |          | any
   12.42 +    //            |        ___________      |
   12.43 +    //            ------> /  NORMAL   \ <----
   12.44 +    //                    \___________/     |
   12.45 +    //                            |         |
   12.46 +    //                            |         |
   12.47 +    //                            -----------
   12.48 +    //                               any
   12.49 +    private enum BitsState {
   12.50 +        /*  A Bits instance is in UNKNOWN state if it has been explicitly reset.
   12.51 +         *  It is possible to get to this state from any other by calling the
   12.52 +         *  reset method. An instance in the UNKNOWN state can pass to the
   12.53 +         *  NORMAL state after being assigned another Bits instance.
   12.54 +         */
   12.55 +        UNKNOWN,
   12.56 +        /*  A Bits instance is in UNINIT when it is created with the default
   12.57 +         *  constructor but it isn't explicitly reset. The main objective of this
   12.58 +         *  internal state is to save some memory.
   12.59 +         */
   12.60 +        UNINIT,
   12.61 +        /*  The normal state is reached after creating a Bits instance from an
   12.62 +         *  existing one or after applying any operation to an instance on UNINIT
   12.63 +         *  or NORMAL state. From this state a bits instance can pass to the
   12.64 +         *  UNKNOWN state by calling the reset method.
   12.65 +         */
   12.66 +        NORMAL;
   12.67 +
   12.68 +        static BitsState getState(int[] someBits, boolean reset) {
   12.69 +            if (reset) {
   12.70 +                return UNKNOWN;
   12.71 +            } else {
   12.72 +                if (someBits != unassignedBits) {
   12.73 +                    return NORMAL;
   12.74 +                } else {
   12.75 +                    return UNINIT;
   12.76 +                }
   12.77 +            }
   12.78 +        }
   12.79 +
   12.80 +    }
   12.81  
   12.82      private final static int wordlen = 32;
   12.83      private final static int wordshift = 5;
   12.84      private final static int wordmask = wordlen - 1;
   12.85  
   12.86 -    private int[] bits;
   12.87 +    public int[] bits = null;
   12.88 +    // This field will store last version of bits after every change.
   12.89 +    public int[] oldBits = null;
   12.90 +
   12.91 +    public BitsOpKind lastOperation = null;
   12.92 +
   12.93 +    private static final int[] unassignedBits = new int[0];
   12.94 +
   12.95 +    private BitsState currentState;
   12.96  
   12.97      /** Construct an initially empty set.
   12.98       */
   12.99      public Bits() {
  12.100 -        this(new int[1]);
  12.101 +        this(false);
  12.102 +    }
  12.103 +
  12.104 +    public Bits(Bits someBits) {
  12.105 +        this(someBits.dup().bits, BitsState.getState(someBits.bits, false));
  12.106 +    }
  12.107 +
  12.108 +    public Bits(boolean reset) {
  12.109 +        this(unassignedBits, BitsState.getState(unassignedBits, reset));
  12.110      }
  12.111  
  12.112      /** Construct a set consisting initially of given bit vector.
  12.113       */
  12.114 -    public Bits(int[] bits) {
  12.115 +    private Bits(int[] bits, BitsState initState) {
  12.116          this.bits = bits;
  12.117 +        this.currentState = initState;
  12.118 +        switch (initState) {
  12.119 +            case UNKNOWN:
  12.120 +                reset(); //this will also set current state;
  12.121 +                break;
  12.122 +            case NORMAL:
  12.123 +                Assert.check(bits != unassignedBits);
  12.124 +                lastOperation = INIT;
  12.125 +                break;
  12.126 +        }
  12.127      }
  12.128  
  12.129 -    /** Construct a set consisting initially of given range.
  12.130 +    /** This method will be called after any operation that causes a change to
  12.131 +     *  the bits. Subclasses can thus override it in order to extract information
  12.132 +     *  from the changes produced to the bits by the given operation.
  12.133       */
  12.134 -    public Bits(int start, int limit) {
  12.135 -        this();
  12.136 -        inclRange(start, limit);
  12.137 -    }
  12.138 +    public void changed() {}
  12.139  
  12.140      private void sizeTo(int len) {
  12.141          if (bits.length < len) {
  12.142 @@ -71,57 +156,110 @@
  12.143      /** This set = {}.
  12.144       */
  12.145      public void clear() {
  12.146 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.147 +        oldBits = bits;
  12.148 +        lastOperation = CLEAR;
  12.149          for (int i = 0; i < bits.length; i++) bits[i] = 0;
  12.150 +        changed();
  12.151 +        currentState = BitsState.NORMAL;
  12.152 +    }
  12.153 +
  12.154 +    public void reset() {
  12.155 +        bits = null;
  12.156 +        oldBits = null;
  12.157 +        currentState = BitsState.UNKNOWN;
  12.158 +    }
  12.159 +
  12.160 +    public boolean isReset() {
  12.161 +        return currentState == BitsState.UNKNOWN;
  12.162 +    }
  12.163 +
  12.164 +    public Bits assign(Bits someBits) {
  12.165 +        lastOperation = ASSIGN;
  12.166 +        oldBits = bits;
  12.167 +        bits = someBits.dup().bits;
  12.168 +        changed();
  12.169 +        currentState = BitsState.NORMAL;
  12.170 +        return this;
  12.171      }
  12.172  
  12.173      /** Return a copy of this set.
  12.174       */
  12.175 -    public Bits dup() {
  12.176 -        int[] newbits = new int[bits.length];
  12.177 -        System.arraycopy(bits, 0, newbits, 0, bits.length);
  12.178 -        return new Bits(newbits);
  12.179 +    private Bits dup() {
  12.180 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.181 +        Bits tmp = new Bits();
  12.182 +        if (currentState != BitsState.NORMAL) {
  12.183 +            tmp.bits = bits;
  12.184 +        } else {
  12.185 +            tmp.bits = new int[bits.length];
  12.186 +            System.arraycopy(bits, 0, tmp.bits, 0, bits.length);
  12.187 +        }
  12.188 +        currentState = BitsState.NORMAL;
  12.189 +        return tmp;
  12.190      }
  12.191  
  12.192      /** Include x in this set.
  12.193       */
  12.194      public void incl(int x) {
  12.195 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.196          Assert.check(x >= 0);
  12.197 +        oldBits = bits;
  12.198 +        lastOperation = INCL_BIT;
  12.199          sizeTo((x >>> wordshift) + 1);
  12.200          bits[x >>> wordshift] = bits[x >>> wordshift] |
  12.201              (1 << (x & wordmask));
  12.202 +        changed();
  12.203 +        currentState = BitsState.NORMAL;
  12.204      }
  12.205  
  12.206  
  12.207      /** Include [start..limit) in this set.
  12.208       */
  12.209      public void inclRange(int start, int limit) {
  12.210 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.211 +        oldBits = bits;
  12.212 +        lastOperation = INCL_RANGE;
  12.213          sizeTo((limit >>> wordshift) + 1);
  12.214 -        for (int x = start; x < limit; x++)
  12.215 +        for (int x = start; x < limit; x++) {
  12.216              bits[x >>> wordshift] = bits[x >>> wordshift] |
  12.217                  (1 << (x & wordmask));
  12.218 +        }
  12.219 +        changed();
  12.220 +        currentState = BitsState.NORMAL;
  12.221      }
  12.222  
  12.223      /** Exclude [start...end] from this set.
  12.224       */
  12.225      public void excludeFrom(int start) {
  12.226 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.227 +        oldBits = bits;
  12.228 +        lastOperation = EXCL_RANGE;
  12.229          Bits temp = new Bits();
  12.230          temp.sizeTo(bits.length);
  12.231          temp.inclRange(0, start);
  12.232 -        andSet(temp);
  12.233 +        internalAndSet(temp);
  12.234 +        changed();
  12.235 +        currentState = BitsState.NORMAL;
  12.236      }
  12.237  
  12.238      /** Exclude x from this set.
  12.239       */
  12.240      public void excl(int x) {
  12.241 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.242          Assert.check(x >= 0);
  12.243 +        oldBits = bits;
  12.244 +        lastOperation = EXCL_BIT;
  12.245          sizeTo((x >>> wordshift) + 1);
  12.246          bits[x >>> wordshift] = bits[x >>> wordshift] &
  12.247              ~(1 << (x & wordmask));
  12.248 +        changed();
  12.249 +        currentState = BitsState.NORMAL;
  12.250      }
  12.251  
  12.252      /** Is x an element of this set?
  12.253       */
  12.254      public boolean isMember(int x) {
  12.255 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.256          return
  12.257              0 <= x && x < (bits.length << wordshift) &&
  12.258              (bits[x >>> wordshift] & (1 << (x & wordmask))) != 0;
  12.259 @@ -130,38 +268,66 @@
  12.260      /** {@literal this set = this set & xs}.
  12.261       */
  12.262      public Bits andSet(Bits xs) {
  12.263 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.264 +        oldBits = bits;
  12.265 +        lastOperation = AND_SET;
  12.266 +        internalAndSet(xs);
  12.267 +        changed();
  12.268 +        currentState = BitsState.NORMAL;
  12.269 +        return this;
  12.270 +    }
  12.271 +
  12.272 +    private void internalAndSet(Bits xs) {
  12.273 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.274          sizeTo(xs.bits.length);
  12.275 -        for (int i = 0; i < xs.bits.length; i++)
  12.276 +        for (int i = 0; i < xs.bits.length; i++) {
  12.277              bits[i] = bits[i] & xs.bits[i];
  12.278 -        return this;
  12.279 +        }
  12.280      }
  12.281  
  12.282      /** this set = this set | xs.
  12.283       */
  12.284      public Bits orSet(Bits xs) {
  12.285 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.286 +        oldBits = bits;
  12.287 +        lastOperation = OR_SET;
  12.288          sizeTo(xs.bits.length);
  12.289 -        for (int i = 0; i < xs.bits.length; i++)
  12.290 +        for (int i = 0; i < xs.bits.length; i++) {
  12.291              bits[i] = bits[i] | xs.bits[i];
  12.292 +        }
  12.293 +        changed();
  12.294 +        currentState = BitsState.NORMAL;
  12.295          return this;
  12.296      }
  12.297  
  12.298      /** this set = this set \ xs.
  12.299       */
  12.300      public Bits diffSet(Bits xs) {
  12.301 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.302 +        oldBits = bits;
  12.303 +        lastOperation = DIFF_SET;
  12.304          for (int i = 0; i < bits.length; i++) {
  12.305              if (i < xs.bits.length) {
  12.306                  bits[i] = bits[i] & ~xs.bits[i];
  12.307              }
  12.308          }
  12.309 +        changed();
  12.310 +        currentState = BitsState.NORMAL;
  12.311          return this;
  12.312      }
  12.313  
  12.314      /** this set = this set ^ xs.
  12.315       */
  12.316      public Bits xorSet(Bits xs) {
  12.317 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.318 +        oldBits = bits;
  12.319 +        lastOperation = XOR_SET;
  12.320          sizeTo(xs.bits.length);
  12.321 -        for (int i = 0; i < xs.bits.length; i++)
  12.322 +        for (int i = 0; i < xs.bits.length; i++) {
  12.323              bits[i] = bits[i] ^ xs.bits[i];
  12.324 +        }
  12.325 +        changed();
  12.326 +        currentState = BitsState.NORMAL;
  12.327          return this;
  12.328      }
  12.329  
  12.330 @@ -187,6 +353,7 @@
  12.331       *  }</pre>
  12.332       */
  12.333      public int nextBit(int x) {
  12.334 +        Assert.check(currentState != BitsState.UNKNOWN);
  12.335          int windex = x >>> wordshift;
  12.336          if (windex >= bits.length) return -1;
  12.337          int word = bits[windex] & ~((1 << (x & wordmask))-1);
  12.338 @@ -202,17 +369,20 @@
  12.339      /** a string representation of this set.
  12.340       */
  12.341      public String toString() {
  12.342 -        char[] digits = new char[bits.length * wordlen];
  12.343 -        for (int i = 0; i < bits.length * wordlen; i++)
  12.344 -            digits[i] = isMember(i) ? '1' : '0';
  12.345 -        return new String(digits);
  12.346 +        if (bits.length > 0) {
  12.347 +            char[] digits = new char[bits.length * wordlen];
  12.348 +            for (int i = 0; i < bits.length * wordlen; i++)
  12.349 +                digits[i] = isMember(i) ? '1' : '0';
  12.350 +            return new String(digits);
  12.351 +        } else {
  12.352 +            return "[]";
  12.353 +        }
  12.354      }
  12.355  
  12.356      /** Test Bits.nextBit(int). */
  12.357      public static void main(String[] args) {
  12.358          java.util.Random r = new java.util.Random();
  12.359          Bits bits = new Bits();
  12.360 -        int dupCount = 0;
  12.361          for (int i=0; i<125; i++) {
  12.362              int k;
  12.363              do {
    13.1 --- a/test/tools/javac/api/TestJavacTaskScanner.java	Sun Apr 28 08:16:41 2013 +0100
    13.2 +++ b/test/tools/javac/api/TestJavacTaskScanner.java	Wed May 08 10:27:52 2013 +0100
    13.3 @@ -1,5 +1,5 @@
    13.4  /*
    13.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
    13.6 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
    13.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.8   *
    13.9   * This code is free software; you can redistribute it and/or modify it
   13.10 @@ -93,7 +93,7 @@
   13.11          System.out.println("#allMembers: " + numAllMembers);
   13.12  
   13.13          check(numTokens, "#Tokens", 1222);
   13.14 -        check(numParseTypeElements, "#parseTypeElements", 136);
   13.15 +        check(numParseTypeElements, "#parseTypeElements", 158);
   13.16          check(numAllMembers, "#allMembers", 52);
   13.17      }
   13.18  
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java	Wed May 08 10:27:52 2013 +0100
    14.3 @@ -0,0 +1,96 @@
    14.4 +/*
    14.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.  Oracle designates this
   14.11 + * particular file as subject to the "Classpath" exception as provided
   14.12 + * by Oracle in the LICENSE file that accompanied this code.
   14.13 + *
   14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.17 + * version 2 for more details (a copy is included in the LICENSE file that
   14.18 + * accompanied this code).
   14.19 + *
   14.20 + * You should have received a copy of the GNU General Public License version
   14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.23 + *
   14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.25 + * or visit www.oracle.com if you need additional information or have any
   14.26 + * questions.
   14.27 + */
   14.28 +
   14.29 +/*
   14.30 + * @test
   14.31 + * @bug 8012723
   14.32 + * @summary strictfp interface misses strictfp modifer on default method
   14.33 + * @run main CheckACC_STRICTFlagOnDefaultMethodTest
   14.34 + */
   14.35 +
   14.36 +import java.util.ArrayList;
   14.37 +import java.util.List;
   14.38 +import java.io.File;
   14.39 +import java.io.IOException;
   14.40 +
   14.41 +import com.sun.tools.classfile.ClassFile;
   14.42 +import com.sun.tools.classfile.ConstantPoolException;
   14.43 +import com.sun.tools.classfile.Descriptor;
   14.44 +import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
   14.45 +import com.sun.tools.classfile.Method;
   14.46 +
   14.47 +import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
   14.48 +
   14.49 +public class CheckACC_STRICTFlagOnDefaultMethodTest {
   14.50 +    private static final String AssertionErrorMessage =
   14.51 +        "All methods should have the ACC_STRICT access flag " +
   14.52 +        "please check output";
   14.53 +    private static final String offendingMethodErrorMessage =
   14.54 +        "Method %s of class %s doesn't have the ACC_STRICT access flag";
   14.55 +
   14.56 +    private List<String> errors = new ArrayList<>();
   14.57 +
   14.58 +    public static void main(String[] args)
   14.59 +            throws IOException, ConstantPoolException, InvalidDescriptor {
   14.60 +        new CheckACC_STRICTFlagOnDefaultMethodTest().run();
   14.61 +    }
   14.62 +
   14.63 +    private void run()
   14.64 +            throws IOException, ConstantPoolException, InvalidDescriptor {
   14.65 +        String testClasses = System.getProperty("test.classes");
   14.66 +        check(testClasses,
   14.67 +                "CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class");
   14.68 +        if (errors.size() > 0) {
   14.69 +            for (String error: errors) {
   14.70 +                System.err.println(error);
   14.71 +            }
   14.72 +            throw new AssertionError(AssertionErrorMessage);
   14.73 +        }
   14.74 +    }
   14.75 +
   14.76 +    void check(String dir, String... fileNames)
   14.77 +        throws
   14.78 +            IOException,
   14.79 +            ConstantPoolException,
   14.80 +            Descriptor.InvalidDescriptor {
   14.81 +        for (String fileName : fileNames) {
   14.82 +            ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName));
   14.83 +
   14.84 +            for (Method method : classFileToCheck.methods) {
   14.85 +                if ((method.access_flags.flags & ACC_STRICT) == 0) {
   14.86 +                    errors.add(String.format(offendingMethodErrorMessage,
   14.87 +                            method.getName(classFileToCheck.constant_pool),
   14.88 +                            classFileToCheck.getName()));
   14.89 +                }
   14.90 +            }
   14.91 +        }
   14.92 +    }
   14.93 +
   14.94 +    strictfp interface StrictfpInterface {
   14.95 +        default void default_interface_method() {}
   14.96 +        static void static_interface_method() {}
   14.97 +    }
   14.98 +
   14.99 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNewInnerImplicitArgs.java	Wed May 08 10:27:52 2013 +0100
    15.3 @@ -0,0 +1,82 @@
    15.4 +/*
    15.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.  Oracle designates this
   15.11 + * particular file as subject to the "Classpath" exception as provided
   15.12 + * by Oracle in the LICENSE file that accompanied this code.
   15.13 + *
   15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.17 + * version 2 for more details (a copy is included in the LICENSE file that
   15.18 + * accompanied this code).
   15.19 + *
   15.20 + * You should have received a copy of the GNU General Public License version
   15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.23 + *
   15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.25 + * or visit www.oracle.com if you need additional information or have any
   15.26 + * questions.
   15.27 + */
   15.28 +
   15.29 +/**
   15.30 + * @test
   15.31 + * @bug 8011591
   15.32 + * @summary BootstrapMethodError when capturing constructor ref to local classes
   15.33 + * @run testng MethodReferenceTestNewInnerImplicitArgs
   15.34 + */
   15.35 +
   15.36 +import org.testng.annotations.Test;
   15.37 +
   15.38 +import static org.testng.Assert.assertEquals;
   15.39 +
   15.40 +/**
   15.41 + * Test the case that a constructor has implicit parameters added to
   15.42 + * access local variables and that this constructor is used in a
   15.43 + * method reference.
   15.44 + * @author Robert Field
   15.45 + */
   15.46 +
   15.47 +@Test
   15.48 +public class MethodReferenceTestNewInnerImplicitArgs {
   15.49 +
   15.50 +
   15.51 +    static class S {
   15.52 +        String b;
   15.53 +        S(String s, String s2) { b = s + s2; }
   15.54 +    }
   15.55 +
   15.56 +    interface I {
   15.57 +        S m();
   15.58 +    }
   15.59 +
   15.60 +    interface I2 {
   15.61 +        S m(int i, int j);
   15.62 +    }
   15.63 +
   15.64 +    public static void testConstructorReferenceImplicitParameters() {
   15.65 +        String title = "Hey";
   15.66 +        String a2 = "!!!";
   15.67 +        class MS extends S {
   15.68 +            MS() {
   15.69 +                super(title, a2);
   15.70 +            }
   15.71 +        }
   15.72 +
   15.73 +        I result = MS::new;
   15.74 +        assertEquals(result.m().b, "Hey!!!");
   15.75 +
   15.76 +        class MS2 extends S {
   15.77 +            MS2(int x, int y) {
   15.78 +                super(title+x, a2+y);
   15.79 +            }
   15.80 +        }
   15.81 +
   15.82 +        I2 result2 = MS2::new;
   15.83 +        assertEquals(result2.m(8, 4).b, "Hey8!!!4");
   15.84 +    }
   15.85 +}

mercurial